13.4.23

Running SQL Server on Machines with More Than 8 CPUs per NUMA Node May Need Trace Flag 8048

По материалам статьи: Running SQL Server on Machines with More Than 8 CPUs per NUMA Node May Need Trace Flag 8048

Данная статья относится к следующим версиям SQL Sever: 2008, 2008 R2, 2012 и 2014. Первый вариант статьи был опубликован в 2011г.

Примечание: в данной статье под количеством процессоров подразумеваются не сокеты, а представленные в системе логические процессоры. Рекомендации статьи применимы в тех случаях, когда для сервера баз данных доступно более восьми логических процессоров.

В зависимости от того, для каких нужд SQL Server использует память, дизайн ядра сервера баз данных предусматривает возможность секционирования распределения памяти. В процессе разработки SQL Server можно было выбирать схему секционирования исполнителя по процессорам, узлам или глобально. Некоторые связанные с распределением памяти функциональные модули SQL Server используют модуль распределения CMemPartitioned. Этот модуль секционирует память по процессорам или NUMA узлам, что может способствовать повышению параллелизма и производительности.

CMemPartitioned можно считать обычной «кучей» (хотя это и не HeapCreate), поскольку используется одна и та же концепция. Если при создании «кучи» вам нужны синхронизированные оценки, то вы можете указать размер по умолчанию и другие атрибуты. Обычно, когда созданию объектов памяти причастны разработчики SQL Server, они обеспечивают индикацию того, что будет задействовано что-то вроде защищённого поточного доступа, схемы секционирования и другие опции.

Разработчик инициирует создание объекта, и потом, когда происходит новое распределение, всё будет происходить по твёрдым правилам, которые иллюстрирует рисунок ниже:



Слева показан приходящий от исполнителя запрос, которому нужен объекта памяти на базе модели секционирования памяти по узлам. Это позволяет использовать объекты синхронизации (обычно типа: CMEMTHREAD или SOS_SUSPEND_QUEUE) уровня узла, и память выделяется из локальной памяти того NUMA узла, для которого назначен этот исполнитель.

Справа приходит запрос на распределение объекта памяти, для которого предписано исполнение на конкретном процессоре. Это позволяет использовать объект синхронизации уровня процессора, и выделять память, локальную для исполнителя этого процессора.

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

Схема секционирования по узлам менее ресурсоёмкая, но может несколько повысить вероятность коллизий. В некоторых особых случаях это может заметно повлиять на производительность. Стоит подчеркнуть, что подобные случаи, с которыми сталкивались в Microsoft CSS, ограничивались очень узкой областью применения и только определёнными шаблонами запросов.

Современные линейки серверов с многоядерными процессорами могут иметь больше 8 процессоров в одном NUMA узле. Microsoft этой статьёй указывает на то, что когда число процессоров в узле начинает превышать восемь, для некоторых типов запросов секционирование по узлам не сможет масштабироваться также эффективно, как при меньшем числе процессоров. Однако, если использовать флаг трассировки 8048 (только в качестве параметр запуска службы SQL Server, т.е. понадобится её перезапуск), секционирование по узлам будет заменено на секционирование по процессорам. Следует учитывать то, что такое секционирование будет потреблять в качестве накладных расходов больше оперативной памяти, но сможет обеспечить прирост производительности для таких многоядерных систем.

Как узнать, нужен ли этот флаг трассировки?

На этот вопрос позволяет ответить анализ результатов, возвращаемых такими DMV, как: dm_os_wait_stats и dm_os_spinlock_stats, где в предикатах будут значения CMEMTHREAD и SOS_SUSPEND_QUEUE соответственно. По мнению Microsoft CSS, если спинлоки достигают триллионов, это может стать «горячей» проблемой.
Примечание переводчика:
Следующий сценарий поможет узнать, сколько ожиданий и кратковременных блокировок указанных выше типов зафиксировано в вашей системе.

SELECT wait_type, waiting_tasks_count FROM sys.dm_os_wait_stats
WHERE wait_type = ‘CMEMTHREAD’ AND waiting_tasks_count > 0

SELECT name, spins FROM sys.dm_os_spinlock_stats
WHERE name = ‘SOS_SUSPEND_QUEUE’

Внимание: Используйте флаг трассировки 8048 в качестве параметра запуска. Можно включить этот флаг трассировки динамически, но его влияние ограничится только теми объектами памяти, которые будут созданы после включения флага. Уже созданные объекты памяти не подпадут под его влияние.

Полезные ссылки:

How It Works: CMemThread and Debugging Them


Комментариев нет:

Отправить комментарий