Статьи

Производительность MySQL: влияние распределителей памяти (часть 2)

Это сообщение от Алексея Строганова из MySQL Performance Blog.

В прошлый раз я писал о распределителях памяти и о том, как они могут повлиять на производительность MySQL в целом. На этот раз я хотел бы исследовать эту тему с несколько иной точки зрения: какое влияние оказывает количество ядер процессора на разные распределители памяти и какую разницу мы увидим в производительности MySQL в этом сценарии?

Позвольте мне сначала сделать вывод: если у вас есть сервер с более чем 8 ядрами, вы должны использовать что-то отличное от используемого по умолчанию распределителя памяти glibc.
Мы рекомендуем jemalloc или tcmalloc
.

В моем тесте я буду использовать Dell R720 box ( spec ), Centos 6.3, предстоящий Percona Server 5.5.30 и 3 распределителя — стандартный glibc 2.13, jemalloc-3.1.0, последний tcmalloc из svn repo. Относительно моего выбора версии jemalloc см. Мои заметки в конце этого поста.

Тестовый блок имеет 2xIntel E5 / 2,2 ГГц с 8 реальными ядрами на сокет — 16 реальных ядер + включенная гиперпоточность дает нам всего — 32 vcpu. В своих тестах я не видел заметной разницы между распределителями до 4 vcpu, поэтому на графиках ниже я выделю результаты от 4 до 32 vcpu.

В качестве тестовой рабочей нагрузки я буду использовать те же 2 теста sysbench — OLTP_RO и POINT_SELECT, которые я использовал ранее.
Набор данных Sysbench — 16 таблиц, каждая 5M строк, равномерное распределение.

Тест OLTP_RO состоит из 5 запросов выбора — select_ranges, select_order_ranges, select_distinct_ranges, select_sum_ranges, point_select. Обработка этих запросов потребует заметного количества операций malloc () / free (), поэтому эффективность распределителя является ключевым фактором для достижения высокой пропускной способности в этом тесте.


malloc_test2_oltp_ro

Замечания:

  • 4 vcpu — результаты практически идентичны для всех распределителей (~ 2500tps)
  • 8 vcpu — удвоенные результаты (~ 5000tps) для jemalloc и tcmalloc , но с помощью glibc malloc мы сократили потоки с 64/128 до ~ 3500tps
  • 16vcpu — увеличение пропускной способности и довольно стабильные результаты для jemalloc и tcmalloc до 4096 потоков (~ 6300tps) и снова падение после 16 потоков для glibc до ~ 4000tps
  • 32vcpu — пропускная способность для jemalloc и tcmalloc возросла до ~ 12500tps, результаты остаются на этом уровне до 1024 потоков, а затем немного уменьшаются, но все равно выглядят нормально. Для glibc tps падает ниже результатов, которые мы наблюдали для 8/16 vcpu (~ 3100tps).

Таким образом, разница в тесте OLTP_RO между glibc и jemalloc / tcmalloc в случае 32vcpu составляет ~ 4x.

POINT_SELECT — очень простой запрос — SELECT c ОТ sbtest WHERE id = N. Тестовая нагрузка с этим запросом
позволяет генерировать значительную нагрузку и проверять поведение сервера под очень высоким давлением

malloc_test2_point_select

Замечания:

  • 4 vcpu — опять нет разницы между распределителями (~ 50,000qps)
  • 8 vcpu — со всеми распределителями мы получили ~ 100,000qps. Результаты для jemalloc / tcmalloc стабильны до 4096 потоков, для glibc malloc наблюдается снижение qps для потоков 2048/4096 до ~ 80.000qps.
  • 16vcpu — со всеми распределителями мы получили ~ 140,000qps. Для jemalloc / tcmalloc до 4096 потоков, для glibc до 512 потоков, затем уменьшите пропускную способность до 100000qps.
  • 32vcpu — со всеми распределителями мы получили ~ 240,000qps. Затем для каждого распределителя мы имеем снижение пропускной способности, но в другой точке и на другом уровне.
    — для glibc удаление malloc после 256 потоков, qps ниже уровня для 8/16 vcpu. (~ 80,000qps).
    — для tcmalloc падение произошло после 1024 потоков, при 2048 потоках qps очень близко к результатам для 16vcpu и при 4096 потоках qps составляет ~ 17000.
    — для jemalloc падение также произошло после 1024 потоков, в 2048 потоках qps очень близок к результатам для 16vcpu и в 4096 потоках — qps немного лучше, чем результаты для 4vcpu (~ 60,000qps). Как вы можете видеть в случае очень высокий параллелизм и заметное количество малых / средних распределений, у нас довольно плохие результаты для jemalloc / tcmalloc. Даже хуже чем для glibc. Это очень специфический случай, когда издержки от продвинутых методов, используемых в этих распределителях, которые должны помочь ускорить выделение, очистить грязные страницы, минимизировать влияние фрагментации памяти, настолько значительны, что становятся узким местом для обработки запросов. Я считаю, что оба распределителя могут быть настроены так, чтобы лучше обрабатывать такие случаи — например, выделять больше арен, но это может заметно увеличить объем памяти.

Вывод:
— если на вашем компьютере 8 ядер или меньше — между glibc malloc и альтернативными распределителями почти нет различий
— если на вашем компьютере более 8 ядер — вам следует попробовать / оценить альтернативные распределители; это может заметно увеличить ваш сервер MySQL бесплатно . Кроме того, альтернативный распределитель должен использоваться, если вы запускаете тесты производительности в этой конфигурации, в противном случае производительность будет ограничена glibc / malloc, а не MySQL.

Примечания относительно версии jemalloc, которую я использовал в своих тестах: я заметил заметное влияние на производительность MySQL после версии 3.2.0 (см. Необработанные результаты ниже), поэтому я использовал jemalloc-3.1.0 в своих тестах. Я предполагаю, что некоторые изменения в 3.2.0, такие как, например, изменения перераспределения страниц и очистки грязных страниц, могут иметь некоторую корреляцию с уменьшением производительности в рабочих нагрузках с MySQL.

# Test: POINT_SELECT:throughput, QPS
#
# Set 1 - 5.5.30pre-jemalloc-3.0.0
# Set 2 - 5.5.30pre-jemalloc-3.1.0
# Set 3 - 5.5.30pre-jemalloc-3.2.0
# Set 4 - 5.5.30pre-jemalloc-3.3.0
#
# Threads        Set 1     Set 2     Set 3     Set 4 
       1024  236575.74 236862.59 211203.42 215098.20
       2048  154829.26 154348.16 135607.69 137162.29