Управление параллелизмом с низкими накладными расходами

       

В системах баз данных управление


В системах баз данных управление параллелизмом используется для обеспечения иллюзии последовательного выполнения транзакций, в то время как на самом деле одновременно выполняется несколько транзакций. Однако в нескольких исследовательских статьях высказывается мнение, что для некоторых специальных баз данных управление параллелизмом может не требоваться [11, 12, 27, 26]. В частности, если данные размещаются в основной памяти, и рабочая нагрузка состоит из транзакций, которые могут выполняться без задержек по вине пользователей, то нет потребности в параллельном выполнении транзакций для полного использования ресурсов одного процессора. Вместо этого, каждую транзакцию можно полностью выполнить до начала обработки следующей транзакции. В предыдущем исследовании системы баз данных Shore [14] было установлено, что при выполнении части тестового набора TPC-C [1] на поддержку блокировок, защелок (latch) и буфера откатов, которая требуется при наличии многопотокового управления параллелизмом, уходит 42% команд процессора. Это говорит о том, что устранение управления параллелизмом может привести к значительному повышению производительности.
В системах баз данных управление параллелизмом также применяется для использования нескольких процессоров путем назначения каждой транзакции своего потока управления. Однако в статье Пэндиса и др. [20] демонстрируется, что этот подход не масштабируется до большого числа процессорных ядер; вместо этого они предлагают подход, ориентированный на данные, при котором каждый поток управления "владеет" некоторым разделом данных, и транзакции передаются разным потокам управления в зависимости от данных, к которым они обращаются. Аналогично этому, в системе H-Store каждому разделу данных также соответствует один поток управления. В этих системах к каждому элементу данных может обратиться только один поток управления, и традиционное управление параллелизмом не требуется.
Разделение данных также применяется в системах без совместного использования ресурсов (sharing-nothing). Данные разделяются между n серверами баз данных, и транзакции направляются в разделы, содержащие требуемые им данные. Этот подход часто используется для повышения производительности систем баз данных. Некоторые приложения являются "полностью разделяемыми", такими, что каждая транзакция может полностью выполняться в некотором одном разделе. В таком случае, если данные сохраняются в основной памяти, каждая транзакция может пропускаться без управления параллелизмом, полностью выполняясь в соответствующм разделе. Однако во многих приложениях имеются некоторые транзакции, охватывающие несколько разделов. Для этих транзакций требуется некоторая форма управления параллелизмом. Поскольку возникают сетевые задержки, необходимо координировать выполнение этих "многораздельных" транзакций, и при отсутствии управления параллелизмом каждый процессор вынуждается ждать.


Эта статья концентрируется на этих "не полностью разделяемых" приложениях. В таких рабочих нагрузках имеются некоторые многораздельные транзакции, вызывающие сетевые задержки, и некоторые "однораздельные" транзакции, которые могут полностью выполняться без задержек, вызываемых обменами с дисками, ожидаением реакции пользователей и передачей данных по сети. Цель состоит в том, чтобы использовать схему управления параллелизмом, позволяющую процессору делать что-нибудь полезное при возникновении сетевых задержек, не нанося при этом значительного ущерба производительности однораздельных транзакций.
Мы изучаем две таких схемы. Первая представляет собой спекулятивный подход, работающий следующим образом: когда многораздельная транзакция t заканчивает работу в одном разделе, но ожидает завершения в других участвующих разделах, выполняются дополнительные спекулятивные транзакции. Однако они не фиксируются до тех пор, пока не зафиксируется t. При спекуляции не удерживаются блокировки и не отслеживаются наборы чтения и записи. Вместо этого предполагается, что спекулятивная транзакция конфликтует с любой транзакцией t, с которой она выполняется параллельно. По этой причине, если t завершается аварийным образом, все спекулятивные транзакции должны быть выполнены повторно.
Вторая схема основывается на двухфазных блокировках. Если отсутствуют какие-либо активные многораздельные транзакции, то однораздельные транзакции успешно выполняются без запроса блокировок. Однако появление любых многораздельных транзакций приводит к тому, что при доступе к данным эти данные блокируются и разблокируются всеми транзакциями с использованием стандартного двухфазного протокола блокировок.
Мы сравниваем сильные стороны и ограничения этих двух схем управления параллелизмом для систем разделенных баз данных в основной памяти, а также простой блокирующей схемы, в которой допускается одновременное выполнение только одной транзакции. Наши результаты показывают, что этот простой блокирующий метод хорошо работает, только если имеется очень мало многораздельных транзакций. Спекулятивное выполнение лучше всего подходит для рабочих нагрузок, состоящих из однораздельных транзакций и многораздельных транзакций, выполняющих по одной порции работы в каждом из затрагиваемых разделов. В частности, из наших экспериментов следует, что спекулятивный подход может удвоить пропускную способность модифицированной рабочей нагрузки TPC-C. Однако для рабочих нагрузок с частым аварийным завершением транзакций этот подход работает плохо, поскольку он приводит к каскадному аварийному завершению одновременно выполняемых транзакций. Схема с блокировками лучше всего годится для рабочих нагрузок, в которых имеется много многораздельных транзакций, в особенности, в тех случаях, когда участники должны выполнить несколько циклов работы с сетевыми взаимодействиями друг с другом. Однако эта схема работает все хуже по мере увеличения числа конфликтов по данным, и хуже всего то, что при ее использовании могут возникать распределенные тупиковые ситуации (distributed deadlock).

Содержание раздела