ЁЯФА рдзрдбрд╛ 03 тАФ Ordering & causality: рдЖрдзреА, рдирдВрддрд░, рдХреА рдПрдХрд╛рдЪ рд╡реЗрд│реА
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 03 ┬╖ рдорд╛рдЧреЗ: lesson-02-clocks ┬╖ рдкреБрдвреЗ: lesson-04-failure-detection
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ02, рдЕрдзрд┐рдХ vector clocks: рдкреНрд░рддреНрдпреЗрдХ рдЪрд┐рдареНрдареАрд╡рд░ рдЕрд╕рдгрд╛рд░рд╛, рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рдЦреЗрд╕рд╛рдареА рдПрдХ counter.
рддреНрдпрд╛рдВрдЪреНрдпрд╛рдореБрд│реЗ рджреЛрди рдШрдЯрдирд╛ рдПрдХрддрд░ before, after, same, рдХрд┐рдВрд╡рд╛
concurrent рдЕрд╕рддрд╛рдд тАФ рдЖрдгрд┐ "concurrent" рдореНрд╣рдгрдЬреЗ рдЦрд░рд╛ conflict, рдЙрд╢реАрд░ рдирд╡реНрд╣реЗ. dist/demo.py рдордзрд▓реЗ
ordering() рдЖрдгрд┐ dist/sim.py рдордзрд▓реЗ VectorClock + compare().
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдЖрддрд╛ рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рдЦрд╛ рдЪрд╛рд░ рдЦрд╛рдиреЗ рдЕрд╕рд▓реЗрд▓реЗ рдПрдХ рдЫреЛрдЯреЗ рдХрд╛рд░реНрдб рдареЗрд╡рддреЗ: рдкреБрдгреЗ, рдирд╛рд╢рд┐рдХ, рдирд╛рдЧрдкреВрд░, рдХреЛрд▓реНрд╣рд╛рдкреВрд░. ЁЯЧВя╕П рдкреНрд░рддреНрдпреЗрдХ рдЦрд╛рдирд╛ рдореЛрдЬрддреЛ "рддреНрдпрд╛ рд╢рд╛рдЦреЗрдХрдбреВрди рдЖрд▓реЗрд▓реНрдпрд╛ рдХрд┐рддреА рдЧреЛрд╖реНрдЯреА рдореА рдкрд╛рд╣рд┐рд▓реНрдпрд╛ рдЖрд╣реЗрдд".
- рдкреБрдгреНрдпрд╛рддрд▓реА рдХрддрд░рд┐рдирд╛ рдХрд╛рд╣реА рд▓рд┐рд╣рд┐рддреЗ рддреЗрд╡реНрд╣рд╛ рддреА рдкреБрдгреЗ рдЦрд╛рдиреНрдпрд╛рдд 1 рдорд┐рд│рд╡рддреЗ.
- рддрд┐рдЪреНрдпрд╛ рдЪрд┐рдареНрдареАрд╡рд░ рддрд┐рдЪреНрдпрд╛ рдХрд╛рд░реНрдбрдЪреА рдПрдХ рдкреНрд░рдд рдЕрд╕рддреЗ.
- рдирд╛рд╢рд┐рдХрдордзрд▓реА рдРрд╢реНрд╡рд░реНрдпрд╛ рддреА рдЪрд┐рдареНрдареА рд╡рд╛рдЪрддреЗ рддреЗрд╡реНрд╣рд╛ рддреА рдкреНрд░рддреНрдпреЗрдХ рдЦрд╛рдиреНрдпрд╛рддрд▓рд╛ рдореЛрдард╛ рдЖрдХрдбрд╛ рдШреЗрддреЗ, рдЖрдгрд┐ рдордЧ рдирд╛рд╢рд┐рдХ рдЦрд╛рдиреНрдпрд╛рдд 1 рдорд┐рд│рд╡рддреЗ.
рдЖрддрд╛ рджреЛрди рдХрд╛рд░реНрдбрд╛рдВрдЪреА рддреБрд▓рдирд╛ рдХрд░рд╛. рдХрд╛рд░реНрдб A рд╡рд░рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЦрд╛рдирд╛ рдХрд╛рд░реНрдб B рдкреЗрдХреНрд╖рд╛ рд▓рд╣рд╛рди рдХрд┐рдВрд╡рд╛ рд╕рдорд╛рди рдЕрд╕реЗрд▓, рддрд░ A рд╣реЗ B рдЪреНрдпрд╛ рдЖрдзреА рдШрдбрд▓реЗ тАФ B рд▓рд┐рд╣рд┐рдгрд╛рд▒реНрдпрд╛рдиреЗ A рдкрд╛рд╣рд┐рд▓реЗ рд╣реЛрддреЗ.
рдкрдг рдирд╛рдЧрдкреВрд░рдордзрд▓реНрдпрд╛ рджреАрдкрд┐рдХрд╛рдиреЗ рдХреЛрдгрддреАрд╣реА рдЪрд┐рдареНрдареА рди рд╡рд╛рдЪрддрд╛ рдХрд╛рд╣реАрддрд░реА рд▓рд┐рд╣рд┐рд▓реЗ. рддрд┐рдЪреЗ рдХрд╛рд░реНрдб рд╕рд╛рдВрдЧрддреЗ "рдирд╛рдЧрдкреВрд░ 1" рдЖрдгрд┐ рдмрд╛рдХреА рд╕рдЧрд│реАрдХрдбреЗ рд╢реВрдиреНрдп. рдРрд╢реНрд╡рд░реНрдпрд╛рдЪреЗ рдХрд╛рд░реНрдб рд╕рд╛рдВрдЧрддреЗ "рдкреБрдгреЗ 1, рдирд╛рд╢рд┐рдХ 1, рдирд╛рдЧрдкреВрд░ 0". рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдбрд╡рд░ рдЕрд╕рд╛ рдПрдХ рдЦрд╛рдирд╛ рдЖрд╣реЗ рдЬреЛ рджреБрд╕рд▒реНрдпрд╛рдкреЗрдХреНрд╖рд╛ рдореЛрдард╛ рдЖрд╣реЗ. рдХреЛрдгреАрдЪ рджреБрд╕рд▒реНрдпрд╛рдЪреЗ рдкрд╛рд╣рд┐рд▓реЗ рдирд╛рд╣реА. рддреНрдпрд╛ concurrent рдЖрд╣реЗрдд тАФ рджреЛрди рдЬрдгреАрдВрдиреА рдПрдХрд╛рдЪ рд╡реЗрд│реА рдПрдХрдЪ рдЧреЛрд╖реНрдЯ рдмрджрд▓рд▓реА, рдЖрдгрд┐ рдХрд╛рдп рдареЗрд╡рд╛рдпрдЪреЗ рддреЗ рдХреЛрдгреАрддрд░реА рдард░рд╡рд╛рдпрд▓рд╛рдЪ рд╣рд╡реЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
e1["e1 at Pune<br/>pune 1 ┬╖ nashik 0 ┬╖ nagpur 0"]
e2["e2 at Nashik, after reading e1<br/>pune 1 ┬╖ nashik 1 ┬╖ nagpur 0"]
e3["e3 at Nagpur, saw nobody<br/>pune 0 ┬╖ nashik 0 ┬╖ nagpur 1"]
e1 -->|"note: e1 before e2"| e2
c["тЪб e2 vs e3: concurrent<br/>a real conflict to resolve"]
e2 --- c
e3 --- c
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/distributed-systems/lesson-diagrams.html#l03
тЭУ рдХрд╛рдп
- Causality тАФ "a рдЪрд╛ b рд╡рд░ рдкрд░рд┐рдгрд╛рдо рд╣реЛрдК рд╢рдХрд▓рд╛ рдЕрд╕рддрд╛": рдзрдбрд╛ 02 рдордзрд▓реНрдпрд╛ happened-before рдЕрд░реНрдерд╛рдиреЗ a тЖТ b.
- Vector clock тАФ counters рдЪреА рдПрдХ рдпрд╛рджреА, рдкреНрд░рддреНрдпреЗрдХ node рд╕рд╛рдареА рдПрдХ. Node рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдиреЗрд╕рд╛рдареА рд╕реНрд╡рддрдГрдЪреНрдпрд╛ entry рдордзреНрдпреЗ 1 рдорд┐рд│рд╡рддреЛ. Receive рд╡рд░, рддреЛ рдЖрдкрд▓рд╛ vector рдЖрдгрд┐ message рдЪрд╛ vector рдпрд╛рдВрдЪрд╛ element-wise maximum рдШреЗрддреЛ, рдЖрдгрд┐ рдордЧ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ entry рдордзреНрдпреЗ 1 рдорд┐рд│рд╡рддреЛ.
- рджреЛрди vectors A рдЖрдгрд┐ B рдЪреА рддреБрд▓рдирд╛:
- same тАФ рдкреНрд░рддреНрдпреЗрдХ entry рд╕рдорд╛рди
- before тАФ A рдЪреА рдкреНрд░рддреНрдпреЗрдХ entry тЙд B (рдЖрдгрд┐ рдХрд┐рдорд╛рди рдПрдХ рд▓рд╣рд╛рди): a тЖТ b
- after тАФ A рдЪреА рдкреНрд░рддреНрдпреЗрдХ entry тЙе B: b тЖТ a
- concurrent тАФ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдЬреВрд▓рд╛ рдПрдЦрд╛рджреА entry рдореЛрдареА: рдХреЛрдгреАрдЪ рджреБрд╕рд▒реНрдпрд╛рдЪреЗ рдкрд╛рд╣рд┐рд▓реЗ рдирд╛рд╣реА
- Lamport clocks рдкреЗрдХреНрд╖рд╛ vector clocks рдХрд╛рдп рдЬрд╛рд╕реНрдд рджреЗрддрд╛рдд тАФ Lamport clocks: a тЖТ b тЗТ L(a) < L(b), рдкрдг рдЙрд▓рдЯ рдирд╛рд╣реА. Vector clocks: a тЖТ b тЗФ V(a) < V(b). рддреНрдпрд╛рдореБрд│реЗ рддреЗ concurrency рдУрд│рдЦрддрд╛рдд; Lamport рдХреНрд░рдорд╛рдВрдХ рдУрд│рдЦреВ рд╢рдХрдд рдирд╛рд╣реАрдд.
- рдХрд┐рдВрдордд тАФ рдкреНрд░рддреНрдпреЗрдХ message рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдард╡рд▓реЗрд▓реНрдпрд╛ value рд╡рд░ рдкреНрд░рддреНрдпреЗрдХ node рдЪреА рдПрдХ entry. рдЦреВрдк nodes (рдХрд┐рдВрд╡рд╛ рдЦреВрдк clients) рдЕрд╕рддреАрд▓ рддрд░ vector рд╡рд╛рдврдд рдЬрд╛рддреЛ; рдЦрд▒реНрдпрд╛ systems version vectors (рдкреНрд░рддреНрдпреЗрдХ client рдирд╡реНрд╣реЗ, рдкреНрд░рддреНрдпреЗрдХ replica рд╕рд╛рдареА рдПрдХ entry) рдЖрдгрд┐ dotted version vectors (Riak) рдЕрд╕реЗ рдкреНрд░рдХрд╛рд░ рд╡рд╛рдкрд░рддрд╛рдд.
- Conflict тАФ рдПрдХрд╛рдЪ item рд╡рд░ рджреЛрди concurrent writes. System рджреЛрдиреНрд╣реА рдареЗрд╡реВ рд╢рдХрддреЗ ("siblings") рдЖрдгрд┐ application рдХрд┐рдВрд╡рд╛ рдорд╛рдгрд╕рд╛рд▓рд╛ рддреЗ merge рдХрд░реВ рджреЗрдК рд╢рдХрддреЗ, CRDT рдиреЗ рдЖрдкреЛрдЖрдк merge рдХрд░реВ рд╢рдХрддреЗ (рдЕрд╕рд╛ data type рдЬреНрдпрд╛рдЪреЗ merges рдиреЗрд╣рдореА рдЬреБрд│рддрд╛рдд, рдЬрд╕реЗ counter рдХрд┐рдВрд╡рд╛ set), рдХрд┐рдВрд╡рд╛ рдПрдХ рдЯрд╛рдХреВрди рджреЗрдК рд╢рдХрддреЗ (last-writer-wins, рдзрдбрд╛ 08).
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг concurrent writes рд╕рд╛рдареА "рд╢реЗрд╡рдЯреА рдХреЛрдгрддрд╛ write рдЖрд▓рд╛?" рдпрд╛ рдкреНрд░рд╢реНрдирд╛рд▓рд╛ рдЙрддреНрддрд░рдЪ рдирд╛рд╣реА. рдЬреА system time stamp рдиреБрд╕рд╛рд░ рдПрдХ рдирд┐рд╡рдбрддреЗ рддреА рджреБрд╕рд░рд╛ рдЧреБрдкрдЪреВрдк рдЧрдорд╛рд╡рддреЗ. Vector clocks рдЕрд╕рд▓реЗрд▓реА system рд╣рд╛ рдлрд░рдХ рдкрд╛рд╣реВ рд╢рдХрддреЗ: "рдРрд╢реНрд╡рд░реНрдпрд╛рдЪреНрдпрд╛ рдмрджрд▓рд╛рдиреЗ рдХрддрд░рд┐рдирд╛рдЪреНрдпрд╛ рдмрджрд▓рд╛рдЪреА рдЬрд╛рдЧрд╛ рдШреЗрддрд▓реА" (before тЖТ рдирд╡рд╛ рдареЗрд╡рд╛) рдЖрдгрд┐ "рдРрд╢реНрд╡рд░реНрдпрд╛ рдЖрдгрд┐ рджреАрдкрд┐рдХрд╛ рджреЛрдШреАрдВрдиреА рди рдХрд│рддрд╛ рдмрджрд▓рд▓реЗ" (concurrent тЖТ рджреЛрдиреНрд╣реА рдареЗрд╡рд╛, merge рдХрд░рд╛ рдХрд┐рдВрд╡рд╛ рд╡рд┐рдЪрд╛рд░рд╛). Conflict рджрд┐рд╕рдгреЗ рд╣реА data рди рдЧрдорд╛рд╡рдгреНрдпрд╛рдЪреА рдкрд╣рд┐рд▓реА рдкрд╛рдпрд░реА рдЖрд╣реЗ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
dist/sim.py рдордзрд▓реЗ VectorClock(me, nodes) рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рдЦреЗрд╕рд╛рдареА рдПрдХ counter рдЕрд╕рд▓реЗрд▓реА
dict рдареЗрд╡рддреЗ. tick() рд╕реНрд╡рддрдГрдЪреНрдпрд╛ entry рдордзреНрдпреЗ 1 рдорд┐рд│рд╡рддреЗ. recv(other) рдкреНрд░рддреНрдпреЗрдХ entry рдЪрд╛ maximum рдШреЗрддреЗ,
рдЖрдгрд┐ рдордЧ tick рдХрд░рддреЗ. compare(a, b) рдкреНрд░рддреНрдпреЗрдХ key рд╕рд╛рдареА a[k] <= b[k] рдЖрдгрд┐ a[k] >= b[k] рддрдкрд╛рд╕реВрди
'same', 'before', 'after' рдХрд┐рдВрд╡рд╛ 'concurrent' рдкрд░рдд рджреЗрддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 dist/demo.py ordering
python3 - <<'EOF'
import sys; sys.path.insert(0, "dist"); from sim import VectorClock, compare
B = ["pune", "nashik", "nagpur", "kolhapur"]
vp, vn, vg = VectorClock("pune", B), VectorClock("nashik", B), VectorClock("nagpur", B)
e1 = vp.tick(); e2 = vn.recv(e1); e3 = vg.recv(e2) # this time Nagpur reads Nashik's note first
print("e3 =", e3)
print("e1 vs e3:", compare(e1, e3), "┬╖ e2 vs e3:", compare(e2, e3), "┬╖ e3 vs e1:", compare(e3, e1))
x = vp.tick(); y = vg.tick() # both write again without talking
print("x =", x); print("y =", y); print("x vs y:", compare(x, y))
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
ordering рд╣реЗ print рдХрд░рддреЗ:
тФАтФА vector clocks: e1 at Pune {'pune': 1, 'nashik': 0, 'nagpur': 0, 'kolhapur': 0}
e2 at Nashik after reading e1 {'pune': 1, 'nashik': 1, 'nagpur': 0, 'kolhapur': 0}
e3 at Nagpur, unaware of both {'pune': 0, 'nashik': 0, 'nagpur': 1, 'kolhapur': 0}
e1 vs e2: before
e2 vs e3: concurrent
e1 vs e3: concurrent
рддреБрдордЪрд╛ snippet рд╣реЗ print рдХрд░рддреЛ:
e3 = {'pune': 1, 'nashik': 1, 'nagpur': 1, 'kolhapur': 0}
e1 vs e3: before ┬╖ e2 vs e3: before ┬╖ e3 vs e1: after
x = {'pune': 2, 'nashik': 0, 'nagpur': 0, 'kolhapur': 0}
y = {'pune': 1, 'nashik': 1, 'nagpur': 2, 'kolhapur': 0}
x vs y: concurrent
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдирд╛рдЧрдкреВрд░рдЪрд╛ рддреЛрдЪ write demo рдордзреНрдпреЗ "concurrent" рдЖрд╣реЗ рдЖрдгрд┐ рддреБрдордЪреНрдпрд╛ snippet рдордзреНрдпреЗ "after". рдПрдХрдореЗрд╡
рдлрд░рдХ: рддреБрдордЪреНрдпрд╛ snippet рдордзреНрдпреЗ рдирд╛рдЧрдкреВрд░рдиреЗ рдЖрдзреА рдЪрд┐рдареНрдареА рд╡рд╛рдЪрд▓реА. Causality рдореНрд╣рдгрдЬреЗ рд▓рд┐рд╣рд┐рдгрд╛рд▒реНрдпрд╛рд▓рд╛ рдХрд╛рдп
рдорд╛рд╣реАрдд рд╣реЛрддреЗ, рдШрдбреНрдпрд╛рд│рд╛рдиреЗ рддреНрдпрд╛рдиреЗ рдХрдзреА рд▓рд┐рд╣рд┐рд▓реЗ рдЕрд╕реЗ рд╕рд╛рдВрдЧрд┐рддрд▓реЗ рддреЗ рдирд╡реНрд╣реЗ. рдЖрдгрд┐ y рдЪреНрдпрд╛ рдмрд╣реБрддреЗрдХ рдЦрд╛рдиреНрдпрд╛рдВрдд рдореЛрдареЗ рдЖрдХрдбреЗ
рдЕрд╕реВрдирд╣реА x рд╡рд┐рд░реБрджреНрдз y concurrent рдЖрд╣реЗ тАФ рдкреБрдгреЗ рдЦрд╛рдиреНрдпрд╛рдд x рдореЛрдард╛ рдЖрд╣реЗ, рддреНрдпрд╛рдореБрд│реЗ рдХреЛрдгреАрдЪ рджреБрд╕рд▒реНрдпрд╛рдЪреЗ
рдкрд╛рд╣рд┐рд▓реЗ рдирд╛рд╣реА.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- "concurrent" рдореНрд╣рдгрдЬреЗ "рдПрдХрд╛рдЪ рд╕реЗрдХрдВрджрд╛рд▓рд╛" рдЕрд╕реЗ рд╕рдордЬрдгреЗ тАФ рддреНрдпрд╛рдЪрд╛ рдЕрд░реНрде "рдХреЛрдгрд╛рд▓рд╛рдЪ рджреБрд╕рд▒реНрдпрд╛рдмрджреНрджрд▓ рдорд╛рд╣реАрдд рдирд╡реНрд╣рддреЗ"
- рдкреНрд░рддреНрдпреЗрдХ conflict last-writer-wins рдиреЗ рд╕реЛрдбрд╡рдгреЗ, рдЖрдгрд┐ рдПрдХ write рдЧрдорд╛рд╡рдгреЗ
- replica рдРрд╡рдЬреА рдкреНрд░рддреНрдпреЗрдХ client рд╕рд╛рдареА рдПрдХ vector entry тАФ vector рдЕрдорд░реНрдпрд╛рдж рд╡рд╛рдврдд рдЬрд╛рддреЛ
- рдкреБрдврдЪреНрдпрд╛ write рд╕реЛрдмрдд vector рдкрд░рдд рдкрд╛рдард╡рд╛рдпрд▓рд╛ рд╡рд┐рд╕рд░рдгреЗ, рддреНрдпрд╛рдореБрд│реЗ рд▓рд┐рд╣рд┐рдгрд╛рд▒реНрдпрд╛рдиреЗ рдХрд╛рдп рдкрд╛рд╣рд┐рд▓реЗ рд╣реЛрддреЗ рддреЗ server рд▓рд╛ рдХрд│рдд рдирд╛рд╣реА
- queue рдХрд┐рдВрд╡рд╛ log рддреНрдпрд╛рдЪреНрдпрд╛ рд╕рдЧрд│реНрдпрд╛ рднрд╛рдЧрд╛рдВрдордзреНрдпреЗ рдПрдХ global order рдареЗрд╡рддреЛ рдЕрд╕реЗ рдорд╛рдирдгреЗ (рдЦрд╛рд▓реА Kafka рдкрд╛рд╣рд╛)
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
Kafka рдлрдХреНрдд рдПрдХрд╛ partition рдЪреНрдпрд╛ рдЖрддрдЪ рдХреНрд░рдо рдареЗрд╡рддреЛ. рдПрдХрд╛ topic рдордзреНрдпреЗ рдЕрдиреЗрдХ partitions рдЕрд╕рддрд╛рдд, рдЖрдгрд┐ consumers рддреЗ рд╕рдорд╛рдВрддрд░ рд╡рд╛рдЪрддрд╛рдд. рдПрдХрд╛рдЪ key рдЪреЗ messages рдПрдХрд╛рдЪ partition рдордзреНрдпреЗ рдЬрд╛рддрд╛рдд, рддреНрдпрд╛рдореБрд│реЗ рддреЗ рдХреНрд░рдорд╛рдиреЗ рд░рд╛рд╣рддрд╛рдд; рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ keys рдЪреНрдпрд╛ messages рдордзреНрдпреЗ рдХреЛрдгрддрд╛рд╣реА рдХреНрд░рдо рдирд╕рддреЛ. On a real account тАФ рдПрдХрд╛ рд╡рд░реНрдЧрд╛рдЪреЗ timetable рдмрджрд▓ рд╡рд░реНрдЧрд╛рд▓рд╛ key рдореНрд╣рдгреВрди рдкрд╛рдард╡рд╛:
kafka-console-producer.sh --bootstrap-server localhost:9092 --topic timetable \
--property parse.key=true --property key.separator=:
# then type lines such as:
# class-3A:exam moved to Tuesday
# class-3A:exam room is 12
рджреЛрдиреНрд╣реА class-3A рдУрд│реА рдПрдХрд╛рдЪ partition рдордзреНрдпреЗ, рддреНрдпрд╛рдЪ рдХреНрд░рдорд╛рдиреЗ рдЬрд╛рддрд╛рдд. class-4B рдЪреА рдУрд│ рддреНрдпрд╛рдВрдЪреНрдпрд╛
рдЖрдзреА рдХрд┐рдВрд╡рд╛ рдирдВрддрд░ рд╡рд╛рдЪрд▓реА рдЬрд╛рдК рд╢рдХрддреЗ.
Dynamo-style stores тАФ рдореВрд│ Amazon Dynamo paper (2007) vector clocks рд╡рд╛рдкрд░рдд рдЕрд╕реЗ рдЖрдгрд┐
рд╕рдЧрд│реНрдпрд╛ concurrent versions merge рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА application рд▓рд╛ рдкрд░рдд рджреЗрдд рдЕрд╕реЗ (shopping cart рджреЛрдиреНрд╣реА versions рдордзрд▓реА
рдкреНрд░рддреНрдпреЗрдХ item рдареЗрд╡рдд рдЕрд╕реЗ). allow_mult рдЪрд╛рд▓реВ рдЕрд╕реЗрд▓ рддрд░ Riak concurrent writes siblings рдореНрд╣рдгреВрди рд╕рд╛рдард╡рддреЗ,
dotted version vectors рдиреЗ track рдХрд░реВрди. рдЗрддрд░ рдЕрдиреЗрдХ systems (Cassandra,
DynamoDB global tables) рддреНрдпрд╛рдРрд╡рдЬреА time stamp рдиреБрд╕рд╛рд░ last-writer-wins рд╡рд╛рдкрд░рддрд╛рдд тАФ рд╕реЛрдкреЗ, рдЖрдгрд┐ рддреЗ
рджреЛрди concurrent writes рдкреИрдХреА рдПрдХ рдЯрд╛рдХреВрди рджреЗрддреЗ.
CRDTs (conflict-free replicated data types) тАФ рдЖрдкреЛрдЖрдк merge рд╣реЛрдгрд╛рд░реЗ counters, sets рдЖрдгрд┐ text types; Redis Enterprise active-active databases рдордзреНрдпреЗ рдЖрдгрд┐ collaborative editors рдордзреНрдпреЗ (Automerge, Yjs) рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддрд╛рдд.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рджреЛрди рдард┐рдХрд╛рдгреА рд▓рд┐рд╣рд┐рддрд╛ рдпреЗрдгрд╛рд▒реНрдпрд╛ data рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рддреБрдХрдбреНрдпрд╛рд╕рд╛рдареА рдЖрдзреАрдЪ рдард░рд╡рд╛: рдХреЛрдгрддреА key рддреНрдпрд╛рдЪреЗ рдмрджрд▓ рдХреНрд░рдорд╛рдиреЗ рдареЗрд╡рддреЗ, рдЖрдгрд┐ рджреЛрди рдмрджрд▓ concurrent рдЕрд╕рддреАрд▓ рддрд░ рдХрд╛рдп рд╣реЛрддреЗ тАФ рджреЛрдиреНрд╣реА рдареЗрд╡рд╛рдпрдЪреЗ, merge рдХрд░рд╛рдпрдЪреЗ, рдХреА рдЬрд╛рдгреВрдирдмреБрдЬреВрди рдПрдХ рдЯрд╛рдХрд╛рдпрдЪрд╛.
тПня╕П рдкреБрдвреЗ
рдЖрддреНрддрд╛рдкрд░реНрдпрдВрдд рдЧрдкреНрдк рд╢рд╛рдЦрд╛ рд╣рд│реВ рдЕрд╕реВ рд╢рдХрддреЗ рдХрд┐рдВрд╡рд╛ рдмрдВрдж рдкрдбрд▓реЗрд▓реА. рддреБрдореНрд╣реА рдард░рд╡рддрд╛ рдХрд╕реЗ? Heartbeats рдЖрдгрд┐ timeouts тАФ рдЖрдгрд┐ рддреЛ рдирд┐рд░реНрдгрдп рдХрдзреАрдЪ рдЦрд╛рддреНрд░реАрдЪрд╛ рдХрд╛ рдирд╕рддреЛ.
git checkout lesson-04-failure-detection