Назад | Перейти на главную страницу

Выбор размера ОЗУ для Linux-машины, на которой запущено несколько Tomcats

У нас есть производственные серверы, работающие под Debian Linux, на которых размещены несколько загруженных экземпляров Tomcat, базы данных и службы поддержки. Системы работали стабильно в течение нескольких лет, но в последнее время мы, кажется, наблюдаем замедление и проблемы с памятью.

За это время приложения, размещенные на Tomcats, выросли в размерах, увеличилось количество пользователей, больше экземпляров Tomcat. Похоже, мы начинаем работать с ограничениями памяти машины.

Я начал знакомиться с мониторингом памяти с помощью таких инструментов, как htop и Java JMX, пытаясь определить текущие требования к памяти. Обозначенные регуляторы на стороне JVM являются переключателями, например, для установки максимального и начального размера пространства кучи. Параметры мониторинга памяти - виртуальная VIRT и зарезервированная память RES.

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

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

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

Прежде чем я начну использовать метод проб и ошибок пополам, увеличивая ОЗУ и измеряя результирующую производительность системы, пока мы не достигнем более спокойной воды, я опубликовал этот вопрос в надежде, что могут быть средства для более точной оценки требований к ОЗУ.

Обновить:

$ cat /proc/meminfo
MemTotal:       66075980 kB
MemFree:         2117304 kB
Buffers:          396328 kB
Cached:          9286764 kB
SwapCached:       794700 kB
Active:         53198584 kB
Inactive:       10075240 kB
Active(anon):   50010632 kB
Inactive(anon):  3587764 kB
Active(file):    3187952 kB
Inactive(file):  6487476 kB
Unevictable:        5604 kB
Mlocked:            5604 kB
SwapTotal:       4194300 kB
SwapFree:            324 kB
Dirty:             49460 kB
Writeback:            72 kB
AnonPages:      52802056 kB
Mapped:            89356 kB
Shmem:              4448 kB
Slab:             388132 kB
SReclaimable:     324892 kB
SUnreclaim:        63240 kB
KernelStack:       11360 kB
PageTables:       126924 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    37232288 kB
Committed_AS:   47441088 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      386700 kB
VmallocChunk:   34325801336 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       93868 kB
DirectMap2M:     8259584 kB
DirectMap1G:    58720256 kB
$

Как упоминал асктяги, возможно, на вашем хосте просто запущено слишком много приложений. В общем, запуск множества JVM на одном хосте может вызвать всевозможные конфликты за ресурсы, где память является только одним из них - другой пример - потоки сборщика мусора, конкурирующие за ЦП, дисковый ввод-вывод и т. Д.

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

Чтобы узнать, сколько памяти требуется вашей программе, необходим надлежащий мониторинг. Вы можете начать экспериментировать на своем локальном компьютере с базовым профилировщиком, таким как VisualVm, наблюдая за поведением GC и пробуя различные настройки -Xmx. Вы также можете попробовать другой алгоритм GC (например, Shenandoah) в зависимости от вашей рабочей нагрузки и того, насколько важны требования к задержке / пропускной способности.

В кластере вам следует включить журналы сборки мусора и, возможно, включить профилирование с минимальными затратами через Java Flight Recorder. Позже вы можете использовать такие инструменты, как jClarity's Censum, чтобы получить представление о журналах GC.

Важно понимать, что вы не можете просто «угадать» требования к памяти вашего приложения, глядя на текущие уровни потребления памяти - JVM будет пытаться использовать столько памяти, сколько вы ей даете, поэтому, если она потребляет 10 ГБ, ей не нужно значит ему это нужно. Он может быть вполне удовлетворен всего лишь 1 ГБ (и даже более производительным, поскольку паузы GC могут быть короче).

В качестве побочного примечания, чрезмерная приверженность (проявляющаяся убийцей OOM) может быть плохой вещью (см. http://www.etalabs.net/overcommit.html), особенно для серверных машин - вы можете полностью отключить свопинг.

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

Если вы по-прежнему хотите рассчитать объем памяти, вам необходимо получить статистические данные о тенденциях использования памяти приложений на основе количества потоков и отчетов о трафике. Это также зависит от других факторов, таких как другие приложения, размещенные на том же компьютере и т. Д.

Надеюсь, это поможет.