Elasticsearch — это мощная система распределенного поиска и анализа данных с открытым исходным кодом, которая в настоящее время используется многими отечественными интернет-компаниями, включая Ctrip, Didi, Toutiao, Ele.me, 360 Security, Xiaomi, vivo и др.
Помимо поиска в сочетании с Kibana, Logstash и Beats, Elastic Stack также широко используется в области анализа больших данных в режиме, близком к реальному времени, включая анализ логов, мониторинг показателей, информационную безопасность и другие области.
Он может помочь вам исследовать огромные объемы структурированных и неструктурированных данных, создавать визуальные отчеты по запросу, устанавливать пороговые значения сигналов тревоги для мониторинга данных и даже автоматически выявлять нештатные ситуации с помощью технологии машинного обучения.
Сегодня мы сначала представим базовый принцип работы ElasticSearch сверху вниз, а затем снизу вверх и попытаемся ответить на следующие вопросы:
Почему мой поиск *foo-bar* не соответствует foo-bar ?
Почему добавление дополнительных файлов приводит к сжатию индекса?
Почему ElasticSearch занимает много памяти?
Диаграмма ElasticSearch
версия эластичного поиска:эластичный поиск-2.2.0.
①Кластеры в облаке
Как показано ниже:
② Ящики в кластере
Каждая белая квадратная рамка внутри облака представляет собой узел — Node.
③ Между узлами
Непосредственно на одном или нескольких узлах несколько маленьких зеленых квадратов объединяются для формирования индекса ElasticSearch.
④Маленький квадратик на указателе
Под индексом маленькие зеленые квадратики, распределенные по множеству узлов, называются осколками — shards.
⑤Осколок=Индекс Lucene
Шард ElasticSearch по сути является индексом Lucene.
Lucene — это библиотека полнотекстового поиска (есть много других), а ElasticSearch построен на основе Lucene.
Большая часть последующего рассказа на самом деле посвящена тому, как ElasticSearch работает поверх Lucene.
Графический Lucene
Мини-указатель: сегмент
В Lucene есть много небольших сегментов, мы можем думать о них как о мини-индексе внутри Lucene.
Внутри сегмента
Внутри Segment есть много структур данных, как показано на рисунке выше:
Inverted Index
Stored Fields
Document Values
Cache
Самый важный инвертированный индекс
Как показано ниже:
Инвертированный индекс в основном состоит из двух частей:
Упорядоченный словарь данных (включая слово Термин и его частоту).
Проводки, соответствующие слову Term (т.е. файлу, в котором существует слово).
Когда мы ищем, мы сначала разбираем содержимое поиска, а затем находим соответствующий термин в словаре, чтобы найти содержимое файла, связанное с поиском.
①Запрос "Ярость"
Как показано ниже:
②Автозаполнение (префикс автозаполнения)
Если вы хотите найти буквы, начинающиеся с буквы «с», вы можете просто выполнить двоичный поиск (бинарный поиск), чтобы найти такие слова, как «выбор», «приход» в таблице инвертированного индекса (термин).
③ дорогой поиск
Если вы хотите найти все слова, содержащие «наши» буквы, система сканирует весь инвертированный индекс, что очень дорого.
В этом случае, если мы хотим выполнить оптимизацию, проблема, с которой мы сталкиваемся, заключается в том, как сгенерировать подходящий термин.
④Трансформация проблемы
Как показано ниже:
Для проблем, подобных приведенным выше, у нас может быть несколько возможных решений:
*suffix→xiffus*, если мы хотим использовать суффикс в качестве условия поиска, мы можем сделать обратное для Term.
(60.6384, 6.5017)→ u4u8gyykk, для информации о местоположении GEO его можно преобразовать в Hash GEO.
123→{1-сотня, 12-десяток, 123}, для простых чисел можно сгенерировать многоформенный термин.
⑤ Исправить орфографические ошибки
Библиотека Python генерирует древовидный конечный автомат для слов с информацией об орфографических ошибках, устраняя орфографические ошибки.
⑥ Поиск поля в сохраненном поле
Когда мы хотим найти файлы, содержащие определенное содержимое заголовка, инвертированный индекс не может решить эту проблему очень хорошо, поэтому Lucene предоставляет другую структуру данных Stored Fields для решения этой проблемы.
По сути, Stored Fields — это простая пара ключ-значение. По умолчанию ElasticSearch сохраняет исходный код JSON всего файла.
⑦Значения документа для сортировки, агрегации
Тем не менее, мы обнаружили, что приведенная выше структура все еще не может решить такие вещи, как: сортировка, агрегация, фасет, потому что нам, возможно, придется прочитать много ненужной информации.
Итак, эту проблему решает другая структура данных: Document Values. Эта структура по существу является хранилищем столбцов, оптимизированным для хранения данных одного и того же типа.
Чтобы повысить эффективность, ElasticSearch может считывать все значения документа по индексу в память для работы, что значительно повышает скорость доступа, но также потребляет много места в памяти.
Короче говоря, эти структуры данных Inverted Index, Stored Fields, Document Values и их кеши находятся внутри сегмента.
когда происходит поиск
При поиске Lucene будет искать все сегменты и возвращать результаты поиска каждого сегмента, а затем объединять их и представлять клиенту.
Некоторые особенности Lucene делают этот процесс очень важным:
**Сегменты неизменяемы: **Удалить? Когда происходит удаление, все, что делает Lucene, — это устанавливает флаг удаления, но файл остается на своем исходном месте без изменений.
Обновлять? Итак, для обновлений, по сути, он делает следующее: сначала удаляет, а затем переиндексирует (Re-index).
**Сжатие везде:** Lucene очень хорошо сжимает данные, практически все методы сжатия, описанные в учебнике, можно найти в Lucene.
**Кэшировать все:** Lucene также кэширует всю информацию, что значительно повышает эффективность запросов.
Кэшированные истории
Когда ElasticSearch индексирует файл, для файла создается соответствующий кеш, и данные периодически (каждую секунду) обновляются, после чего в этих файлах можно искать.
По мере увеличения времени у нас будет много сегментов, как показано ниже:
Таким образом, ElasticSearch объединит эти сегменты, и в этом процессе сегменты в конечном итоге будут удалены.
Вот почему добавление файлов может уменьшить индекс, вызвать слияние и, возможно, большее сжатие.
взять каштан
Есть два сегмента, которые будут объединены:
Эти два сегмента в конечном итоге будут удалены и объединены в новый сегмент, как показано ниже:
В это время новый Сегмент находится в состоянии «Холод» в кэше, но большинство Сегментов остаются неизменными и находятся в состоянии «Тепло».
Вышеупомянутые сценарии часто происходят внутри Lucene Index, как показано ниже:
Искать в Осколке
Процесс поиска ElasticSearch в сегменте аналогичен процессу поиска в сегменте Lucene.
В отличие от поиска в Lucene Segment, Shards могут быть распределены по разным узлам, поэтому при поиске и возврате результатов вся информация будет передаваться по сети.
**Примечание: **1 поиск 2 осколков = 2 отдельных поиска осколков.
**Обработка файлов журналов:** Когда мы хотим найти журналы, созданные на определенную дату, путем сегментации и индексации файлов журналов в соответствии с метками времени, эффективность поиска будет значительно повышена.
Также очень удобно, когда мы хотим удалить старые данные, просто удаляем старый индекс.
В предыдущем случае у каждого индекса было два осколка.
как масштабировать
Как показано ниже:
Осколки не будут разделены дальше, но осколки могут быть перемещены в другие узлы.
Таким образом, если нагрузка на узлы кластера возрастет до определенного уровня, мы можем рассмотреть возможность добавления новых узлов, что потребует от нас переиндексации всех данных, которые мы не хотим видеть.
Поэтому при планировании нам нужно четко продумать, как сбалансировать взаимосвязь между достаточным количеством узлов и недостаточным числом узлов.
Распределение узлов и оптимизация сегментов:
Выделите более производительные машины для более важных инодов данных.
Убедитесь, что каждый шард имеет информацию о реплике Replica.
**Маршрутизация Маршрутизация.** Каждый узел ведет таблицу маршрутизации, поэтому, когда запрос поступает к любому узлу, ElasticSearch может перенаправить запрос в сегмент нужного узла для дальнейшей обработки.
реальный запрос
Как показано ниже:
①Запрос
Как показано ниже:
Запрос имеет тип filtered и запрос multi_match.
②Агрегация
Как показано ниже:
Агрегируйте по автору, чтобы получить информацию о топ-10 авторов топ-10 хитов.
③ Запрос на распространение
Этот запрос может быть распространен на любой узел в кластере, как показано на следующем рисунке:
④Узел Бога
Как показано ниже:
В этот момент этот узел становится координатором текущего запроса, который решает:
В соответствии с информацией индекса определите, к какому основному узлу будет направлен запрос.
и какая копия доступна.
и Т. Д.
⑤Маршрутизация
Как показано ниже:
⑥ Перед настоящим обыском
ElasticSearch преобразует Query в Lucene Query, как показано ниже:
Затем выполните расчеты во всех сегментах, как показано ниже:
Также будет кеш для самого условия фильтра, как показано ниже:
Но запросы не кэшируются, поэтому, если один и тот же запрос выполняется повторно, кеширование должно выполняться самим приложением.
так:
Фильтры можно использовать в любое время.
Запрос используется только тогда, когда требуется Score.
⑦Возврат
После завершения поиска результаты будут возвращаться слой за слоем по нисходящему пути, как показано на следующем рисунке: