Week 1 · Day 3 · Durability

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?

Teka dulu (30 saat): topic RF=3, producer 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:

acksLeader balas bila…Boleh hilang bila…
0tak balas langsung. Producer anggap OK sebaik je dia hantar.apa² jadi pun. Offset pun ko tak tahu.
1leader dah tulis dalam log dia sendirileader mati sebelum follower sempat copy
all (= -1)semua replika dalam ISR sekarang dah ada record tuISR 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)

Normal ISR leader follower 1 follower 2 acks=all → tunggu 3 replika Follower 2 senyap > 30 s ISR leader follower 1 follower 2 acks=all → tunggu 2 replika je "all" = semua dalam ISR sekarang, bukan semua replika. ISR mengecut → "all" pun mengecut.

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)

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.

Ni terus kena kat edge ko. 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)

SettingJava defaultlibrdkafka defaultConfig lab/edge ko
acksall-1 (= all)all
enable.idempotencetruefalsetrue (set sendiri, bagus)
min.insync.replicassetting broker/topic (default 1), sama untuk dua-dua clientlab 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? 😬

Bacaan utama (10 minit): Apache Kafka docs: Replication. Baca bahagian ISR, "committed", dan trade-off 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.