Cara Kerja
Halaman ini menelusuri alur pesan sebenarnya antara klien dan server (cluster) untuk menjelaskan cara kerja Ticketing. Spesifikasi byte-per-byte yang persis dari apa yang mengalir di wire ada di Protokol (API) dan Protokol (Cluster).
Struktur Keseluruhan
Layanan yang menerima request pengguna (misalnya, server event yang menangani pembukaan penjualan tiket) mengantre pada key yang sama terhadap cluster Ticketing, dan hanya server yang mendapat giliran yang melanjutkan pekerjaan seperti mengurangi stok atau menetapkan kursi.
Acquire dan Release Lock
Alur dasarnya begini. Key yang kosong langsung diterbitkan; key yang sedang dipegang menunggu gilirannya di antrean FIFO. Saat pemegang melepaskan lock, lock diserahkan langsung ke antrean terdepan tanpa perebutan ulang — penunggu berikutnya langsung melanjutkan dengan token baru, sehingga tidak pernah ada momen lock kosong, dan tidak ada yang bisa menyerobot antrean.
leaseadalah jaring pengaman. Jika klien mati atau lupa melakukan release, setelah durasileaseberlalu server akan mengambil kembali key dan menyerahkannya ke penunggu berikutnya. Atur nilainya dengan longgar — lebih lama dari waktu terburuk yang mungkin dibutuhkan critical section Anda. v1 hanya menerima 1-250 detik; pekerjaan yang lebih lama secara eksplisit tidak didukung dan ditolak.waitadalah batas atas berapa lama klien menunggu. Jika gilirannya tidak datang dalam waktu itu, server merespons denganT(timeout) alih-alih memberikan lock, sehingga tidak ada lock yang bocor.0berarti satu percobaan langsung tanpa masuk antrean. Tidak ada wait tanpa batas.- Jika klien yang sama mencoba acquire ulang key yang sudah dipegangnya, ia tetap mengantre seperti penunggu lain — ini bukan reentrant lock.
Lihat Matriks Request × Status Key untuk aturan lengkap perilaku server per status key, dan Batasan Field untuk rentang nilai field.
Fencing Token
Sekalipun lock server sempurna, ia tidak bisa mengontrol jam klien. Ticketing sendiri tidak bisa mencegah kasus pemegang basi (stale holder): klien yang berhenti sejenak karena GC pause atau overload saat memegang lock, lalu bangun kembali — tanpa sadar lease-nya sudah kedaluwarsa — dan melanjutkan pekerjaannya. Karena itu, token di setiap respons acquire adalah integer u64 yang dijamin selalu bertambah setiap kali diterbitkan. Untuk DB finansial atau persistent, perbandingan dan pembaruan high-water fencing per key harus atomik dengan business write sebenarnya dalam DB transaction yang sama atau satu conditional write. Memperbarui fencing row lebih dahulu dan menjalankan write sebenarnya kemudian tidak aman.
Monotonisitas juga berlaku di seluruh cluster — penghitung token sendiri direplikasi melalui konsensus, sehingga bahkan setelah pergantian leader, leader baru selalu melanjutkan dari angka yang lebih besar dari sebelumnya. Lihat Fencing Token (spek) untuk format field yang persis.
Cluster — Tanpa Henti via Konsensus Raft
Dalam mode cluster, node-node berbagi satu status lock melalui konsensus Raft. Hanya leader yang menangani request klien, dan setiap perubahan status lock (acquire, release, expiry) hanya final setelah dicatat oleh mayoritas node. Terhubung ke node yang bukan leader akan mendapat respons M (dialihkan) yang menunjuk ke leader.
- Jika leader mati, konfigurasi saat ini memilih leader baru dalam sekitar 2,3-2,5 detik. Logical acquire yang sama hanya boleh dilanjutkan dalam sisa anggaran
waitjika belum ada satu byte request pun yang terkirim. Acquire yang sudah terkirim tanpa respons terkonfirmasi adalahIndeterminatedan tidak pernah dikirim ulang otomatis. - Bahkan kedaluwarsa
leasemelewati konsensus. Lock hanya hilang setelah leader melakukan commit perintah expiry, sehingga perbedaan jam kecil antar node tidak pernah membuat status lock berbeda. - Jika cluster kehilangan mayoritas (misalnya 2 dari 3 node mati), cluster berhenti menerima penulisan alih-alih mengambil risiko menerbitkan lock yang salah (keamanan diutamakan). Jika volatile process state dari 2 dari 3 (atau 3 dari 5) node hilang, cluster/fencing domain tersebut tidak boleh dipulihkan atau otomatis di-bootstrap dengan identity yang sama.
Karena mayoritas adalah kuncinya, hanya 3 atau 5 node yang diperbolehkan. Jumlah node genap hanya menambah biaya tanpa meningkatkan toleransi kegagalan, sehingga server menolak untuk dijalankan dengan jumlah genap.
| Jumlah node | Tanpa henti | Kegagalan bersamaan yang ditoleransi | Catatan |
|---|---|---|---|
| 1 | ✗ | — | Monotonisitas token hanya dijamin selama process lifetime; tidak didukung untuk melindungi persistent DB yang dapat di-restart |
| 3 | ✓ | 1 | Konfigurasi tanpa henti standar. Cukup untuk kebanyakan kasus |
| 5 | ✓ | 2 | Redundansi tetap terjaga bahkan saat satu node sedang pemeliharaan |
Lihat Protokol (Cluster) untuk aturan framing dan port RPC antar peer, dan penggantian learner NodeId baru tanpa downtime untuk mengganti node satu per satu.
Perilaku Klien
Klien resmi berbagi perilaku berikut secara umum (lihat Libraries untuk API spesifik bahasa).
- Menjaga satu koneksi persisten per alamat di background. Diberikan satu alamat saja, klien menjaga dua koneksi ke node yang sama, sehingga gangguan singkat pada satu socket tidak mengganggu layanan.
- Memilih koneksi dengan prioritas leader, lalu round-robin. Klien mengingat leader terakhir yang diarahkan lewat
Mdan mengirim request berikutnya langsung ke sana. - Request dipipeline. Request berikutnya bisa dikirim tanpa menunggu respons — lihat Aturan Pencocokan Respons untuk cara respons dipasangkan dengan request.
- Koneksi yang terputus terus mencoba reconnect dengan exponential backoff (0,1 detik hingga batas 3,2 detik). Koneksi yang mati tidak merusak objek broker — ia pulih dengan sendirinya.
- Logical acquire yang sama dicoba ulang secara internal hanya jika belum ada satu byte request pun yang terkirim.
Byang berkorelasi adalah Busy/tidak memperoleh yang pasti dan segera dikembalikan ke caller tanpa retry internal.Mhanya leader hint untuk koneksi berikutnya; tanpa owner/key, itu bukan alasan untuk mengirim ulang request pending yang sudah terkirim. Acquire terkirim tanpa respons terkonfirmasi dilaporkanIndeterminate; critical section tidak boleh dimasuki. - Explicit release dan kompensasi known-token memakai pencocokan owner/token/key yang persis dan dedicated queue yang bounded. Retry berhenti pada deadline absolut 5 detik sejak request/enqueue, bukan hingga sisa lease. Tanpa respons sukses, explicit release tidak dilaporkan atau dianggap berhasil; server-side lease tetap menjadi jaring pengaman terakhir.
Koneksi dan Keamanan
Setiap koneksi (klien maupun peer) dibangun dengan urutan TCP → (TLS) → autentikasi challenge-response. Klien meng-hash nonce dari server bersama tokennya untuk merespons, sehingga token tidak pernah dikirim dalam bentuk plaintext di atas wire, dan nonce baru di setiap koneksi mencegah replay. Lihat Auth Handshake untuk spesifikasi yang persis.
Catatan tentang Konsistensi
- Mutual exclusion dijamin oleh konsensus. Karena setiap penerbitan melewati commit mayoritas, key yang sama tidak akan pernah diterbitkan ke dua pemegang sekaligus, bahkan saat terjadi partisi jaringan atau pergantian leader.
- Persistent DB wajib menerapkan fencing. Hanya kondisi high-water per key yang dijalankan atomik dengan protected write dalam transaction/conditional write yang sama dapat menghentikan klien yang bangun setelah
leasekedaluwarsa. Lock mengurutkan pekerjaan; DB fencing memblokir stale write terakhir.