Транзакции в распределённых системах — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 1: Строка 1:
 +
{| class="wikitable" align="center" style="color: red; background-color: black; font-size: 56px; width: 800px;"
 +
|+
 +
|-align="center"
 +
|'''НЕТ ВОЙНЕ'''
 +
|-style="font-size: 16px;"
 +
|
 +
24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян.
 +
 +
Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием.
 +
 +
Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей.
 +
 +
Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить.
 +
 +
''Антивоенный комитет России''
 +
|-style="font-size: 16px;"
 +
|Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению.
 +
|-style="font-size: 16px;"
 +
|[https://meduza.io/ meduza.io], [https://www.youtube.com/c/popularpolitics/videos Популярная политика], [https://novayagazeta.ru/ Новая газета], [https://zona.media/ zona.media], [https://www.youtube.com/c/MackNack/videos Майкл Наки].
 +
|}
 +
 
[[Категория: Параллельное программирование]]
 
[[Категория: Параллельное программирование]]
 
== Зачем ==
 
== Зачем ==

Версия 08:08, 1 сентября 2022

НЕТ ВОЙНЕ

24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян.

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

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

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

Антивоенный комитет России

Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению.
meduza.io, Популярная политика, Новая газета, zona.media, Майкл Наки.

Зачем

Пусть у нас есть несколько узлов (процессов), которых хранят какие-то непересекающиеся данные. Например, на одном узле хранятся банковские счета пользователей на "А", на другом — на "Б", и так далее.

Тогда мы можем хотеть транзакционно изменять данные на разных узлах (см. BEGIN TRANSACTION и COMMIT TRANSACTION в SQL).

Определение:
Транзакция — это единица работы над множеством элементов из базы данных, которую можно в процессе работы целиком отменить (либо сама база данных, либо пользователь, см. ROLLBACK TRANSACTION), либо подтвердить (база данных может иногда не справиться, тогда транзакция отменяется).

У транзакции обычно выделяют свойства по аббревиатуре ACID:

  1. Atomicity (атомарность) — транзакция либо полностью применила все свои изменения, либо полностью откатилась (отменилась)
  2. Consitency (согласованность) — в конце транзакции система находится в согласованном состоянии
  3. Isolation (изолированность) — параллельные транзакции не должны влиять друг на друга (например, при помощи phantom reads и non-repeatable reads), а должны выполняться как будто последовательно
  4. Durability (надёжность) — завершённые (commited) транзакции сохраняются даже в случае сбоев и перезапуска системы

Атомарность и надёжность

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

Undo log

Каждый узел сначала записывает предыдущие значения в надёжный журнал (лог, обычно append-only и сохраняется на диск), а только потом изменяет состояние в памяти. Когда транзакция подтверждается, надо записать произведённые изменения в надёжное место и можно стереть кусок журнала. Если транзакцию надо откатить (например, после перезапуска системы в журнале нет записи "транзакция успешна"), то мы идём с конца журнала и восстанавливаем старые значения.

Redo log

Мы вообще не делаем изменения в данных до подтверждения транзакции, а просто пишем в журнал все операции, которые надо произвести с данными. Когда транзакция успешно завершается, у нас две опции:

  • Изменить данные прямо на диске.
  • Записать об этом в журнал на диск (append-only), а состояние просто каждый раз восстанавливать из этого журнала. Иногда делать checkpoint'ы для сохранения состояния. Это сейчас на практике популярнее.

Согласованность и изоляция

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

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

Более сложная штука — MVCC (MultiVersion Concurrency Control), это когда мы для каждой транзакции создаём "снимок" базы данных (наверняка при помощи персистентных структур данных) и дальше транзакция работает с ним. Например, в транзакциях только на чтение это позволяет экономить блокировки. А если появились записи, то надо как-то пробовать решать конфликты или даже просто откатывать транзакцию, если данные, которые она читала, уже кем-то были изменены.

Подтверждение транзакции в распределённой системе

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