Topik temu duga representatif

Temu duga reka bentuk sistem: Mereka bentuk log peristiwa dengan snapshot dan pemadatan (compaction)

Reka bentuk sistemSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Pelbagai penyewa (tenants) menulis perubahan akaun ke log peristiwa, dan pengguna (consumers) mesti memainkan semula mengikut penyewa dan pulih dengan cepat selepas kegagalan. Reka bentuk append, pemetakan, replikasi, snapshot, pemadatan, pengekalan, titik semak pengguna, dan evolusi skema, serta terangkan cara data yang dimampatkan masih membina semula keadaan yang betul.

Gesaan dan konteks

Reka bentuk log peristiwa untuk perkhidmatan akaun berbilang penyewa (multi-tenant). Setiap perubahan baki, kebenaran, atau konfigurasi mengeluarkan satu peristiwa, dan pengguna boleh memainkan semula sejarah untuk membina semula keadaan (state). Kegagalan tika (instance failure) tidak boleh mengimbas sejarah yang tidak terikat dari awal. Sistem ini memerlukan penambahan (appends) berkemampuan tinggi, susunan mengikut penyewa, kemajuan pengguna yang bebas, pemulihan snapshot, dan kos storan yang terikat. Terangkan pemadaman, peristiwa tidak mengikut urutan, dan evolusi skema.

Ini sesuai untuk temu duga reka bentuk sistem peringkat kanan, platform, dan infrastruktur data. Artikel Event Sourcing oleh Martin Fowler mentakrifkan idea teras untuk mengekalkan perubahan keadaan sebagai urutan peristiwa. Dokumentasi reka bentuk Apache Kafka menerangkan log terpetak, kedudukan pengguna, dan pemadatan log yang mengekalkan nilai terkini bagi setiap kunci. Gesaan reka bentuk sistem awam juga menyenaraikan log append-only terpetak, replikasi, pengekalan, pemadatan, dan pemulihan sebagai bidang penilaian. Sumber-sumber ini menyokong keterwakilan topik ini, tetapi tidak menetapkan gesaan syarikat atau kekerapan temu duga yang tetap. Kategorinya ialah system-design kerana kemahiran terasnya ialah ketekalan hujung ke hujung, sempadan pemulihan, dan pertukaran kapasiti.

Perkara yang dinilai oleh penemu duga

Pertama, bolehkah calon memisahkan sejarah peristiwa daripada keadaan semasa yang dizahirkan (materialized current state)? Snapshot ialah lapisan pecutan terbitan; ia tidak boleh menggantikan peristiwa tidak boleh ubah (immutable events) atau merentasi sempadan peristiwa yang tidak konsisten.

Kedua, adakah kunci petak memenuhi kedua-dua penyusunan dan skala? Pemetakan mengikut penyewa atau ID agregat mengekalkan susunan satu agregat, tetapi penyewa hangat, transaksi rentas agregat, dan susunan global memerlukan had yang jelas.

Ketiga, adakah mereka memahami semantik pemadatan? Pemadatan kunci mengekalkan rekod terkini bagi setiap kunci dan sesuai untuk aliran perubahan keadaan; ia bukan sejarah peristiwa. Pemadaman memerlukan tombstone dan tetingkap pengekalan, dan pengguna tidak boleh menganggap ofset rawak membawa maksud yang sama sebelum dan selepas pemadatan.

Akhir sekali, adakah mereka merangkumi operasi: pengesahan snapshot, versi peristiwa, titik semak atomik, pengesahan replikasi, kos pengekalan, kelengahan pengguna (consumer lag), dan keserasian skema mestilah boleh diperhatikan.

Soalan penjelasan untuk ditanya terlebih dahulu

  • Adakah peristiwa merupakan fakta audit tidak boleh ubah atau perubahan keadaan semasa yang boleh dibina semula? Pengauditan memerlukan sejarah penuh; aliran keadaan boleh menggunakan pemadatan kunci.
  • Apakah skop penyusunan? Agregat yang sama sahaja, bagi setiap penyewa, atau global? Setiap jaminan mengubah pemetakan dan daya pemprosesan (throughput).
  • Adakah pengguna mesti memainkan semula dari mana-mana masa? Jika ya, pemadatan kunci terkini sahaja tidak mencukupi; simpan arkib atau log audit berasingan.
  • Siapakah yang mencipta dan mengesahkan snapshot? Pengeluar, pengguna, dan pekerja snapshot mempunyai tanggungjawab yang berbeza; ikat snapshot pada kedudukan log dan versi skema.
  • Bagaimanakah pemadaman diwakili? Tombstone berversi atau peristiwa pemadaman perniagaan mempunyai maksud pemadatan dan pematuhan yang berbeza.

Kerangka jawapan 30 saat

“Saya memetakkan peristiwa setiap agregat mengikut ID agregat, append sahaja, dan mengesahkan pengeluar pada ofset terikat (committed) yang direplikasi. Peristiwa merangkumi ID peristiwa, versi agregat, versi skema, dan cap masa. Pengguna membuat titik semak ofset selepas mengemas kini paparan dizahirkan (materialized view) mereka, menggunakan ID peristiwa untuk penyahduplikasian sekurang-kurangnya sekali (at-least-once deduplication), dan membina semula daripada snapshot serta peristiwa berikutnya. Snapshot menyimpan keadaan, ofset peristiwa terakhirnya, dan versi skema; pemulihan mengesahkannya sebelum memainkan semula ofset seterusnya. Pemadatan kunci hanya terpakai pada aliran keadaan semasa yang boleh dibina semula dan mengekalkan tombstone untuk tetingkap yang ditetapkan; peristiwa audit pergi ke arkib yang tidak dipadatkan. Saya memantau kelengahan replikasi, kelengahan pengguna, usia snapshot, tunggakan pemadatan, dan perbezaan pengesahan main semula.”

Jawapan mendalam

1. Takrifkan medan peristiwa dan sempadan penyusunan

Peristiwa merangkumi eventId, aggregateId, aggregateVersion, schemaVersion, muatan (payload), masa penciptaan, dan sumber. aggregateVersion meningkat secara monotonik untuk satu agregat. Penambahan bersyarat (conditional append) menolak versi lama, menghalang dua penulis serentak daripada menulis ganti antara satu sama lain secara senyap.

Gunakan ID agregat sebagai kunci petak supaya satu agregat memasuki satu log tersusun. Jangan janjikan susunan rentas petak global. Jika produk memerlukan fakta atomik rentas agregat, kodkan hasil transaksi sebagai satu peristiwa agregat atau gunakan outbox transaksi dan bukannya mengisih mengikut cap masa.

2. Append, replikasi, dan pengesahan (acknowledge)

Ketua (leader) menambah secara setempat dan mereplikasi kepada pengikut yang mencukupi; hanya selepas syarat komit yang dikonfigurasikan dipenuhi barulah ia mengesahkan penerimaan. ID peristiwa dan nombor urutan pengeluar menyokong penyahduplikasian percubaan semula. Segmen cakera berguling mengikut saiz atau masa, dan indeks membantu pengguna mencari ofset.

Jadikan pengesahan itu eksplisit: ini bermakna peristiwa itu berada dalam log terikat yang boleh dipulihkan, bukan bermakna setiap pengguna telah memprosesnya atau model bacaan yang dizahirkan adalah terkini. Kegagalan pengguna tidak mengembalikan (roll back) peristiwa yang telah ditambah.

3. Titik semak pengguna dan keidempotanan (idempotency)

Setiap kumpulan pengguna menyimpan ofset petaknya sendiri. Proses peristiwa dan kemas kini model bacaan sebelum melakukan komit titik semak; ranapan mungkin mengulangi pemprosesan, jadi pengendali mestilah idempoten mengikut ID peristiwa atau versi agregat. Jika model dan titik semak memerlukan gandingan atomik, tulis kedua-duanya dalam satu stor transaksi atau rekodkan hasilnya dalam outbox.

Kekalkan log apabila pengguna ketinggalan; jangan langkau peristiwa yang belum diproses semata-mata untuk mengurangkan kelengahan. Paparan yang boleh dibina semula boleh bermula daripada ofset snapshot. Kesan sampingan luaran yang tidak boleh dibina semula memerlukan pampasan atau semakan dan bukannya main semula secara membuta tuli.

4. Protokol snapshot

Snapshot menyimpan ID agregat, keadaan bersiri, ofset terakhir yang digunakan, versi agregat dan skema, checksum, dan masa penciptaan. Janakannya pada sempadan yang stabil: rekod ofset sasaran, gunakan peristiwa sehingga ofset tersebut, dan tulis snapshot dengan sempadan yang sama. Pemulihan hanya menerima snapshot yang disahkan yang ofsetnya milik petak agregat tersebut.

Pemulihan memuatkan snapshot dan memainkan semula daripada snapshotOffset + 1. Jika skema adalah lama, jalankan migrasi berversi sebelum menerbitkan keadaan; kegagalan migrasi mesti menyekat keadaan yang tidak sah. Snapshot ialah cache: memadamkannya tidak merosakkan sebarang log dan hanya meningkatkan masa pemulihan.

5. Asingkan pengekalan, pemadatan, dan arkib

Pengekalan masa mengalih keluar data log lama dan sesuai untuk peristiwa dengan tetingkap main semula yang ditetapkan. Pemadatan kunci mengekalkan nilai terkini bagi setiap kunci dalam petak dan membolehkan pengguna keadaan membina semula keadaan semasa daripada log yang lebih pendek. Ia tidak dapat menyokong audit atau main semula titik-dalam-masa (point-in-time) sebarangan kerana peristiwa perantaraan mungkin telah tiada.

Tombstone mewakili kunci yang dipadamkan. Kekalkannya sehingga setiap pengguna yang diliputi oleh kontrak boleh memerhatikannya, kemudian benarkan pemadatan untuk mengalih keluarnya. Simpan peristiwa audit dalam arkib tidak boleh ubah dengan kawalan akses, penyulitan, dan peraturan pengekalan; log keadaan yang dipadatkan bukanlah bukti audit yang lengkap.

6. Skema, gangguan susunan, dan peristiwa beracun (poison events)

Gunakan peraturan skema serasi ke belakang (backward-compatible): tambah medan pilihan, kekalkan makna lama, dan biarkan pengguna mengabaikan medan yang tidak diketahui. Perubahan yang memecahkan (breaking changes) memerlukan versi skema baharu, tempoh dwi-bacaan, atau tetingkap migrasi. Rekodkan versi skema dan kegagalan penghuraian; jangan sekali-kali mengikat ofset peristiwa yang tidak boleh dihuraikan secara senyap.

Peristiwa yang tidak mengikut urutan bagi satu agregat biasanya menunjukkan pelanggaran pengeluar atau replikasi. Tolak versi agregat lama dan tahan jurang untuk pembaikan. Peristiwa rentas agregat memerlukan peraturan pampasan masa perniagaan atau ID bersebab (causal-ID); masa ketibaan pelayan bukanlah pengganti untuk kebersendirian/kausaliti.

7. Kapasiti, pemulihan, dan kebolehcerapan (observability)

Modelkan peristiwa sesaat, saiz muatan purata dan ekor (tail), faktor replikasi, tetingkap pengekalan, saiz snapshot, penjimatan pemadatan, dan kelajuan main semula. Selang snapshot yang lebih pendek meningkatkan pemulihan tetapi menambah amplifikasi penulisan dan storan. Pemadatan yang lebih agresif mengurangkan kos pembinaan semula keadaan tetapi melemahkan audit dan pertanyaan sejarah.

Pantau kependaman pengesahan pengeluar, kelengahan replikasi, segmen cakera, tunggakan pemadatan, kelengahan pengguna, usia snapshot, kadar main semula, ralat skema, kadar duplikasi, dan perbezaan checksum snapshot. Secara berkala, bina semula keadaan sampel daripada snapshot dan peristiwa serta bandingkannya dengan paparan yang dizahirkan; kekalkan ofset dan sampel peristiwa apabila ketidakpadanan muncul.

Contoh jawapan berkualiti tinggi

“Saya menggunakan ID agregat sebagai kunci petak, menambah peristiwa tidak boleh ubah, dan menolak penulisan basi serentak dengan versi agregat. Pengesahan pengeluar bermakna peristiwa itu berada dalam log terikat yang direplikasi; setiap pengguna mengikat ofset petaknya sendiri selepas menggunakan peristiwa, jadi ranapan hanya menyebabkan ulangan yang boleh dinyahduplikasi.

Snapshot mengandungi keadaan agregat, ofset peristiwa terakhir, versi agregat dan skema, serta checksum. Pemulihan mengesahkan snapshot dan memainkan semula daripada ofset seterusnya; memadam snapshot hanya melambatkan pemulihan. Pemadatan kunci terhad kepada aliran keadaan semasa yang boleh dibina semula, dengan tombstone dikekalkan untuk kontrak pengguna. Aliran audit kekal sebagai arkib tidak boleh ubah.

Saya menjanjikan susunan hanya dalam satu agregat, bukan merentasi petak. Model kapasiti merangkumi replikasi, pengekalan, pemadatan, dan amplifikasi penulisan snapshot. Metrik merangkumi kelengahan, usia snapshot, tunggakan pemadatan, ralat skema, dan perbezaan pengesahan main semula, dengan pemeriksaan pembinaan semula snapshot-plus-peristiwa secara tetap.”

Kesilapan biasa

  • Menganggap snapshot sebagai sumber peristiwa → memadamkannya membuang pemulihan dan bukti audit → snapshot ialah pemecut terbitan yang terikat pada ofset.
  • Menganggap log yang dipadatkan sebagai sejarah penuh → peristiwa perantaraan dan keadaan titik-dalam-masa telah tiada → arkibkan peristiwa audit dan padatkan aliran keadaan sahaja.
  • Mengisih semua peristiwa mengikut cap masa → penyelewengan jam (clock skew) mewujudkan susunan palsu → takrifkan susunan mengikut versi agregat dan kontrak petak.
  • Melakukan komit ofset selepas kesan sampingan sebarangan → duplikasi tidak dapat dielakkan tetapi tidak ditentukan → jadikan pengendali idempoten dan takrifkan gandingan model/titik semak.
  • Memadam tombstone serta-merta → pengguna yang ketinggalan boleh menghidupkan semula kunci → kekalkannya melalui tetingkap kontrak pengguna.
  • Melangkau skema yang tidak diketahui dan melakukan komit → log dan paparan menyimpang secara senyap → jeda, asingkan peristiwa beracun, dan kekalkan bukti.
  • Melangkau pemodelan kapasiti → snapshot, pemadatan, atau main semula menjadi hambatan (bottleneck) gangguan → kira kelengahan, masa pemulihan, dan amplifikasi penulisan.
  • Mendakwa tepat-sekali (exactly-once) menyelesaikan setiap duplikasi → kesan sampingan luaran masih boleh berulang → gunakan kunci keidempotanan, transaksi, atau pampasan.

Soalan susulan dan jawapan

Mengapa tidak menyimpan keadaan semasa sahaja dalam pangkalan data?

Jika hanya bacaan semasa yang penting, pangkalan data adalah lebih mudah. Log peristiwa menyediakan main semula, audit, berbilang pengguna, dan pembinaan semula paparan yang berbeza, dengan kos skema, main semula, kapasiti, dan keidempotanan kesan sampingan. Pilihlah ia untuk keperluan tersebut dan bukannya menganggap penyumberan peristiwa (event sourcing) secara universal lebih unggul.

Bagaimanakah pengguna baharu boleh membina semula dari awal selepas pemadatan?

Ia hanya boleh membina semula keadaan semasa yang masih diwakili selepas pemadatan; sejarah perantaraan yang dipadamkan tidak boleh dibina semula. Jika sejarah penting, simpan arkib yang tidak dipadatkan atau log perubahan berasingan dan dokumentasikan keupayaan main semula setiap topik.

Bagaimana jika peristiwa baharu tiba semasa snapshot sedang dibina?

Pilih ofset sasaran yang stabil. Peristiwa selepas ofset tersebut terus ditambah tetapi bukan sebahagian daripada snapshot; pemulihan memuatkan snapshot dan memainkan semula daripada ofset seterusnya. Jika penulisan snapshot gagal, simpan snapshot lama dan log dan bukannya menerbitkan fail separa.

Bagaimanakah anda memigrasikan skema peristiwa?

Takrifkan medan keserasian dan versi terlebih dahulu, kemudian biarkan pengguna membaca versi lama dan baharu semasa tetingkap migrasi. Penulis menambah medan baharu dan menghentikan medan lama hanya selepas semua pengguna dinaik taraf. Perubahan yang memecahkan menggunakan jenis peristiwa baharu atau migrasi luar talian, yang disahkan oleh ujian main semula ke atas peristiwa sejarah.

Sumber awam

Soalan berkaitan

Alat temu duga berkaitan

Gunakan Jawab untuk jawapan reka bentuk sistem

Jelaskan keperluan terlebih dahulu, kemudian teruskan dengan skala, seni bina, pilihan komponen dan pertukaran (trade-off).

Lihat alat