Без SQL: учимся работать с данными на Elasticsearch

Андрій Денисенко

Elasticsearch — это поисковый и аналитический движок, с помощью которого ваша команда может быстро искать информацию в любых типах данных и анализировать их.

Он позволяет управлять релевантностью результатов и проводить масштабирование.

Объемы данных растут все быстрее и быстрее. Их становится сложнее структурировать и выделять полезную информацию. Так реляционные базы данных отходят на задний план, а хранилища и поисковые системы без использования SQL становятся все популярнее.

Elasticsearch — это распределенный механизм на основе архитектуры RESTful. Наряду с Kibana, Beats и Logstash, Elasticsearch — это компонент комплекта приложений Elastic Stack, который дает возможность надежно и безопасно получать данные из любого источника и в любом формате, искать, анализировать и визуализировать данные в режиме реального времени.

С помощью Elasticsearch можно решать многие задачи:

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

Кроме прочего, нужно сказать, что Elasticsearch — это программное обеспечение с открытым исходным кодом, которое распространяется бесплатно.

Хранение и поиск данных

Документы

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

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

Вместо этого информация хранится в виде сериализованных документов JSON. Этот формат позволяет хранить произвольные структуры данных.

Например, коллекцию сериалов можно представить так:

В СУБД В виде объектов

В формате JSON эти объекты записываются просто:

Удобно, что пользователи сами могут определять структуру данных в документах. Из них проще извлекать информацию, и их можно легко менять.

Поиск

В руководстве по Elasticsearch утверждается, что полнотекстовый поиск осуществляется в течение одной секунды. Если Elasticsearch работает с большим объемом данных, как ему удается проводить поиск по всему их тексту в режиме, близкому к реальному времени?

Это возможно благодаря использованию обратного индекса. При индексировании составляется список уникальных слов, встречающихся во всех документах, со ссылками на документы, в которых содержится каждое слово. Поэтому Elasticsearch создан на базе библиотеки для полнотекстового поиска Apache Lucene, в которой используется обратный индекс.

Поиск с помощью Elasticsearch

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

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

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

Индекс

Elasticsearch использует индекс Lucene, который напоминает базу данных: данные находятся в пространстве  имен и для их упорядочения используется схема. По своей сути индекс представляет собой логическую группу, состоящую из одного или нескольких физических сегментов (shards), которые являются экземплярами Lucene.

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

Давайте сравним Elasticsearch, MongoDB и PostgreSQL с точки зрения возможностей, обеспечиваемых индексом.

Elasticsearch MongoDB PostgreSQL
Поисковик Хранилище документов База данных
Документы JSON со связями (mappings) в индексе Документы BSON в коллекциях Данные в таблицах
Одна запись, много чтений. Высокая скорость поиска Высокая эффективность операций, связанных с записью Высокая эффективность операций, связанных с записью
Гибкая схема Гибкая схема Схема обязательна, что дает возможность проводить операции, которые иначе было бы невозможно провести

Если имеется большой объем данных, использование распределенного индекса снижает нагрузку на систему. Она работает не с большим объемом данных, а со сравнительно небольшими индексами.

Поэтому в Elasticsearch предусмотрена возможность регулировать количество сегментов в параметре index.number_of_shards. По умолчанию его значение равно 5, но вы можете изменить его в зависимости от того, сколько сегментов будет участвовать в поиске.

Кроме того, следует учесть, что по мере заполнения данными Elasticsearch объединяет малые сегменты в большие, поэтому нужно следить за тем, чтобы они не становились слишком крупными и не снижали эффективность работы.

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

Масштабирование

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

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

Кластеры и управление ими

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

Кластер

Кластер — это группа узлов с одним и тем же значением атрибута cluster.name. Если запущен один экземпляр Elasticsearch, то кластер состоит из единственного узла. Все первичные узлы находятся на нем, и он готов к использованию. Но создать на нем реплицированные сегменты невозможно, поэтому в случае сбоя могут быть потеряны данные.

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

По умолчанию добавляемый узел может быть как узлом данных, так и master-узлом, который управляет кластером. Рекомендуем помещать в кластер небольшое фиксированное количество узлов, которые могут быть выбраны основными (master-eligible nodes). Такие узлы отвечают, например, за создание или удаление индекса, отслеживание узлов, которые входят в кластер, и принятие решений о распределении сегментов между узлами. Добавлять же в кластер лучше те узлы данных, которые не могут быть выбраны основными.

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

Репликация данных

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

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

Чтобы не потерять данные, лучше создать реплики

Для обеспечения отказоустойчивости нужно создать реплику каждого сегмента. Общее количество реплик должно быть не меньше количества узлов данных. Тогда при отказе одного узла можно будет пользоваться репликой данных на другом узле во время восстановления поврежденного. Чтобы использовать реплики эффективно, можно указать их количество в параметре number_of_replicas.

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

Мы рассмотрели, как обеспечить отказоустойчивость в случае отказа узла данных. Но как обезопасить систему на случай сбоя основного узла? Ведь его потеря приведет к тому, что весь кластер перестанет быть работоспособным.

На этот случай можно создать несколько основных узлов. На роль основного узла могут претендовать узлы, которые могут быть выбраны основными.

Когда отказывает один такой узел, новым основным узлом будет выбран тот, который обладает самой актуальной информацией о кластере. Выбор делается при достижении кворума во время голосования узлов, которые имеют право голоса. Он должен быть нечетным и составлять 50% + 1 голос.

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

Взаимодействие

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

HTTP Встроенная поддержка. Использует API. Время ответа менее 100 мс.

Производительность зависит от клиентской библиотеки и часто требует проведения настройки.

Встроенный двоичный протокол Elasticsearch Разработан для внутреннего взаимодействия между узлами.

Рекомендуется использовать только из Java, чтобы избежать объемной пользовательской сериализации.

Высокоуровневый клиент REST для Java Принимают объекты запросов и возвращают объекты ответов, обрабатываемые клиентом.

API можно вызывать синхронно и асинхронно.

Этот клиент принимает и возвращает такие же объекты, как и помеченный на удаление клиент TransportClient.

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

Частый запуск и остановка клиентов узлов приводит к лишнему «шуму» в кластере.

Встроенный клиент отвечает на внешние запросы, как и любой другой клиент.

Также существуют отдельные библиотеки для:

  • JavaScript (только поиск для приложений);
  • Node.js (поисковый клиент для приложений и рабочего места);
  • PHP (только поиск для приложений);
  • Python (клиент для корпоративного поиска);
  • Ruby (клиент для корпоративного поиска).

Заключение

Эффективность Elasticsearch как поискового движка обеспечивается благодаря обратному индексу и распределению данных. По мере увеличения или уменьшения их объема он удобно масштабируется, вы можете не переживать о потере данных — они надежно защищены с помощью реплик и избыточных узлов.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

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

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023