Незначительная оптимизация индекса Elasticsearch

Node.js задняя часть Elasticsearch Logstash
Незначительная оптимизация индекса Elasticsearch

TL;DR

Если вы хотите уменьшить размер индекса в ES, вы можете попробовать добиться этого следующими способами:

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

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

уменьшить размер индекса

Файлы записей в ES будут храниться на диске.Учитывая, что текущая цена хранения на диске довольно низкая, уменьшение занимаемого места индекса не является особо существенным для внешней памяти.Конечно, избыточный объем данных также будет иметь негативное влияние по скорости записи..

Чрезмерный индекс также повлияет на использование памяти кучи.Когда ES используется в качестве поисковой системы, существует инвертированный индекс, используемый для связывания ключевых слов и документов, и неинвертированный индекс, т. е.fileddataОн используется для сортировки и агрегации.Когда ES используется в качестве TSDB, если все хранится в памяти в соответствии с настройками ES по умолчанию, легко взорвать память.Когда группа впервые использовала ES много лет назад, было много всплесков памяти.Ситуация, которая приводит к зависанию кластера.

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

Используйте соответствующий тип сопоставления полей шаблона

Давайте сначала посмотрим на индекс с несколькими числовыми полями. Этот индекс используется для записи сводки вызовов интерфейса в минуту. Конкретные данные следующие:

{
"200-500": 0,
"max": 5070000000,
"length": 8200000000,
"count": 60000,
"900-2s": 0,
"500-900": 1,
"5s+": 0,
"url": "/get/info",
"2xx": 6,
"3xx": 0,
"min": 47000,
"type": "minute",
"@timestamp": "2017-09-05T16:22:00.000Z",
"4xx": 0,
"size": 1928,
"<80": 5,
"80-200": 0,
"5xx": 0,
"domain": "sample.com",
"@version": "1",
"2s-5s": 0,
"id": "cae573eadeaedaeeb1e3fe3680001c45"
}

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

Когда этот индекс содержит 72 записи, размер индекса достигает287.91MB.

long-template

На самом деле, если проанализировать его детально, там много полей, которые не превысятintegerдиапазон представления, поэтому, если для нескольких конкретных сопоставлений полей установлено значениеlongТолько что:

...
"length": {
"index": "not_analyzed",
"doc_values": true,
"type": "long"
},
"size": {
"index": "not_analyzed",
"doc_values": true,
"type": "long"
},
"count": {
"index": "not_analyzed",
"doc_values": true,
"type": "integer"
},
...

После изменения отображения заполняемость одного и того же набора данных значительно улучшилась:

long-template

от287.91MBсокращено до236.25MB, Сохранено51.66MBКосмос.

Сократите ненужные поля

Взглянув еще раз на сами данные, есть ли еще место для оптимизации?

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

такой жеidПоля также можно оптимизировать.idПервоначальная цель поля заключалась в назначении уникальногоid, когда logstash пишет в ES указать уникальность документаid(Это может предотвратить повторный ввод данных):

output {
if (type == "minute") {
elasticsearch {
hosts => ["es.sample.com:9200"]
flush_size => 10000
index => "minute-%{+YYYY.MM}"
document_id => "%{id}"
}
}
}

Однако ЭС будетidПолевые записи в_idполе, а в записи документаid. Эта часть данных может быть оптимизирована.

Однако удалять эти поля с помощью mutate непосредственно в фильтре нецелесообразно, поскольку они также используются в выводе.

Решение очень простое, можно переписать@metadataданные в , затем удалите эти поля и, наконец, используйте@metadataДанные дополняют существующую роль этих полей.

filter {
mutate {
add_field => {
"[@metadata][id]" => "%{id}"
"[@metadata][type]" => "%{type}"
}
remove_field => [ "id", "type" ]
}
}

output {
if ([@metadata][type] == "minute") {
elasticsearch {
hosts => ["es.sample.com:9200"]
flush_size => 10000
index => "minute-%{+YYYY.MM}"
document_id => "%{[@metadata][id]}"
}
}
}

После этого размер индекса изменится на175.21MB:

long-template

После двух указанных выше способов размер индекса уменьшается.112.7MB, коэффициент потери веса39.1%, эффект замечательный.

о@metadata, допустимыйздесьУзнать больше.

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

Включение сегментации слов для всех полей столь же расточительно, как и лишние поля.2.xВерсия устанавливает соответствующее поле в файле шаблона наnot_analyzedВот и все.

Примечания по использованию индексов

количество индексов

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

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

Слишком много индексов приведет к слишком большому количеству осколков Проблема, вызванная слишком большим количеством осколков, заключается в скорости восстановления.1.xСкорость восстановления версии ES чрезвычайно впечатляет, а давление ввода-вывода между кластерами довольно велико.2.xНесмотря на значительное улучшение, скорость восстановления положительно связана с количеством осколков.

Проблема на GitHubCreating Index painfully slow on cluster with large indicesупоминается в:

When you create an index, that causes a change to the routing table. A cluster state update task is submitted to the nodes in the cluster. When that cluster state update task arrives, each node must process the new routing table to see if they need to remove indices, delete shards, start shards, etc. Currently, applying deleted shards is O(number of indices * number of shards). I opened #18788 to address this.

Тем не менее, вы все равно будете здесь страдать.Имея 10000 индексов на двух узлах с одной репликой, вы напрашиваетесь на боль.Это означает, что у вас есть как минимум 10000 осколков на каждом узле, если у вас есть один осколок на индекс, и, возможно, 50000 осколки на каждом узле, если вы используете количество осколков по умолчанию на индекс. В любом случае, это слишком много осколков. Таким образом, #18788 не предназначен для непосредственного решения вашей проблемы, просто для повышения производительности в общем случае. нужно сделать что-то о том, сколько у вас индексов и осколков.

Проще говоря, если в кластере ES будет слишком много индексов, это напрямую повлияет на добавление и модификацию индексов, потому что эти операции нужно блокировать Мастеру.

Если время обнаружения кластера истеклоdiscovery.zen.ping.timeoutЕсли конфигурация слишком низкая, если кластер слегка нагружен, это даже напрямую приведет к потере Мастера, и весь кластер войдет в период недоступности.

С другой стороны, индексы в ES будут организованы в файлы.Если индексов и сетевых подключений слишком много, это может привести к тому, что процесс достигнет предела FD, которые можно открыть.too many open filesПроблемы, приводящие к невозможности подключения к ЭП, приводящие к недоступности услуг, хотя это может бытьДинамически изменять, но не принципиальное решение в конце концов.

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

индекс слияния

elasticsearch-dumpЭто хороший инструмент, написанный на основе Node, который легко выполняет эту функцию.

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

./elasticdump/bin/elasticdump --input=http://es.sample.com:9200/pv-2016* --output=pv-2016.json

./elasticdump/bin/elasticdump --input=pv-2016.json --output=http://es.sample.com:9200/pv-2016/

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

индексировать заранее

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

использованная литература

Полное руководство по ELKStack (2-е издание)