acks & ISR: bila "acked" betul² selamat?
Callback ko kata OK. Tapi OK tu maksudnya berapa broker dah simpan record ko? Dan kenapa acks=all kat edge ko sebenarnya sama je dengan acks=1?
acks=all. Dua broker mati, tinggal leader sorang. Produce masih jalan ke tak? Tulis jawapan dulu, baru scroll.
1. acks: siapa kena ada record sebelum dapat OK
Dari lesson 0001: send() bagi Future, dan Future tu "done" bila broker balas. acks tentukan bila leader broker balas:
acks | Leader balas bila… | Boleh hilang bila… |
|---|---|---|
0 | tak balas langsung. Producer anggap OK sebaik je dia hantar. | apa² jadi pun. Offset pun ko tak tahu. |
1 | leader dah tulis dalam log dia sendiri | leader mati sebelum follower sempat copy |
all (= -1) | semua replika dalam ISR sekarang dah ada record tu | ISR mengecut sampai tinggal leader sorang (section 3) |
Default: Java acks=all (sejak Kafka 3.0), librdkafka acks=-1 (= all). Dua-dua sama. Config lab dan edge ko pun set acks=all.
(ProducerConfig · librdkafka CONFIGURATION.md)
2. ISR: siapa yang dikira "in sync"
ISR (in-sync replicas) ialah senarai replika yang tengah kejar leader dengan elok. Follower kena buang dari ISR kalau dia tak fetch dari leader, atau tak sampai hujung log leader, dalam masa replica.lag.time.max.ms (default 30 s).
(ReplicationConfigs)
Ni part paling penting dalam lesson ni: acks=all maksudnya semua dalam ISR, bukan semua replika. Kalau ISR mengecut sampai tinggal leader sorang, acks=all diam² jadi sama dengan acks=1.
3. min.insync.replicas: lantai keselamatan
Nak halang benda tu jadi, set min.insync.replicas. Setting ni diletak kat broker atau topic, bukan kat producer. Kalau acks=all dan saiz ISR < min.insync.replicas, broker tolak write tu dengan NotEnoughReplicas (atau NotEnoughReplicasAfterAppend).
(TopicConfig: MIN_IN_SYNC_REPLICAS_DOC)
- Default dia 1 😬 (ServerLogConfigs). Dengan default ni, takde lantai langsung.
- Setting ni hanya diperiksa untuk
acks=all.acks=1danacks=0tak peduli langsung. - Error
NotEnoughReplicastu retriable. Producer akan retry sampaidelivery.timeout.mshabis (Day 4), dan lepas tu error sampai ikut jalan B (callback /on_delivery), bukan throw. Ingat lesson 0001?
Lab ko (docker-compose.yml): RF=3, min.insync.replicas=2. Maksudnya ko boleh hilang 1 broker dan produce masih jalan. Hilang 2, produce stall dan akhirnya fail.
4. Soalan roadmap: kenapa acks=all + RF=1 = acks=1?
RF=1 maksudnya cuma ada satu replika, iaitu leader. So ISR = {leader}, dan "semua dalam ISR" = leader sorang. Itulah definisi acks=1.
edge-cluster/compose.yml set RF=1, min.insync.replicas=1. Tapi comment dalam clients/config/edge-producer.properties tulis "all = every in-sync replica (min.insync.replicas=2)". Comment tu salah untuk edge. Kat edge, acks=all tak bagi perlindungan lebih dari acks=1.
Satu lagi plot twist: Kafka tak fsync setiap mesej by default.
flush.messages default dia Long.MAX_VALUE, dan docs Kafka sendiri cadangkan guna replication untuk durability, bukan fsync. (ServerLogConfigs · FLUSH_MESSAGES_INTERVAL_DOC) So kat edge RF=1, record yang dah di-ack mungkin masih dalam page cache je. Kalau power terputus sebelum OS sempat flush, record yang dah "acked" tu boleh hilang. Simpan dulu soalan ni untuk Week 4 (pilihan HA untuk edge).
Java vs librdkafka (lab ko)
| Setting | Java default | librdkafka default | Config lab/edge ko |
|---|---|---|---|
acks | all | -1 (= all) | all |
enable.idempotence | true | false | true (set sendiri, bagus) |
min.insync.replicas | setting broker/topic (default 1), sama untuk dua-dua client | lab 2 · edge 1 | |
librdkafka default enable.idempotence=false: CONFIGURATION.md. Idempotence kita bedah dalam Day 5.
5. Latihan
Jawab ikut ingatan. Soalan 1 ulang kaji lesson 0001 😉
6. Lab preview 💻 desktop only
Guna lab 3-broker, BUKAN node edge production. Ni sebahagian weekend lab #1. Sebelum run, tulis dulu ramalan ko untuk setiap langkah:
cd ~/workspaces/kafka-in-depth
kafka-topics --describe --topic orders # tengok kolum Isr
python clients/producer.py -t orders -n 0 -r 5 &
podman stop kafka-2 # ramal: masih deliver?
kafka-topics --describe --topic orders # ISR tinggal berapa?
podman stop kafka-3 # ramal: apa jadi?
# tunggu ~2 minit, tengok output producer
podman start kafka-2 kafka-3
Check ramalan
Lepas stop kafka-2: ISR jadi 2 replika (≥ min.insync.replicas=2), so produce masih jalan. Lepas stop kafka-3: ISR tinggal 1 < 2, broker tolak dengan NotEnoughReplicas. Delivery stall sbb producer retry, kemudian fail lepas delivery.timeout.ms (120 s dalam config ko) melalui on_delivery. Kalau ko tukar ke -X acks=1, langkah kedua tu terus "berjaya" walaupun tinggal satu replika. Bahaya kan? 😬
min.insync.replicas. Ni sumber asal untuk semua yang ada dalam lesson ni.
Cheat sheet: acks, ISR & min.insync.replicas.
Ada yang blur? Tanya je dalam chat. Contohnya "kenapa Kafka tak fsync by default?" atau "kalau edge RF=1, apa pilihan untuk tak hilang data masa power cut?" Aku cikgu ko untuk topik ni.