17.1.23

Новшества SQL Server 2005 для поддержки современных серверных платформ

По материалам статьи Slava Oks: A new platform layer in SQL Server 2005 to exploit new hardware capabilities and their trends

Тенденции развития аппаратных средств вычислительной техники оказывают влияние на то, как мы проектируем и разрабатываем программное обеспечение. Для сегодняшнего состояния рынка, персональные компьютеры с большим числом процессоров больше не редкость - это действительность.
Наличие таких возможностей как симметричная многопоточность (SMT), много-ядерные процессоры, слабо совместимые модели, память и процессоры с горячей заменой - становятся все более важны для достижения требуемых уровней производительности систем, их масштабируемости и администрирования. Есть две основные проблемы, связанные с проектированием программного обеспечения для современных аппаратных средств: недостаток хороших инструментов и неадекватный опыт разработчиков. Сервера базы данных пытаются использовать новые возможности серверных платформ, т.к. они стали доступны. Обычно сервер базы данных содержит встроенный уровень поддержки платформы, который скрывает от большинства разработчиков сервера базы данных специальные сообщения от аппаратных средств. SQL Server в предыдущих версиях имел довольно простой уровень поддержки платформы с ограниченной функциональностью. В SQL Server 2005 мы создали новый уровень поддержки платформы, который позволяет максимально задействовать параллелизм, секционирование и размещение. Этот уровень называется SQLOS. SQLOS - операционная система непривилегированного режима, которая встроена в иерархию дизайна сервера баз данных, точно также, как в эту иерархию входят аппаратные средства, на которых запускается сервер. Основные объекты SQLOS, это узлы, планировщики и задачи. SQLOS может подстраиваться и корректироваться под имеющуюся аппаратную конфигурацию сервера, на который он устанавливается. Это реализуется за счёт довольно сложного дизайна API, который позволяет разработчикам получать максимум преимуществ аппаратной платформы при написании программ, как на высоком, так и на низком уровне. Имеется встроенная поддержка размещения, параллелизма, и администрирования. SQLOS позволяет существенно поднять производительность и масштабируемости SQL Server 2005. В новой версии DBA получили возможность балансировать нагрузку SQL Server между компонентами имеющейся аппаратной конфигурации, в соответствии со своими бизнес задачами. В процессе разработки SQLOS мы получили очень много ценной информации и наметили ряд возможных усовершенствований на будущее.

Введение

Тенденции развития аппаратных средств

Сегодня, архитектура вычислительных систем все более и более разнообразна и сложна в эксплуатации, достижении максимальной производительности и масштабируемости. То, что вчера ещё только испытывалось, сегодня получило широкое распространение в промышленных системах. Если оглянуться на несколько лет назад, мы увидим, что компьютеры с несколькими процессорами были редкостью. Сегодня же, многопроцессорные серверы больше не являются привилегией больших корпораций, и господствуют такие технологии, как Symmetric Multi Threading (SMT), которые применяются уже в большинстве настольных компьютеров, используемых даже в домашних условиях. Кроме того, уже довольно продолжительное время производители компьютеров поставляют многопроцессорные конфигурации с несколькими ядрами на кристалл. Если такая тенденция сохраниться, то завтра рынок компьютеров с большим числом процессоров, и большим объёмом памяти станет основной тенденцией. Такие архитектуры вычислительных систем, как Non Uniform Memory Access (cc-NUMA) продолжают расширять свой рынок. Некоторые производители процессоров внедряют собственные шины памяти для каждого процессора, внедряя, таким образом, cc-NUMA даже в архитектуре начального уровня.
Тенденции дизайна корпоративных аппаратных средств стали ещё более драматичными. Корпоративные серверы сегодняшнего дня очень похожи на вчерашние супер-ЭВМ. В настоящее время компьютеры с 64-мя процессорами и 512 Гб памяти - обычное дело. Поскольку эти тенденции продолжаются, скоро конфигурация с 256-ю физическими/логическими процессорами и с превышающей 1 TB памятью будут доминировать в инсталляциях предприятий. Поскольку многопроцессорные серверы становятся всё более популярными, производители аппаратных средств всё более предпочитают архитектуру cc-NUMA в замен SMP. Сегодня на рынке серверов архитектура cc-NUMA стала стандартом для платформ с количеством процессоров от 16-ти и больше. Размер памяти и множество процессоров не единственные выигрышные тенденции на корпоративном рынке серверов. Производители аппаратных средств пытаются сократить время простоя систем и повысить их гибкость, вводя поддержку горячей замены памяти и процессоров. Горячая замена даёт возможность системным администраторам автоматически реконфигурировать аппаратные средства, не перезагружая систему.
Хотя процессорная мощность и количество доступной памяти продолжает расти со скоростью по закону Мора, время ожидания доступа к памяти не удаётся поддерживать на столь высоком уровне. Производители аппаратных средств инвестировали большие средства в улучшение взаимодействия процессора с памятью. Они не только добавили несколько уровней кэшей, но также увеличили поддержку параллелизма на уровне инструкций процессора, слабо совместимых моделей, и предварительной выборки.
Понимание и использование в своих интересах этих возможностей стали очень важным фактором программной инженерии, при разработке ориентированных на производительность, масштабируемых приложений с гибкой поддержкой администрирования.


Воздействие на программирование

Тенденции развития аппаратных средств значительно повлияли на дизайн программ. Чтобы получить адекватную производительность и масштабируемость, разработчики программ должны явным образом задействовать все те преимущества и возможности, которыми обладают аппаратные средства.
Часть нагрузки, но не всё, помещена в компиляторы. Сложность компиляторов постоянно возрастает. Сегодня они используют в своих целях параллелизм на уровне инструкций, задействуют разные семантические последовательности, и даже выполняют предварительную выборку из кэша. Однако, не смотря на все эти полезные возможности, компиляторы все ещё не достаточно помогают разработчикам в дизайне конкурентного доступа, распараллеливания операций и многопоточных приложений. Приложения, не разработанные специально для параллельной, мультипроцессорной архитектуры, могут терять в производительности при инсталляции на современных аппаратных платформах. Компиляторы помогают разработчикам эксплуатировать только некоторые из аппаратных возможностей, но определенно не все.
Что бы воспользоваться новыми возможностями и тенденциями современных платформ, программное обеспечение должно уметь эксплуатировать параллелизм и возможности имеющихся решений по повышению параллелизма. Исторически так сложилось, что дизайн и разработка нацеленных на параллелизм программ с использованием для этого особенностей платформы были отвергнуты большинством разработчиков. Главные причины этого:

  1. Параллельное программирование отличается от нашего естественного мышления.

  2. Доступные инструменты (например: компиляторы, языки программирования и отладчики) не обеспечивают адекватную поддержку.

Инструментарий обычно относится к двум крайностям: часть инструментов пытается полностью скрывать параллелизм, или не поддерживает его вообще; в то время как некоторые другие инструменты требуют великолепного знания вопросов эксплуатации параллелизма - явный параллелизм. При этом от разработчика требуется высокая квалификация во время разработки и проектирования, что бы в результате получилась программа с правильным параллелизмом.
Дизайн и разработка решений, использующих в программном обеспечении параллелизм, должны выполняться чрезвычайно тщательно, т.к. задействующие параллелизм приложения могут в итоге работать как не использующие параллелизм или даже хуже таковых, из-за не подходящих внешних факторов воздействия. Программное обеспечение должно разрабатываться с учётом эксплуатационных факторов размещения данных. Глобальное представление данных должно быть секционировано или от него нужно полностью отказаться. Есть два различных типа размещения: размещение исполнения и размещение в памяти/данных. Каждый тип размещения может иметь многоуровневую семантику. Например, данные могут присутствовать в процессорном кэше второго уровня и могут быть распределены узлу cc-NUMA, которому принадлежит этот процессор. Как и при использовании параллелизма, эксплуатация размещения во многих случаях может вызывать трудности из-за неадекватной поддержки со стороны платформы, на которой приложение может работать. Кроме того, размещение можно значительно повлиять на правильность выбора дизайна. Например, приложение с длинными командами может использовать меньшие показатели CPI (Clock Per Instruction), и работать лучше, чем приложение с более короткими командами, но с более высоким показателем CPI. Высокий CPI может быть результатом многих причин, таких как неправильное размещения данных, излишние вызовы виртуальных функций или ошибки на стадии проектирования.
Точно так же программное обеспечение аппаратных средств должно поддержать горячую замену компонент, чтобы системные администраторы могли реконфигурировать системы без перезагрузки. Это не простая задача с точки зрения программирования, так как программы должны формировать необходимый уровень абстракции, который бы скрывал сложности реконфигурации.


Воздействие на серверы баз данных

Серверы систем управления базами данных (СУБД) являются одним из основных типов программ, которым важно использовать новые тенденции развития аппаратных платформ. СУБД не только должны использовать такие тенденции, но в некоторых случаях они должны быть способны их предсказать. Обычно, серверы базы данных используют многоуровневую архитектуру. В таких случаях средства, предоставляемые платформой, и уровень абстракции операционной системы являются фундаментом обеспечения возможности приложений использовать все возможности, предоставляемые платформой. Microsoft SQL Server можно считать одним из примеров таких приложений. В предыдущей версии SQL Server, уровень платформы был довольно ограничен. Это ослабляло возможности по поддержке параллелизма, и не позволяло эксплуатировать многие из возможностей размещения данных. Даже при том, что некоторая поддержка размещения всётаки была, она была размазана по коду и создавала трудности в её использовании. Кроме того, в платформенный уровень не были заложены возможности предсказания новых тенденций аппаратных платформ, особенно это касается динамического изменения компонент аппаратных средств. Мы поняли, что для дальнейшего развития сервер должен иметь цельный уровень взаимодействия с платформой, который бы обеспечивал полную поддержку потоков и учитывал те возможности, которые появятся в будущем. Изучая тенденции исследовательских работ, мы пришли к выводу, что нужно сформировать новую платформу уровня пользовательской операционной среды. Эта новая операционная система должна примирить существующую поддержку параллелизма и нововведения в поддержке размещения и динамической конфигурации. Мы назвали этот новый уровень взаимодействия с операционной системой - SQLOS. Главная цель SQLOS не состоит в том, чтобы обеспечить независимость от платформы, она призвана предоставить возможность разработчикам использовать в SQL Server существующие и ожидаемые в будущем возможности серверных платформ. Было выдвинуто несколько основных требований к SQLOS. Уровень SQLOS должен быть с легко перестраиваемой конфигурацией, чтобы SQL Server мог хорошо работать на минимальной или на высокопроизводительной аппаратной платформе. SQLOS должна скрывать сложности реализации от разработчиков на языках высокого уровня, но в то же время предоставить высокую гибкости разработчикам на языках низкого уровня. Кроме того, она должна поддерживать службы операционной системы, отвечающие за новые аппаратные средства, даже если операционная система (на которой запущена СУБД) имеет ограниченную поддержку таких служб.


SQLOS

В последнюю версию SQL Server мы встроили SQLOS, которая является операционной системой пользовательского уровня, и имеет множество настроек, мощный API, а также умеет выполнять автоматическое размещение и обеспечивает более развитые возможности поддержки параллелизма. SQLOS старается маскировать от программистов на языках высокого уровня сложности используемого оборудования, и в то же время она предоставляет мощный и многоплановый набор возможностей для программистов, желающий воспользовался возможностями аппаратных средств, на которых исполняется операционная система. SQLOS берёт на себя такие функции операционной системы, как не приоритетное планирование, управление памятью, обнаружение тупиковых блокировок, обработка исключений, хостинг Common Language Runtime (CLR) и т.п. В настоящее время главными пользователями SQLOS являются SQL Server и разработчики CLR. В ближайшем будущем, мы надеемся научить и другие компоненты сервера использовать возможности уровня SQLOS. В следующих главах я опишу внутреннюю архитектуру SQLOS, кратко коснусь принципов дизайна SQLOS, расскажу про её API, о том, что мы узнали во время разработки, и о том, что планируем сделать.


Архитектура SQLOS

Тенденции развития аппаратных средств показывают, что исследования в области размещения данных - это ключевое направление в совершенствовании масштабирования приложений, и особенно это важно при работе приложений на разных платформах. Размещение можно определять различными способами. Наиболее распространённым способом для этого является разработка иерархии семейства объектов, в которой каждый объект поддерживает централизованное управление функционалом и сервисами, которые применимы для его уровня в иерархии.
Одним из главных требований к дизайну SQLOS было обеспечение масштабируемости приложений. SQLOS призвана обеспечить масштабируемость и для высокопроизводительных серверов, и для серверов в минимальной конфигурации. Так как анализ размещения является одним из способов обеспечения требований масштабируемости, а само размещение можно исследовать через иерархию, SQLOS предоставляет развитую архитектуру иерархии. Главными объектами в дизайне SQLOS являются узлы, планировщики и задачи. Каждый объект на своём уровне обеспечивает присущую ему функциональность таким образом, что бы максимизировать использование своего локального состояния/окружения и минимизировать зависимость от глобального состояния системы. SQLOS пытается минимизировать глобальное состояние на столько, на сколько это возможно. На рисунке 1 показана схема SQLOS, которая запускается на сервере с cc-NUMA архитектурой, имеющей два узла, с двумя процессорами в каждом узле. SOS - это одно из названий SQLOS.


Рисунок 1

Память и процессорные узлы

На вершине иерархии объектов SQLOS находятся узлы памяти. Можно говорить об узле памяти как о примитиве или абстракции памяти, назначенной процессору или нескольким процессорам. Разные аппаратные платформы имеют различные схемы взаимодействия процессоров с памятью. Например, в SMP архитектуре память используется совместно всеми процессорами, и в то же время в архитектуре cc-NUMA совместно используют память только группы процессоров. Совместно используемую память может назвать локальной или ближней памятью, что описывает характер её распределения и размещения. Целью узла памяти является обеспечение управления и размещения памяти на cc-NUMA или для похожих на cc-NUMA платформ.
Процессорные узлы занимают следующий уровень в иерархии объектов SQLOS. Процессорные узлы призваны обеспечивать логическую группировку процессоров. В SMP архитектуре существует единственный процессорный узел. По умолчанию, в архитектуре cc-NUMA процессорных узлов может быть столько, сколько процессоров имеется в используемой платформе. Процессорные узлы отвечают за ссылочное размещение и привязку планировщиков. Это даёт возможность разработчикам посылать связанные задачи процессору друг за другом.
Отношения между узлами памяти и процессорными узлами очень важны. Процессорный узел является собственным подмножеством объектов узла памяти. Как показано на рисунке 1, процессорный узел может быть связан только с одним узлом памяти, но узел памяти может быть связан с несколькими процессорными узлами. Это правило позволяет обойти две проблемы. Во-первых, это упрощает моделирование программ, и задаёт четкие отношениям между узлами. Во-вторых, это дает возможность SQLOS моделировать разные конфигурации узлов на платформе cc-NUMA, а так же и на высокопроизводительных SMP платформах.


Рисунок 2

В дополнение к возможности строгой аппаратной конфигурации, SQLOS может быть настроена на использование логических процессорных узлов. В силу исторических причин, конфигурацию системы, которая не отображает полностью реальную аппаратную конфигурацию, называют "Программным NUMA". Концепция программного NUMA реализована очень мощной. Она позволяет серверу приложений взаимодействовать с вершиной иерархии SQLOS, и получать возможность использовать разные типы размещений, поддерживаемых платформой и подходящих характеру прикладной области. Например, SMP система с четырьмя двух-ядерными процессорами может быть настроена таким образом, чтобы в итоге получился один узел памяти, содержащий четыре процессорные узла, каждый из которых будет управлять двумя процессорами. Такая конфигурация показана на рисунке 2. К выгодам от использования программного NUMA также относиться то, что при использовании этого способа для тестирования поддержки SQLOS и SQL Server архитектуры cc-NUMA, фактически не потребуется наличия дорогостоящих аппаратных средств.
Также процессорный узел обеспечивает такую функциональность, как балансировка нагрузки его планировщиков, привязку I/O и локальной памяти. Рисунок 3 иллюстрирует верхний уровень инфраструктуры процессорного узла.


Рисунок 3

Каждый процессорный узел содержит набор планировщиков. Планировщик связан с процессорным узлом. Процессорный узел принимает решение, где разместить новую задачу, в зависимости от загрузки планировщиков. Как показано на рисунке 3, процессорный узел в дополнение к планировщикам, имеет связанный с ним порт I/O. Порт ввода - вывода (I/O) может быть связан с множеством устройств ввода - вывода, таких как сетевые платы или диски. Наличие у узла порта ввода - вывода обеспечивает такое размещение I/O, чтобы все запросы на I/O могли быть намечены и завершены непосредственно на том процессорном узле, которому они были предназначены.

Локальная (ближняя) память процессорного узла может использоваться для хранения и привязки локальных данных к узлу. Наличие локальной памяти на уровне узла дает возможность разработчикам использовать локальное состояние узла, а так же разделять глобальное состояние между узлами.


Планировщики и Задачи

Главной целью планировщика является назначение задач заданному процессору. Единовременно, планировщик может выполнять только одну задачу, которая активизируется на процессоре, привязанном к этому планировщику. Передавая планировщику только одну из текущих задач, SQLOS минимизирует запросы процессоров в системе, что приводит к уменьшению числа переключений контекста и, поэтому, повышает производительность и масштабируемость сервера, как приложения. Такой подход приводит к необходимости выполнения дополнительной работы для разработчиков, потому что SQLOS являясь неприоритетной операционной системой, и требует дополнения кода для учёта этой специфики, что бы задачи, которые не правильно освобождают ресурсы, не могли привести к деградации производительности. Так же как процессорные узлы, планировщики могут использоваться для сохранения локального состояния процессоров, а так же для разделения глобального состояния между процессорами. Кроме диспетчеризации задач, планировщики обеспечивают поддержку не приоритетного ввода - вывода. Асинхронный ввод - вывод, который заканчивается в течение переключения контекста планировщика, называют не приоритетным вводом - выводом. И наоборот, асинхронный ввод - вывод, обслуживаемый портом I/O процессорного узла, называется приоритетным вводом - выводом. Преимущество неприоритетного ввода - вывода состоит в том, что его завершение не приводит к дополнительным переключениям контекста. Недостатком является то, что в некоторых случаях ввод - вывод может выполняться дольше, чем для этого требуется. SQL Server использует приоритетный ввод - вывод для обслуживания сети, а не приоритетный ввод - вывод для обслуживания дисков.
Объект "Задача SQLOS" завершает основную иерархию SQLOS. Задача, это модуль исполнения. В зависимости от режима задачи, она отображается на поток или нить. Задача посылается планировщиком на процессор. Аналогично узлам и планировщикам, задачи имеют локальную память, что позволяет более тонко разделять данные и обеспечивает более тонкое размещение. Когда задача посылается на исполнение, она будет активна пока ее квант времени не истёк или пока она не будет приостановлена объектом синхронизации. Она проверяет истечение своего кванта времени, вызывая периодически соответствующие методы SQLOS, имеющиеся в коде SQLOS, так же как и в коде SQL Server. Задачи SQLOS могут прерываться асинхронно. Каждый раз, когда задача прерывается, она ожидает получения кода возврата, включая возвращаемый код аварийного завершения, пока аварийное завершение её исполнения не будет обработано и сброшено.


Поддержка параллелизма в SQLOS

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

  1. Одиночной задачей может быть постановка в очередь для SQLOS.

  2. Одиночной задачей может быть постановка в очередь для заданного процессорного узла.

  3. Не одиночной задачей может быть постановка в очередь для нескольких планировщиков или узлов в одном запросе.

Первый метод используется разработчиками, когда они хотят использовать механизмы SQLOS для балансировки нагрузки, чтобы задача запускалась на менее загруженном узле. Второй метод предоставляет разработчикам возможность запускать задачу на заданном узле. Этот метод должен использоваться тогда, когда задача требует определенного места для исполнения. При использовании этого метода нужно быть внимательным, так как выбор не верного места для исполнения задачи может вывести SQLOS из равновесия. Последний метод очень полезен и очень производителен. Он используется тогда, когда несколько задач должны исполняться параллельно в одно время, но с разными требованиями к месту исполнения. Например, уровень в SQL Server, отвечающий за исполнение запросов, использует этот метод при выполнении параллельных запросов для отправки задач на разные планировщики.
Для разработчиков на языках высокого уровня SQLOS предоставляет набор мощных конструкций, предоставляющих возможность решать сложные проблемы параллелизма и, в то же время, избегать излишней сложности. Эти конструкции включают кэши, семафоры ресурсов и библиотеку высокого параллелизма. Они предназначены для таких распространённых структур данных, как списки, хеш-таблицы, перечислители и т.д.
Для разработчиков на языках низкого уровня, предпочитающих формировать свои собственные решения с параллелизмом, и поэтому нуждающихся в большей гибкости, SQLOS предоставляет набор таких объектов синхронизации низкого уровня, как spinlocks, события, взаимные исключения, блокировки записи - чтения, секционируемые взаимные исключения и другое.


Поддержка динамической конфигурации SQLOS

SQLOS поддерживает динамическую конфигурацию, т.е. её конфигурация может быть автоматически откорректирована без перезагрузки. SQLOS поддерживает онлайновое и офлайновое (автономное) состояние узлов и планировщиков. Планировщик находится в автономном состоянии, когда для него не поставлено в очередь ни одной задачи. Автономным процессорный узел считается тогда, когда все его планировщики находятся в автономном состоянии. Автономный процессорный узел не выполняет никакой работы. Узел памяти, у которого все процессорные узлы автономны, не будет использоваться в SQLOS как узел памяти, хотя он и представлен в качестве компонент аппаратных средствах, и он может использоваться другими приложениями. Если узла памяти до этого не было, и он был добавлен, SQLOS может его задействовать, увеличивая свои ресурсы. Во время начальной загрузки, SQLOS распределяет требуемые ресурсы так, чтобы обеспечить поддержку возможной аппаратной конфигурации, предоставляемой платформой, и теми установками на основе логической конфигурации, которые были сделаны администратором. После запуска SQLOS, администратор может перевести узлы и планировщиков в автономное и онлайновое состояние, в зависимости от планируемой им конфигурации.


SQLOS API

Дизайн SQLOS API был ключевым моментом для интеграции SQLOS в SQL Server. Требования к дизайну API были противоречивы: мы должны были максимально скрыть понятия размещения от разработчиков на языках высокого уровня, и в то же время оставить максимум возможностей для задействования функциональности аппаратных средств на нижнем уровне. В качестве решения было выбрано создание двух наборов API: один с неявным использованием размещения, и второй, который требует явное понимание размещения.
Первый набор API обеспечивает в рамках текущего контекста исполнения неявную поддержку набора локальных объектов SQLOS, таких как задачи, планировщики, процессорные узлы и узлы памяти. Использование этого API предоставляет возможность разработчикам работать без необходимости учёта аппаратных особенностей платформы нижнего уровня. Также, это помогает избежать распространённых ошибок выбора контекста, что предотвращает вызванную подобными ошибками потерю масштабируемости и деградацию производительности. Например, SQLOS имеет для каждой задачи свой хип, который называется "объектом памяти". Этот хип может использоваться только связанной с ним задачей и больше ни чем. Есть несколько способов получить объект памяти задачи. Ниже представлен один из примеров того, как это можно сделать:

SOS_Task* pTask = SOS_OS::GetCurrentTask (); SOS_MemoryObject* memObj = pTask->GetMemoryObject ().

Такой подход довольно опасен, т.к. позволяет разработчику запрашивать объект задачи, и создаётся впечатление, что всё работает правильно, и задача и её объекты памяти. SQLOS использует для этого другой подход. Она маскирует явный доступ к объекту задачи:

SOS_MemoryObject* pMemoObj = SOS_Task::GetMemoryObject ();

Такой подход все еще не совершенен, однако, разработчики могут более свободно оперировать объектом памяти. Чтобы избавиться от подобных проблем, SQLOS предоставляет возможность использования макрокоманд, одна из которых позволяет распределять память объекта задачи:

MyObject* pMyObject = NewTask () MyObject;

И планировщики и процессорные узлы имеют объекты памяти. SQLOS использует один механизм для обеспечения локального распределения, предотвращающий перемещение объектов. Большинство разработчиков будут использовать макрокоманды для распределения памяти объектов задачи. Однако, представленный API все еще будет полезен в случаях, когда разработчику нужно исполнить несколько распределений.
Второй набор API предназначен для продвинутых разработчиков, которым нужно получить максимум выгод от аппаратных средств, например, в таких случаях, когда на уровне исполнения запроса принимается решение в очередь какого процессорного узла лучше отправить задачу, принимая во внимание загрузку имеющихся узлов и доступность памяти. Являясь частью представленных в SQLOS развитых API, этот набор интерфейсов обеспечивает секционирование объектов памяти, что дает разработчикам возможность распределять часть памяти для каждого процессорного узла или планировщика. Использование такого рода указателей позволяет обслуживать "горячие" структуры данных, которые очень чувствительны к ложным распределениям. Например:

MyObj* pPointerOnCurrentNode = partitionedObject->Alloc (sizeof (MyObj)); pPointerOnCurrentNode->Method1 (); // Чтобы эффективно использовать указатель на другом узле нужно получить секцию MyObj pPointerOnOtherNode = pObjOnCurrentNode ->GetSibling (NodeId);

Концепция секционирования объектов памяти очень продуктивна, но с другой стороны, если её использовать неправильно, это может привести к деградации производительности, вызванной значительной дороговизной операций распределения объектов. Вообще то, наши эксперименты с явным извлечением секций посредством API показывали экономичные и эффективные результаты, и это только подтверждалось на реальных запросах.
Одной из главных целей API в SQLOS является устранение излишних ссылок памяти, что иногда называют Pointer chasing. Pointer chasing может значительно повредить производительности, особенно, когда объекты распределены в разные строки кэша или даже хуже того - на разных страницах операционной системы. Размещение объектов на разных страницах может привести к потерям Transition Lookaside Buffer (TLB), а это действительно плохо сказывается на производительности. С самого начала проекта мы старались добиться, что бы объекты SQLOS оставались достаточно "горячими". Мы достигли требуемых характеристик производительности, сохраняя при этом простоту объектной модели, распределяя объекты близко друг к другу и полностью устраняя виртуальные функции. Эти меры значительно улучшили поведение SQLOS с кэшем процессора, а, следовательно, общую производительность.


SQL Server и SQLOS

SQLOS повышает масштабируемость SQL Server посредством своей инфраструктуры и дизайна API. Разработчики SQL Server создали платформу с легко перестраиваемой конфигурацией, которая позволила эксплуатировать компоненты аппаратных средств и написать высокопроизводительный и масштабируемый сервер базы данных. Разработчики SQL Server извлекли максимум преимуществ из SQLOS, развивая этим функциональные возможности сервера. Кроме того, начиная с SQL Server 2005, DBA имеет возможность выбора между конфигурацией и динамической реконфигурации SQL Server, в соответствии с имеющимися аппаратным средствам, или в соответствии с требованиями прикладной среды. Например, если DBA обслуживает два приложения, совместно использующие SQL Server, сервер баз данных может быть настроен таким образом, чтобы работать в конфигурации с двумя узлами, и чтобы каждое приложение использовало свой собственный узел. Это позволит полностью разнести две разные нагрузки, причём, без реализуемой средствами SQLOS балансировки нагрузки, весь сервер был бы подвержен очень интенсивной утилизации ресурсов.


Новые знания

Работая над SQLOS мы извлекли очень много интересных уроков. SQLOS имеет иерархический, многоуровневый дизайн, который оказался сам по себе очень ценным. SQLOS позволила существенно поднять производительность и нарастить масштабируемость SQL Server на cc-NUMA серверах, а также и на архитектуре с программным NUMA. Поддержка программного NUMA оказалась очень полезной при тестировании возможностей cc-NUMA, теперь для этого фактически не требуются дорогие сервера. Двойной дизайн API в SQLOS оказался и удобным и одновременно строгим, не позволяющим случайно создать проблемы, как для программистов на языках высокого уровня, так и низкого уровня. Ограничение использования глобального окружения и разделяемого состояния оказалось не простой задачей, которая иногда требовала полного реинженеринга приложений. Неполное секционирование может стать причиной неприятных последствий. Оказалось, что во многих случаях неполное секционирование не дает никакого преимущества в производительности по сравнению с единым глобальным разделяемым состоянием, и может привести к потере производительность и масштабируемости точно так же, как и в случае с не единичным использованием глобального состояния. Проектирование SQLOS показало, что исследование тенденций развития аппаратных средств является важной частью в прогнозировании и дизайне программного обеспечения будущего. Изначально, SQLOS разрабатывалась с поддержкой cc-NUMA. В дополнение к cc-NUMA и программному NUMA, мы добавили поддержку и других топологий, а также динамическую реконфигурацию. Эти решения уже сегодня позволяют SQLOS использовать возможности большинства систем с много - ядерными процессорами, и других, появляющихся на сегодняшнем рынке аппаратных решений.


Работа на будущее

Поскольку SQLOS уже поддерживает это, в следующих версиях продолжится развитие использования возможностей размещения и параллелизма. Уже продолжается работа, начатая при формировании структур секционирования таких данных, как стеки, списки связей и т.д. Следующая версия SQLOS будет поддерживать секционирование кэшей и пула. Это облегчит разработчикам написание использующих параллелизм приложений, и даст им возможность эксплуатировать явный и неявный параллелизм в своей предметной области. Например, типы загрузки Single Instruction Multiple Data (SIMD) смогут обрабатываться неявно без необходимости знания разработчиком каких - либо типов синхронизации. В будущем мы ожидаем, что SQLOS будет интенсивно использоваться и другими приложениями, кроме SQL Server.


Ссылки

  1. D. Patterson, "Computer Organization and Design Second Edition: The Hardware/Software Interface." Morgan Kaufmann; 2nd edition (August 1, 1997) ISBN: 1558604286.

  2. A. Tanenbaum, "Modern Operating Systems (2nd Edition)." Prentice Hall; 2nd edition (February 28, 2001) ISBN: 0130313580.

  3. J. Gray, and A, Reuter, "Transaction Processing: Concepts and Techniques (Morgan Kaufmann Series in Data Management Systems." Morgan Kaufmann; 1st edition (1993) ISBN: 1558601902.

  4. M. Russinovich, and D. Solomon, "Microsoft Windows Internals, Fourth Edition: Microsoft Windows Server(TM) 2003, Windows XP, and Windows 2000 (Pro-Developer)." Microsoft Press; 4th edition (December 8, 2004) ISBN: 0735619174.

  5. J. Richter, and J. Clark, "Programming Server-Side Applications for Microsoft Windows 2000." Microsoft Press; (March 1, 2000) ISBN: 0735607532.

  6. M. Stonebraker, "Operating System support for Database Management", in Comm. of ACM, Vol. 24, No. 7, 1981.

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

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