На днях узнал о шокирующей новости — появлении ACID транзакций в Apache Cassandra (в распределенной leaderless базе КАРЛ!)
Да да, случилась по-сути революция в Computer Science: то что еще недавно считалось невозможным иметь строгие и быстрые распредленные транзакции в leaderless базах данных, теперь — реальность!
За счет чего такой прорыв?
Умные инженеры (видимо еще и очень упорные) в Apple при содействии Университета Мичигана, решили бросить вызов одной из самых сложных проблем в индустрии — быстрые транзакции в leaderless-архитектурах, и разработали новый протокол консенсуса ACCORD.
Accord — это первый практичный протокол, который одновременно дает:
- 🤯 Strict-Serializable Consistency: Serializable и Linearizable (подробнее про модели согласованности)
- 🧠 Leaderless: Отсутствие глобального лидера
- 🚀Устойчивый к Contention: конкурирующие транзакции не приводят к гарантированному slow-path (за счет reorder buffer)
- ⚡️Согласование ВСЕГО ЗА 1 ROUND TRIP в оптимистичном сценарии и за 2 Round Trip при конфликтах
- ⚛️ Может работать на произвольных multi-key / multi-shard транзакций (ваши ключи могут быть в разных партициях и даже таблицах, и при этом вы можете атомарно их обновить)
Что это дает?
Этот протокол дает современным БД возможность быть одновременно масштабируемыми, быстрыми и транзакционными — без лидеров, без компромиссов и без атомных часов. Это кардинально меняет целый класс AP-систем — таких как Cassandra (а в перспективе, вероятно, и другие базы данных начнут интегрировать Accord). Уверен, что в ближайшие пять лет мы увидим массовый переход компаний на подобные решения, и это станет новым технологическим трендом.
Уже в следующей версии Cassandra должны добавить поддержку транзакций. Классическая задача резервации стоков теперь будет решаема на Cassandra:
BEGIN TRANSACTION
// Find out how many PlayStations are left
LET inventory = (SELECT inventory_count FROM ks.products WHERE item = 'Play Station 5');
// Return the inventory_count
SELECT item, inventory_count FROM ks.products WHERE item = 'Play Station 5';
// Take a PlayStation out of inventory and put it in users shopping cart
IF inventory.inventory_count > 0 THEN
UPDATE ks.products SET inventory_count -= 1 WHERE item = 'Play Station 5';
INSERT INTO ks.shopping_cart(user_name, item, item_count) VALUES ('leo', 'Play Station 5', 1);
END IF
COMMIT TRANSACTION;
