awesome-everything EN
↑ Обратно к восхождению

Распределённые системы

Часы: построй хранилище с детекцией конфликтов

Суть Практический проект — построй реплицированное KV-хранилище, воспроизведи тихую потерю данных под last-write-wins на сбитых часах, затем почини её vector clock, которые выносят конкурентные записи как siblings.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 240 min

Читать, что last-write-wins роняет данные на сбитых часах — не то же самое, что увидеть это вживую и затем заставить прекратиться. Построй крошечное реплицированное хранилище ключ-значение, впрысни clock skew, воспроизведи тихую потерю, затем подставь vector clock и докажи, что конкурентные записи выживают как siblings, а не одна из них исчезает.

Цель

Преврати ментальную модель юнита в работающий код: воспроизведи тихую потерю данных от clock skew под LWW, реализуй сравнение happens-before через vector clock, детектируй конкурентность и продемонстрируй, что ни одна конкурентная запись не теряется молча.

Проект
0 из 7
Цель

Построй небольшое in-memory реплицированное KV-хранилище с двумя стратегиями разрешения конфликтов — настенный last-write-wins и vector clock — воспроизведи тихую потерю данных под LWW на сбитых часах, затем покажи, что vector clock детектируют конкурентные записи и держат обе как siblings.

Требования
Критерии приёмки
  • Воспроизводимый демо-скрипт, который под LWW с впрыснутым skew печатает отброшенную запись и успешный ack — сигнатуру тихой потери данных.
  • Тот же скрипт под vector clock печатает 'concurrent' для двух записей и возвращает обе siblings, без молча отброшенных записей.
  • Тесты проходят, показывая, что happens-before пары схлопываются в одну версию, а concurrent пары выносятся как siblings.
  • Текст в один абзац, объясняющий, почему LWW потерял запись (наибольший timestamp принадлежит самым быстрым часам, а не самой поздней записи) и почему vector clock — нет (они сравнивают причинно, а не по физическому времени).
Senior-стретч
  • Замерь стоимость метаданных: логируй размер вектора при росте с 3 до 50 узлов, затем реализуй пруниг (кэп записей или dotted version vectors) и покажи, что siblings всё ещё корректно детектируются при ограниченных метаданных.
  • Добавь tombstone с будущей датой: удали K с timestamp на час вперёд под LWW и покажи, что он подавляет каждую более позднюю реальную запись; затем покажи, что хранилище с vector clock трактует удаление просто как ещё одну конкурентную версию.
  • Добавь стратегию Lamport clock третьим вариантом и продемонстрируй пробел: она даёт чистый тотальный порядок, но молча выбирает победителя для конкурентной пары (без siblings), располагаясь между LWW и vector clock.
  • Набросай (или реализуй мок) путь commit-wait в стиле TrueTime: назначь commit timestamp, пережди настраиваемое ε и аргументируй, что external consistency дала бы здесь по сравнению с подходом vector clock.
Итог

Это цикл за каждым реальным решением о разрешении конфликтов: воспроизведи сбой (LWW молча роняет более новую запись, потому что наибольший timestamp принадлежит самым быстрым часам), затем почини его правильным примитивом (vector clock сравнивают причинно, детектируют конкурентность и держат siblings вместо угадывания). Построив это один раз — впрыск skew, сравнение happens-before, вынос siblings и стоимость метаданных, которую платишь за детекцию — ты превращаешь ментальную модель юнита в инстинкт, к которому потянешься, когда продакшен-хранилище начнёт терять записи.

Продолжить восхождение ↑Саги: долгоживущие транзакции между сервисами без 2PC
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.