КатегорииElasticsearch

Elasticsearch — Урок 3.9 Маршрутизация или в поисках шарда

Ранее мы обсуждали, что индекс может состоять из одного или нескольких осколков (shards). Во время индексации идентификатор документа используется для определения того, к какому осколку отнести документ, используя следующую формулу:

hash(document_id) % no_of_shards

То же самое справедливо при запросе документа, используется эта же формула для определения осколка:

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

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

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

Во время индексирования вы должны указать идентификатор, который будет использоваться для определения осколка. Вместо использования идентификатора документа значение маршрутизации используется для определения осколка. Например, если все заказы индексируются с использованием идентификатора пользователя в качестве значения маршрутизации, в таком случае запросы с использованием user_id будут выполняться на одном шарде.

Задать обязательную маршрутизацию можно так:

 PUT example3/_mapping/order
 {
  "_routing": {
     "required": true
   },
   "properties": {
     "order_id": {
       "type": "text"
     },
     "user_id": {
       "type": "keyword"
     },
     "order_total": {
       "type": "integer"
     }
   }
 }

Теперь мы можем проиндексировать документ и установить маршрутизацию следующим образом:

 PUT example3/order/1?routing=user1
 {
   "order_id": "23y86",
   "user_id": "user1",
   "order_total": 15
 }

Обратите внимание, как мы устанавливали маршрутизацию в URL-адресе, при добавлении заказа. Если значение маршрутизации не указано, произойдет ошибка. Мы можем получить документ заказа, который мы только что проиндексировали, так:

GET example3/order/1?routing=user1

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

Данная техника позволяет убрать излишнюю нагрузку на кластер, но использовать ее стоит очень аккуратно.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *