К основному содержимому
к выпуску
Конспект выпуска2022Fellow

Database Internals — выпуск 3

Третий выпуск по Database Internals открывает вторую часть — распределённые системы — и собирает двух гостей: Олега Бондаря из Яндекса, развивающего базу данных, и Константина Евтеева, руководителя IT-департамента платформы экспресс-доставки в X5, до этого шесть лет руководившего разработкой. Саша и Вова Чистяков вместе с ними проходят четыре главы: введение с заблуждениями о сети, обнаружение отказов, выбор лидера и модели консистентности.

Code of Architecture · книжный клуб7 минут

Конспект сокращён относительно полного выпуска; примеры и оценки передают опыт и позиции участников.

Основная линия материала
01

Заблуждения, каналы и невозможность консенсуса

Саше нравится, как начинается вторая часть: современные книги не уговаривают уйти с монолита, а констатируют, что ваша система уже распределена, и вопрос в том, как с ней жить, — в духе фразы известного исследователя консенсуса о том, что распределённая система — это система, в которой тебя может подвести то, о существовании чего ты даже не знал. Костя добавляет термины: конкурентность и параллелизм автор разводит метафорой двух очередей к одной кофемашине против двух кофемашин. Другой участник добавляет, оговариваясь, что может ошибаться: клиенты — тоже часть распределённой системы, и при проектировании об этом часто забывают. Заблуждения Питера Дойча 1994 года Петров расширяет: обработка занимает время, состояние может побиться (слайд про часы участники решают пропустить). Отсюда backpressure — Костя приводит ресторан, который закрывает дверь и не даёт вставать в очередь, потому что ждать два часа бессмысленно, — и очереди, которые развязывают по времени, сглаживают всплески и позволяют принимать запросы дёшево, а обрабатывать позже; рассчитывать систему на миллион RPS, если 99% времени она живёт на десяти тысячах, экономически бессмысленно. Олег рассказывает случай из облачной базы: приложение не могло стартовать, потому что при нехватке соединений отшибало старых клиентов, а надо было новых.

Саша формулирует свойство, которого ждут от такой системы: не живучесть таракана, а предсказуемость — сломаться честно и умереть, а не выдавать неконсистентные ответы; и признаётся, что распределённые системы делают из разработчика параноика, как у руководителя, который в кинотеатре первым делом ищет запасной выход. Костя проходит каналы связи: с потерями, с подтверждениями и повторами, с гарантией порядка, которая в асинхронной системе стоит дорого, и «ровно один раз», которого на практике добиваются идемпотентностью на стороне приёмника; следом другой участник уточняет, что ключ идемпотентности можно выдавать и на стороне клиента, и вспоминает — с оговоркой «если не ошибаюсь», — что Google в Spanner часть проблем решил, гарантировав идеальную сеть, что мало кому доступно. Дальше два генерала, три свойства консенсуса — согласие, валидность, завершение — и теорема FLP: без ограничений по времени нельзя отличить медленного курьера от пойманного, поэтому системы делают частично синхронными с таймаутами.

02

Отказы, их обнаружение и выбор лидера

Модели отказов Олег разбирает по нарастающей: crash-stop — честная остановка процесса с описанной процедурой восстановления; omission — пропуск хода из-за медленной сети или очередей; произвольные, они же византийские, — автор термина, по словам Олега, сначала вроде бы хотел назвать их албанскими, но ему сказали, что так делать некрасиво, и он взял что-то совсем из древности; на практике это и баги, и злоумышленники, и старая нода с несовместимым кодом, которая возвращается в кластер. Обнаружение отказов: простые проверки живости вроде пинга, но Олег отдельно предупреждает про health check вида select 1 — он быстрый, ничего не координирует и радостно отвечает, пока система лежит; вероятностный детектор, который отвечает не «работает / не работает», а с какой-то вероятностью; слухи, которые при большом числе нод резко умножаются — Костя видел, как это происходит, и напоминает про пределы применимости и стоимость каждого алгоритма.

Выбор лидера нужен, чтобы не договариваться на каждом шагу, как на большой встрече, где голосуют за каждый чих; свойства — уникальность в рамках группы и живучесть. Алгоритмы автор проходит бегло: сначала тот, где лидером становится нода с наибольшим рангом, а претендент опрашивает старших по рангу на живость; затем вариант, где преемник известен заранее и раундов ожидания нужно меньше; затем кольцевой обход, который собирает идентификаторы и выбирает максимальный, — все уязвимы к split brain, когда часть кластера решает выбирать заново; оптимизация с кандидатами и обычными узлами важна для больших систем — Олег хотел бы видеть на картинке три кандидата и три тысячи обычных нод. Костя эксплуатировал базу с кольцевым протоколом: когда сеть моргает, кластер разваливается и собирать его очень сложно; более надёжные алгоритмы автор оставляет на следующую главу про консенсус.

03

Репликация и модели консистентности

Репликация — избыточность ради отказоустойчивости, и участники обращают внимание, что CAP автор называет печально известной теоремой: при разделении сети выбираешь между консистентностью и доступностью, но ползунок можно крутить — отдавать 99 результатов из 100 (harvest) или считать долю успешно обработанных запросов. Здесь Олег спорит: чувствуется, что с нами говорит человек, причастный к Cassandra, и для огромного класса систем отдать 99 из 100 — жесточайшая ошибка; Саша списывает это на профдеформацию обеих сторон, а Костя мирит: где считаем деньги — одно, где сайт должен хоть что-то показать — другое. Олег добавляет PACELC Даниэля Абади: даже без разделения сети выбираешь между задержкой и консистентностью, и это свойство работающей системы, а в книге ему уделён абзац.

Модели: линеаризуемость с точкой, до которой значения не было, а после — оно видно всем, и ограничением скорости света; последовательная — одинаковый порядок для всех, но не обязательно реальный; причинная, где следующая операция может опираться на предыдущую. Саша замечает, что «консистентность» у авторов значит разное: уровни изоляции в одной ноде и модели в распределённой системе — не одно и то же, и это хороший вопрос на собеседовании. Костя добавляет, что serializable на мастере не гарантирует того же на реплике. Сессионные гарантии Олег проходит с точки зрения клиента: чтение своих записей, монотонные чтения без откатов в прошлое, монотонные записи в порядке записи, writes-follow-reads. Саша делится сомнением: в книге Алекса Сю кворум подаётся как strong consistency, а на самом деле без read repair при чтении гарантии нет; один из гостей соглашается, что «strong» и линеаризуемость — разные уровни: линеаризуемость теоретична и почти никем не достижима, а «strong» реализуем; тема тянет на отдельную встречу. Следующий выпуск — распределённые транзакции и консенсус.

Выводы

Что стоит унести с собой

  1. 01Ваша система уже распределена: заблуждения Дойча дополнены временем обработки и порчей состояния; спасают backpressure, очереди и честная смерть вместо неконсистентных ответов.
  2. 02«Ровно один раз» на практике — повторы плюс идемпотентность на стороне приёмника, а ключ идемпотентности можно выдавать и на стороне клиента; без таймаутов нельзя отличить медленную сеть от отказа (FLP), поэтому системы частично синхронны.
  3. 03Health check вида select 1 лжёт; алгоритмы выбора лидера — по рангу, с заранее известным преемником, кольцевой — уязвимы к split brain; слухов с ростом числа нод резко прибавляется, а кольцевой протокол разваливается, когда сеть моргает.
  4. 04CAP крутится через harvest и долю успешно обработанных запросов, но 99 из 100 недопустимо для многих систем; PACELC добавляет выбор задержка–консистентность в норме, а кворум без read repair не даёт strong consistency.

Источники