Когда мы начинаем использовать Elasticsearch, мы должны понимать некоторые важные концепции. Понимание этих концепций очень важно для нас, чтобы использовать стек Elastic в будущем. В сегодняшней статье давайте сначала представим эластичный стексамое важноенекоторые концепции.
Во-первых, давайте взглянем на следующую картинку:
Cluster
Кластер также означает кластер. Кластер Elasticsearch состоит из одного или нескольких узлов, которые можно определить по имени кластера. Обычно имя кластера можно задать в файле конфигурации в Elasticsearch. По умолчанию, если наш Elasticsearch уже запущен, он автоматически создаст кластер под названием «elasticsearch». Мы можем настроить имя нашего кластера в config/elasticsearch.yml:
Кластер Elasticsearch выглядит следующим образом:
Мы можем пройти:
GET _cluster/state
чтобы получить статус всего кластера. Это состояние может быть изменено только главным узлом. Результат, возвращаемый вышеуказанным интерфейсом:
{
"cluster_name": "elasticsearch",
"compressed_size_in_bytes": 1920,
"version": 10,
"state_uuid": "rPiUZXbURICvkPl8GxQXUA",
"master_node": "O4cNlHDuTyWdDhq7vhJE7g",
"blocks": {},
"nodes": {...},
"metadata": {...},
"routing_table": {...},
"routing_nodes": {...},
"snapshots": {...},
"restore": {...},
"snapshot_deletions": {...}
}
node
Один экземпляр Elasticsearch. В большинстве сред каждый узел работает на отдельной машине или виртуальной машине. Если каждый файл конфигурации elasticsearch.yml имеет одинаковое имя cluster.name и находится в одной сети, то они автоматически образуют кластер. Кластер состоит из одного или нескольких узлов. В тестовой среде я могу запустить несколько узлов на сервере. При фактическом развертывании в большинстве случаев по-прежнему необходимо запускать узел на сервере.
По роли узла его можно разделить на следующие типы:
-
master-eligible: может использоваться в качестве главного узла. Став главным узлом, он может управлять настройками и изменениями всего кластера: создавать, обновлять, удалять индексы, добавлять или удалять узлы, назначать узлы узлам.
-
данные: узел данных
-
прием: доступ к данным (например,pipepline)
-
machine learning (Gold/Platinum License
В общем, узел может иметь одну или несколько из вышеперечисленных функций. Мы можем определить его в командной строке или в файле конфигурации Elasticsearch (Elasticsearch.yml):
Тип узла | Параметры конфигурации | По умолчанию |
---|---|---|
master-eligible | node.master | true |
data | node.data | true |
ingest | node.ingest | true |
machine learning | node.ml | true (кроме выпусков OSS) |
Вы также можете заставить узел выполнять исключительные функции и роли. Если указанные выше параметры конфигурации узла не имеют никакой конфигурации, то мы можем считать этот узел Координирующим узлом. В этом случае он может принимать внешние запросы и перенаправлять их на соответствующие узлы для обработки.
В реальном использовании мы можем отправить запрос на узел данных, но не на главный узел.
Во всей эластичной архитектуре связь между узлом данных и кластером выражается следующим образом:
Document
Elasticsearch ориентирован на документы, а это означает, что наименьшая единица данных, которые вы индексируете или ищете, является документом. Документы имеют несколько важных свойств в Elasticsearch:
-
Это независимо. Документ содержит поля (имена) и их значения.
-
Он может быть многослойным. Думайте об этом как о документе в документе. Значение поля может быть таким же простым, как значение поля местоположения может быть строкой. Он также может содержать другие поля и значения. Например, поле местоположения может содержать город и почтовый адрес.
-
Гибкая структура. Ваши документы не зависят от предопределенной схемы. Например, не для всех событий требуется значение описания, поэтому это поле можно полностью опустить. Но для этого могут потребоваться новые поля, такие как широта и долгота местоположения.
Документы обычно представляют собой JSON-представление данных. JSON через HTTP — это наиболее широко используемый способ связи с Elasticsearch, и именно его мы используем в этой книге. Например, событие на вашем веб-сайте встреч может быть представлено в следующем документе:
{
"name": "Elasticsearch Denver",
"organizer": "Lee",
"location": "Denver, Colorado, USA"
}
Многие думают, что документ сравнивают с реляционной базой данных, он соответствует каждой записи в ней.
type
Типы — это логические контейнеры для документов, так же как таблицы — это контейнеры для строк. Вы помещаете документы с разной структурой (схемой) в разные типы. Например, вы можете использовать один тип для определения групп агрегации, а другой — для событий, когда собираются люди.
Каждый тип определения поля называется картой. Например, имя будет сопоставлено со строкой, а поле геолокации под местоположением будет сопоставлено со специальным типом geo_point. (Мы рассмотрим, как использовать геопространственные данные, в Приложении A.) Каждое поле обрабатывается по-разному. Например, вы ищете слово в поле имени, а затем ищете группы по местоположению, чтобы найти группы поблизости от того места, где вы живете.
Многие думают, что Elasticsearch не имеет схемы. Все даже думают, что база данных в Elasticsearch не нуждается в отображении. На самом деле это неправильная концепция. Правильное понимание schemaless в Elasticsearch заключается в том, что нам не нужно заранее определять таблицу в реляционной базе данных, чтобы использовать базу данных. В Elasticsearch мы можем писать напрямую в указанный нами индекс, не начиная определять сопоставление. Отображение этого индекса создается динамически. Каждый тип данных элемента данных в нем динамически идентифицируется. Например, время, строки и т. д., хотя некоторые типы данных по-прежнему необходимо настраивать вручную, например, geo_point и другие данные о географическом местоположении. Кроме того, это также имеет значение того же типа, мы можем добавлять новые элементы данных в будущий ввод данных, тем самым создавая новое отображение. Это также динамически регулируется.
из-за некоторыхпричина, После Elasticsearch 6.0 индекс может содержать только один тип. Причина этого в том, что поля с одинаковыми именами в разных типах сопоставления одного и того же индекса одинаковы; в индексе Elasticsearch поля с одинаковыми именами в разных типах сопоставления поддерживаются одним и тем же полем в Lucene. По умолчанию это _doc. В следующей версии 8.0 шрифт будет полностью удален.
index
В Elasticsearch индекс — это набор документов.
Каждый Индекс состоит из одного или нескольких документов, и эти документы могут быть распределены по разным сегментам.
Многие думают, что индекс похож на базу данных в реляционной базе данных. В этом утверждении есть доля правды, но это не совсем то же самое. Одна из важных причин заключается в том, что документы в Elasticsearch могут иметь объектную и вложенную структуры. Индекс — это логическое пространство имен, которое сопоставляется с одним или несколькими первичными осколками и может иметь ноль или более осколков реплик.
Для индекса многоузлового облачного хранилища его структура больше похожа на следующую:
Всякий раз, когда приходит документ, вычисление хэша будет автоматически выполняться в соответствии с идентификатором документа и сохраняться в вычисляемом экземпляре сегмента.Этот результат может сделать все сегменты более сбалансированными для хранения, а некоторые сегменты не будут очень заняты.
shard_num = hash(_routing) % num_primary_shards
По умолчанию _routing выше является одновременно _id документа. Если естьroutingучастие, то эти документы могут храниться только в определенном сегменте, преимущество этого в том, что в некоторых случаях мы можем быстро синтезировать нужные нам результаты без необходимости получать запросы через узлы. Из приведенной выше формулы также видно, что номер нашего шарда нельзя динамически изменять, иначе в будущем соответствующий номер шарда не будет найден. Следует отметить, что,Количество реплик может быть динамически изменено.
shard
Поскольку Elasticsearch — это распределенная поисковая система, индексы часто разбиваются на элементы, называемые осколками, которые распределяются по нескольким узлам. Elasticsearch автоматически управляет расположением этих осколков. Он также перебалансирует осколки по мере необходимости, поэтому пользователям не нужно беспокоиться о деталях.
Индекс может хранить большие объемы данных за пределами аппаратных ограничений одного узла. Например, индекс с 1 миллиардом документов занимает 1 ТБ дискового пространства, а ни у одного узла нет такого большого дискового пространства, или один узел обрабатывает поисковые запросы и отвечает слишком медленно.
Для решения этой проблемы Elasticsearch предоставляет возможность разделить индекс на несколько частей, которые называются осколками. При создании индекса вы можете указать желаемое количество осколков. Каждый сегмент сам по себе является полнофункциональным и независимым «индексом», который можно разместить на любом узле кластера.
Разделение важно по двум основным причинам:
-
Позволяет горизонтально разделить/расширить емкость контента
-
Позволяет выполнять распределенные параллельные операции поверх сегментов (возможно, на нескольких узлах), повышая производительность/пропускную способность.
Существует два типа осколков: основной осколок и осколок-реплика.
-
Основной сегмент: каждый документ хранится в основном шаре. При индексировании документа он сначала индексирует первичный шар, затем все реплики этого шарда. Индекс может содержать один или несколько основных сегментов (по умолчанию 5). Это число определяет масштабируемость индекса относительно размера данных индекса. После создания индекса количество первичных сегментов в индексе изменить нельзя.
-
Осколок реплики: каждый основной осколок может иметь ноль или более реплик. Реплика — это реплика основного шарда, которая служит двум целям: Увеличение отказоустойчивости: в случае основного сбоя сегменты реплик могут быть повышены до основных сегментов.
Улучшенная производительность: запросы на получение и поиск могут обрабатываться осколками мастера или реплики.
По умолчанию каждый основной сегмент имеет одну реплику, но количество реплик может динамически изменяться в существующем индексе. Осколок реплики никогда не запускается на том же узле, что и его основной осколок.
На следующем рисунке показано, что индекс имеет 5 сегментов и 1 реплику.
Мы можем установить соответствующее значение сегмента для каждого индекса:
curl -XPUT http://localhost:9200/another_user?pretty -H 'Content-Type: application/json' -d '
{
"settings" : {
"index.number_of_shards" : 2,
"index.number_of_replicas" : 1
}
}'
Например, в приведенном выше REST-интерфейсе мы установили 2 шарда для индекса other_user, и есть реплика. Как только количество осколков установлено, мы не можем его изменить. Это связано с тем, что Elasticsearch будет иметь этот номер и будет выделять соответствующий документ соответствующему осколку в соответствии с идентификатором каждого документа и количеством осколков. Если этот номер изменить позже, соответствующий осколок может не быть найден при каждом поиске.
Мы можем просмотреть настройки в нашем индексе через следующий интерфейс:
curl -XGET http://localhost:9200/twitter/_settings?pretty
Выше мы можем получить информацию о настройке индекса Twitter:
{
"twitter" : {
"settings" : {
"index" : {
"creation_date" : "1565618906830",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "rwgT8ppWR3aiXKsMHaSx-w",
"version" : {
"created" : "7030099"
},
"provided_name" : "twitter"
}
}
}
}
replica
По умолчанию Elasticsearch создает пять основных сегментов и одну реплику для каждого индекса. Это означает, что каждый индекс будет содержать пять первичных сегментов, а каждый сегмент будет иметь одну реплику.
Выделение нескольких сегментов и реплик — это суть дизайна функции распределенного поиска, обеспечивающей высокую доступность и быстрый доступ к документам в индексе. Основное различие между первичными осколками и репликами заключается в том, что только первичные осколки могут принимать запросы на индексирование. И реплика, и первичные сегменты могут обслуживать запросы запросов.
На приведенной выше диаграмме у нас есть кластер Elasticsearch, состоящий из двух узлов с конфигурацией сегментирования по умолчанию. Elasticsearch автоматически распределяет пять основных сегментов по двум узлам. Существует сегмент реплики, соответствующий каждому основному сегменту, но расположение этих сегментов реплик полностью отличается от расположения основных сегментов. Опять же, подумайте о заданиях.
Позвольте уточнить: имейте в виду, что значение number_of_shards относится к индексу, а не ко всему кластеру. Это значение указывает количество сегментов на индекс (а не общее количество основных сегментов в кластере).
Мы можем получить информацию о работоспособности индекса через следующий интерфейс:
http://localhost:9200/_cat/indices/twitter
Приведенный выше интерфейс может возвращать следующую информацию:
Далее запрос, мы видим:
Если индекс отображается красным цветом, это означает, что некоторые узлы этого индекса сломаны, а к некоторым шардам и их соответствующим репликам нет нормального доступа. Если он зеленый, это означает, что у каждого сегмента индекса есть резервная копия, и эта резервная копия успешно реплицирована в соответствующий сегмент реплики. Если один из узлов выйдет из строя, будет работать реплика соответствующего другого узла или его основного сегмента, так что потери данных не произойдет.
Следующий шаг: Если вы хотите узнать больше о хранилище данных Lucene в Shard, вы можете прочитать "Elasticsearch: инвертированный индекс, doc_values и источник".