Падает эластик после обновления до 6.4

Добрый день!

Раньше я использовал elasticsearch 5.1 на одной виртуальной машине (4Gb RAM, 4 CPU). Heap 1Gb (при 2-х почему-то эластик вылетал), объем данных 20Gb. Все работало долго и стабильно. Затем решил обновиться до последней версии и перенести данные в новое место.

Настроил тестовый кластер из 3 нод (мастер-нода и 2 дата-ноды - 4Gb RAM, 2 CPU, Centos7.5). Все настройки в соответствии с рекомендованными в документации.
bootstrap.memory_lock: true, minimum_master_nodes: 2, -Xms2g, -Xmx2g.

После 3-х часовой индексации данных (индекс - 3 шарды, 1 реплика) получаю OutOfMemoryError: Java heap space. Никаких поисковых запросов нет вообще. На одной старой ноде в 5.1 все работает без проблем вместе с поиском.

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

Последние логи:

нода 1

[2018-09-27T02:21:23,750][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-1] fatal error in thread [elasticsearch[node-1][refresh][T#1]], exiting

java.lang.OutOfMemoryError: Java heap space

at org.apache.lucene.util.packed.DirectMonotonicWriter.<init>(DirectMonotonicWriter.java:56) ~[lucene-core-7.4.0.jar:7.4.0 9060ac689c270b02143f375de0348b7f626adebc - jpountz - 2018-06-18 16:51:45]

[2018-09-27T02:21:23,752][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-1] fatal error in thread [elasticsearch[node-1][search][T#4]], exiting

java.lang.OutOfMemoryError: Java heap space

at org.apache.lucene.util.packed.DirectMonotonicReader.getInstance(DirectMonotonicReader.java:96) ~[lucene-core-7.4.0.jar:7.4.0 9060ac689c270b02143f375de0348b7f626adebc - jpountz - 2018-06-18 16:51:45]

нода 2

[2018-09-27T02:10:10,784][WARN ][o.e.m.j.JvmGcMonitorService] [node-2] [gc][219589] overhead, spent [6s] collecting in the last [6.2s]

[2018-09-27T02:16:35,849][WARN ][o.e.t.n.Netty4Transport  ] [node-2] send message failed [channel: NettyTcpChannel{localAddress=0.0.0.0/0.0.0.0:9300, remoteAddress=/10.135.94.206:36596}]
java.nio.channels.ClosedChannelException: null
  at io.netty.channel.AbstractChannel$AbstractUnsafe.write(...)(Unknown Source) ~[?:?]

[2018-09-27T02:16:02,863][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-2] fatal error in thread [elasticsearch[node-2][search][T#2]], exiting
java.lang.OutOfMemoryError: Java heap space
  at java.util.stream.SpinedBuffer.ensureCapacity(SpinedBuffer.java:143) ~[?:1.8.0_181]
  at java.util.stream.SpinedBuffer.increaseCapacity(SpinedBuffer.java:154) ~[?:1.8.0_181]
  at java.util.stream.SpinedBuffer.accept(SpinedBuffer.java:258) ~[?:1.8.0_181]
  
[2018-09-27T02:22:13,604][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-2] fatal error in thread [elasticsearch[node-2][search][T#1]], exiting
java.lang.OutOfMemoryError: Java heap space

node-1-%20advanced

есть еще heapdump (2,6Gb)

Похоже, что машина падает не из-за индексации, а из-за поиска. Вы когда данные переносили, вы схему индекса не изменили?

Да, нет, не изменял. Маппинг один в один, только реплику 1 добавил.

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

А когда у вас 1 машина была - поиск проходил нормально?

Да, нормально.

А как он с 2G падал?

Это я уже подзабыл, года полтора назад падал. Я тогда просто экспериментально подобрал такие параметры 4Gb оперативы и 1Gb куча и все стало стабильно.

Там сейчас такая картинка:

Правда тоже есть непонятный мне момент из-за которого я и захотел переходить на новую версию. Где-то раз в 1-2 месяца вдруг резко и необоснованно начинает расходоваться жесткий диск. У меня там диск 40 Gb, обычно свободно 11-13. В такие моменты бывает место на диске кончается совсем, хотя объем загружаемых данных такой же как всегда.

Надо копать в поиске. Возможно, что между 5.1 и 6.4 что-то изменилось, что вызывает использование дополнительной памяти. Как этот поиск выглядит и какая версия elasticsearch у вас стоит? 6.4.0 или 6.4.1?

Версия - 6.4.1

На всякий случай опишу как переносил информацию. Вначале поставил 5.6 и сделал тот же маппинг у всех индексов. Запустил reindex from remote. Затем обновил до 6.4.1. Пробовал из kibana запускать upgrade helper - .kibana index обновился, а .watches и .triggered_watches выдавал ошибки.
Теперь в логах ругается на эти индексы (не знаю что с этим делать):

[WARN][o.e.x.w.WatcherService] [node-2] not starting watcher, upgrade API run required: .watches[false], .triggered_watches[false]

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

  1. В 0:00 стартует обработка, которая только загружает информацию в эластик (без поиска) с помощью upserts. Длится 1 ч. 15 мин. Загружает примерно 1 млн документов.

  2. В 1:15 стартует другая обработка, которая в течении 30 мин посылает 3500 поисковых запросов к эластику (в которых используется bool query, match query, function score, filters); 3500 запросов с различными metrix aggregations и 3500 запросов с filters aggregation

  3. С 2 до 5 ничего не происходит

  4. С 5 до 5:22 эластик умирает с такими сообщениями (в логах время UTC на 3 ч меньше):

     [2018-09-28T02:10:04,958][WARN ][o.e.m.j.JvmGcMonitorService] [node-1] [gc][63779] overhead, spent [2.6s] collecting in the last [2.9s]
    
     [2018-09-28T02:16:01,937][WARN ][o.e.a.b.TransportShardBulkAction] [node-1] [[.monitoring-kibana-6-2018.09.28][0]] failed to perform indices:data/write/bulk[s] on replica [.monitoring-kibana-6-2018.09.28][0], node[1Xk1Ls-zSCWK9_FHxaTEaQ], [R], s[STARTED], a[id=4a4Ce9irRYaoR935PmLgFw]
    
     [2018-09-28T02:15:38,896][INFO ][o.e.m.j.JvmGcMonitorService] [node-2] [gc][old][63793][59] duration [27.9s], collections [5]/[28s], total [27.9s]/[4.9m], memory [1.9gb]->[1.9gb]/[1.9gb], all_pools {[young] [133.1mb]->[133.1mb]/[133.1mb]}{[survivor] [15.3mb]->[16.6mb]/[16.6mb]}{[old] [1.8gb]->[1.8gb]/[1.8gb]}
    
     [2018-09-28T02:15:38,897][WARN ][o.e.m.j.JvmGcMonitorService] [node-2] [gc][63793] overhead, spent [27.9s] collecting in the last [28s]
    
     [2018-09-28T02:19:49,963][ERROR][o.e.t.n.Netty4Utils ] fatal error on the network layer
    

node-1

Относительно 5.1 в работе приложения ничего не менялось. Странно, что вылет происходит не в период пиковой активности, а в период простоя. (Если быть совсем точным, то почти простоя. С 5 до 5:10 запускается обработка, аналогичная первой без поиска и обрабатывает всего несколько тысяч документов)

Единственное отличие в структуре индексов - наличие реплики в 6.4. Может это повлияло?

С 5 до 5:10 запускается обработка, аналогичная первой без поиска и обрабатывает всего несколько тысяч документов)

Аналогичная первой или точно такая же? У вас в этой обработки агрегация стоит, которая сервер убивает.

Игорь, естественно, вы абсолютно правы! Я искал совсем не там, где была собака зарыта. Помимо точно такой же обработки как и первая, оказывается одновременно запускалась еще одна. И она была с совершенно гигантской 3-х уровневой агрегацией и очень большим количеством корзин. Я про нее давно забыл, а в 5.1 она у меня сразу отваливалась с какой-то другой некритичной ошибкой. Так что дело было именно в этом одном запросе.

Спасибо большое за помощь! Можно вам заодно задать еще пару небольших вопросов в этой ветке?

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

Я заметил, что время отклика эластика в конфигурации из 3-х нод с 2-х процессорными машинами у меня упало по сравнению с 5.1 на одной машине с 4 CPU. (search latency - было до 100 мс, стало до 250 мс). Причем 5.1 стоит на одной машине вместе с веб-сервером, а 6.4 отдельно. Я ожидал, что вместе с дополнительной устойчивостью (что в моем случае пока не подтвердилось :grinning:), я получу и улучшение респонса, т.к. поиск должен быть одновременно по основному индексу и по реплике…

Может в моем случае не имеет большого смысла использовать несколько машин, а вместо этого взять одну помощнее? Или может быть нужно сделать индекс с 2-мя, а не 3-мя шардами и не делать реплики?

И по поводу кучи еще вопрос. В статье A Heap of Trouble говориться, что если куча используется на 65%, то ее размер слишком большой. У меня сейчас получается где-то так или меньше. Не стоит ли мне поставить ее размер обратно в 1Gb как было на старом сервере? Нужно ли применять какие-то дополнительные настройки JVM или оставить все по дефолту?

Скорее всего это время, которое уходит на пересылку информации по сети. У вас сеть быстрая?

Если вы время от времени запросы агрегации которые используют большое количество field data посылать не будете - то думаю, что имеет смысл. Сейчас у вас эта память используется только для накопления мусора.

По умолчанию стоит

-Xms1g
-Xmx1g

Так что можно оставить по дефолту.

Игорь, спасибо! Я тоже подумал про сеть, хотя она и должна быть быстрой - все в одном дата-центре.

Еще один вопрос применительно к потреблению памяти из-за агрегаций. Я не совсем понимаю как быть, если мне нужно в terms aggregation вернуть все корзины (size = очень большое значение) в условиях ограниченной памяти. Может быть нужен какой-то другой подход?

Зависит от конкретного случая. Например, для terms - можно воспользоваться partitions, если бакетов много - можно посмотреть на composite aggs.

Понял, спасибо!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.