Ответ 1
Питер описал общие варианты JVM, доступные сегодня, чтобы снизить влияние NUMA-характеристик на производительность. Чтобы это было коротко, JVM, поддерживающий NUMA, будет разбивать кучу по отношению к узлам NUMA, а когда поток создает новый объект, объект выделяется в NUMA node ядра, который запускает этот поток (если тот же поток позже использует его, объект будет находиться в локальной памяти). Кроме того, при уплотнении кучи NUMA JVM избегает перемещения больших блоков данных между узлами (и уменьшает длину событий stop-the-world).
Таким образом, на любом аппарате NUMA и для любого Java-приложения вероятно должна быть включена опция -XX: + UseNUMA.
Но для ActivePivot это мало помогает: ActivePivot - это база данных в памяти. Существуют обновления в режиме реального времени, но основная часть данных хранится в основной памяти в течение всего срока службы приложения. Независимо от параметров JVM данные будут разделены между узлами NUMA, а потоки, выполняющие запросы, будут случайным образом получать доступ к памяти. Зная, что большинство разделов механизма запросов ActivePivot работают так же быстро, как память, могут быть извлечены, влияние NUMA особенно заметно.
Итак, как вы можете извлечь максимальную пользу из своего решения ActivePivot на аппарате NUMA?
Существует простое решение, когда приложение ActivePivot использует только часть ресурсов (мы обнаруживаем, что часто бывает, что несколько решений ActivePivot работают на одном сервере). Например, решение ActivePivot, использующее только 16 ядер из 64 и 256 ГБ из TeraByte. В этом случае вы можете ограничить сам процесс JVM NUMA node.
В Linux вы префикс запуска JVM со следующей опцией (http://linux.die.net/man/8/numactl):
numactl --cpunodebind=xxx
Если весь сервер посвящен одному решению ActivePivot, вы можете использовать распределенную архитектуру ActivePivot для разделения данных. Если есть 4 узла NUMA, вы запускаете 4 JVM, на которых размещаются 4 узла ActivePivot, каждый из которых привязан к NUMA node. С помощью этого развертывания запросы распределяются между узлами, и каждый node будет выполнять свою долю работы при максимальной производительности в пределах правой NUMA node.