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

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

Raft: чтение кода и логов

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

Баги Raft прячутся в четырёх местах: consistency check в AppendEntries, продвижение commit index, правило выдачи голоса и state machine, применяющая лог. Читай каждый сниппет так, как читал бы на ревью или в инциденте, и выбирай то, что senior-инженер пометит первым.

Цель

Потренируйся читать протокол там, где он реально живёт — в обработчиках RPC и строках лога — и замечать off-by-one, отсутствующую проверку и сигнатуру расхождения, отделяющие корректный Raft от портящего данные.

Сниппет 1 — consistency check в AppendEntries

// follower handling AppendEntries
func (r *Raft) handleAppend(a AppendEntries) AppendReply {
    if a.Term < r.currentTerm {
        return AppendReply{Term: r.currentTerm, Success: false}
    }
    // BUG IS HERE: appends without the prevLog check
    r.log = append(r.log[:a.PrevLogIndex+1], a.Entries...)
    r.fsync()
    return AppendReply{Term: r.currentTerm, Success: true}
}
Викторина

В этом обработчике follower'а нет одной проверки, на которой держится безопасность Raft. Какой именно и что ломается без неё?

Сниппет 2 — продвижение commit index

// leader, after collecting matchIndex[] from followers
func (r *Raft) advanceCommit() {
    for n := r.commitIndex + 1; n <= r.lastIndex(); n++ {
        count := 1 // count self
        for _, m := range r.matchIndex {
            if m >= n {
                count++
            }
        }
        if count >= r.majority() {
            r.commitIndex = n   // committed by majority
        }
    }
}
Викторина

Majority реплицировал запись n, поэтому код её коммитит. Но статья Raft добавляет ещё одно условие перед тем, как лидер может продвинуть commitIndex до n. Какое и почему?

Сниппет 3 — выдача голоса

// handling RequestVote
func (r *Raft) handleVote(v RequestVote) VoteReply {
    if v.Term < r.currentTerm {
        return VoteReply{Term: r.currentTerm, Granted: false}
    }
    if r.votedFor == nil || r.votedFor == v.CandidateID {
        r.votedFor = v.CandidateID
        return VoteReply{Term: v.Term, Granted: true}
    }
    return VoteReply{Term: v.Term, Granted: false}
}
Викторина

Этот обработчик голоса соблюдает один-голос-на-term, но пропускает проверку. Что теперь может сделать кандидат и какое свойство безопасности отказывает?

Сниппет 4 — реальный лог AppendEntries

15:42:08 INFO  raft: AppendEntries -> D failure (mismatch at idx=400100 term=12 vs follower idx=400100 term=11)
15:42:09 INFO  raft: AppendEntries -> D retry prevIdx=400050 (decremented)
15:42:09 INFO  raft: AppendEntries -> D failure (mismatch at idx=400050 term=12 vs follower idx=400050 term=10)
15:42:10 INFO  raft: AppendEntries -> D retry prevIdx=399000 (decremented)
15:42:10 INFO  raft: AppendEntries -> D failure (mismatch at idx=399000 term=12 vs follower idx=399000 term=8)
15:42:11 WARN  raft: D has diverged extensively; consider InstallSnapshot
Викторина

Лидер раз за разом декрементирует nextIndex для follower'а D по одному шагу. Читая этот лог, какой диагноз и правильная операционная реакция?

Итог

Четыре обработчика несут безопасность Raft. AppendEntries обязан гейтить каждую вставку совпадением prevLogIndex/prevLogTerm, иначе логи тихо расходятся. Лидер вправе напрямую коммитить лишь запись своего текущего term — подсчёт реплик на записи прошлого term снова открывает перезапись figure-8. RequestVote обязан сравнивать lastLogTerm/lastLogIndex, иначе устаревший кандидат побеждает и ломает Leader Completeness. А длинная серия пошаговых декрементов nextIndex с падающими term’ами — сигнатура расхождения, означающая «переключайся на InstallSnapshot». Читай протокол там, где он живёт — в обработчиках и логах — и это ровно те строки, которые senior-инженер проверяет первыми.

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

Trademarks belong to their respective owners. Editorial reference only.