консистентность данных что это

Консистентность данных

Консистентность данных

Консистентность данных (англ. data consistency или data validity) — это согласованность данных друг с другом, целостность данных, а также внутренняя непротиворечивость. Множество всех условий, налагаемых на данные определяется моделью (структурой) данных.

Содержание

Условия консистентности данных в ER-модели

Если данные представляют собой связанные отношениями узлы различного типа, в которых хранятся какие-то данные, то в модели данных могут быть оговорены условия: какие именно данные там могут хранится, и узлы каких типов могут быть связаны заданными в модели отношениями (связями) (см. w:en:Entity-relationship model, ER-модель данных).

Например, в базе данных людей, отношение «родитель» направленное от узла X к узлу Y подразумевает, что узел Y связан с X либо отношением «дочь» либо отношением «сын», причём это непосредственно зависит от значения атрибута «пол» узла X. Другим очевидным условием консистентности базы данных людей является требование, чтобы один узел был связан не более, чем с двумя другими узлами отношением «родитель», причём атрибут «пол» у этих узлов должен различаться.

Условия консистентности могут включать в себя указание того, какие значения могут принимать атрибуты узлов, какие отношения могут устанавливаться между узлами, каково минимальное и максимальное число отношений определённого типа, в котором может участвовать один узел, а также другие типы условий.

Консистентность в базах данных

Понятие консистентности впервые появилось в области систем управления базами данных.
Условия целостности данных (integrity constraints) стали записывать в виде правил и ввели триггеры — процедуры, которые вызывались до и после выполнения запроса. До запроса (триггер типа BEFORE) проходила проверка того, что данные имеют состояние, которое позволяет осуществить данный тип запроса. А после выполнения запроса (триггер типа AFTER) проверялось, что состояние базы данных удовлетворяет условим целостности. Если один из триггеров не срабатывал (возвращал НЕУСПЕХ или срабатывал с ошибкой), то транзакция откатывалась (отменялась).

Kонсистентность является важнейшим понятием теории управления данными (data management) и входит в четвёрку ACID (Atomicity, Consistency, Isolation, и Durability) — Атомарность, Консистентность, Замкнутость и Живучесть (стойкость).

Консистентность в теории алгоритмов и структур данных

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

Например, условие консистентности двоичного дерева поиска — это возрастание ключей в узлах дерева слева направо, а именно ключ в корневом узле должен быть меньше ключей узлов правого поддерева и больше ключей узлов левого поддерева. Если в каждом узле дерева поиска хранится также указатель parent на родительский узел, то возникает дополнительное условие консистентности двоичного дерева поиска: в каждом узле X указатель на родительский узел должен указывать на такой узел, в котором ровно один из указателей на детей (left или right) указывает на узел X.

Проблема поддержки консистентности данных

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

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

Источник

Консистентно о Консенсусе

Здравствуйте, меня зовут Дмитрий Карловский. А вы на канале Core Dump, где мы берём различные темы из компьютерной науки и раскладываем их по полочкам.

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

Согласованность данных

Начнём с консистентности или согласованности. Это — логическая непротиворечивость хранимых данных.

Например, если у Алисы родителем значится Боб, а у Боба родителем значится Алиса, то это явно какая-то лажа. Не могут они быть родителями друг друга одновременно. Данные не консистентны!

Согласованность часто путают с консенсусом. Особенно, когда данные частично хранятся на одном сервере, а частично на другом, но при этом должны быть согласованы друг с другом. Однако, консенсус немного о другом..

Согласие между участниками

Консенсус — это согласие группы участников касательно значения некоторого состояния. Например, если все считают Боба мужчиной, но сам он считает себя вертолётом, то согласия тут не наблюдается. Консенсус не достигнут!

Важно понимать, что даже если у каждого участника состояние само по себе консистентно, между участниками согласия при этом может и не быть. И наоборот, участники могут достигнуть консенсуса касательно несогласованного состояния. Тогда… Эта база данных сломалась. Несите следующую!

Достижение согласия

Все подходы по достижению консенсуса можно разделить на две большие группы..

Первая — это конкуренция за единый источник истины. Участники толпятся вокруг него, толкаются локтями и пытаются внести в него свои изменения. Транзакции в базах данных, атомарные операции в процессоре, протоколы консенсуса в распределённых системах — это всё из этой оперы.

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

Конкуренция за источник истины

Разберём подробнее конкуренцию за источник истины. Это может быть мастер-реплика СУБД, оракул в распределённых системах, основной поток приложения или просто общий участок памяти.

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

Тут можно выделить два вида блокировок: пессимистичная и оптимистичная.

В базах данных это соответственно пессимистичные и оптимистичные транзакции. В распределённых системах это мастер-слейв репликация и двухфазные коммиты. А во многопоточке это мьютексы и lock-free алгоритмы.

Пессимистичная блокировка

Идея пессимистичной блокировки простая: сначала участник запирает ресурс, затем производит его обновление, по завершении которого ресурс отпирается. Это если ему повезло прийти первым. Если же он пришёл, а ресурс уже кем-то заперт, то он сидит, ничего не делает, и ждёт его отпирания.

Это самый простой и надёжный подход. Однако у него есть проблемы с производительностью. Либо из-за постоянных ожиданий, либо из-за холостых запираний, которые так-то весьма не бесплатны.

Читайте также:  какую систему линукс лучше установить

Смертельное запирание

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

Запирание разве не блокировка?

Тут стоит подчеркнуть разницу между запиранием и блокировкой.

Запирание (locking) — это воздействие на ресурс таким образом, чтобы никто другой не мог с ним взаимодействовать.

Блокировка же (blocking) — это когда мы сами не можем продолжать работу по той или иной причине. Например, когда ожидаем отпирания ресурса, завершения ввода-вывода или просто какого-либо события.

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

Оптимистичная блокировка

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

Тут участник сначала готовит новое состояние, а потом атомарно применяет его к источнику истины. Если повезёт. А если не повезёт, и кто-то успеет раньше него, то вся проделанная работа выкидывается, и начинается заново.

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

Более того, один из вариантов реализации, например, мьютекса — это запирание с пробуксовкой, или spin-lock. То есть кручение в бесконечном цикле в ожидании отпирания ресурса, чтобы тут же рвануть на полной скорости получив зелёный свет.

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

Преимуществами данного подхода является высокая производительность в условиях низкой конкуренции, и существенно более сложное достижение взаимной блокировки, которая в этом случае уже называется оживлённым запиранием или live-lock.

К недостаткам же можно отнести большой объём холостой работы при высокой конкуренции, и существенно более сложные алгоритмы, чувствительные к архитектурным особенностям.

Задача византийских генералов

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

Анжелла и Константин выступают на битву со вселенским злом, а Блейд такой: «Ой, я из другой франшизы, это не моя битва, всем пока». В результате наши герои терпят поражение в неравном бою. А ведь могли бы отступить, и например, позвать Бимэна с его кучей артефактов.

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

В случае же конвергенции, никто никого не спрашивает «отступать или нападать?». В бой идут все! И даже ты, Блейд, иначе снова отправим на нары. Так что догоняй!

Вы, возможно, спросите меня: «Кто все эти люди и при чём тут компьютеры?». Что ж, стоит пояснить, что в распределённых системах наступление — это применение изменений, а отступление — это их откат.

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

Терпимость к разделению

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

Это — фундаментальная дилемма между консенсусом и доступностью также известная как CAP-теорема. Если мы выбираем консенсус, то участники, не имеющие доступа к источнику истины, не смогут изменить никакие данные. Если же им всё же позволить менять данные, то мы автоматически получаем ситуацию со множеством источников истины, которые могут друг другу противоречить.

И, как говорится, «Не можешь победить? Возглавь!». Так что давайте рассмотрим как можно жить без конкуренции за единый источник истины.

Сходимость к согласию

Если вы работали с распределёнными системами, то скорее всего вы слышали термин «Eventual Cоnsistency» или «Согласованность в конечном счёте». Так вот, оно на самом деле не про консистентность, а именно про конвергенцию или сходимость.

Wait-free алгоритмы межпоточного взаимодействия основаны на той же идее — отсутствие конкуренции за общий ресурс. Поэтому именно они, в отличие от lock-free, являются неблокирующими на самом деле.

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

Алгоритмы, обеспечивающие сходимость, можно разделить на 3 основных класса. Это: упорядоченные, полу-упорядоченные и… беспорядочные. Давайте рассмотрим их подробнее..

Упорядоченная сходимость

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

Но как же так, Алиса ведь уже внесла своё красное изменение А3 после А1, сверху докинула С4, а тут прилетает В2 и его нужно как-то вставить задним числом?

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

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

Читайте также:  крыса боится человека что делать

Разумеется, в таком наивном виде эти алгоритмы не применимы на практике. Поэтому к ним добавляют дополнительные костыли и идут на множество компромиссов. Например, обрезают старую историю, группируют изменения, делают периодические снепшоты состояния и тд. Это сглаживает углы, но не решает проблемы полностью. Зато ещё сильнее усложняет и без того не простые алгоритмы.

Полу-упорядоченная сходимость

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

CmRDT: Conflict-free Commutative Replicated Data Type

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

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

Беспорядочная сходимость

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

CvRDT: Conflict-free Convergent Replicated Data Type

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

CROWD — CvRDT нового поколения

Именно на конвергентные типы данных я и делаю ставку в своих проектах, используя уникальные CROWD алгоритмы для синхронизации распределённых состояний..

Но это уже совсем другая история, достойная отдельного разбора.

Согласны?

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

Что ещё почитать?

Если вам захочется больше информации к размышлению, то могу порекомендовать статью Пэта Хелланда о конвергенции и консистентности.

Буду рад, если подкинете ещё каких-либо материалов по этой теме.

Продолжение следует..

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

А на этом пока что всё. С вами был… беспорядочный программер Дмитрий Карловский.

Источник

Консистентность и ACID-гарантии в распределенных системах хранения данных

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

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

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

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

Эта статья основана на наших материалах по консистентности и ACID-гарантиям в распределенных системах.

Что это такое и зачем это нужно?

«Согласованность данных (иногда консистентность данных, англ. data consistency) — согласованность данных друг с другом, целостность данных, а также внутренняя непротиворечивость.» (Wikipedia)

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

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

Например, если у меня есть система из 4 узлов: A, B, C и D, которая обслуживает банковские транзакции, и узлы C и D отделились от A и B (скажем, из-за сетевых проблем), вполне возможно, я теперь не имею доступа к части транзакций. Как мне действовать в этой ситуации? Разные системы принимают разные подходы.

На верхнем уровне есть 2 ключевых направления, которые выражены в CAP-теореме.

«Теорема CAP (известная также как теорема Брюера) — эвристическое утверждение о том, что в любой реализации распределённых вычислений возможно обеспечить не более двух из трёх следующих свойств:

Когда CAP-теорема говорит о консистентности, она подразумевает достаточно строгое определение, включающее линеаризацию записей и чтений, и оговаривает только консистетность при записи отдельных значений. (Martin Kleppman)

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

И хотя, на первый взгляд выходца из мира классических СУБД, кажется, что выбор очевиден, и консистетность — самое главное, что у нас есть, это далеко не всегда так, что ярко иллюстрирует взрывной рост целого ряда NoSQL СУБД, которые сделали другой выбор и, несмотря на это, получили огромную пользовательскую базу. Apache Cassandra с ее знаменитой eventual consistency является хорошим примером.

Все из-за того, что это выбор, который подразумевает, что мы чем-то жертвуем, и далеко не всегда мы этим жертвовать готовы.

Часто проблема консистентности в распределенных системах решается просто отказом от этой консистентности.

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

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

Читайте также:  покраска стен в классе

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

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

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

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

Лучше, если корзина интернет-магазина скажет «попробуйте позднее, распределенная СУБД недоступна», чем если отрапортует об успехе и забудет заказ. Лучше получить отказ в транзакции из-за недоступности сервисов банка, чем отбивку об успехе и потом разбирательства с банком из-за того, что он забыл, что вы внесли платеж по кредиту.

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

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

Как это обеспечить?

Соответственно, первое решение, которое вам нужно принять — где вы находитесь в CAP-теореме, вы хотите консистентность или доступность в случае инцидента.

Далее нужно понять, на каком уровне вы хотите проводить изменения. Возможно, вам хватит обычных атомарных записей, затрагивающих единственный объект, как умела и умеет MongoDB (сейчас она расширяет это дополнительно поддержкой полноценных транзакций). Напомню, что CAP-теорема ничего не говорит о консистентности операций записи, затрагивающих множественные объекты: система вполне может быть CP (т.е. предпочитать консистентность доступности) и при этом предоставлять только атомарные одиночные записи.

Если вам этого не хватает, мы начинаем подходить к концепции полноценных распределенных ACID-транзакций.

Замечу, что даже переходя в дивный новый мир распределенных ACID-транзакций, мы зачастую вынуждены чем-то жертвовать. Так например, ряд распределенных систем хранения имеет распределенные транзакции, но только в рамках одной партиции. Или, например, система может не поддерживать «I»-часть на нужном вам уровне, не имея изоляции, либо имея недостаточное количество уровней изоляции.

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

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

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

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

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

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

Рассмотрим на примере двухфазного коммита, который использует, например, Apache Ignite.



Процедура коммита делится на 2 фазы: prepare и commit.

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

На фазе commit отправляется фактическое выполнение commit на узлах кластера. Если по какой-то причине часть узлов была недоступна или ответила ошибкой, то к этому времени данные занесены в их redo-лог (поскольку prepare был выполнен успешно), и коммит в любом случае может быть завершен хотя бы в отложенном состоянии.

Наконец, если отказывает координатор, то на prepare-этапе коммит будет отменен, на commit-этапе может быть выбран новый координатор, и, если все узлы выполнили prepare, он может проверить и обеспечить выполнение этапа commit.

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

Выводы

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

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

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

Оценивая продукты с этой стороны, стоит обращать внимание на то:

Источник

Образовательный портал