Переведено с:И в самом большом было сказано «Перенос» — Эффективное управление временными индексами Elasticsearch.
Люди, которые используют Elasticsearch для индексации данных, основанных на времени, таких как события журнала, могут использовать модель «индексирования в день»: используйте имя индекса с разбивкой по дням для хранения данных журнала за день, а затем создайте новый индекс после день прошел. Новые индексированные свойства могут быть указаны с помощьюшаблон индексаконтролировать заранее.
Этот шаблон легко понять и легко реализовать, но он скрывает некоторые сложности управления индексами:
- Для достижения высокой скорости записи сегменты активного индекса должны быть распределены вНасколько это возможнона узле.
- Чтобы повысить скорость поиска и снизить потребление ресурсов, необходимо увеличить количество осколков.как можно меньше, Но вы не можете иметь слишком большой маневр поворота одного ломтика
- Один индекс в день действительно легко очищает устаревшие данные, но сколько осколков вам нужно в день?
- Является ли ежедневное давление записи постоянным? Или в один день осколков слишком много, а в следующий — недостаточно?
В этом посте я расскажу о новом «скользящем режиме» и API-интерфейсах, используемых для его реализации, что делает управление индексами на основе времени проще и эффективнее.
режим прокрутки
Рабочий процесс в режиме прокрутки выглядит следующим образом:
- Существует псевдоним индекса для записи, который указывает на активный индекс
- Другой псевдоним индекса для чтения (поиска), указывающий на неактивный индекс
- Активный индекс имеет столько же осколков, сколько и горячих узлов, что позволяет полностью использовать возможности записи индекса на дорогом оборудовании.
- Когда активный индекс слишком заполнен или слишком стар, онпрокрутить: Создайте новый индекс, и псевдоним индекса автоматически переключится со старого индекса на новый индекс.
- переместите старый индекс на холодный узел иуменьшитьза осколок, то можнопринудительное слияниеи сжатие.
начиная
Допустим, у нас есть 10горячийузел и ахолодноКластер пулов узлов. В идеале наш активный индекс (тот, который получает все записи) должен иметь сегмент, равномерно распределенный по каждому горячему узлу, чтобы максимально распределить давление записи на несколько машин.
У нас есть реплика для каждого основного сегмента, чтобы узел мог выйти из строя без потери данных. Это означает, что наш активный индекс должен иметь 5 основных сегментов, всего 10 сегментов (по одному на узел). Мы также могли бы использовать 10 основных сегментов (всего 20 сегментов, включая избыточность), чтобы каждый узел имел два сегмента.
Сначала создайте активный индексшаблон индекса:
PUT _template/active-logs
{
"template": "active-logs-*",
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1,
"routing.allocation.include.box_type": "hot",
"routing.allocation.total_shards_per_node": 2
},
"aliases": {
"active-logs": {},
"search-logs": {}
}
}
Индексы, созданные по этому шаблону, будут присвоеныbox_type:hot
На узле,total_shards_per_node
Конфигурация гарантирует, что осколки будут равномерно распределены междугорячийв узле. Я установил его на2
вместо1
, чтобы при сбое узла можно было продолжать выделять осколки.
мы будем использоватьactive-logs
Псевдоним, чтобы написать текущий активный индекс, сsearch-logs
Псевдоним для запроса всего индекса журнала.
Ниже приведен шаблон для неактивного индекса:
PUT _template/inactive-logs
{
"template": "inactive-logs-*",
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"routing.allocation.include.box_type": "cold",
"codec": "best_compression"
}
}
Архивные индексы должны быть присвоеныхолодноузел и использоватьdeflate
Сжатие для экономии места на диске. Я объясню позже, почемуreplicas
Установить как0
.
Теперь можно создать первый активный индекс:
PUT active-logs-1
Rollover API преобразует-1
Признан счетчиком.
События журнала индекса
при созданииactive-logs-1
При индексировании мы также создалиactive-logs
Псевдоним. После этого мы должны использовать псевдоним только для записи, документ будет отправлен на текущий индекс деятельности:
POST active-logs/log/_bulk
{ "create": {}} { "text": "Some log message", "@timestamp": "2016-07-01T01:00:00Z" }
{ "create": {}} { "text": "Some log message", "@timestamp": "2016-07-02T01:00:00Z" }
{ "create": {}} { "text": "Some log message", "@timestamp": "2016-07-03T01:00:00Z" }
{ "create": {}} { "text": "Some log message", "@timestamp": "2016-07-04T01:00:00Z" }
{ "create": {}} { "text": "Some log message", "@timestamp": "2016-07-05T01:00:00Z" }
индекс качения
В какой-то момент активный индекс становится слишком большим или слишком старым, и вы хотите заменить его новым пустым индексом.Rollover APIПозволяет указать определенный размер или ограничение по времени для запуска действия прокрутки.
Насколько велик слишком большой? Как всегда, это зависит. Это зависит от производительности вашего оборудования, типа ваших операций поиска, производительности, которую вы хотите достичь, времени восстановления сегмента, которое вы можете принять, и т. д. Вы можете начать с таких чисел, как 100 миллионов или 1 миллиард, и увеличивать или уменьшать их в зависимости от производительности поиска, времени хранения данных и доступного места на диске.
Существует жесткое ограничение на количество документов, которые может содержать шард: 2 147 483 519. Если вы планируете сжать активный индекс до сегмента, количество документов в активном индексе не может превышать 2,1 миллиарда. Если документы в активном индексе не помещаются в один сегмент, вы можете сократить активный индекс до нескольких сегментов, если целевое количество сегментов является коэффициентом исходного количества сегментов, например, от 6 до 3 или от 6 до 2.
Прокручивание индекса по времени удобно, потому что индекс можно организовать по часам, дням или неделям. Но на самом деле более эффективно свернуть индекс по количеству документов в индексе. Одним из преимуществ прокатки по количеству является то, что все осколки будут примерно одинакового размера, что упрощает балансировку нагрузки.
Вы можете использовать запланированную задачу для периодического вызова API ролловера, чтобы проверить, прибыл ли он.max_docs
илиmax_age
предел. При превышении определенного лимита индекс пролонгируется. Поскольку в нашем примере мы проиндексировали только 5 документов, мыmax_docs
установлено значение5
, и (для полноты) будетmax_age
Установите на неделю:
POST active-logs/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 5
}
}
Этот запрос рассказывает Elasticsearch для прокруткиactive-logs
Псевдоним указывает на индекс, если индекс создан не менее чем за семь дней или содержит не менее пяти документов. Ответь на следующее:
{
"old_index": "active-logs-1",
"new_index": "active-logs-2",
"rolled_over": true,
"dry_run": false,
"conditions": {
"[max_docs: 5]": true,
"[max_age: 7d]": false
}
}
потому что доволенmax_docs: 5
состояние,active-logs-1
индекс прокручивается доactive-logs-2
показатель. Это означает, чтоactive-logs-2
Индекс создается (на основеactive-logs
шаблон) иactive-logs
псевдоним изactive-logs-1
переключить наactive-logs-2
.
Кстати, если вы хотите переопределить некоторые значения в шаблоне индекса (например.settings
илиmappings
), просто вставьте их_rollover
в теле запроса (иСоздайте индекс APIТакой же).
почему бы не поддержатьmax_size
предел?
Поскольку вы хотите сделать осколки как можно более похожими по размеру, почему бы и нет?max_docs
плюс поддержкаmax_size
Как насчет ограничений? Ответ заключается в том, что размер сегмента не является надежной мерой, поскольку текущие слияния приводят к значительному временному увеличению размера сегмента, которое исчезает после завершения слияния. Пять основных сегментов, каждый из которых находится в процессе объединения в сегмент размером 5 ГБ, временно увеличат размер индекса на 25 ГБ! По количеству документов его рост предсказуем.
Узкий индекс
В настоящее времяacitve-logs-1
Больше не используется для записи, мы можем переместить его на холодный узел и сжать до осколка, этот новый индекс называетсяinactive-logs-1
. Перед минификацией мы должны:
- установить индекс только для чтения
- Переместите все осколки в один и тот же узел. Целевой узел можно выбрать произвольно, например, выбрать узел с наибольшим оставшимся пространством.холодноузел
Сделайте эти вещи со следующей командой:
PUT active-logs-1/_settings
{
"index.blocks.write": true,
"index.routing.allocation.require._name": "some_node_name"
}
allocation
Конфигурация гарантирует, что по крайней мере одна копия каждого сегмента будет перемещена вsome_node_name
на узле. Это не перемещает все осколки, так как реплицированные осколки не могут быть размещены на том же узле, что и первичный, но гарантирует перемещение по крайней мере одного основного или реплицированного осколка.
Когда индекс был перенесен (сAPI работоспособности кластерадля проверки), используйте следующий запрос для сжатия индекса:
POST active-logs-1/_shrink/inactive-logs-1
Если ваша файловая система поддерживает жесткие ссылки, минификация будет мгновенной. Если ваша файловая система не поддерживает жесткие ссылки, вам нужно дождаться, пока все файлы сегментов будут скопированы из одного индекса в другой...
ты можешь использовать этоAPI запросов на восстановление состоянияИли API работоспособности кластера для мониторинга процесса сжатия:
GET _cluster/health/inactive-logs-1?wait_for_status=yellow
Когда минификация завершена, вы можете начатьsearch-logs
Удалите старый индекс и добавьте новый индекс из псевдонима:
POST _aliases
{
"actions": [
{
"remove": {
"index": "active-logs-1",
"alias": "search-logs"
}
},
{
"add": {
"index": "inactive-logs-1",
"alias": "search-logs"
}
}
]
}
сэкономить место
Наш индекс сократился до одного фрагмента, но он по-прежнему содержит то же количество файлов сегментов, что и раньше, иbest_compression
设置并没有生效,因为没有任何写入操作。 мы можем использоватьпринудительное слияниеЧтобы оптимизировать односегментный индекс в односегментный, выполните следующие действия:
POST inactive-logs-1/_forcemerge?max_num_segments=1
Этот запрос создает новый сегмент для замены предыдущих сегментов. А поскольку Elasticsearch должен создавать новые сегменты,best_compression
настройки будут работать, и новый сегмент будет использоватьdeflate
Сжато пишет.
Нет смысла запускать принудительное слияние на первичном и реплицированном осколках по отдельности, поэтому наш неактивный шаблон индексаnumber_of_replicas
установлен на0
. Теперь, когда принудительное слияние закончилось, мы можем открыть фрагмент копии, чтобы получить избыточность:
PUT inactive-logs-1/_settings
{ "number_of_replicas": 1 }
После выделения осколков реплики (с?wait_for_status=green
запрос API), мы можем быть уверены, что у нас есть избыточность, которую можно смело удалить в это время.active-logs-1
показатель:
DELETE active-logs-1
удалить старый индекс
Принятие решения о том, какие индексы следует удалить, удобно при использовании старого шаблона однодневных индексов. При использовании скользящего режима кажется, что непросто определить, за какой период времени индекс содержит данные.
К счастью,Полевая статистика API.Их можно легко определить. Нам нужно только иметь возможность найти максимальное значение, превышающее наш порог@timestamp
Индексированный список полей подойдет:
GET search-logs/_field_stats?level=indices
{
"fields": ["@timestamp"],
"index_constraints": {
"@timestamp": {
"max_value": {
"lt": "2016/07/03",
"format": "yyyy/MM/dd"
}
}
}
}
Все индексы, возвращаемые этим запросом, могут быть удалены.
будущие улучшения
пройти черезпрокрутить,уменьшить,принудительное слияниеиПолевая статистикаAPI, мы предоставляем вам основные инструменты для эффективного управления временными индексами.
Конечно, здесь есть много шагов, которые можно автоматизировать, чтобы сделать жизнь лучше. Эти шаги не очень легко реализовать в Elasticsearch, потому что нам нужно уведомлять других, когда происходит что-то неожиданное. За это отвечает инструмент или приложение, созданное поверх Elasticsearch.
ожидать быть вCurator index management toolиX-PackСм. соответствующий рабочий процесс и пользовательский интерфейс в файлах .