Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Проблемы с ACID, и как их устранить, не прибегая к использованию NoSQL

Оригинал: Daniel Abadi, Alexander Thomson. The problems with ACID, and how to fix them without NoSQL. DBMS Musings, August 31, 2010

От редактора перевода

Я благодарен Юрию Кудрявцеву за то, что он нашел эту заметку, перевел ее и навел меня на статью Абади и Томсона, которую я было упустил. Статья очень, что называется, "в жилу", и я собираюсь ее в скором времени перевести 1. А пока почитайте, о чем, собственно, идет речь.

Не секрет, что набирающее в последнее время популярность движение NoSQL направлено отнюдь не на устранение SQL из систем баз данных. Скорее, основной целью разработчиков систем, подобных Bigtable, HBase, Hypertable, Cassandra, Dynamo, SimpleDB (и множеству других хранилищ "ключ-значение"), PNUTS/Sherpa и т.д., является достижение масштабируемости системы. Масштабирование традиционных ACID-совместимых реляционных СУБД на дешевых серверах и горизонтально масштабируемой (scale-out) архитектуре "shared-nothing" оказывается очень сложной задачей. Поэтому в системах NoSQL отбрасываются некоторые из гарантий ACID, чтобы можно было достичь их горизонтальной масштабируемости. Однако масштабируемость в данном случае достигается за счет усложнения разработки приложений, т.к. необходимые примитивы синхронизации запросов и транзакций нужно создавать самостоятельно. Таким образом, NoSQL скорее означает NoACID.

В этой заметке нам хотелось бы прежде всего объяснить, почему так тяжело масштабируется ACID-система. В то же время, хочется подчеркнуть, что NoSQL/NoACID – это, на наш взгляд, слишком "простой" (lazy way) путь. Вместо того, чтобы обходить проблемы, мешающие масштабированию ACID-систем, было бы лучше попытаться их решить. Несомненно, это сложная задача, но у нас есть пара новых идей.

ACID, Масштабируемость и репликация

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

В ситуации, когда транзакция затрагивает данные, расположенные на нескольких физических машинах, поддерживать свойства ACID становится сложнее. Чтобы можно было гарантировать атомарность (atomicy), требуется соблюдать распределенный протокол фиксации транзакций (например, двухфазная фиксация) на всех машинах, участвующих в транзакции. Чтобы можно было гарантировать изолированность (isolation) транзакции, требуется удерживать все ее блокировки на все время выполнения этого протокола. В современных OLTP-системах большая часть рабочей нагрузки состоит из достаточно легковесных транзакций (для выполнения которых требуется менее 10 микросекунд), и поэтому добавление двух достаточно медленных сетевых взаимодействий для фиксации каждой распределенной транзакции может привести к тому, что блокировки будут удерживаться на время, на порядки большее, чем время реальной работы транзакции. Подобная ситуация приводит ко все возрастающему числу взаимных блокировок между транзакциями, что достаточно серьезно ограничивает пропускную способность системы.

Кроме того, все более критичным становится требование к доступности масштабируемых транзакционных систем, и обычно оно удовлетворяется за счет репликации и автоматического перенаправления запросов в случае сбоя одного из узлов. Поэтому разработчики ожидают, что гарантии согласованности (consistency) ACID-систем (первоначально заключавшиеся в локальной поддержке определенных пользователями инвариантов) будут распространены на обеспечение строгой согласованности (того, что все реплики одних и тех же данных в любой момент времени будут являться идентичными копиями, т.е. в этом случае согласованность подразумевается в смысле CAP/PACELC).

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

В современных системах обычно используется репликация после записи (post-write replication), когда каждая транзакция сначала выполняется на первичном узле, и после ее выполнения обновления рассылаются во все реплики. Обычная схема master-slave с пересылкой журналов транзакций является самым простым примером репликации после записи. В эту же категорию попадают и схемы, в которых выполнение транзакции происходит на одном из нескольких ведущих узлов. При использовании подобной схемы велика вероятность чтения устаревших данных из подчиненных реплик, и системы, построенные на такой логике, становятся жертвами фундаментального противопоставления "задержка-надежность-согласованность". Ведущий узел либо ждет подтверждения от всех подчиненных узлов до окончательной фиксации транзакции, либо фиксирует транзакцию, не дожидаясь этого. В последнем случае текущие транзакции, которые нужно было переслать в подчиненные узлы, могут быть потеряны при отказе ведущего узла, что нарушает свойство долговечности (durability) транзакций. Или же эти транзакции могут быть получены в подчиненных узлах после восстановления ведущего узла, что может привести к нарушению согласованнности, если над репликами выполнялись какие-либо транзакции до момента восстановления.

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

Решения класса NoACID

Разработчки NoSQL-систем, зная о подобных проблемах, ослабляют некоторые гарантии ACID для достижения масштабируемости и высокой доступности. Обычно требования ACID остабляются одним из двух способов. Во-первых, системы типа BigTable, SQL Azure, MySQL с поддержкой репликации и хранилищ "ключ-значение" поддерживают атомарность и изолированность транзакций, только когда каждая транзакция затрагивает только данные некоторого подмножества записей базы данных (один кортеж в BigTable и хранилищах "ключ-значения" или один раздел базы данных в SQL Azure и в MySQL с поддержкой репликации). Это устраняет потребность в дорогостоящем протоколе распределенной фиксации транзакций, но в результате любая транзакция, затрагивающая больше чем одно подмножество записей, должна разбиваться на разные транзакции на уровне приложения. В этой ситуации система больше не гарантирует атомарность или изолированность на уровне произвольных логических транзакций. Поэтому разработчик должен реализовывать требуемую функциональность ACID на уровне приложения.

В качестве второго варианта испольуются "ленивые" (lazy) схемы репликации, при использовании которых согласованность достигается со временем (eventually). В соответствие с теоремой CAP, в сетевой среде можно достичь высокой доступности, жертвуя строгой согласованностью. Однако, исключая случаи некоторых широко известных приложений Web 2.0, потеря согласованности является слишком дорогой ценой и ведет к усложнению разработки приложений.

Решение проблем ACID без перехода к решениям NoSQL

Как нам кажется, решение сообщества NoSQL ослабить требования ACID является слишком "простым" (lazy) решением проблем масштабируемости и реплицируемости. В NoSQL системах заботы об атомарности, согласованности и изолированности транзакций просто перекладываются на плечи разработчика. На наш взгляд, необходимо придумать решения, позволяющие масштабировать ACID-системы на архитектурах shared-nothing. Решению подобных проблем посвящено наше иссследование и статья, которую мы представляем на конференции VLDB'10.

Каким бы парадоскальным это не казалось, но, на наш взгляд, проблема не в том, что требования ACID слишком высоки, и что это серьезно мешает масштабировать подобные системы на кластерах shared-nothing. Скорее, наоборот, требования являются слишком низкими, и из-за этого страдает масштабируемость систем.

Корнем этих проблем является свойство изоляции транзакций в ACID-системе. В частности, требование сериализуемости транзакций (стандартный уровень изолированности транзакций в ACID-системе) гарантирует что выполнение набора транзакций происходит в порядке, эквивалентном некоторому последовательному порядку выполнения этих транзакций. В реальности выполнение может быть многопоточным и параллельным. Так что если три транзакции A, B и C одновременно выполняются в ACID-системе, ее финальное состояние будет одинаковым, если запустить их последовательно в некотором порядке одну за другой. Однако ничего нельзя сказать относительно этого порядка выполнения транзакций, это может быть и A-B-C, и В-A-C, и т.д.

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

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

Если ужесточить требование изолированности транзакции, введя обязательный предопределенный порядок выполнения транзакций (сохраняя при этом высокий уровень параллельного выполнения транзакций) и добавить дополнительный уровень в систему, который будет принимать транзакционные запросы, определять универсальный порядок выполнения и отправлять упорядоченный набор транзакций во все реплики, то проблемы a) и c) будут решены. Если же еще дополнительно запретить системный откат транзакций (причинами которого часто являются падения узлов и синхронизационные тупики), то также будет решена и проблема b).

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

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

Прототип детерминированной СУБД

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

В статье также приводятся результаты сравнительных экспериментов полностью ACID-совместимого прототипа СУБД, построенного на подобной модели, и стандартной (недетерминированной) системы с протоколом двухфазной блокировки. Оказывается что детерминированная система плохо работает в средах, зависящих от производительности дисковой подсистемы, но по мере сокращения времени выполнения транзакций (что тесно связано с появлением flash-дисков и уменьшающейся стоимостью основной памяти) система становится все более жизнеспособной. По результатам тестирования на современной аппаратуре, детерминированная система не уступает традиционной на стандартных тестах TPC-C и при этом является намного более производительной и масштабируемой при увеличивающемся количестве транзакций, затрагивающих несколько узлов.

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


1 14.10.2010 опубликован перевод статьи Абади и Томсона "Доводы в пользу детерминизма в системах баз данных"

Комментарии

Сергей Кузнецов, Fri Sep 24 15:10:51 2010:
Должен сказать, что основная их статья, на которую есть ссылки в заметке, еще интереснее. Я ее активно перевожу, так что вскоре можно будет почитать по-русски.
Огрищще, Thu Sep 23 17:28:14 2010:
Звучит интересно. Стоит поковыряться с их прототипом, когда выложат в открытый доступ.
Владимир, Thu Sep 23 11:41:43 2010:
лучшая статья про СУБД, что читал за последнее время.

Ваш комментарий

Имя:

Текст комментария (HTML-теги не допускаются):

Новости мира IT:

Архив новостей

Последние комментарии:

Loading

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...