Памятки по проектированию системы ElasticSearch

Советы по проектированию системы ElasticSearch

Понимайте, как и когда использовать ElasticSearch в системах с помощью трех практических примеров проектирования системы

Вступление

Что такое поиск? И почему это важно?

Если вы читали мои предыдущие статьи о поиске, вы знаете, насколько критичен поиск для приложения. Подумайте об этом: из всех разных веб-приложений и мобильных приложений, которые вы используете каждый день, будь то Netflix, Amazon, Swiggy и другие, поле поиска, вероятно, единственный общий элемент пользовательского интерфейса, и он обычно находится на главной странице, прямо вверху. Если вы разрабатываете систему, в девяносто девяти случаях из ста вы будете думать о том, как обеспечить поиск.

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

Что такое ElasticSearch?

ElasticSearch – это популярная база данных, которая делает то, с чем большинство баз данных борются: поиск. Поиск настолько ключевой для ElasticSearch, что он буквально входит в его название!

Но если вы не слышали о ElasticSearch, вы, вероятно, задаетесь вопросом: почему поиск так сложен? Почему реляционная база данных не может выполнять поиск? Большинство реляционных баз данных поддерживают различные способы поиска и фильтрации данных, такие как запрос “WHERE”, ключевое слово “LIKE” или индексы. Или почему нельзя использовать документную базу данных, такую ​​как MongoDB? В MongoDB также можно писать запросы find.

Чтобы понять ответ, представьте, что вы создаете новостной сайт. Когда пользователь ищет новости с помощью вашей строки поиска, например, “заражения COVID19 в Нью-Дели”, пользователь интересуется всеми статьями, которые говорят о заражениях COVID в Нью-Дели. В простой системе поиска это означало бы сканирование всех статей в базе данных и возврат тех, которые содержат слова “COVID19”, “заражения” или “Нью-Дели”. Этого нельзя сделать с помощью реляционной базы данных. Реляционная база данных позволяет искать статьи на основе определенных атрибутов, например, статьи, написанные конкретным автором или статьи, опубликованные сегодня и т.д., но она не может (по крайней мере, не так эффективно) выполнить поиск, при котором сканируются все новостные статьи (обычно в десятках миллионов) и возвращаются те, которые содержат определенные слова.

Кроме того, есть еще много нюансов, которые нужно учесть. Как вы оцениваете эти статьи? Может быть, есть статья, которая говорит о распространении заражения COVID19, а может быть, есть статья, которая говорит о новых заражениях – как определить, какая статья более релевантна для запроса пользователя или, другими словами, как отсортировать эти статьи по релевантности?

Ответ: ElasticSearch! ElasticSearch может сделать все это и даже больше.

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

ElasticSearch

Возможности поиска

ElasticSearch предоставляет способ выполнения “полнотекстового поиска”. Полнотекстовый поиск относится к поиску фразы или слова в огромном корпусе документов. Вернемся к нашему предыдущему примеру: представьте, что вы создаете новостной сайт, который содержит миллионы новостных статей. Каждая статья содержит некоторые данные, такие как заголовок, подзаголовок, содержимое статьи, дата публикации и т. д. В контексте ElasticSearch каждая статья хранится как JSON-документ.

Вы можете загрузить все эти документы в ElasticSearch, а затем искать конкретные слова или фразы в каждом из этих документов за несколько миллисекунд. Таким образом, если вы загрузите все новостные статьи и выполните поиск по запросу “заражения COVID19 в Дели”, ElasticSearch вернет все статьи, в которых есть слова “COVID19”, “заражения” или “Дели”.

Для демонстрации поиска в ElasticSearch настроим Elasticsearch и загрузим в него некоторые данные. Для этого поста я буду использовать этот набор данных новостей, который я нашел на Kaggle(Misra, Rishabh. “News Category Dataset.” arXiv preprint arXiv:2209.11429 (2022)) (Источник) (Лицензия). Набор данных довольно простой, он содержит около 210 000 новостных статей со своими заголовками, краткими описаниями, авторами и некоторыми другими полями, которые нам не очень важны. Нам не нужно все 210 000 документов, поэтому я загружу около 10 000 документов в ES и начну искать.

Вот несколько примеров документов в наборе данных —

[  {    "link": "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",    "headline": "Почему управление выборов в Нью-Йорке - это беспорядок",    "short_description": "«Проблема заключается в наличии партийных избирательных комиссий», - сказал адвокат по выборам в Нью-Йорке.",    "category": "ПОЛИТИКА",    "authors": "Дэниел Мэрэнс",    "country": "IN",    "timestamp": 1689878099  },  ....]

Каждый документ представляет собой новостную статью. Каждая статья содержит link, headline, short_description, category, authors, country(случайные значения, добавленные мной) и timestamp(опять же случайные значения, добавленные мной).

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

Один из самых простых запросов с полнотекстовым сопоставлением – это запрос multi_match(не беспокойтесь слишком много о запросах данных в ElasticSearch, это довольно просто и мы поговорим об этом в конце статьи). Идея проста, вы пишете запрос, а Elasticsearch выполняет полнотекстовый поиск, сканируя все документы в вашей базе данных, находя те, которые содержат слова из этого запроса, присваивая им рейтинг и возвращая их. Например,

GET news/_search{  "query": {    "multi_match": {      "query": "инфекции COVID19"    }  }}

Вышеприведенный запрос находит соответствующие статьи для запроса “инфекции COVID19”. Вот результаты, которые я получил –

 [      {        "_index" : "news",        "_id" : "czrouIsBC1dvdsZHkGkd",        "_score" : 8.842152,        "_source" : {          "link" : "https://www.huffpost.com/entry/china-shanghai-lockdown-coronavirus_n_62599aa1e4b0723f8018b9c2",          "headline" : "Строгие карантинные меры из-за коронавируса в Китае продолжаются с ростом инфекций",          "short_description" : "Доступ в Гуанчжоу, промышленный район с 19 миллионами жителей рядом с Гонконгом, был приостановлен на этой неделе.",          "category" : "МИРОВЫЕ НОВОСТИ",          "authors" : "Джо Макдональд, AP",          "country" : "IN",          "timestamp" : 1695106458        }      },      {        "_index" : "news",        "_id" : "ODrouIsBC1dvdsZHlmoc",        "_score" : 8.064016,        "_source" : {          "link" : "https://www.huffpost.com/entry/who-covid-19-pandemic-report_n_6228912fe4b07e948aed68f9",          "headline" : "Количество случаев и смертей от COVID-19 продолжает снижаться глобально, говорит ВОЗ",          "short_description" : "Всемирная организация здравоохранения заявила, что новые инфекции снизились на 5 процентов на прошлой неделе, продолжая снижаться глобально.",          "category" : "МИРОВЫЕ НОВОСТИ",          "authors" : "",          "country" : "US",          "timestamp" : 1695263499        }      },      ....]

Как вы можете видеть, он возвращает документы, которые обсуждают инфекции COVID19. Он также возвращает их отсортированными по степени релевантности (поле _score указывает, насколько конкретный документ релевантен).

ElasticSearch имеет богатый язык запросов с множеством функций, но пока достаточно знать, что создание простой системы поиска очень легко – просто загрузите все ваши данные в ElasticSearch и используйте простой запрос, о котором мы говорили. У нас есть множество вариантов для улучшения, настройки и настройки производительности и релевантности поиска (еще больше о поисковых запросах в конце этого поста).

Распределенная архитектура

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

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

Масштабируемость

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

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

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

Моделирование данных на основе документов

ElasticSearch – это база данных на основе документов, которая хранит данные в формате JSON-документа, аналогичном MongoDB. Таким образом, в нашем примере каждая новостная статья хранится в виде JSON-документа в кластере.

Анализ данных в реальном времени

Анализ данных в реальном времени означает анализ действий пользователей в режиме реального времени и понимание образцов и поведения пользователей. Мы можем представлять графически поведение пользователя и лучше понимать наших пользователей, используя это мы можем улучшить наш продукт. Например, предположим, что мы измеряем каждый отдельный клик, скроллинг и время чтения на пользователя на нашем новостном веб-сайте. Мы делаем график этих показателей на панели управления и наблюдаем за ними несколько дней. Используя это, мы можем получить много действенных идей для улучшения нашего новостного приложения. Мы выяснили, что пользователи обычно используют веб-сайт с 9 до 10 часов утра, и мы узнали, что пользователи обычно нажимают на статьи, которые относятся к их стране. Исходя из этой информации, мы можем увеличить ресурсы во время пиковых часов (с 9 до 10 утра) и, возможно, показывать статьи из страны пользователя на их домашней странице.

Elasticsearch прекрасно подходит для анализа данных в реальном времени благодаря своей распределенной архитектуре и мощным возможностям поиска. Когда речь идет о работе с данными в реальном времени, такими как журналы, метрики или обновления в социальных сетях, Elasticsearch эффективно индексирует и хранит эту информацию. Благодаря его практически мгновенной индексации данные становятся доступными для поиска практически мгновенно после ввода. ElasticSearch также хорошо работает с другими инструментами, такими как Kibana для визуализации или Logstash и Beats для сбора метрик.

В конце статьи мы рассмотрим архитектуру, облегчающую это.

Стоимость

ElasticSearch дорого стоит в эксплуатации и поддержке. Как и все в этом мире, все хорошее имеет свою цену. Для выполнения полнотекстового поиска ElasticSearch хранит большое количество данных в ОЗУ и создает сложные индексы. Это означает, что ему требуется много ОЗУ для работы, что дорого.

Итак, короче говоря, он обеспечивает потрясающую производительность при выполнении полнотекстового поиска, но это не дешево.

Когда не использовать ElasticSearch

Соответствие ACID

ElasticSearch, как и большинство NoSQL-баз данных, имеет очень ограниченную поддержку ACID. Поэтому, если вам нужна сильная согласованность или транзакционная поддержка, ElasticSearch может не быть подходящим выбором базы данных для вас. Последствия этого заключаются в том, что если вы вставляете документ (называемый “индексацией” документа в ElasticSearch) в ElasticSearch, он может не быть доступен для других узлов немедленно и может занять несколько миллисекунд, прежде чем станет видимым для других узлов.

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

Когда вам нужны сложные объединения

ElasticSearch не поддерживает операции JOIN или отношения между различными таблицами. Если вы использовали реляционные базы данных, то это может вызвать некоторое потрясение, поскольку большинство NoSQL-баз данных имеют ограниченную поддержку подобных операций.

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

Небольшой набор данных или простые запросы

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

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

Как использовать ElasticSearch в проектировании вашей системы

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

Допустим, вы хотите создать сервис видеостриминга, что-то вроде Netflix. Давайте узнаем, где может пригодиться ElasticSearch в этом примере.

В качестве системы поиска

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

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

У нас может быть подобная архитектура:

Image by author

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

Как потоковый анализ данных в режиме реального времени

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

Например, в нашем приложении видеостриминга мы можем публиковать событие с данными о пользователе и фильме, когда пользователь нажимает на фильм или шоу. Затем мы можем анализировать и создавать агрегаты, чтобы лучше понять, как пользователи используют наш продукт. Например, мы можем обнаружить, что пользователи чаще используют наш продукт вечером, чем днем, или что пользователи предпочитают шоу или фильмы на своем родном языке перед другими языками. Используя это, мы можем разрабатывать наш продукт, чтобы улучшить пользовательский опыт.

Так будет выглядеть базовая система для анализа данных в режиме реального времени с использованием ElasticSearch и Kibana (инструмента для создания панелей управления, хорошо совместимого с ElasticSearch):

Image by author

Как система рекомендаций

Мы можем создавать запросы в ElasticSearch, которые предпочитают некоторым атрибутам больший вес (называемый усилением). Например, вместо простого запроса

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

Понимание языка запросов, умение повышать релевантность определенных полей и выполнять агрегации – это большая тема сама по себе, но я написал блог-пост, в котором рассматриваю основы здесь:

Овладение Elasticsearch: Руководство начинающего по мощным запросам и точности — Часть 1

Разблокируйте мощь Elasticsearch в части 1: Погрузитесь в Elasticsearch, овладейте основными поисковыми запросами и исследуйте лексически…

towardsdatascience.com

Вывод

Как разрабатывать кластеры ElasticSearch?

Создание архитектуры кластера ElasticSearch – это нелегкая задача, она требует знания о узлах, шардах, индексах, а также о том, как оркестрировать все эти компоненты. Существует бесчисленное количество архитектурных выборов, и область постоянно развивается (особенно с увеличением популярности ИИ и поиска, основанного на ИИ). Чтобы обсудить это подробнее, я написал полный блог-пост, который начинается с самых основ до всего, что вам нужно знать для создания архитектуры поискового кластера:

betterprogramming.pub

Понимание поисковых запросов и улучшение поисковых систем

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

Овладение Elasticsearch: Руководство начинающего по мощным запросам и точности — Часть 1

Разблокируйте мощь Elasticsearch в части 1: Погрузитесь в Elasticsearch, овладейте основными поисковыми запросами и исследуйте лексически…

towardsdatascience.com

Поиск, осведомленный о контексте

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

Или вы можете представить поисковую систему как библиотекаря. Когда пользователь задает вопрос, допустим, “Какую роль играл Уинстон Черчилль во второй мировой войне?”, библиотекарь не просто сообщает ему о книгах, в которых есть слова “Уинстон”, “Черчилль” или “Вторая мировая война”. Вместо этого библиотекарь оценивает и понимает клиента и контекст. Возможно, это школьник, поэтому вместо рекомендации огромного учебника она найдет книгу, более подходящую для более молодого ребенка. Или, возможно, у нее нет книги с названием Уинстон Черчилль, поэтому она находит книгу, которая рассказывает о Второй мировой войне или британских премьер-министрах и рекомендует ее вместо этого. Библиотекарь может даже рекомендовать разные книги для экзаменов и разные для летних каникул (некоторые из вас, возможно, не знают об этом, но в некоторых странах вам дается огромное количество домашнего задания на летние каникулы)

Это легко понять для вас и для меня, но как наша система узнает, что Уинстон Черчилль был британским премьер-министром и рекомендует книги о Великобритании во время Второй мировой войны или как наша система понимает контекст обсуждения, понимает пользователя и рекомендует подходящие книги?

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

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

Другие базы данных

Я пишу о концепциях проектирования систем, таких как базы данных, очереди и системы публикации-подписки, поэтому следите за мной здесь, на VoAGI, чтобы читать подобные статьи. Я также пишу много коротких материалов на LinkedIn (например, этот пост о различиях между RabbitMQ и Kafka), поэтому следите за мной на LinkedIn для кратких форм контента.

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

Sanil Khurana на VoAGI отобрал несколько списков

Начните исследовать Linux, Cassandra, вопросы на собеседования и многое другое

VoAGI.com