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

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

Распределённый капстоун: чтение кода и конфига

Суть Читай реальный конфиг и код со всего трека — размер кворума, проверка fencing, компенсация саги, backoff — предскажи провал и выбери фикс с наибольшим рычагом.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Баги композиции ловятся чтением конфига и кода в швах, а не прозы. Прочитай каждый сниппет, предскажи его поведение под сбоем и выбери фикс, который сеньор делает первым.

Цель

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

Сниппет 1 — конфиг кворума

# реплицированное хранилище заказов
replication:
  N: 3          # реплик на ключ
  W: 1          # ack-ов для подтверждения записи
  R: 1          # реплик читается на get
Викторина

При N=3, W=1, R=1 что чтение гарантирует о только что подтверждённой записи и как починить это для read-your-writes?

Сниппет 2 — проверка fencing

# ресурс, охраняющий шаг саги; вызывается тем, кто считает себя лидером
highest_token_seen = 0

def apply_step(step, token):
    global highest_token_seen
    # принять запись, затем запомнить токен
    write(step)
    highest_token_seen = max(highest_token_seen, token)
    return "ok"
Викторина

Приостановленный старый лидер просыпается с token=7, пока новый уже применил шаги при token=12. Что делает этот код и каков фикс?

Сниппет 3 — компенсация саги

# компенсация для отменённого заказа; вызывается слоем ретраев по таймауту
def refund(order_id, amount):
    # ключ идемпотентности не протянут
    charge_id = payment_api.create_refund(order_id=order_id, amount=amount)
    return charge_id
Викторина

Возврат первого вызова прошёл, но его ответ потерян; слой ретраев вызывает refund() снова в рамках бюджета. Что происходит и каков единственный фикс с наибольшим рычагом?

Сниппет 4 — политика ретраев

def call_with_retry(fn, attempts=6):
    for i in range(attempts):
        try:
            return fn()
        except Timeout:
            # фиксированная задержка, без jitter, без бюджета
            sleep(1.0)
    raise
Викторина

Сервис вниз по стеку мигает на две секунды под нагрузкой. Тысячи вызывающих гоняют ровно эту политику. Что даёт фиксированный sleep 1.0s и что меняет сеньор?

Итог

Каждый распределённый инцидент читается в шве: кворум с R + W не больше N молча отдаёт устаревшие чтения; fencing, который пишет до проверки токена, даёт устаревшему лидеру повредить состояние; компенсация, вызванная слоем ретраев без общего ключа, дважды возвращает деньги; а ретрай с фиксированной задержкой без jitter и бюджета превращает миг в herd. Прочитай конфиг и код, почини шов — добавь пересечение, отвергай до записи, протяни ключ, добавь jitter и бюджет — затем проверь под инъекцией сбоев.

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

Trademarks belong to their respective owners. Editorial reference only.