Mematikan Raft: dari konsensus ZooKeeper ke Lux Quasar, tertaut secara native
Bagaimana Hanzo Datastore mengganti mesin NuRaft di bawah ClickHouse Keeper dengan Lux Quasar — konsensus pasca-kuantum tanpa pemimpin yang ditautkan langsung ke server C++ — sambil mempertahankan ZooKeeper API yang dipakai replikasi.

Di halaman ini
Hanzo Datastore mengoordinasikan tabel tereplikasi hari ini seperti yang dilakukan ClickHouse: Keeper tertanam yang kompatibel dengan ZooKeeper, menjalankan Raft di dalam proses server. Itu bekerja. Ia juga komponen klasik terakhir yang berbasis pemimpin dan pra-kuantum di tumpukan ini. Tulisan ini menjelaskan bagaimana kami mematikannya, dan mengapa "mematikan ZK" tidak berarti menulis ulang replikasi.
Memisahkan Keeper: API versus mesin
Naluri saat mendengar "mengganti ZooKeeper" adalah membayangkan menyentuh setiap Replicated*MergeTree. Anda tidak perlu melakukannya, karena ClickHouse Keeper sudah berupa dua hal yang dapat dipisah dan terjalin dalam satu daemon:
-
ZooKeeper API — pohon kunci-nilai yang dapat diurutkan secara linear, dengan simpul berurutan, versi, dan watch. Di sumber, ini adalah
KeeperStorage, dibungkus olehKeeperStateMachine(src/Coordination/KeeperStateMachine.h,class IKeeperStateMachine : public nuraft::state_machine). Inilah kontrak. Setiap tabel tereplikasi, setiap kuerisystem.zookeeper, dan setiap pemilihan pemimpin berbicara dengannya. -
Mesin konsensus — hal yang mengambil aliran permintaan tulis, membuat kuorum simpul menyepakati urutannya, lalu memanggil
commit(log_idx, data)pada mesin keadaan dalam urutan yang disepakati itu. Hari ini itu NuRaft:KeeperServer::launchRaftServer(src/Coordination/KeeperServer.cpp) membangun sebuahnuraft::raft_server, sebuahasio_service, sebuahKeeperStateManager, dan sebuahKeeperLogStore.
Pengamatan yang bersih, pengamatan Rich Hickey, adalah bahwa KeeperStateMachine sudah ditulis terhadap antarmuka konsensus yang generik (nuraft::state_machine: pre_commit, commit, rollback, snapshot). Ia tidak tahu dan tidak peduli bahwa Raft ada di bawahnya. Mesin adalah nilai yang dapat ditukar, bukan tempat yang dilas ke dalam API.
Jadi: pertahankan mesin keadaan, ganti mesinnya. ZooKeeper API yang diandalkan replikasi tetap utuh. Yang mati adalah NuRaft, pemilihan pemimpin, dan keharusan menjalankan kuorum Raft terpisah.
Apa yang menggantikannya
Mesin itu menjadi Quasar — konsensus tanpa pemimpin, berbasis DAG, dan pasca-kuantum dari Lux. Tugas Quasar di sini identik dengan tugas Raft: menyepakati urutan log dan memberi isyarat saat sebuah entri final. Bedanya ada pada cara menyepakati: tidak ada satu pemimpin untuk diambil alih saat gagal, tanda tangan ML-DSA alih-alih tanda tangan klasik, dan finalitas ambang keyakinan alih-alih mayoritas pada term yang tetap.
Yang terpenting, Quasar bukan layanan Go yang kami panggil lewat shell. Ia menghadirkan mesin C native dengan ABI yang siap untuk C++ (libluxconsensus). Server Datastore adalah C++. Jadi mesin tertaut ke dalam proses yang sama — tanpa sidecar, tanpa lompatan jaringan ke koordinator, tanpa bahasa kedua pada saat runtime.
Sambungannya terbukti, pada mesin keadaan yang sesungguhnya
Ini bukan sketsa, dan bukan lagi sebuah model. Kami membangun program yang menautkan pustaka server ClickHouse yang sesungguhnya (libdbms.a) dan menggerakkan KeeperStateMachine<KeeperMemoryStorage> produksi — kelas yang sama yang dilalui koordinasi ReplicatedMergeTree — sepenuhnya di atas Quasar, dengan NuRaft tidak ada di jalur pengurutan. Ia berada di pohon Datastore pada src/Coordination/examples/keeper_quasar_poc.cpp dan dibangun serta dijalankan pada host Linux yang sungguhan (aarch64, clang-21).
Alurnya setia pada cara dispatcher menggerakkan NuRaft hari ini — dua fase, preprocess saat permintaan ditambahkan dan commit saat konsensus memfinalkan urutannya:
state_machine->preprocess(rfs, /*lock_mutex*/ true); // append-time, pre-consensus (≙ nuraft pre_commit)
auto buf = IKeeperStateMachine::getZooKeeperLogEntry(rfs); // the real ZooKeeper log entry
lux_chain_add_block(chain, &blk); // the entry rides Quasar (the slot raft_server occupies)
lux_consensus_process_vote(...); // validators agree — no leader
lux_consensus_is_accepted(chain, id, &accepted);
state_machine->commit(height, *buf); // finality → the real KeeperStorage mutates, in order
Dijalankan terhadap urutan koordinasi sepuluh permintaan ReplicatedMergeTree — pendaftaran replika, kenaikan nomor blok, pemilihan pemimpin — ia mempraproses setiap permintaan, mengurutkannya lewat Quasar, memfinalkan, melakukan commit ke KeeperStorage yang sesungguhnya, dan menegaskan bahwa pohon yang dihasilkan tepat benar, masing-masing diterapkan sekali, dalam urutan konsensus:
== REAL Keeper state machine reached consensus on Quasar — zero Raft, zero ZK ensemble ==
Di bawahnya ada demonstrasi C-ABI minimal (pkg/c/examples/cpp_consumer.cpp, make test-cpp) yang menautkan libluxconsensus dan memfinalkan satu blok — mesin yang sama, tanpa ketergantungan ClickHouse. Keduanya dapat direproduksi; contoh Datastore bersifat ikut serta (-DENABLE_EXAMPLES=1 -DLUXCONSENSUS_DIR=...) dan tidak pernah menjadi bagian dari build normal.
Petakan ke Keeper satu lawan satu:
| Keeper / NuRaft hari ini | Native di Quasar |
|---|---|
nuraft::raft_server mengurutkan log | lux_chain_t mengurutkan log |
KeeperLogStore / Changelog | Log DAG Quasar |
| Pemilihan pemimpin Raft | voting keyakinan tanpa pemimpin |
state_machine->commit(idx, data) | panggilan yang sama, dipicu pada is_accepted |
| tanda tangan klasik, pemimpin term tetap | tanda tangan ML-DSA, tanpa pemimpin |
| kuorum ZK/Keeper terpisah untuk beroperasi | konsensus di dalam proses, di dalam server |
KeeperStateMachine::commit adalah titik sambung. NuRaft memanggilnya hari ini; penggerak Quasar memanggil metode yang sama besok. Mesin keadaan tidak dapat membedakannya — dan itulah sifat yang membuat ini pertukaran, bukan penulisan ulang.
Mengapa ini penting di luar "pasca-kuantum"
- Tanpa pemimpin. Raft punya satu pemimpin terpilih tiap term; kegagalannya menahan penulisan sampai pemilihan ulang. Kesepakatan tanpa pemimpin dari Quasar menghapus ketergantungan di kepala antrean itu.
- Tanpa kuorum kedua untuk dijalankan. Koordinasi berhenti menjadi sistem terpisah yang Anda sediakan, pantau, dan cadangkan. Ia adalah server itu sendiri.
- Pasca-kuantum karena konstruksinya. Tanda tangan yang melindungi kesepakatan adalah ML-DSA, bukan kurva klasik, sehingga lawan kuantum di masa depan tidak dapat memalsukan pesan konsensus.
- Satu cerita transport. Ia tersusun dengan sisa arah ini — TCP/HTTP native sekarang, ZAP berikutnya, dan primitif Lux yang sama yang dipakai rantai.
Status yang jujur
Arsitektur di atas nyata, dan buktinya kini berjalan pada KeeperStateMachine produksi — bukan pada model — dibangun dan lulus di host Linux yang sungguhan. Yang tersisa adalah pertukaran di dalam mesin: memperkenalkan backend konsensus Quasar di dalam KeeperServer di samping NuRaft, menjadikannya bawaan, lalu membawa sisa yang dilakukan KeeperServer — snapshot, pemulihan, kedaluwarsa sesi, rekonfigurasi — ke atasnya dengan seluruh rangkaian uji Coordination berwarna hijau. Itu kerja yang nyata, dan kami tidak akan mengatakan Raft sudah hilang pada hari kami membuktikan jalur commit. Kami mengatakan sambungan bertahan terhadap tipe yang sesungguhnya, titik sambungnya adalah KeeperStateMachine::commit, dan itulah seluruh pertaruhannya.
Saat itu mendarat, contrib/NuRaft/ dan mesin Raft meninggalkan pohon. ZooKeeper API tetap selama replikasi berbicara dengannya. Begitulah komponen pra-kuantum terakhir dimatikan tanpa menyentuh satu pun MergeTree.
- Datastore: github.com/hanzoai/datastore
- Konsensus Lux: github.com/luxfi/consensus
Baca selengkapnya

Memperkenalkan Hanzo Datastore: mesin OLAP kolom yang siap untuk era pascakuantum
Gudang kolom turunan ClickHouse, dibangun ulang di sekitar pemisahan penyimpanan dan komputasi pada Hanzo S3, dioptimalkan dengan panduan profil dan saat penautan hingga kira-kira separuh memori, dengan gRPC dicabut dan jalur menuju koordinasi pascakuantum tanpa pemimpin.

Router adalah registri
Hanzo Cloud tidak punya berkas OpenAPI yang di-check-in. Tabel rute yang hidup adalah sumbernya, diproyeksikan dengan tiga cara, dan uji bijeksi menggagalkan build jika ada proyeksi yang menyimpang. 1,362 operasi pada 963 path, dihasilkan per proses pada saat permintaan.

Jin 2.0: The Next Generation of Multimodal AI
Announcing Jin 2.0, a major upgrade to our unified multimodal AI architecture with expanded capabilities and improved performance.