Шарды, реплики и кластер

Разбираем, как Elasticsearch распределяет данные по машинам и переживает отказ части серверов.

Шард — часть индекса, самостоятельный кусок данных; реплика — его копия; кластер — группа узлов, между которыми всё это распределено.

Зачем делить индекс

Индекс на терабайт не поместится и не будет искаться быстро на одной машине. Поэтому ES режет индекс на части — шарды — и раскладывает их по разным узлам (серверам). Поиск идёт параллельно по всем шардам, а данные масштабируются добавлением машин.

Первичные шарды и реплики

ПонятиеСмысл
Первичный шард (primary)оригинальная часть данных индекса
Реплика (replica)точная копия первичного шарда на другом узле
Узел (node)один экземпляр ES (обычно один сервер)
Кластерсовокупность узлов, работающих вместе

Число первичных шардов задаётся при создании индекса и потом не меняется (данные распределяются по ним хешированием id). Число реплик можно менять в любой момент.

Как это выглядит

  Индекс products: 2 первичных шарда, 1 реплика на каждый

   Узел A           Узел B           Узел C
  +--------+       +--------+       +--------+
  | P0     |       | P1     |       | R0     |
  | R1     |       | R0 ... |       | R1 ... |
  +--------+       +--------+       +--------+

  P = primary (первичный), R = реплика
  Реплика всегда на ДРУГОМ узле, чем её первичный шард

Что дают реплики

  • Отказоустойчивость. Упал узел с первичным шардом — реплика на другом узле становится первичной, данные не потеряны.
  • Пропускная способность чтения. Поисковые запросы могут обслуживаться и первичным шардом, и репликами — нагрузка распределяется.

Как работает под капотом

При индексации документа ES вычисляет, в какой первичный шард он попадёт: shard = hash(_id) % число_первичных_шардов. Документ пишется в первичный шард, затем копируется в его реплики. При поиске координирующий узел рассылает запрос по одному экземпляру каждого шарда (первичному или реплике — что свободнее), собирает частичные результаты и сливает их. Master-узел следит за состоянием кластера и при отказе узла переназначает шарды, повышая реплику до первичной. Поэтому кластер из правильно настроенных реплик переживает падение отдельных машин без простоя и потери данных.

Частые ошибки

  • Слишком много мелких шардов (over-sharding). Каждый шард — это накладные расходы. Тысячи крошечных шардов перегружают кластер. Ориентир — десятки гигабайт на шард, а не мегабайты.
  • Один узел и реплики. На одноузловом кластере реплики не размещаются (копия должна быть на другом узле) — индекс будет в статусе yellow. Это нормально для разработки, но не для прода.
  • Менять число первичных шардов на лету. Нельзя: оно фиксируется при создании. Чтобы изменить — reindex в новый индекс.

Итоги

  • Индекс делится на первичные шарды (распределяются по узлам), у каждого есть реплики-копии.
  • Реплики дают отказоустойчивость и масштабируют чтение; всегда лежат на других узлах.
  • Число первичных шардов неизменно после создания; реплики можно менять; избегайте over-sharding.
Проверьте себя
1. Что такое реплика шарда?
AЧасть индекса с уникальными данными
BТочная копия первичного шарда, размещённая на другом узле для отказоустойчивости и масштабирования чтения
CРезервная копия всего кластера на диск
DОтдельный индекс
2. Что можно менять у существующего индекса, а что нет?
AМожно менять и число первичных шардов, и число реплик
BЧисло первичных шардов фиксировано после создания, а число реплик можно менять
CНичего менять нельзя
DМожно менять только число первичных шардов