Aliases and zero-downtime reindexing

Elasticsearch · Advanced · 11 min

Mappings and analyzers can't change in place, so every long-lived index eventually needs a reindex without downtime.

An alias is a secondary name pointing at one or more indices. Applications should read and write through an alias (products) rather than the concrete index (products-v3), because then you can switch the underlying index without touching code.

The zero-downtime workflow when a mapping must change:

  • create products-v4 with the new mappings and settings,
  • copy data with POST _reindex from products-v3 to products-v4 (it runs as a task; use slices for parallelism and wait_for_completion=false for long jobs),
  • catch up writes that happened during the copy (dual-write from the app, or reindex documents changed since the start),
  • swap the alias in one atomic POST _aliases request with a remove and an add action,
  • delete the old index when you're confident.

Aliases can also carry a filter (a per-tenant view) and routing. When an alias points at several indices, one can be marked is_write_index to receive writes; this is how rollover works for time-based indices.

_reindex can also transform documents with a script or ingest pipeline, and pull from a remote cluster for migrations. Remember it reads _source, so indices with _source disabled can't be reindexed.

Index templates (PUT _index_template/...) apply settings and mappings automatically to new indices matching a pattern, keeping versions consistent.

Example

PUT /products-v4
{ "mappings": { "properties": {
  "name":  { "type": "text", "analyzer": "english" },
  "price": { "type": "scaled_float", "scaling_factor": 100 } } } }

POST /_reindex?wait_for_completion=false&slices=auto
{ "source": { "index": "products-v3" }, "dest": { "index": "products-v4" } }
# { "task": "oTUltX4IQMOUUVeiohTt8A:12345" }
GET /_tasks/oTUltX4IQMOUUVeiohTt8A:12345

POST /_aliases
{ "actions": [
  { "remove": { "index": "products-v3", "alias": "products" } },
  { "add":    { "index": "products-v4", "alias": "products" } } ] }
# both actions apply atomically: clients never see a gap

GET /_alias/products

Remember

  • Applications use aliases, never concrete index names
  • Change mappings by creating a new index and _reindex
  • Swap aliases with one atomic _aliases request
  • Index templates apply mappings to new indices automatically

Watch out for

  • Hard-coding index names in the application, which makes every reindex a deployment.

Check yourself

  1. Why put remove and add in one _aliases request instead of two calls?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.elastic.co/guide/en/elasticsearch/reference/current/aliases.html