Производительность , особенно предсказуемая, становится приоритетом с каждым выпуском Hazelcast. Одна из проблем производительности в выпусках до 3.5 заключается в том, что между бенчмарками — каждый бенчмарк получает новый кластер — часто бывают большие колебания производительности, хотя производительность во время бенчмарка довольно стабильна.
Например, если у нас есть базовый тест карты, который выполняется с использованием нашего распределенного инструмента тестирования нагрузки / производительности Hazelcast Simulator .
class=com.hazelcast.simulator.tests.map.StringStringMapTest
threadCount=40
keyLocality=Random
keyLength=20
valueLength=100
keyCount=10000
valueCount=1000
putProb=0.0
basename=map
logFrequency=100000
probe-getLatency = latency
probe-putLatency = latency
Это тест карты вызова IMap.get от случайных членов в IMap. Если мы запустим нашу старую тестовую лабораторию с 4 узлами (4 Xeon Sandy Bridge Boxs с двумя сокетами и сетью 1 GbE) в течение 5 минут на запуск, и мы запустим ее 10 раз, мы получим следующие данные:
Выполнить операции / сек 1 +487785,57666666666 2 412653,88 3 527906,43 4 492721,67 5 +438349,95666666667 6 435373.49 7 +516845,0466666667 8 457152,36666666664 9 439493,16 10 +496815,06666666665 Операции / мин второй 412653,88 527906,43 макс ср 470509.664333333
Как видите, разница между минимумом и максимумом огромна. Самый быстрый пробег на 28% быстрее самого медленного. Такие большие различия в производительности между запусками очень раздражают:
- это затрудняет использование Hazelcast в производственной среде, поскольку трудно предсказать, какой будет производительность.
- это делает настройку производительности практически невозможной, потому что мы не знаем, сделали ли мы что-то быстрее или нам повезло.
После добавления всех видов специальных метрик в систему, чтобы выяснить, что происходит, мы, наконец, поразили золото, когда начали отслеживать количество обработанных событий для каждого селектора.
in-0.readEvents=1519057
in-1.readEvents=6076514
in-2.readEvents=4
out-0.writeEvents=13867449
out-1.writeEvents=6
out-2.writeEvents=8701814
Как вы можете видеть, первые входные и выходные переключатели полностью несбалансированы по сравнению с другими переключателями. Вы можете спросить себя: «Что делают эти селекторы?». В Hazelcast мы используем неблокирующий ввод-вывод в сочетании с селекторами . Это позволяет обрабатывать многие соединения всего несколькими потоками. Каждый селектор обрабатывается одним потоком, и по умолчанию у нас есть 3 входных селектора и 3 выходных селектора. Если поток ввода ожидает данных для чтения из буферов сокетов, он получит событие чтения от селектора ввода, и значение readEvents увеличивается. И каждый раз, когда выходной поток получает событие записи, после ожидания свободного места в буферах сокетов, writeEvents увеличивается.
В кластере из 4 узлов должно быть 3 соединения на узел, так как узел не должен подключаться сам. Используя 3 входных и 3 выходных селектора, соединения должны быть идеально распределены по селекторам; но, как вы можете видеть, это не так. Следствием этого дисбаланса является то, что элемент получает несбалансированную нагрузку на селекторы, и это заставляет систему работать неоптимально. Время от времени вы получаете супер отличную производительность, когда каждый узел идеально сбалансирован, но в большинстве случаев большинство участников имеют дисбаланс.
Почему возникает дисбаланс?
Следующий вопрос, на который нужно ответить: почему возникает дисбаланс? Ответ заключается в одновременном запуске узлов Hazelcast. Когда узлы не сформировали кластер, они пытаются соединиться со всеми другими хорошо известными IP-адресами, и это может привести к дублированию соединений между участниками, когда они пытаются связаться друг с другом. В конце концов, используется только одно соединение, но это дублирующее соединение вызывает проблему в механизме назначения циклического соединения между селектором и селектором.
Чтобы доказать эту теорию, я добавил хак, который по умолчанию отключен, который заставляет соединения с одного хоста всегда заканчиваться одним и тем же селектором. Взлом может быть включен в Hazelcast 3.4 с помощью следующей настройки JVM ‘-Dhazelcast.selectorhack.enabled = true’. Он должен использоваться только для экспериментов.
После того, как я добавил хак и сделал несколько сравнительных тестов, селекторы теперь идеально сбалансированы:
in-0.readEvents=2220801
in-1.readEvents=2412388
in-2.readEvents=2514934
out-0.writeEvents=6159812
out-1.writeEvents=6108344
out-2.writeEvents=6155557
Но какое влияние оказывает взломщик на производительность? Когда мы запустим его снова, но с включенным взломом селектора, мы получим следующие данные:
Выполнить операций / секунду 1 568136.3033333333 2 580225.72 3 550599.2766666666 4 560531.0966666667 5 548103.9666666667 6 544054.8133333334 7 554470.4433333334 8 539209,21 9 552880,8966666666 10 532643 566 5,6 5 5 5 5 5 5 5 5 5 5 5 5 5 7 5 5 5 5 5 6 5 5 5 6 5 5 5 6 7 5 5 6 5 5 565 526 5 6 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 5 6 6 6 5 6 6 6 6 6 ВПЕ ВНУТРЕННИХ ДАННЫХ 5 564643 566 Операции 5 532643 532 Операции 5 532643 532 Операционные показатели 532643,566 525 Оперативная часть 532643,566 525 Операционные показатели 532643 566 525 Оперативные единицы 532643,566 525 Операционные показатели 532643,566 Операции 532643 566 525 Операционные / сек.
Разница в производительности между минимальным и максимальным составляет всего 9%; Сравните это с разницей в производительности 28%, когда взломать отключен Кроме того, средняя пропускная способность увеличилась на 18%!
С отключенным взломом селектора время от времени вы получаете очень хорошую производительность, если нет дисбалансов. С включенным взломом селектора вы всегда получите эту хорошую производительность.
IO-балансир
В Hazelcast 3.5 мы заменили селектор-хак на правильное решение под названием IO-балансировщик. Периодически проверяет селекторы и проверяет дисбаланс. При обнаружении дисбаланса самое загруженное соединение из самого загруженного селектора, имеющего как минимум 2 соединения, переносится в наименее загруженный селектор. По умолчанию балансировщик ввода-вывода проверяет такое мигрируемое соединение каждые 20 секунд, но это можно изменить с помощью свойства -Dhazelcast.io.balancer.interval.seconds = seconds. Если установлено отрицательное значение, IO-балансировщик отключен.
IO-балансировщик не только полезен для одновременных проблем запуска узла; это также очень полезно в средах, где участники присоединяются и покидают кластер. То, что находится в идеальном балансе в какой-то момент времени, может выйти из равновесия чуть позже, если участник присоединится или уйдет. Еще одна интересная вещь — клиенты полагаются на тот же механизм подключения, что и участники, поэтому они также получают баланс! Клиенты в большинстве случаев менее постоянны, чем члены кластера.
В Hazelcast 3.6 мы добавим новую функцию под названием «Метрики». Он будет предоставлять все виды внутренних проб и периодически записывать их в файл. Это должно обеспечить глубокое понимание того, что происходит. Конечно, селекторы являются одним из ключевых датчиков в системе метрик.
Будьте на связи!
Не забудьте, вы можете получить 30-дневную бесплатную пробную версию, чтобы проверить Hazelcast Enterprise! Скачать сейчас «