DETS dan persistensi

Tabel DETS berbasis disk, perbaikan saat shutdown tidak bersih, dan batas ukurannya.

Daftar isi

Topik ini memperkenalkan DETS (Disk Erlang Term Storage), tabel tuple yang isinya menetap di berkas disk: siklus buka-tulis-tutup, jaminan sinkronisasi, perbaikan otomatis saat berhenti tidak bersih, dan batas ukurannya. DETS melengkapi ETS pada topik ETS untuk data yang harus selamat dari hilangnya VM.

ETS yang menetap pada disk#

DETS memakai bentuk API yang mirip ETS, tetapi berkasnya yang menjadi wadah: membuka tabel berarti membuka berkas, dan menulis berarti menulis ke disk. Satu tabel DETS dibuka oleh banyak proses sekaligus melalui nama yang sama, dan DETS menyusun operasinya secara internal. Batas yang paling sering disebut adalah ukuran: satu tabel DETS maksimal sekitar dua gigabyte, sehingga DETS tepat untuk katalog kecil dan menengah, bukan arsip besar.

Siklus buka, tulis, tutup#

Sesi berikut memuat seluruh siklus hidup DETS, termasuk menutup dan membuka ulang berkas yang sama:

erlang Siklus DETS dari nol sampai terbuka ulang
Erlang/OTP 29 [erts-17.1.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

Eshell V17.1.1 (press Ctrl+G to abort, type help(). for help)
1> dets:open_file(tiket_disk, [{file, "tiket.dets"}]).
{ok,tiket_disk}
2> dets:insert(tiket_disk, {no1, "Ali"}).
ok
3> dets:insert(tiket_disk, {no2, "Budi"}).
ok
4> dets:lookup(tiket_disk, no1).
[{no1,"Ali"}]
5> dets:sync(tiket_disk).
ok
6> dets:close(tiket_disk).
ok
7> dets:open_file(tiket_disk, [{file, "tiket.dets"}]).
{ok,tiket_disk}
8> dets:lookup(tiket_disk, no2).
[{no2,"Budi"}]
9> dets:close(tiket_disk).
ok

Nama tiket_disk berperan sebagai pegangan tabel setelah dibuka, dan opsi file menentukan lokasi berkasnya di folder kerja. Tulisan menjadi tahan terhadap kehilangan daya setelah dets:sync/1. Tanpa sinkronisasi, isi mungkin masih di buffer dan hilang saat VM mati mendadak. Pembukaan ulang di baris ketujuh menemukan berkas yang sama dan datanya tetap utuh, yang merupakan seluruh alasan DETS ada.

Menyinkronkan dan membaca ukuran#

Dua fungsi pelengkap yang sering dipakai adalah info/2 untuk membaca properti tabel dan sync/1 yang sudah dilihat di atas. Ukuran terisi berupa jumlah baris yang tersimpan:

erlang Membaca ukuran tabel DETS
1> dets:open_file(tiket_disk, [{file, "tiket.dets"}]).
{ok,tiket_disk}
2> dets:info(tiket_disk, size).
2
3> dets:close(tiket_disk).
ok

Tabel dari sesi pengenalan masih memuat dua baris, dan angka itu mencerminkan isi disk, bukan isi buffer. Untuk pengaman kehilangan yang otomatis, opsi auto_save pada open_file/2 menerima interval dalam milidetik atau jumlah tulisan, sehingga penyelamatan terjadi tanpa memanggil sync/1 secara manual. Interval yang terlalu rapat memakan I/O, sedangkan yang terlalu jarang memperbesar potensi kehilangan, dan pilihannya mengikuti nilai data per barisnya.

Perbaikan saat shutdown tidak bersih#

Berkas DETS yang terakhir ditulis tanpa sync atau close ditandai tidak bersih, dan DETS menanganinya dengan perbaikan otomatis saat dibuka berikutnya. Proses perbaikan membaca seluruh berkas, membuang bagian yang tidak konsisten, dan menyiapkan berkas baru, dan hasilnya dilaporkan pada nilai kembalian open_file/2. Karena perbaikan menyapu seluruh berkas, berkas besar membuat pembukaan berikutnya lambat, dan kebiasaan yang sehat adalah menyinkronkan secara berkala serta menutup tabel secara teratur sebelum VM dihentikan. Opsi repair pada open_file/2 dan opsi auto_save memberi kendali lebih rinci atas perbaikan dan penyelamatan, dan semuanya didokumentasikan lengkap di manual resmi.

Kesalahan umum#

  • Mengharapkan setiap insert langsung tahan terhadap kehilangan. Tanpa sync/1 atau auto_save, sebagian tulisan masih menunggu di buffer. Kehilangan daya sebelum sinkronisasi mengembalikan tabel ke titik sinkron terakhir.
  • Memakai DETS untuk data besar. Batas sekitar dua gigabyte per tabel bukan saran melainkan batas. Melewati itu berarti berpindah ke Mnesia atau basis data eksternal.
  • Membuka tabel DETS dari beberapa node sekaligus dengan asumsi penuh. Akses lintas node pada satu berkas membutuhkan kendali tambahan. DETS dirancang untuk akses proses-proses di satu node.

Kapan DETS cukup#

Keputusan memakai DETS dipandu tiga pertanyaan yang jawabannya konkret. Pertama, berapa besar data saat ini dan setahun lagi dibandingkan batas dua gigabyte per tabel yang bersifat permanen. Kedua, apakah seluruh akses berasal dari satu node, karena DETS tidak menyebarkan berkasnya. Ketiga, apakah kehilangan sebagian tulisan sejak sinkron terakhir dapat diterima sebagai harga model auto_save-nya. Tabel berikut merangkum jalurnya:

KebutuhanPilihan
Indeks kecil, satu node, tahan kehilangan sebagianDETS
Cache besar, umur proses, boleh hilangETS
Terdistribusi, transaksional, ukuran sedangMnesia
Besar, lintas aplikasi, administrasi matangBasis data eksternal

Dua tabel DETS untuk dua katalog kecil biasanya lebih sederhana daripada satu Mnesia yang dihidupkan hanya untuk itu, dan keputusan yang sehat adalah yang mudah dipindahkan: API yang membungkus DETS membuat migrasi ke Mnesia menjadi pekerjaan satu lapisan.

Ringkasan#

  • DETS adalah tabel tuple berbasis disk dengan API yang mirip ETS dan batas sekitar dua gigabyte per tabel.
  • open_file/2 membuka atau membuat berkas, insert/2 menulis, dan sync/1 menjamin tulisan selamat dari kehilangan daya.
  • Berkas yang ditutup tidak bersih diperbaiki otomatis saat dibuka ulang, dan perbaikan itu menyapu seluruh berkas.
  • DETS melayani katalog kecil dan menengah di satu node, sedangkan kebutuhan besar atau terdistribusi naik ke Mnesia.

Referensi#