Команда LogiEM, используя внутренний опыт компании Didi в использовании Elasticsearch (ES), сформулировала несколько лучших практик использования ES и платформы LogiEM. Основной акцент сделан на создание индексов, установление маппингов, оптимизации запросов и записи данных.
На данный момент рекомендовано использовать шаблоны индексов, основанные на времени для разделения данных, обычно это деление по дням, месяцам или годам. Индексы, запрошенные пользователями, являются логическими индексами, а фактические хранимые индексы — физическими.
Например, если имя шаблона индекса при регистрации пользователя равно "abc", и выбрано хранение по месяцам, то фактические хранимые индексы будут иметь вид "abc_201812" и "abc_201901".
Создание индексов по временным периодам позволяет избежать создания слишком больших индексов, обеспечивает быстрое восстановление индексов и удаление старых исторических индексов.
Для индексов, срок хранения которых превышает 90 дней, рекомендуется использовать разделение по месяцам вместо разделения по дням. Долгосрочное хранение индексов по дням может привести к увеличению количества индексов в кластере, что в свою очередь приведет к увеличению количества шардов, увеличению метаданных и снижению стабильности кластера, а также замедлению процесса его восстановления после перезапуска.
Рекомендуется использовать временное разделение индексов в соответствии с бизнес-временем. Отсутствие разделения индексов может привести к замедлению записи данных после превышения предполагаемого объема данных, а также к проблемам расширения, перемещения и восстановления индексов, что негативно влияет на работу бизнеса.
В сценариях журналирования сообщение используется для хранения оригинального журнала. В стандартных сценариях KV формата сообщения можно выполнять специализированное очистное преобразование для конкретных полей, таких как traceId и actionName.Запрещено выполнять полное очистное преобразование сообщений без указания конкретных полей для очистки. Полное очистное преобразование может привести к увеличению размера маппинга, что затрудняет поиск и негативно влияет на производительность и стабильность системы.## 2.2 Недопустимо выполнение словесного анализа сообщений в сценариях журналирования
Логическая сцена использует поле message
для хранения исходного текста логов; обычно поиск в поле message
в Elasticsearch (ES) не выполняется, даже если это нестандартный формат ключ-значение. Очистка поля message
или выполнение по нему поиска не рекомендуются.
Поле message
может быть очень длинным, содержание также не всегда постоянное, поэтому выполнение поиска по этому полю требует значительного количества хранилища.
Для такой ситуации рекомендуется при формировании логов следовать внутренним правилам компании Didi, а затем выполнять поиск по необходимым полям после очистки данных.
Свойство free schema Elasticsearch позволяет пользователям динамически менять маппинг, записывая данные в формате JSON. Однако, если свойства JSON постоянно меняются и увеличиваются, это приведёт к тому, что количество полей в маппинге будет расти.
Рекомендуется заранее определять маппинг перед записью данных в Elasticsearch, чтобы эффективнее управлять типами данных.
Для данных, записанных в Elasticsearch, рекомендуется выполнять агрегацию по конкретной необходимости полей. Для полей, которые не требуют агрегации, следует отключить её в маппинге, установив значение "doc_values" как false. Это позволит существенно сэкономить ресурсы.
Elasticsearch автоматически выбирает тип индекса на основе содержимого поля. Например, status=1 автоматически преобразуется в long тип, name="es" — в keyword тип.
Различные типы индексов используют различные структуры данных. Числовой тип long, integer использует BKD как основную структуру данных, подходящую для запросов диапазона, но не для точных запросов key=value. Точное число сравнений числовых полей потребует значительного использования процессора для создания битсета. Keyword тип использует FST и SkipList как основную структуру данных, подходящую для точных запросов key=value, где идентификаторы документов, удовлетворяющие условиям, уже хранятся в обратном индексе, и нет необходимости в реальном времени создавать битсет.
Особое внимание: для полей базы данных MySQL, предназначенных для хранения перечисляемых значений, таких как поле status, xxx_type, следует использовать keyword как тип индекса Elasticsearch, а не long тип.Запросы можно сначала рассмотреть в рекомендациях по оптимизации запросов от официального сайта ElasticSearch: https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html
При поиске в Elasticsearch поддерживаются префиксы со звездочками (), такие как abc, что будет соответствовать всем индексам, начинающимся с abc, таким как abc_201501 до abc_201901. Добавление сложных условий поиска приведёт к полному сканированию таблицы, что может легко вызвать проблемы с работой Elasticsearch.
Поэтому использование звездочек (*) в запросах не рекомендуется. Прямое использование * запрещено в шлюзе LogiEM. Вместо этого следует использовать реальные названия индексов при выполнении запросов, например: SELECT * FROM abc_201901; SELECT * FROM abc_201901, abc_201902;
Агрегирующие запросы в Elasticsearch требуют сортировки или агрегации документов, удовлетворяющих условиям, прямо в памяти. При очень больших объёмах данных и сложных условиях агрегации это может потребовать значительного количества оперативной памяти, что может привести к её переполнению.
Шлюз LogiEM и более новые версии Elasticsearch следят за использованием памяти при выполнении агрегирующих запросов. Если расход памяти становится слишком большим, запрос будет заблокирован.Используйте агрегирующие запросы (aggs) осторожно, особенно если они используют ключевые слова cardinality и script, так как они могут существенно увеличивать нагрузку на память и вызывать проблемы производительности.
Каждый запрос Elasticsearch возвращает все совпадающие данные, что может привести к необходимости просмотра всех совпадающих записей. Это может привести к замедлению общего времени выполнения запроса.
Например, запросы без фильтрации или запросы списка могут значительно замедлиться, если к ним добавлены условия сортировки. Даже если используется ограничение по количеству возвращаемых записей (LIMIT), это не влияет на время выполнения запроса.
При записи документов в Elasticsearch можно указать поле маршрутизации (routing field). Указание этого поля в условиях запроса может повысить скорость выполнения запроса.
Пример: Поле abc.id
может быть использовано как поле маршрутизации для индекса abc
. В условиях запроса можно указать abc.id
, например: SELECT * FROM abc_201901 WHERE abc.id = 123 AND abc.passenger_id = 123 GROUP BY abc.driver_id;
Elasticsearch использует указанное поле маршрутизации для быстрого нахождения конкретного раздела (shard) и последующего выполнения фильтрации и агрегации только внутри этого раздела, что позволяет избежать полного прохода через все разделы индекса и повышает эффективность выполнения запроса. ## 3.5 Не рекомендуется выполнять сложные запросы на больших индексахСуществуют индексы с очень большим объёмом данных, превышающим миллиарды записей. При выполнении запросов на таких индексах следует обратить особое внимание на сложность запросов. Когда условия фильтрации попадают в большое количество данных, запрос может выполняться очень медленно, даже превышая время ожидаемого завершения. Кроме того, такие индексы обычно имеют множество шардов, что требует значительных ресурсов для каждого запроса.
При работе с большими индексами обращайте внимание на оптимизацию запросов и выбор наиболее подходящего способа выполнения запроса. Основной принцип — это минимизация области поиска.
По умолчанию Elasticsearch сортирует данные по значению score, вычисляемому для каждой записи. Для пользователей, которым не требуется специальная сортировка, можно использовать внутренний порядок _doc, чтобы избежать этапа расчёта score. Однако при сортировке по другим полям производительность запроса снижается, так как каждая запись должна получить значение своего поля из DocValues, что может вызвать операции чтения/записи (IO) и замедлить выполнение запроса.
Пример DSL и SQL для сортировки по _doc:
DSL:
"sort": [
{
"_doc": {
"order": "asc"
}
}
]
SQL: ORDER BY _doc## 3.7 Внимание при использовании ключевого слова post_filter
Elasticsearch поддерживает использование post_filter
для разделения результатов запроса и агрегаций. На практике эта возможность используется редко, и многие пользователи ошибочно используют его вместо обычного фильтра запроса. В версиях до 2.3.3 внешние фильтры автоматически преобразовывались в post_filter
, что могло негативно влиять на производительность системы.
Дополнительная информация о post_filter
доступна по адресу: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-post-filter.html
timeout
)timeout
в запросах Elasticsearch применяется к отдельному шарду. Если запрос одного шарда превышает указанное время ожидания, он немедленно прекращает выполнение и возвращает частичный результат. Это может привести к тому, что результат будет неполным. В ответе на запрос поле timed_out
указывает, был ли запрос прерван из-за превышения времени ожидания. Значение false
означает, что запрос завершился успешно, без прерываний. Значение true
указывает на то, что запрос был прерван из-за превышения времени ожидания, и пользователь должен проверить целостность полученного результата. Например, если timed_out=false
, это значит, что запрос завершился без прерываний.```json
{
"took": 9,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"failed": 0
},
"hits": {
...
}
}По умолчанию значение `timeout` в Elasticsearch обычно составляет 5-10 секунд. При выполнении массовых запросов может возникнуть превышение времени ожидания (`timeout`). Пользователи могут указывать значение `timeout` в параметрах запроса, подробнее см.: <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html>. Интерфейсы SQL также поддерживают установку значения `timeout`.2\. В шлюзе LogiEM (Gateway) можно настроить параметр `socket_timeout`, который представляет время ожидания ответа от ES. Если время ожидания превышено, клиент получает сообщение о превышении времени ожидания (`timeout`). Конкретное имя параметра `socket_timeout` имеет максимальное значение 120 секунд.
3\. Клиенты могут самостоятельно настраивать параметр `timeout`, используя SDK различных языков программирования. Этот параметр применяется только к клиентской части, но не влияет на время ожидания в шлюзе Gateway и внутреннем окружении ES. Поэтому при настройке `timeout` следует проявлять осторожность. Рекомендовано устанавливать `timeout` в зависимости от сложности запроса.
## 3.9 Оценка полноты результатов поиска
Результаты поиска в ES выглядят следующим образом:
```json
{
"took": 9,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"failed": 0
},
"hits": {
...
}
}
Чтобы убедиться, что результаты поиска корректны, помимо получения вышеописанной информации, необходимо проверить следующие два аспекта:
1. Убедитесь, что timed_out
равно false
. Подробное описание параметра timed_out
см. в разделе: 3.8 Настройка параметров timeout
.
2. Убедитесь, что failed
в _shards
равно 0. Если это число больше нуля, значит часть shards запроса завершилась с ошибками. В этом случае будет предоставлена информация об этих ошибках.
1. Ограничение длины строки запроса Рекомендуется ограничивать длину строки запроса до 20 символов.
2. Исключение использования * в начале строки запроса Использование * в начале строки запроса заставляет Elasticsearch выполнять полное сканирование всех индексов, что крайне невыгодно с точки зрения производительности и расхода ресурсов. Рекомендуется избегать такого подхода.
3. Использование полнотекстового поиска вместо wildcard-запросов Elasticsearch поддерживает полнотекстовый поиск, который намного более эффективен, чем wildcard-запросы. Дополнительная информация о типах полнотекстового поиска доступна здесь: https://www.elastic.co/guide/en/elasticsearch/reference/current/text.html
clear
после завершения скроллинга для освобождения занятых ресурсов.Для точного совпадения типов полей рекомендуется использовать тип keyword
, а для диапазонных запросов — number
(integer/long/double/float и т.д.).## 3.14 Лучше запретить сортировку по _id
Сортировка по _id
использует fielddata
, что может легко привести к переполнению памяти. Поэтому сортировка по _id
должна быть запрещена.
fielddata
для полей типа text
Для полей типа text
лучше не использовать fielddata
, чтобы избежать переполнения памяти из-за слишком большого размера fielddata
.
Указание конкретного разделённого шарда для запроса, настройка Routing
, indexSort
и ограничение количества попаданий в общие шарды
Для оптимизации записи можно обратиться к руководству Elasticsearch по оптимизации скорости индексации: https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html
bulk
для записиРекомендуется использовать bulk
для записи. Количество записей в одном bulk
запросе должно быть разумным, зависящим от конфигурации сервера и размера документов. В качестве примера можно указать значение 1000 или до 2МБ.
Многопоточность может повысить производительность записи, но количество потоков не должно быть чрезмерным.
Данные внутри одного bulk
запроса должны быть распределены по одному шарду, чтобы избежать эффекта длинного хвоста и обеспечить высокую производительность записи.## 4.4 Уникальный идентификатор
Если уникальный идентификатор не требуется, его следует не указывать при записи, позволяя Elasticsearch генерировать его автоматически. Это позволяет избежать проверки версий и идентификаторов, повышая производительность.
В экстренных случаях, таких как отключение питания, когда допустимо потерять некоторые данные, рекомендуется установить режим записи translog в асинхронном режиме.
Время обновления и буфер записи могут быть увеличены для улучшения производительности.
В маппингах поля, которые не требуют индексации или сортировки, следует удалить свойства index
и doc_values
для повышения производительности записи.
SSD накопители
Изоляция ролей master, client и data node
По спецификации оборудования возможно использование одного экземпляра на одной машине, нескольких экземпляров на одной машине или нескольких кластеров на одной машине
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )