Elasticsearch Введение — 1.4 Масштабируемость и доступность

Предположим, мы хотим проиндексировать миллиард документов и обойтись только одним сервером возможно не получиться. Elasticsearch позволяет разделить данные на несколько машин, что позволяет выйти за пределы одной машины и поддерживать высокопроизводительные операции. Части на которые можно разбить данные называются осколками (shards) или шардами. По сути надо только сообщить Elasticsearch количество осколков, остальное он возьмет на себе.

В Elasticsearch есть два типа осколков — мастер и реплика. Мастер — тут происходит как запись так и чтение он главный. Реплика — это точная копия мастера с нее можно только читать. В случае если мастер выходит из строя реплика становиться мастером. Собственно, так обеспечивается обработка отказа. Поскольку реплики являются точными копиями можно обрабатывать запрос, как с мастера, так и с реплики что увеличивает количество одновременных запросов, которые Elasticsearch может обработать.

Поскольку индекс распределяется по нескольким осколкам, запрос к индексу выполняется параллельно по всем осколкам. Затем результаты каждого осколка собираются и отправляются обратно клиенту. В результате получаем значительное повышение производительности.

Связь между узлом, индексом и осколком

Шардинг часто является запутанной темой, если вы еще не сталкивались с Elasticsearch. Примеры наше все, на них мы наглядно рассмотрим как работает шардинг.

Три осколка без реплик

Начнем с индекса esintroduction с тремя осколками. Распределение осколков в кластере из трех узлов выглядит следующим образом:

Поскольку у нас пока только три осколка они равномерно распределены по узлам, когда новые документы будут индексироваться, данные так же будут распространяться на три узла.

Шесть осколков без реплик

Поскольку у нас только три узла, каждый узел возьмет на себя по два осколка:

Если вдруг эти три машины не будут справляться с нагрузкой, можно будет легко добавить еще 3 машины и осколки автоматически мигрируют на них, получиться  уже 6 узлов с одним осколком на борту.

Шесть осколков одна реплика

Давайте рассмотрим случай с шестью осколками и одной репликой. По факту получается у нас есть 6 мастер осколков и 6 реплик, всего 12 осколков. Поскольку у нас только три узла  и двенадцать осколков, каждый узел теперь будет содержать четыре осколка. Зелеными квадратиками помечены реплики.

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

Распределенный поиск

Одна из причин почему запросы в Elasticsearch работают так быстро состоит в том что они распределенные. Несколько осколков действуют как один индекс. Поиск запроса по индексу выполняется параллельно по всем осколкам.

Давайте рассмотрим пример: на рисунке ниже, у нас есть кластер с двумя узлами в которых находятся осколки с репликами:

Предположим что в индексе храниться 100 документов, соответственно по 50 в каждом осколке. И вы хотите запросить все документы, содержащие слово Elasticsearch. Запрос будет выполнен параллельно на S0 и S1. Результат собирается со всех осколков и отправляется обратно клиенту. Таким образом можно добиться ошеломительной производительности. Например в одном эксперименте было проиндексировано порядка 100 миллионов документов в распределенном кластере. Что самое интересно ответ на запросы редко превышали 50 миллисекунд. Добиться такого результата на одном сервере очень сложно если вообще возможно (нужен очень очень шустрый сервер).

Отказоустойчивость

Elasticsearch автоматически обрабатывает отказы . Допустим, у нас есть индекс с двумя осколками и одной репликой. На следующей диаграмме осколки, представленные сплошной линией, являются мастерами, а осколки в пунктирной линии — это репликами:

Как показано на предыдущей диаграмме, изначально мы имеем кластер с двумя узлами. Поскольку индекс имеет два осколка и одну реплику, осколки распределены по двум узлам. Чтобы обеспечить доступность, мастера и реплики не существуют на одном узле. Если если упадут оба сервера данные не будут доступны. Допустим мы добавили еще два узла:

Теперь кластер содержит 4 узла, осколки автоматически назначаются новым узлам. Каждый узел теперь содержит по одному осколку либо мастер, либо реплику. Предположим что Node2, который содержит мастер осколок S1, падает:

Поскольку S1 был мастером, Node3 с репликой S1 становиться мастером, заменяя упавший S1. Чтобы обеспечить коэффициент реплики 1, копия осколка S1 создается на Node1. Этот процесс известен как перебалансировка кластера.

В зависимости от приложения количество создаваемых осколков может быть настроено при создании индекса. Процесс перебалансировки осколков на другие узлы полностью прозрачен для пользователя и автоматически обрабатывается Elasticsearch.