open atlas
↑ К треку
Основы System Design SD · 04 · 08

Распределение данных: шардируй, реплицируй и сломай

Практический проект: возьми датасет, спроектируй ключ партиционирования и репликацию, построй крошечное шардированное хранилище на consistent hashing, затем намеренно вызови горячий шард, потерю записи при failover и устаревшее кворумное чтение — и докажи, что меры работают.

SD Senior ◷ 240 min
Уровень
ОсновыJuniorMiddleSenior

Прочитать, что async-failover теряет записи и что mod-N рушит решардинг, — не то же, что увидеть это на хранилище, которое ты построил. Возьми датасет, спроектируй ключ партиционирования и репликацию, реализуй крошечное шардированное key-value хранилище на consistent hashing, а затем намеренно воспроизведи три фирменных отказа юнита — горячий шард, потерю записи и устаревшее кворумное чтение — и докажи, что твои меры реально закрывают каждый.

Этот проект делает весь юнит операциональным: ты выберешь ключ партиционирования и режим репликации, замаршрутизируешь ключи кольцом, а затем вызовешь каждый отказ намеренно, чтобы мера была чем-то измеренным, а не прочитанным.

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

Спроектируй и построй крошечное распределённое key-value хранилище (любой язык, в процессе или мультипроцессно), которое шардирует данные по выбранному ключу партиционирования, маршрутизирует ключи через consistent hashing и реплицирует каждый шард — затем намеренно воспроизведи горячий шард, потерю записи при failover и устаревшее кворумное чтение, и продемонстрируй меру для каждого.

Требования
Критерии приёмки
  • Абзац брифа с доминирующим запросом, отношением чтений к записям и кардинальностью ключа плюс обоснованный ключ партиционирования, выбранный из паттерна доступа.
  • Измерение, показывающее, что consistent hashing двигает ~1/N ключей при смене членства против базлайна mod-N, двигающего почти все — с приведёнными реальными долями.
  • Воспроизведённый горячий шард (нагрузка одного шарда сильно выше остальных при перекосе) и измерение после, показывающее, что мера размазала нагрузку.
  • Воспроизведённая потеря записи при async-failover и повтор при полусинхроне, где та же подтверждённая запись выживает — с точной последовательностью, давшей каждый исход.
  • Демонстрация кворума: устаревшее чтение при R + W ≤ N и гарантированно свежее чтение при R + W > N, с использованными значениями N, W, R.
  • Короткая заметка об архитектурных решениях, связывающая каждый выбор (ключ, режим репликации, кворум, точка CAP/PACELC) с конкретной гарантией или компромиссом, что он покупает.
Senior-стретч
  • Добавь split-brain: раздели кластер на партиции, дай обеим сторонам принимать записи, затем заживи и покажи разошедшиеся истории — и реализуй fencing или кворумное повышение, не дающее второму лидеру принимать записи.
  • Добавь путь решардинга: вырасти кольцо с N до N+2 узлов под живыми записями через двойную запись или change-data-capture и покажи, что ни одна подтверждённая запись не потеряна во время cutover.
  • Добавь bounded-load consistent hashing (ограничь каждый узел c×среднее и переливай по часовой) и покажи, что он укрощает горячий шард для маршрутизации запросов, сохраняя свойство движения ~1/N.
  • Добавь мульти-лидерный режим с двумя регионами, принимающими записи, инжектируй конфликтующую параллельную запись и реализуй разрешение конфликта (last-write-wins против вектора версий) — обсуждая, какое тихо теряет данные.
Вспомните перед уходом
  1. 01
    Как показать, что consistent hashing бьёт mod-N при смене членства?
  2. 02
    Какая точная последовательность даёт потерю записи при async-failover и как полусинхрон её чинит?
  3. 03
    Как показать, что кворум гарантирует (или не гарантирует) свежее чтение?
Итог

Этот проект превращает юнит распределения данных в то, что ты эксплуатировал, а не лишь прочитал. Ты выбираешь ключ партиционирования из доминирующего паттерна доступа и кардинальности, маршрутизируешь ключи по кольцу consistent hashing с виртуальными узлами (и измеряешь движение ~1/N против базлайна mod-N, переотображающего почти все), и реплицируешь каждый шард в синхронном и асинхронном режимах. Затем ты воспроизводишь три фирменных отказа юнита намеренно и закрываешь каждый: горячий шард при перекосе (смягчён разбивкой, кешированием или изоляцией ключа-знаменитости), потерю записи при async-failover (починена полусинхроном, чтобы ack означал «на двух узлах») и устаревшее кворумное чтение при R + W ≤ N (починено R + W > N, чтобы множества чтения и записи пересекались). Заметка об архитектурных решениях связывает каждый выбор — ключ, режим репликации, кворум, точку CAP/PACELC — с конкретной гарантией, что он покупает. Инженер, однажды построивший и сломавший это хранилище, распределяет данные намеренно, выбирая, какое расхождение терпеть, заранее, вместо того чтобы обнаруживать потерянную запись или снесённый кеш во время failover в 3 ночи.

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.