Записи в кількох регіонах: де насправді фіксується зміна?
Маршрутизація доставляє запит у регіон; атомарним запис робить лише межа транзакції. Назвіть інваріант, виберіть власника, а потім спроєктуйте повтор навколо нього.
Два сервери застосунку в двох регіонах, один клієнт, що пише через VPN, і питання, яке ніхто не записав: який компонент вирішує, що запис відбувся? Маршрутизація доставляє запит процесу. Межа транзакції вирішує, коли зміна стає довговічною і видимою. Це різні завдання, які виконують різні системи, і розрив між ними — те місце, де живе більшість помилок запису в кількох регіонах.
Почніть із бізнес-правила, а не з карти
Почніть із речення про бізнес-правило, а не про географію: які читання й записи мають вдатися разом і які одночасні зміни мають бути неможливими, поки це відбувається. Для резервування запасів це означає, що перевірка залишку й резервування або обидва набувають чинності, або жодне, і жодне друге замовлення не може витратити ту саму одиницю між ними.
| Requirement | What satisfies it | What does not |
|---|---|---|
| All-or-nothing application | A transaction inside one owning system | A VPN path between regions |
| No double spend | Isolation strong enough to exclude the conflict | Atomicity alone |
| Survive a region loss | Replication the database itself documents | Two independent databases behind one client |
Саме цей середній рядок команди й пропускають. Атомарність без достатньої ізоляції дозволяє двом транзакціям кожній правильно підтвердитися і все ж породити стан, який бізнес вважає неможливим, і жодна кількість логіки повтору це потім не виправить.
Одна авторитетна межа перемагає два регіональні сервери
Регіональні сервери застосунку можуть залишатися на місці, якщо вони передають операцію службі, яка виконує її в межах однієї підтримуваної межі транзакції. Рівень застосунку стає маршрутизатором наміру; рівень даних володіє істиною.
Тримайте цю межу короткою й близько до даних, яких вона торкається. Транзакція, що залишається відкритою, поки людина відповідає на запит або поки виклик перетинає два регіони, витрачає час на утримання блокувань і збільшує шанс, що щось інше спіткнеться за нею. Ця відмова виглядає як проблема бази даних і насправді є проблемою проєктування, вдягненою в такий костюм. Перенесення рішення на рівень даних зазвичай усуває її повністю.
BEGIN;
UPDATE inventory SET reserved = reserved + 1
WHERE sku = 'A-100' AND available >= 1;
INSERT INTO reservation (sku, order_id) VALUES ('A-100', 'ord-9f');
COMMIT;
Читайте цей начерк як межу, а не як рекомендацію щодо продуктивності. Суть у тому, що перевірка й вставка поділяють одне підтвердження, тож одночасне замовлення або бачить запас витраченим, або не бачить його зовсім.
Що дає й чого не дає реплікована база даних
Реплікована база даних може дати ширшу межу, коли це підтримує її власна модель транзакцій. Spanner документує атомарні транзакції читання-запису в межах однієї бази даних по таблицях, з визначеною ізоляцією та поведінкою повтору. Це гарантія, яку читають, тестують і на яку навмисно спираються.
Це також гарантія, що походить від продукту, а не від маршруту. VPN між регіонами змінює те, як подорожують пакети й як виявляються відмови. Він не розширює межу транзакції ні на один рядок, хоч би як здорово виглядав тунель. Змішування обох породжує архітектури, де кожен компонент проходить власну перевірку, а дані все одно не узгоджуються.
Дві бази даних не стають однією системою
Дві незалежно керовані бази даних не отримують спільного менеджера транзакцій через те, що клієнти можуть дістатися обох. Якщо бізнесу справді потрібне атомарне зобов’язання по цій парі, механізм координації, учасники й процес відновлення мають бути обрані та атестовані, а не припущені.
Подумайте про момент, коли учасник або зв’язок зникає після того, як роботу підготовлено. Підтримуване розподілене підтвердження може залишити невизначений стан, що потребує процедури відновлення й людського рішення, і воно не обіцяє, що кожен регіон залишиться доступним для запису при кожному розділенні.
Якщо натомість прийнятною є асинхронна координація, скажіть це явно й запишіть проміжні бізнес-стани та правила звіряння. Ланцюг локально підтверджених кроків із компенсацією — законний проєкт; просто це не одна атомарна транзакція під іншою назвою.
Спроєктуйте повтор до першого збою
Клієнт може втратити відповідь після того, як операцію підтверджено, тож викликач не може вважати тайм-аут відмовою. Зберігайте стійку ідентичність запиту й перед повтором зміни використовуйте результат служби або механізм ідемпотентності, інакше повтор стане другим записом.
Автоматичні зворотні виклики транзакцій також можуть виконуватися більше одного разу після повторюваного переривання, що робить їх поганим домом для незворотних зовнішніх ефектів. Тримайте їх поза зворотним викликом, якщо робочий процес не визначає для них явний безпечний протокол. Така сама обережність стосується всього, що коштує грошей або надсилає повідомлення. Подвійне списання — значно складніша розмова, ніж подвійний рядок журналу.
Приймання має відтворити чотири сценарії: два клієнти змагаються за той самий рядок, переривання, яке служба називає повторюваним, підтвердження, відповідь на яке ніколи не надходить, і втрата регіону або зв’язку між ними. Запишіть підтверджений бізнес-результат і невирішені стани поряд із проєктом маршрутизації, щоб ніхто не сплутав мережу з компонентом, що дає гарантію.