Большой размер виртуальной памяти ElasticSearch JVM
Я использую JVM для поддержки ElasticSearch. Я все еще работаю над определением размеров и настроек, поэтому я оставил максимальный размер кучи JVM по умолчанию в ElasticSearch, равном 1 ГБ. После помещения данных в базу данных, я обнаружил, что процесс JVM показывает 50 ГБ в размере в top
выход. Похоже, что это на самом деле вызывает проблемы с производительностью в системе; другие процессы имеют проблемы с распределением памяти.
Задавая вопрос сообществу ElasticSearch, они предположили, что это "просто" кэширование файловой системы. По моему опыту, кеширование файловой системы не отображается как память, используемая определенным процессом. Конечно, они могли говорить о чем-то ином, чем кеш файловой системы ОС, возможно, о чем-то, что JVM или ElasticSearch делают поверх ОС. Но они также сказали, что он будет выпущен в случае необходимости, и этого, похоже, не происходит.
Так может кто-нибудь помочь мне понять, как настроить JVM, или, может быть, сам ElasticSearch, чтобы не использовать так много оперативной памяти.
Система Solaris 10 x86 с 72 ГБ оперативной памяти. JVM - это среда выполнения Java(TM) SE (сборка 1.7.0_45-b18).
1 ответ
Я почти уверен, что ответ, который вы получили от сообщества ElasticSearch, касается ZFS ARC (Adaptive Replacement Cache). Это, конечно, предполагает, что ваша файловая система ZFS?
На ZFS ARC потенциально займет все доступное ОЗУ на хосте менее 1 Гб. Так на ZFS-хосте такие инструменты, как top
иногда будет показывать, что ваша физическая память близка к пределу, даже если это не так. Это по замыслу. ARC автоматически освободит память для процессов, которые нуждаются в памяти. То, какая память использует ARC, считается памятью ядра, поэтому вы не сможете увидеть ее в выводе процесса.
В большинстве систем Solaris, на которые я смотрю ежедневно, физическое потребление ОЗУ составляет около 90%. Это не потому, что они очень загружены, это ZFS, которая захватывает неиспользуемую оперативную память для своих собственных целей. Не пугайтесь этого. Поскольку ARC является частью ядра, она может освобождать память для процессов, которые нуждаются в ней, так сказать, со скоростью света. Следовательно - хотя вы можете - я обычно не вижу смысла в ограничении размера ZFS ARC. Лучше позволить ZFS делать свою работу.
Итак, если мы говорим о ZFS, то да, кеширование файловой системы не отображается как потребление памяти отдельным процессом. Вам нужно выполнить что-то вроде:
echo "::memstat" | mdb -k
чтобы показать, как ваша память на самом деле используется. Строка "Anon" охватывает все процессы пользователя земли, которые вы видите, например, prstat
выход.
Другая вещь, которую вы должны знать, - это то, как JVM работает с точки зрения выделения памяти и освобождения памяти. JVM захватывает память из ОС, так как она нуждается только в ограничении JVM -Xmx
параметр командной строки. Открытый вопрос: как (если когда-либо) JVM освободит память обратно в ОС, если она больше не нужна? Вы обнаружите, что найти информацию по этому вопросу очень сложно. Кажется, это зависит от того, какой сборщик мусора используется. Поскольку трудно получить точную информацию по этому вопросу (не знаю, почему на самом деле), лучшим вариантом будет предположить, что JVM крайне неохотно высвобождает память обратно в ОС. Другими словами: если вы позволите процессу JVM захватить, скажем, 50 ГБ памяти, то вам лучше быть в состоянии, когда вы можете себе это позволить постоянно, а не предполагать, что это просто взрыв.
Поэтому, если вы хотите ограничить объем памяти, который может потреблять процесс ElasticSearch, вам нужно изучить параметры командной строки JVM, в частности -Xmx
вариант.