ЁЯОп рдзрдбрд╛ 11 тАФ Exactly-once рдЪреЗ рдорд┐рдердХ: at-least-once + idempotency
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 11 ┬╖ рдорд╛рдЧреЗ: lesson-10-locks-leases ┬╖ рдкреБрдвреЗ: lesson-12-backpressure
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ10, рдЖрдгрд┐ delivery guarantees: at-most-once, at-least-once, рдЖрдгрд┐ systems рдЬреНрдпрд╛рдЪреА рдЬрд╛рд╣рд┐рд░рд╛рдд рдХрд░рддрд╛рдд рддреЗ "exactly-once". Network рдкрд▓реАрдХрдбреЗ message рдиреЗрдордХрд╛ рдПрдХрджрд╛рдЪ рдкреЛрд╣реЛрдЪрд╡рддрд╛ рдпреЗрдд рдирд╛рд╣реА тАФ рдкрдг рддреНрдпрд╛рдЪрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХрджрд╛рдЪ рдШрдбреВ рд╢рдХрддреЛ: **at-least-once delivery
- idempotent processing = effectively once**. dist/demo.py рдордзреАрд▓
exactlyonce()рдЖрдгрд┐ dist/sim.py рдордзреАрд▓deliver().
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдореБрдЦреНрдп office рдлреА рдкрд░рддрд╛рд╡рд╛ рдирд┐рд░реЛрдкреНрдпрд╛рдорд╛рд░реНрдлрдд рдкрд╛рдард╡рддреЗ: рдХрддрд░рд┐рдирд╛рд▓рд╛ рдкреИрд╕реЗ рджреНрдпрд╛, рджреАрдкрд┐рдХрд╛рд▓рд╛ рдкреИрд╕реЗ рджреНрдпрд╛, рдРрд╢реНрд╡рд░реНрдпрд╛рд▓рд╛ рдкреИрд╕реЗ рджреНрдпрд╛. ЁЯТ╕
рдирд┐рд░реЛрдкреНрдпрд╛ "рджреАрдкрд┐рдХрд╛рд▓рд╛ рдкреИрд╕реЗ рджреНрдпрд╛" рдкреЛрд╣реЛрдЪрд╡рддреЛ. рджреАрдкрд┐рдХрд╛рдЪреА рд╢рд╛рдЦрд╛ рддрд┐рд▓рд╛ рдкреИрд╕реЗ рджреЗрддреЗ. рд╢рд╛рдЦрд╛ рдкрд░рдд "рдЭрд╛рд▓реЗ" рдЕрд╕реЗ рдХрд│рд╡рддреЗ тАФ рдЖрдгрд┐ рддреА рдЪрд┐рдареНрдареА рд╣рд░рд╡рддреЗ (рдзрдбрд╛ 01). рдореБрдЦреНрдп office рд▓рд╛ рдХрд╛рд╣реАрдЪ рдХрд│рдд рдирд╛рд╣реА. рдореНрд╣рдгреВрди рддреЗ "рджреАрдкрд┐рдХрд╛рд▓рд╛ рдкреИрд╕реЗ рджреНрдпрд╛" рдкреБрдиреНрд╣рд╛ рдкрд╛рдард╡рддреЗ. рджреАрдкрд┐рдХрд╛рд▓рд╛ рджреЛрдирджрд╛ рдкреИрд╕реЗ рдорд┐рд│рддрд╛рдд. ЁЯШм
рдореБрдЦреНрдп office рдиреЗ рддреЗ рдлрдХреНрдд рдПрдХрджрд╛рдЪ рдкрд╛рдард╡рд▓реЗ, рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛ рдХрдзреАрдЪ рдирд╛рд╣реА, рддрд░? рдордЧ рдкрд╣рд┐рд▓реА рдЪрд┐рдареНрдареАрдЪ рд╣рд░рд╡рд▓реА рддрд░ рджреАрдкрд┐рдХрд╛рд▓рд╛ рд╢реВрдиреНрдп рд╡реЗрд│рд╛ рдкреИрд╕реЗ рдорд┐рд│рддрд╛рдд. рддреЗрд╣реА рд╡рд╛рдИрдЯрдЪ.
рдореНрд╣рдгреВрди рд╢рд╛рдЦрд╛ рдХрд╛рд╣реАрддрд░реА рд╣реБрд╢рд╛рд░реАрдЪреЗ рдХрд░рддрд╛рдд. рдкреНрд░рддреНрдпреЗрдХ рдЖрджреЗрд╢рд╛рд▓рд╛ рдПрдХ рдирд╛рд╡ рдЕрд╕рддреЗ: pay-dipika. рд╢рд╛рдЦрд╛
рдЖрдзреАрдЪ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдирд╛рд╡рд╛рдВрдЪреА рдпрд╛рджреА рдареЗрд╡рддреЗ. ЁЯУЛ "pay-dipika" рджреБрд╕рд▒реНрдпрд╛рдВрджрд╛ рдЖрд▓рд╛ рдХреА
рдХрд╛рд░рдХреВрди рдпрд╛рджреА рддрдкрд╛рд╕рддреЗ, рддреЗ рдирд╛рд╡ рддрд┐рдереЗ рдкрд╛рд╣рддреЗ, рдЖрдгрд┐ рдХрд╛рд╣реАрдЪ рдХрд░рдд рдирд╛рд╣реА тАФ рдкрдг рддрд░реАрд╣реА "рдЭрд╛рд▓реЗ" рдЕрд╕реЗ рд╕рд╛рдВрдЧрддреЗ.
рд╣рд╡реЗ рддрд┐рддрдХреНрдпрд╛ рд╡реЗрд│рд╛ рдкрд╛рдард╡рд╛. рдкреИрд╕реЗ рдПрдХрджрд╛рдЪ рдЬрд╛рддрд╛рдд.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
q["ЁЯУм queue<br/>at-least-once: may deliver again"] -->|"pay-katrina, pay-dipika,<br/>pay-aishwarya, pay-dipika again"| c1["plain consumer"]
q -->|"same four deliveries"| c2["idempotent consumer<br/>checks a list of done keys"]
c1 --> e1["4 effects<br/>Dipika paid twice"]
c2 --> e2["3 effects<br/>every payment once"]
ЁЯЧ║я╕П рд░реЗрдЦрд╛рдЯрд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/distributed-systems/lesson-diagrams.html#l11
тЭУ рдХрд╛рдп
- At-most-once тАФ рдПрдХрджрд╛ рдкрд╛рдард╡рд╛, рдХрдзреАрдЪ retry рдХрд░реВ рдирдХрд╛. Duplicates рдирд╛рд╣реАрдд, рдкрдг рд╣рд░рд╡рд▓реЗрд▓рд╛ message рдХрд╛рдпрдордЪрд╛ рд╣рд░рд╡рддреЛ. рдЬреЗ рдЪреБрдХрд▓реЗ рддрд░реА рдЪрд╛рд▓реЗрд▓ рдЕрд╢рд╛ metrics рд╕рд╛рдареА рдареАрдХ.
- At-least-once тАФ acknowledgement рдорд┐рд│реЗрдкрд░реНрдпрдВрдд retry рдХрд░рд╛. рдХрд╛рд╣реАрдЪ рд╣рд░рд╡рдд рдирд╛рд╣реА, рдкрдг message рдПрдХрд╛рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рд╡реЗрд│рд╛ рдпреЗрдК рд╢рдХрддреЛ (рдХрд╛рдо рдЭрд╛рд▓реЗ, "рдЭрд╛рд▓реЗ" рд╣рд░рд╡рд▓реЗ). рдмрд╣реБрддреЗрдХ queues рддреБрдореНрд╣рд╛рд▓рд╛ рд╣реЗрдЪ рджреЗрддрд╛рдд тАФ SQS standard queues, processing рдирдВрддрд░ offsets commit рдХрд░рдгрд╛рд░реЗ Kafka consumers, acknowledgements рд╕рд╣ RabbitMQ.
- Exactly-once delivery тАФ message рдПрдХрджрд╛ рдЖрдгрд┐ рдлрдХреНрдд рдПрдХрджрд╛рдЪ рдпреЗрддреЛ. рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп network рдкрд▓реАрдХрдбреЗ рдпрд╛рдЪреА рд╣рдореА рджреЗрддрд╛ рдпреЗрдд рдирд╛рд╣реА: рдкрд╛рдард╡рдгрд╛рд▒реНрдпрд╛рд▓рд╛ "рд╣рд░рд╡рд▓рд╛" рдЖрдгрд┐ "рдЭрд╛рд▓реЗ, рдкрдг рдЙрддреНрддрд░ рд╣рд░рд╡рд▓реЗ" рдпрд╛рдВрддрд▓рд╛ рдлрд░рдХ рд╕рд╛рдВрдЧрддрд╛ рдпреЗрдд рдирд╛рд╣реА (рдзрдбрд╛ 01), рдореНрд╣рдгреВрди рддреНрдпрд╛рдиреЗ рдПрдХрддрд░ retry рдХрд░рд╛рдпрд▓рд╛ рд╣рд╡рд╛ (duplicates рдЪрд╛ рдзреЛрдХрд╛) рдХрд┐рдВрд╡рд╛ рдирд╛рд╣реА (рд╣рд░рд╡рдгреНрдпрд╛рдЪрд╛ рдзреЛрдХрд╛).
- Idempotent тАФ рджреЛрдирджрд╛ рдХреЗрд▓реЗ рддрд░реА рдкрд░рд┐рдгрд╛рдо рдПрдХрджрд╛ рдХреЗрд▓реНрдпрд╛рд╕рд╛рд░рдЦрд╛рдЪ. "Grade A set рдХрд░рд╛" рд╣реЗ idempotent рдЖрд╣реЗ; "100 рд░реБрдкрдпреЗ рдЬреЛрдбрд╛" рд╣реЗ рдирд╛рд╣реА тАФ рдЬреЛрдкрд░реНрдпрдВрдд рддреНрдпрд╛рд╡рд░ рддрдкрд╛рд╕рд▓реА рдЬрд╛рдгрд╛рд░реА key рдирд╕рддреЗ.
- Effectively once ("exactly-once" рдЪрд╛ рдЦрд░рд╛ рдЕрд░реНрде) тАФ at-least-once delivery +
idempotent processing. рд╕рд╛рдзрдиреЗ:
- рдкреНрд░рддреНрдпреЗрдХ message рдХрд┐рдВрд╡рд╛ request рд╡рд░ idempotency key / dedupe key (
pay-dipika, рдХрд┐рдВрд╡рд╛ client рдПрдХрджрд╛ рддрдпрд╛рд░ рдХрд░реВрди retries рдордзреНрдпреЗ рдкреБрдиреНрд╣рд╛ рд╡рд╛рдкрд░рддреЛ рддреЛ UUID) - processed keys рдЪреА dedupe table, рдкрд░рд┐рдгрд╛рдорд╛рдЪреНрдпрд╛ рддреНрдпрд╛рдЪ transaction рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реЗрд▓реА
- рдЖрдВрдзрд│реНрдпрд╛ increments рдРрд╡рдЬреА upserts рдЖрдгрд┐ conditional writes ("рдирд╕реЗрд▓ рддрд░ insert рдХрд░рд╛", "рдЕрдЬреВрди 4 рдЕрд╕реЗрд▓ рддрд░ version 5 set рдХрд░рд╛")
- outbox pattern тАФ рдмрджрд▓ рдЖрдгрд┐ рдкрд╛рдард╡рд╛рдпрдЪрд╛ message рдПрдХрд╛рдЪ database transaction рдордзреНрдпреЗ рд▓рд┐рд╣рд╛; рдПрдХ рд╡реЗрдЧрд│реА process рддреЛ message рдирдВрддрд░ рдкрд╛рдард╡рддреЗ (at-least-once, key рд╕рд╣)
- рдкреНрд░рддреНрдпреЗрдХ message рдХрд┐рдВрд╡рд╛ request рд╡рд░ idempotency key / dedupe key (
- Kafka рдЪреА exactly-once semantics (EOS) тАФ рдЦрд░реА, рдЖрдгрд┐ Kafka рдЪреНрдпрд╛ рдЖрдд: idempotent
producer (broker producer ID рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ partition рд╕рд╛рдареА sequence number рд╡рд╛рдкрд░реВрди duplicate retries
рдЯрд╛рдХреВрди рджреЗрддреЛ) рдЕрдзрд┐рдХ transactions (consumer рдЪреЗ read, output topics рд╡рд░рдЪреЗ рддреНрдпрд╛рдЪреЗ writes рдЖрдгрд┐
рддреНрдпрд╛рдЪрд╛ offset commit рдПрдХрддреНрд░ рдпрд╢рд╕реНрд╡реА рдХрд┐рдВрд╡рд╛ рдЕрдпрд╢рд╕реНрд╡реА рд╣реЛрддрд╛рдд;
read_committedрдЕрд╕рд▓реЗрд▓реНрдпрд╛ readers рдирд╛ рдлрдХреНрдд committed results рджрд┐рд╕рддрд╛рдд). Kafka рдЪреНрдпрд╛ рдмрд╛рд╣реЗрд░реАрд▓ рдкрд░рд┐рдгрд╛рдо тАФ database row, email, payment тАФ рдпрд╛рдВрдирд╛ рдЕрдЬреВрдирд╣реА idempotency рд▓рд╛рдЧрддреЗ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг retries рд╕рдЧрд│реАрдХрдбреЗ рдЕрд╕рддрд╛рдд: clients, load balancers, SDKs, queues, рдЖрдгрд┐ timeout рдирдВрддрд░ рддреБрдордЪрд╛ рд╕реНрд╡рддрдГрдЪрд╛ code. рдкреНрд░рддреНрдпреЗрдХ рдЬрдг рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЬрд╛рдЧреА рдмрд░реЛрдмрд░ рдЕрд╕рддреЛ, рдЖрдгрд┐ рд╕рдЧрд│реЗ рдорд┐рд│реВрди duplicates рдкреЛрд╣реЛрдЪрд╡рддрд╛рдд. Idempotent рдирд╕рд▓реЗрд▓реЗ payment, email рдХрд┐рдВрд╡рд╛ stock count production рдордзреНрдпреЗ рджреЛрдирджрд╛ рдШрдбрдгрд╛рд░рдЪ; рдкреНрд░рд╢реНрди рдлрдХреНрдд рдХрд┐рддреА рд╡реЗрд│рд╛ рдЗрддрдХрд╛рдЪ. Product рдЪреНрдпрд╛ page рд╡рд░ рдЫрд╛рдкрд▓реЗрд▓реНрдпрд╛ "Exactly once" рдЪрд╛ рдЕрд░реНрде рд╕рд╣рд╕рд╛ "рдЖрдордЪреНрдпрд╛ system рдЪреНрдпрд╛ рдЖрдд" рдЕрд╕рд╛ рдЕрд╕рддреЛ тАФ рддреНрдпрд╛ system рдЪреА рдХрдб рдореНрд╣рдгрдЬреЗрдЪ рдЬрд┐рдереЗ рддреБрдордЪреА idempotency key рдЬрд╛рддреЗ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
dist/sim.py рдордзреАрд▓ deliver(messages, redeliver, idempotent) рдЖрдзреА
messages рдЖрдгрд┐ рдордЧ redeliveries process рдХрд░рддреЗ (at-least-once). рд╕рд╛рдзрд╛ consumer рдкреНрд░рддреНрдпреЗрдХ
message рд▓рд╛рдЧреВ рдХрд░рддреЛ. Idempotent consumer message keys рдЪрд╛ рдПрдХ seen set рдареЗрд╡рддреЛ рдЖрдгрд┐ рдЖрдзреАрдЪ
рд▓рд╛рдЧреВ рдХреЗрд▓реЗрд▓реА рдХреЛрдгрддреАрд╣реА key рд╡рдЧрд│рддреЛ. рддреЗ рдкрд░рд┐рдгрд╛рдорд╛рдВрдЪреА рдпрд╛рджреА рдкрд░рдд рдХрд░рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 dist/demo.py exactlyonce
python3 - <<'EOF'
import sys; sys.path.insert(0, "dist"); from sim import deliver
msgs = ["pay-katrina", "pay-dipika", "pay-aishwarya"]
again = ["pay-dipika", "pay-dipika", "pay-katrina"] # a bad night: three redeliveries
for idem in (False, True):
eff = deliver(msgs, again, idem)
print(f"{'idempotent' if idem else 'plain '} тЖТ {len(eff)} payments: {eff}")
print("at-most-once (never redeliver) and a lost message тЖТ", deliver(["pay-katrina", "pay-aishwarya"], [], True))
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
exactlyonce рд╣реЗ print рдХрд░рддреЗ:
тФАтФА the queue redelivers pay-dipika (at-least-once) ┬╖ plain consumer тЖТ effects ['pay-katrina', 'pay-dipika', 'pay-aishwarya', 'pay-dipika']
тФАтФА the queue redelivers pay-dipika (at-least-once) ┬╖ idempotent consumer тЖТ effects ['pay-katrina', 'pay-dipika', 'pay-aishwarya']
рддреБрдордЪрд╛ snippet рд╣реЗ print рдХрд░рддреЛ:
plain тЖТ 6 payments: ['pay-katrina', 'pay-dipika', 'pay-aishwarya', 'pay-dipika', 'pay-dipika', 'pay-katrina']
idempotent тЖТ 3 payments: ['pay-katrina', 'pay-dipika', 'pay-aishwarya']
at-most-once (never redeliver) and a lost message тЖТ ['pay-katrina', 'pay-aishwarya']
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рддреАрди redeliveries рдореБрд│реЗ рд╕рд╛рдзреНрдпрд╛ consumer рд╕рд╛рдареА 3 payments рдЪреЗ 6 рдЭрд╛рд▓реЗ, рдЖрдгрд┐ idempotent consumer рд╕рд╛рдареА рдХрд╛рд╣реАрдЪ
рдмрджрд▓рд▓реЗ рдирд╛рд╣реА. рд╢реЗрд╡рдЯрдЪреА рдУрд│ рджреБрд╕рд░реА рдмрд╛рдЬреВ рджрд╛рдЦрд╡рддреЗ: at-most-once рдордзреНрдпреЗ рд╣рд░рд╡рд▓реЗрд▓рд╛
pay-dipika рд╕рд░рд│ рдирд╛рд╣реАрд╕рд╛ рд╣реЛрддреЛ тАФ duplicates рдирд╛рд╣реАрдд, рдЖрдгрд┐ payment рд╣реА рдирд╛рд╣реА. рдпрд╛ рджреЛрдШрд╛рдВрдкреИрдХреА at-least-once +
key рд╣рд╛рдЪ рдЕрд╕рд╛ рдЖрд╣реЗ рдЬреЛ рддреБрдореНрд╣реА рджреБрд░реБрд╕реНрдд рдХрд░реВ рд╢рдХрддрд╛.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- queue рдЪреЗ "exactly once" рддреБрдордЪреНрдпрд╛ consumer рдиреЗ рдХреЗрд▓реЗрд▓рд╛ database write рдХрд┐рдВрд╡рд╛ email рд╕реБрджреНрдзрд╛ рдХрд╡реНрд╣рд░ рдХрд░рддреЗ рдЕрд╕реЗ рдорд╛рдирдгреЗ
- key рдкрд░рд┐рдгрд╛рдорд╛рдирдВрддрд░ рд╡реЗрдЧрд│реНрдпрд╛ step рдордзреНрдпреЗ рдиреЛрдВрджрд╡рдгреЗ тАФ рджреЛрдШрд╛рдВрдЪреНрдпрд╛ рдордзреНрдпреЗ crash рдЭрд╛рд▓рд╛ рддрд░ рдкрд░рд┐рдгрд╛рдо рдкреБрдиреНрд╣рд╛ рдШрдбрддреЛ
- expiry рдирд╕рд▓реЗрд▓реА dedupe table, рдХрд┐рдВрд╡рд╛ рд╕рд░реНрд╡рд╛рдд рд▓рд╛рдВрдм рд╢рдХреНрдп redelivery рдкреЗрдХреНрд╖рд╛ рдХрдореА expiry
- рдкреНрд░рддреНрдпреЗрдХ attempt рд╕рд╛рдареА server рд╡рд░ рдмрдирд╡рд▓реЗрд▓реНрдпрд╛ keys, рддреНрдпрд╛рдореБрд│реЗ retry рд▓рд╛ рдирд╡реА key рдорд┐рд│рддреЗ
- рдЬрд┐рдереЗ "version 4 рдЕрд╕реЗрд▓ рддрд░ 600 set рдХрд░рд╛" idempotent рдард░рд▓реЗ рдЕрд╕рддреЗ рддрд┐рдереЗ "100 рдЬреЛрдбрд╛" updates
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
SQL рдордзреНрдпреЗ idempotent consumer тАФ key рдиреЛрдВрджрд╡рдгреЗ рдЖрдгрд┐ рдкрд░рд┐рдгрд╛рдо рд▓рд╛рдЧреВ рдХрд░рдгреЗ рдПрдХрд╛рдЪ transaction рдордзреНрдпреЗ рдХрд░рд╛. On a real account (PostgreSQL):
BEGIN;
INSERT INTO processed_messages (message_id) VALUES ('pay-dipika')
ON CONFLICT (message_id) DO NOTHING; -- 0 rows inserted тЖТ already done: ROLLBACK and ack
UPDATE fees SET refunded = true WHERE student = 'dipika';
COMMIT; -- then delete the message from the queue
Amazon SQS тАФ standard queues at-least-once рдЕрд╕рддрд╛рдд (рдЖрдгрд┐ рдХреНрд░рдо рдмрджрд▓реВрди рджреЗрдК рд╢рдХрддрд╛рдд). рдЬреЛ
message рддреНрдпрд╛рдЪреНрдпрд╛ visibility timeout рдордзреНрдпреЗ delete рд╣реЛрдд рдирд╛рд╣реА рддреЛ рдкреБрдиреНрд╣рд╛ рджрд┐рд▓рд╛ рдЬрд╛рддреЛ. FIFO
queues 5-minute рдЪреНрдпрд╛ window рдордзреНрдпреЗ рддреНрдпрд╛рдЪ MessageDeduplicationId рд╕рд╣ рдкрд╛рдард╡рд▓реЗрд▓рд╛ message рдЯрд╛рдХреВрди рджреЗрддрд╛рдд
тАФ рдпрд╛рдореБрд│реЗ duplicate sends рдерд╛рдВрдмрддрд╛рдд, рдкрдг рддреБрдордЪрд╛ consumer message delete рдХрд░рдгреНрдпрд╛рдЖрдзреА crash рдЭрд╛рд▓рд╛ рддрд░ рддреЛ рдЕрдЬреВрдирд╣реА
message рджреЛрдирджрд╛ process рдХрд░реВ рд╢рдХрддреЛ:
aws sqs send-message --queue-url https://sqs.ap-south-1.amazonaws.com/111122223333/refunds.fifo \
--message-body '{"student":"dipika","amount":600}' \
--message-group-id dipika --message-deduplication-id pay-dipika
Kafka тАФ рд╢рдмреНрджрд╛рдВрдд: idempotent producer (enable.idempotence=true, Kafka 3.0 рдкрд╛рд╕реВрди
default, acks=all рд╕рд╣) producer рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ retries рдореБрд│реЗ рд╣реЛрдгрд╛рд░реЗ duplicates рдерд╛рдВрдмрд╡рддреЛ.
Transactions (producer рд╡рд░ transactional.id; consumers рд╡рд░ isolation.level=read_committed)
Kafka рдЪреНрдпрд╛ рдЖрдд read-process-write рд╕рд░реНрд╡-рдХрд┐рдВрд╡рд╛-рдХрд╛рд╣реАрдЪ рдирд╛рд╣реА рдЕрд╕реЗ рдХрд░рддрд╛рдд, consumer
offsets рд╕рдХрдЯ. Kafka Streams рд╣реЗ processing.guarantee=exactly_once_v2 рдиреЗ рдЪрд╛рд▓реВ рдХрд░рддреЗ. Database рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рдгрд╛рд▒реНрдпрд╛
consumer рд▓рд╛ рддрд┐рдереЗ рдЕрдЬреВрдирд╣реА key рдХрд┐рдВрд╡рд╛ upsert рд▓рд╛рдЧрддреЛ.
HTTP APIs тАФ POST requests рд╡рд░ Idempotency-Key header рд╕реНрд╡реАрдХрд╛рд░рд╛ (Stripe рдЕрд╕реЗ рдХрд░рддреЗ) рдЖрдгрд┐
рдкреБрдиреНрд╣рд╛ рдЖрд▓реЗрд▓реНрдпрд╛ key рд╕рд╛рдареА рдЬрддрди рдХреЗрд▓реЗрд▓рд╛ response рдкрд░рдд рдХрд░рд╛.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рдкреИрд╕реЗ рд╣рд▓рд╡рдгрд╛рд░рд╛, messages рдкрд╛рдард╡рдгрд╛рд░рд╛ рдХрд┐рдВрд╡рд╛ counts рдмрджрд▓рдгрд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ consumer рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ POST endpoint рдпрд╛рджреАрдд рд▓рд┐рд╣рд╛. рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА рддреНрдпрд╛рдЪреА idempotency key рдЖрдгрд┐ рддреА key рдХреБрдареЗ рд╕рд╛рдард╡рд▓реА рдЬрд╛рддреЗ рддреЗ рд╕рд╛рдВрдЧрд╛. "Queue exactly-once рдХрд░рддреЗ" рд╣реЗ рдЙрддреНрддрд░ рдирд╡реНрд╣реЗ.
тПня╕П рдкреБрдвреЗ
рд╢реЗрд╡рдЯрдЪреА рдЕрдбрдЪрдг: рдЦреВрдк рдЬрд╛рд╕реНрдд рдХрд╛рдо. Retries, bursts рдЖрдгрд┐ рд╣рд│реВ рдкреНрд░рддреА рд╕рд╛рдЪрдд рдЬрд╛рддрд╛рдд, рдЖрдгрд┐ рд╕рдЧрд│реЗ рд╕реНрд╡реАрдХрд╛рд░рдгрд╛рд░реА system рд╕рдЧрд│реНрдпрд╛рдВрд╕рд╛рдареАрдЪ рд╣рд│реВ рд╣реЛрддреЗ. рдкреБрдвреЗ: backpressure тАФ рдЖрдгрд┐ рд╕рдВрдкреВрд░реНрдг рдирдХрд╛рд╢рд╛.
git checkout lesson-12-backpressure