-
Notifications
You must be signed in to change notification settings - Fork 124
Description
Summary
Add support for zero-downtime schema migrations using RediSearch index aliases instead of the current DROP+CREATE approach.
Problem
The current migration system (Migrator.run()) detects schema changes and performs:
FT.DROPINDEXon the existing indexFT.CREATEwith the new schema
This causes downtime because queries fail while the index is being recreated and data is being reindexed.
Proposed Solution
Use RediSearch aliases (FT.ALIASADD, FT.ALIASUPDATE) to enable atomic index switching:
Index Naming Convention
Real index: {prefix}:{model}:index:v1, {prefix}:{model}:index:v2, ...
Alias: {prefix}:{model}:index (what queries use)
Migration Flow
- Create new versioned index (e.g.,
idx:Product:v2) with updated schema - Reindex/copy documents to new index (queries continue hitting v1 via alias)
- Atomically switch alias:
FT.ALIASUPDATE idx:Product idx:Product:v2 - Drop old index
idx:Product:v1
Implementation Requirements
-
Version tracking - Store current version in Redis key (e.g.,
{prefix}:{model}:index:version) -
Initial setup - First migration creates
v1index and adds alias pointing to it -
Model queries - No change needed; already use
Meta.index_namewhich becomes the alias -
New migration commands:
om migrate run --zero-downtime- Use alias-based migrationom migrate status- Show current index version and alias target
-
Background reindexing - Copy documents from old index to new (may need batching for large datasets)
Key Redis Commands
FT.ALIASADD <alias> <index> # Create alias (first time)
FT.ALIASUPDATE <alias> <index> # Atomic switch to new index
FT.ALIASDEL <alias> # Delete alias
Benefits
- Zero downtime during schema migrations
- Queries continue working throughout migration
- Atomic switchover (no partial state)
- Easy rollback (switch alias back to previous version)
Considerations
- Increased Redis memory during migration (two indexes exist temporarily)
- Reindexing time depends on dataset size
- Need to handle concurrent writes during migration
References
- RediSearch Alias Documentation
- Proof of concept tested in QA:
.ai/qa_alias_migration.py