Успехи в области оборудования и архитектур СУБД вселяют надежду в возможность решения задачи линейного масштабирования транзакционных нагрузок: наработки в сфере сегментирования и дезагреграции, а также ожидаемые новинки в аппаратуре, такие как CXL 2.0 (Compute Express Link — открытый стандарт для подключения процессора к внешним устройствам), «умные» и байтоадресуемые накопители, создают для этого необходимые предпосылки.

Попытки масштабирования транзакционных нагрузок ведутся уже давно — NoSQL, NewSQL, «мультимастер», сегментирование, однако каждый раз все выливается в паллиативные решения, не обеспечивающие фундаментальные свойства СУБД либо применимые только в четко ограниченном пространстве.

Вслед за успехом Hadoop, предложившим массовый параллелизм на недорогих узлах, обеспечивающий линейно-масштабируемую обработку практически любых объемов данных, возникло и течение горизонтального масштабирования атомарных операций с данными — NoSQL. Термином «агрегатная модель» хорошо характеризуются все горизонтально масштабируемые NoSQL-модели: «ключ — значение», «семейство столбцов», документоориентированная. Для роста по горизонтали вся коллекция связанных с ключом данных должна храниться в близлежащей к нему, возможно, сложной структуре, так, чтобы систему можно было по ключу распределять по узлам без необходимости хождения между ними. Однако ценой за десятки миллионов атомарных операций в секунду стало упрощение моделей данных и частичный отказ от согласованности и атомарности — ключевых требований ACID (Atomicy — «атомарность», Consistency — «согласованность», Isolation — «изолированность», Durability — «долговечность»), без которых не приходится говорить о полноценной транзакционности.

Как следствие, поднялась новая волна — NewSQL [1] (в английском прочтении можно услышать как «новая школа»), которую определили как категорию систем, обеспечивающих характерные для NoSQL свойства масштабируемости, но при этом выполняющих требования ACID. Участников этой «волны» разбили на три категории: новые полновесные СУБД (Clustrix, CockroachDB, Google Spanner, H-Store, HyPer, MemSQL, NuoDB, SAP HANA и VoltDB); связующее ПО, обеспечивающее единую логическую базу данных над сегментами, управляемыми независимыми экземплярами традиционных реляционных СУБД (dbShards, MariaDB MaxScale, ScaleArc, ScaleBase); облачные системы (Amazon Aurora и ClearDB). Эти классы можно переопределить как новые системы с автосегментированием, сегментирование над традиционными системами (MySQL, PostgreSQL) и дезагрегированные. Отдельно стоит отметить и смену представлений о «традиционных системах», которые до этого в корпоративном мире считались «любительскими» — практически весь второй и третий класс так или иначе построен на базе PostgreSQL, а представители первой категории стремятся предоставить PostgreSQL- или MySQL-совместимый интерфейс, и без него уже трудно конкурировать на этом рынке.

«Мультимастер» — другая идея решения задачи транзакционного горизонтального масштабирования путем организации работы множества независимых экземпляров СУБД, каждый со своим экземпляром базы данных, синхронизированным с другими (рис. 1). По задумке такой подход должен был решить две проблемы: масштабирование вычислительной мощности экземпляра и обеспечение высокой доступности.

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

Ограниченность вычислительной мощности одного узла с точки зрения транзакционной нагрузки была особенно характерна для малоядерных систем, в те же времена, когда для широкого класса серверного программного обеспечения (FTP-, веб-, почтовые серверы) решалась проблема десятка тысяч одновременных подключений. В том же PostgreSQL была избрана концепция выделения процесса на каждое подключение, обеспечивающая много полезных свойств с точки зрения разработки и обслуживания (управляемость, ресурсная изоляция), но быстро приводящая к насыщению по количеству подключений — даже 2–3 тыс. подключений на узел и сегодня почти предел, за которым уже следует непредсказуемое поведение системы. «Мультимастер» мог бы решить проблему, распределяя между узлами каждые 2–3 тыс. подключений.

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

Рис. 2. Мультимастер: все узлы кластера содержат синхронные копии базы данных, доступные на запись

Однако накладные расходы на разрешение конфликтов при применении транзакции на несколько узлов могут превзойти все мыслимые выгоды. Например, с блочным журналом предзаписи, который используется в PostgreSQL, практическая реализация чрезвычайно сложна. Одним из решений мог бы стать строчный журнал предзаписи, предлагаемый в проекте OrioleDB Александра Короткова взамен стандартному блочному, с ним уже проще реализовать общий линеаризуемый журнал и Raft (определение консенсуса для распределенных систем). Более радикальный путь — специализированный протокол для общего линеаризуемого журнала был предложен в проекте Corfu, реализация такого журнала на подключенном к сети ПЛИС еще в 2013 году позволила добиться производительности до 1 млн четырехкилобайтных операций для кластера из 16–32 узлов [2].

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

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

Сегментирование

Прямой путь к масштабированию по размеру — сегментирование (рис. 3) — дробление базы данных на фрагменты, управляемые собственным экземпляром СУБД. Этот шаблон был применен в NoSQL-системах с разменом масштабируемости на транзакционность.

 

Рис. 3. Сегментирование: узлы кластера содержат части базы данных — сегменты, каждый под управлением собственного экземпляра СУБД; отказоустойчивость достигается синхронной копией сегментов; «широковещание» небольших таблиц (конфигураций, справочников) позволяет повысить производительность

Первой коммерческой ACID-системой с сегментированием в качестве решения задачи горизонтальной масштабируемости OLTP-нагрузок стала VoltDB [3], работающая в резидентном режиме, без разделяемых ресурсов, обслуживающая каждый сегмент одним аппаратным потоком, она воплотила ключевые идеи Стоунбрейкера, риторика публикаций которого с критикой подхода NoSQL зачастую звучала как откровенная поддержка VoltDB. Были даже опубликованы результаты эталонных тестов, для корректности названные «TPC-C-подобными», и выглядели они весьма неплохо, однако сам дизайн TPC-C устроен так, что допускает сегментирование базы данных, обеспечивая при этом изолированное выполнение нагрузок на каждом сегменте. Однако как только система попадала на межсегментные транзакции, результаты становились неудовлетворительными, к тому же используемый алгоритм консенсуса приводил к потерям в случае разделения сети.

Тем не менее обрела популярность идея построить полноценную ACID-систему под транзакционные нагрузки, сравнимую с функционалом с классическими РСУБД, но растущую по горизонтали без разделяемых ресурсов. В CocroachDB и YugabyteDB в качестве низкоуровневого движка были взяты варианты RocksDB (PebbleDB и DocDB соответственно), а поверх движка (автомасштабируемого и строго согласованного распределенного «ключа — значения») построены совместимые с PostgreSQL системы, поддерживающие транзакции уровня упорядочиваемости (serializable). И хотя оба производителя затратили немало усилий на пропаганду своего подхода и есть успешные установки в геораспределенном режиме, но из независимых сведений о реальной эксплуатации этих систем становится ясна достаточно серьезная ограниченность в масштабе — это в лучшем случае сотни транзакций в секунды при межсегментной нагрузке, да и кластеры, как выясняется, состоят из единиц узлов и даже на таком уровни сложны в обслуживании. К тому же нет уверенности в реализации Raft в обеих системах — тесты Jepsen (фреймворк для тестирования распределенных систем, написанный на Lisp-подобном языке) «разваливали» и CocroachDB, и YugabyteDB.

Родные прикладные области транзакционных систем — финансы, материальный учет, учет продукции, конфигурирование заказов — не терпят компромиссов в вопросе потери данных. И в этом смысле аккуратная реализация алгоритма консенсуса становится жизненно необходимой для признания распределенной СУБД как транзакционной. На этом сфокусировались разработчики Picodata — ответвления Tarantool, созданного под руководством Константина Осипова. Эту СУБД можно корректно применять для финансовых транзакций, тогда как удел большинства ее «одноклассников» — выросших из резидентных гридов и движков «ключ — значение» SQL-систем — это: кэши, быстрые витрины, промежуточные данные, которые иногда можно и потерять.

Средством поднять производительность для сегментированных транзакционных систем может стать переход от автоматического, неразборчивого сегментирования к обеспечивающему локализацию в одном сегменте большей части транзакций, так, чтобы основная масса проверок ограничений целостности не требовала запросов к другим сегментам. В этом случае наилучший ключ сегментирования — сквозной, от диапазона первичных ключей основных данных, позволяет в одном сегменте сконцентрировать, например, данные об одном пуле клиентов и всех их транзакциях, приближая модель к агрегатной. Иногда можно использовать технику, известную для аналитических горизонтальных систем как «широковещание» небольших таблиц (справочников, конфигурационных данных), то есть повторение их на всех сегментах. Изменения в таких реплицированных на все сегменты таблицах, конечно же, будут медленными, но при аккуратном проектировании такие таблицы будут невелики и изменяться очень редко (в аналитическом случае для такого рода объектов даже сложилось понятие «медленно меняющегося измерения»), а 99% всех операций будут локализованы внутри сегмента, не требуя двухфазной фиксации или более сложных протоколов. Неудивительно, что именно такую стратегию сегментирования предлагают расширения для традиционных реляционных СУБД — Oracle Database Sharding и «Шардман» в СУБД Postgres Pro. Однако произвольную базу произвольной модели положить в такую конструкцию не получится, но если изначально проектировать схему данных, подразумевая «сквозное» сегментирование и возможное «широковещание», то можно даже в рамках реляционной классики обслуживать объемы в сотни терабайт.

Дезагрегация

Рис. 4. Дезагрегация по типу Amazon Aurora: ведущий вычислительный экземпляр обрабатывает транзакции, может быть запущено множество экземпляров для синхронного чтения; журнал записывается в систему хранения, которая самостоятельно восстанавливает базу данных — единую и доступную всем вычислительным экземплярам

Облачные провайдеры, поначалу ориентировавшиеся на развитие удобного для них NoSQL, столкнулись с тем, что подписчикам нужны реляционные СУБД с полновесной транзакционностью, а когда виртуальные экземпляры для PostgreSQL и MySQL быстро «заканчивались», где-то в пределах «тысячи подключений, тысячи операций в секунду, тысячи гигабайт», то задумались о решении вопроса адаптации традиционных систем к новым реалиям. Наиболее радикальные новации в виде дезагрегации (рис. 4) предложили в Amazon в продукте Aurora для PostgreSQL и MySQL. В этих сильно модифицированных СУБД были разделены слои хранения и обработки, а вычислительные экземпляры отделены от базы данных, которая живет на отдельной системе хранения, которая является общей для всех подключаемых вычислительных экземпляров. Ведущий вычислительный экземпляр только пишет журнал предзаписи, а система хранения сама восстанавливает из него базу данных. Производительность, по сравнению с виртуальной реализацией, удалось существенно повысить, но пока известные показатели производительности далеки до показателей, удовлетворительных для больших промышленных систем. Так, компания SeveralNines, которую нельзя упрекнуть в предвзятости к Amazon или в незнании PostgreSQL, получала на Aurora для PostgreSQL производительность на уровне 3,5 тыс. транзакций в секунду для нагрузки TPC-B (тест pgbench), что много меньше, например, чем для классического трехузлового кластера «ведущий — синхронная реплика — асинхронная реплика» машины баз данных Скала^р МБД.П с СУБД Postgres Pro — 40 тыс. транзакций в секунду на терабайтных масштабах при полной отказоустойчивой конфигурации. Еще одно ограничение Amazon Aurora — только один пишущий вычислительный экземпляр, но можно добавить практически без потерь производительности экземпляры на чтение, но и, в частности, в МБД.П при использовании RDMA можно множить синхронные читающие реплики почти без вреда ведущему узлу [4].

Дезагрегированный дизайн с восстанавливающейся из журнала базой еще в 2019 году был реализован для Microsoft Socrates — облачной инкарнации Microsoft SQL Server, а в 2021 году — в Google Alloy DB, но все это доступно только подписчикам Azure и Google Cloud Platform.

Есть несколько попыток повторить дезагрегированный дизайн и для открытого продукта. Стартап Neon предлагает тиражируемый аналог Aurora: вычислительные узлы и узлы хранения разделяются, экземпляр СУБД передает слою хранения только журнал предзаписи, а уже слой хранения его разбирает и хранит. Слой хранения организован в формате «ключ — значение», что позволяет его горизонтально масштабировать. Ключ состоит из идентификатора таблицы или индекса («отношения» в терминах PostgreSQL) и номера блока, значение — либо восьмикилобайтная страница, либо запись в журнале предзаписи. В метаданных, кроме прочего, ведется информация о размерах таблиц и индексов, дополняя информацию для оптимизатора. В этой организации есть некоторое сходство с LSM (журнально-структурированным деревом со слиянием): журналы предзаписи поначалу буферизуются в памяти, и когда буфер достигает размера 1 Гбайт — он материализуется в новый файл слоя, другой фоновый процесс объединяет и компактифицирует (преобразует в компактные) старые файлы. Проект пока в разряде «начинающих», но у него потенциально есть предпосылки превзойти Aurora для PostgreSQL.

Следующий уровень дезагрегации предложен в YDB [5]: над общей распределенной системой хранения работают микросегменты — «таблетки», вычислительные экземпляры, обслуживающие строго выделенный набор данных в несколько гигабайт. При увеличении вычислительной нагрузки или объема таблетка разделяется, при этом распределенное хранилище остается общим, с которым система работает напрямую, как с блочным устройством. Это довольно редкое и важное свойство, например, в пропагандистских материалах Oracle тезис о том, что у системы собственный менеджер томов, работающий напрямую с блочными устройствами, часто используется как признак совершенства. Еще одно принципиальное усовершенствование YDB — использование Calvin (алгоритм механизма планируемых распределенных транзакций) вместо протоколов двухфазной фиксации или их вариаций. Практика эксплуатации в «Яндексе» доказывает, что система эффективна в больших масштабах, хотя и специфическая — для работы с ней нужно представлять ее структуру, например, в ней нет внешних ключей, а сегментирование идет по первичному ключу, который должен быть подобран с учетом равномерности и потенциально высокой фрагментации.

Аппаратное ускорение

За четыре года, минувших со времени обзора [4], среди направлений аппаратного ускорения для СУБД одно утрачено — корпорация Intel отказалась от развития энергонезависимой памяти Optane, которая была первой и единственной на сегодня реализацией, применимой для серверных баз данных. В машинах Oracle Exadata модули Optane используются для моментальной записи журнала предзаписи на ячейку хранения — со скоростью операций с памятью достигнуты свойства устойчивости и отказоустойчивости (ячейки хранения — отдельные узлы, подключенные по RDMA, Remote Direct Memory Access). Для экспериментальной версии машины баз данных «Скала^р» был разработан специальный движок OrioleDB, работающий напрямую с Optane как с символьным устройством через PMDK (persistent memory development kit) в режиме devdax. Результаты, которые он показывает на тестах TPC-B (pgbench), — до 180 тыс. транзакций в секунду, что ранее было недостижимо на любых вариантах PoatgreSQL на любом оборудовании.

Есть надежда, что не пропадут результаты, полученные за короткую жизнь Optane, — PMDK и процессорные инструкции, обеспечивающие сброс кэша в энергонезависимую область, будут использованы с другими байтоадресуемыми энергонезависимыми устройствами. Первые кандидаты на вакансию, образовавшуюся после ухода Optane, — байтоадресуемые SSD, которые можно подключить через CXL 2.0 в режиме памяти, тем самым на новом уровне повторить возможности Optane. Кроме того, CXL 2.0 позволяет доставить до узла практически бесконечную память и даже организовать ее в отказоустойчивом режиме, что, в свою очередь, позволяет сделать резидентные системы «резиновыми» и надежными, причем без работы с блочным устройством.

PCIe 5.0 и CXL 2.0 открывают также новые возможности для применения ПЛИС и графических ускорителей, которые теперь можно переподключать к разным узлам, и, главное, обеспечивая высокую пропускную способность, недостаток которой, собственно, и ограничивал их применимость для технологий баз данных [4]. Более радикальные шаги состоят в погружении ПЛИС и процессоров общего назначения непосредственно в накопители — уже несколько производителей выпускают сейчас такого рода устройства, обозначаемые как «SmartSSD» или «Computational storage device» (Eideticom, Samsung, NGD, ScaleFlux). Небольшие эксперименты с автосжимающими средствами бортового ПЛИС накопителей ScaleFlux CSD2000 дали обнадеживающие результаты для PostgreSQL (при снижении коэффициента заполнения без потери пространства) и Arenadata DB (при отключении сжатия на стороне СУБД без потери емкости), и есть шанс, что с выходом в свет серии SSD ScaleFlux CSD3000 с полноценным ARM-процессором можно будет получить значимый эффект. Еще одним новым направлением стали устройства, представляющие интерфейс «ключ — значение», притом как SSD (Samsung), так и ПЛИС (Pliops), а поскольку многие горизонтальные СУБД строятся над такими движками, то открываются интересные возможности и в этом направлении. Они уже встроены в аппаратуру, и остается лишь ими эффективно воспользоваться.

Путь в гипермасштаб

Стандарт CXL 2.0 и приходящие с ним возможности позволяют организовать объединение (пулирование) ресурсов памяти и почти безубыточное для производительности подключение ускорителей и накопителей по сети. Это дает фактически готовую конструкцию для масштабирования одноузловой резидентной системы на десятки терабайт, а также позволяет реализовать консолидационные сценарии, когда в одном большом пуле узлов можно разместить множество «аренд» — экземпляров СУБД с различной нагрузкой, в одноузловом режиме выполняя каждый экземпляр, по мере необходимости подключая ресурсы из общего пула. Байтоадресуемые накопители, подключаемые по CXL 2.0, позволяют организовать полновесную отказоустойчивость со скоростью неотказоустойчивой системы: журнал предзаписи ведется на таком накопителе на удаленном узле с практически моментальной фиксацией, без сетевых операций, сериализаций и трансформаций. В этом случае даже асинхронная реплика, восстанавливающаяся из такого журнала, может практически не отставать от ведущего узла, а переключение при его сбое может быть даже быстрее, чем в синхронном случае. Ведение двух журналов на двух байтоадресуемых накопителях на разных узлах при минимальных дополнительных накладных расходах позволяет полностью обнулить RPO (Recovery point objective — максимальный период, за который могут быть потеряны данные).

Возможность пулирования ресурсов памяти может возродить интерес к гибридным транзакционно-аналитическим системам (HTAP, «транслитическим» — translytical — в терминологии Forrester). Резидентная транзакционная часть с журналом предзаписи на байтоадресуемом устройстве на удаленном узле позволяет обеспечить сверхвысокую производительность отказоустойчивой атомарной записи, а концентрация удаленных устройств памяти в единый пул позволяет работать в транзакционном режиме с большими базами с одного узла. При этом аналитическую часть, организованную в столбцовых форматах, уже можно эффективно сегментировать на множество узлов — эти механизмы хорошо отработаны. Ускорить работу со столбцовыми форматами могут ускорители на базе ПЛИС — известно множество достойных реализаций для форматов Apache Arrow, Parquet и ORC, а также есть реализации для столбцового формата Greenplum (Deepgreen DB). Широкое применение таких форматов до сих пор сдерживалось необходимостью пересылать данные по «узкому» PCI Express. С пятой версией этой шины и CXL 2.0, а также с внедрением высокопроизводительной памяти в ПЛИС открываются широкие перспективы применения ПЛИС для моментального «столбцевания» данных, получаемой из транзакционных журналов, а с учетом продолжающихся исследований в области эффективных на атомарную вставку столбцовых форматов есть шанс на таком техническом оснащении построить истинно универсальную систему OLTP + OLAP.

Следующий уровень масштабирования — к сотням терабайтов и десяткам тысяч подключений с практически неограниченным по чтению — может стать применение схемы дезагрегации вычислительной части и хранения, по тем же принципам, что и в Amazon Aurora, но с усовершенствованием. Журнал предзаписи может вестись непосредственно на подключенном по CXL байтоадресуемом накопителе, при этом интегрированные в него ускорители могут быть задействованы для восстановления базы данных по журналу.

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

Реальное гипермасштабирование даже со всеми аппаратными новшествами невозможно без сочетания схем дезагреграции с техниками разделения и локализации обработки. Для этого необходимы устройства, работающие как движки хранения; ускорители, ведущие линеаризованный журнал распределенной системы с использованием неконфликтующих структур (CRDT, conflict-free replicated datatypes); вычислительные экземпляры, включающиеся по требованию и работающие с единственным или строго ограниченным наборов сегментов (рис. 5).

***

Сейчас пока сложно предсказать изменения, в долгосрочной перспективе возможные для масштабирования транзакционных нагрузок, тем более что намечаются прорывы в совершенно неожиданных направлениях, таких как сверхъемкая и сверхбыстрая память, притом продолжаются работы как над энергозависимой (3D-DRAM), так и энергонезависимой памятью, а также интеграции в модули памяти процессорных устройств (PiM, processing-in-memory). Кроме этого, сверхплотное хранение на ДНК, про реальность которого недавно заявили в Nature Nanoelectronics, может привести к пересмотру всех техник и алгоритмов в сфере обработки данных. Однако уже в ближайшие годы и даже месяцы будут доступны новые технологии, которые позволят обеспечить кардинальный сдвиг в решении задачи масштабирования транзакционной нагрузки.

При этом не стоит ждать появления универсальной и простой программной системы, установка которой на произвольный набор серверных узлов, связанных произвольной сетью, обеспечит желаемые свойства — для настоящего гипермасштаба необходимо преодолеть множество барьеров, а реальное решение будет на стыке аппаратных новшеств, алгоритмических находок и определенных правил их использования. Но самым важным является то, что подобные системы можно построить без привлечения проприетарного ноу-хау.

Литература

1. Pavlo A., Aslett M. What's Really New with NewSQL? // ACM SIGMOD Record. 2016, vol. 45, № 2, 2016, pp. 45–55, DOI: 10.1145/3003665.3003674.

2. Balakrishnan M. et al. CORFU: A distributed shared log // ACM Trans. Comput. Syst. 2013, vol. 31, № 4, art. 10, 24 p. DOI: 10.1145/2535930.

3. Андрей Николаенко, Дмитрий Волков. ОС для данных // Открытые системы. СУБД. — 2021. — № 1. — С. 8–13. URL: https://www.osp.ru/os/2021/01/13055824 (дата обращения: 21.06.2023).

4. Дмитрий Волков, Андрей Николаенко. На пути к «железным» СУБД // Открытые системы. СУБД. — 2019. — № 2. — С. 8–13. URL: https://www.osp.ru/os/2019/02/13054946 (дата обращения: 21.06.2023).

5. Андрей Фомичев, Олег Бондарь. Бессерверная альтернатива традиционным базам данных // Открытые системы.СУБД. — 2021. — № 1. — С. 20–23. URL: osp.ru/os/2021/01/13055826 (дата обращения: 21.06.2023). DOI: 10.51793/OS.2021.86.20.003.

Андрей Николаенко (anikolaenko@acm.org) — главный архитектор, «СКАЛА-Р»; Дмитрий Волков (vlk@keldysh.ru) — старший научный сотрудник ИПМ им. М. В. Келдыша РАН (Москва).

DOI: 10.51793/OS.2023.68.19.005