32 poin oleh xguru 2022-05-16 | 6 komentar | Bagikan ke WhatsApp
  • Ben Johnson, pembuat BoltDB (DB key-value embedded), kini mengembangkan Litestream di FlyIO
  • Struktur yang masuk akal untuk aplikasi full-stack adalah n-Tier: server aplikasi + server DB
    → Dalam arsitektur ini SQLite dulu hanya dipakai untuk unit test, tetapi sekarang sudah cukup layak dipakai sebagai lapisan data dan persistensi
  • Litestream adalah open source yang memungkinkan SQLite dipakai pada aplikasi full-stack melalui replikasi

Sejarah singkat database aplikasi

  • 50 tahun bukan waktu yang singkat, dan cara perangkat lunak mengelola data telah berubah sangat besar
    → Pada era 70-an ada "aturan Codd" yang mendefinisikan database relasional
    → Semua data ada di tabel, dengan CRUD, skema, bahasa SQL, dan sebagainya
    → Pada era 80-an dan 90-an, database SQL seperti Oracle/DB2/Postgres/MySQL meledak jumlahnya
    → Database XML di era 2000-an tidak begitu bagus, sementara pada periode yang sama muncul database kolom yang hebat
    → Pada era 2010-an, proyek database terdistribusi open source berskala besar dirilis, dan kini siapa pun bisa membuat klaster serta mengueri data dalam skala terabyte

  • Seiring evolusi database, strategi menghubungkan DB ke aplikasi juga ikut berkembang
    → Sejak Codd, lapisannya mulai dipisah berdasarkan tier
    → Awalnya ada tier database
    → Lalu tier caching seperti memcached dan Redis
    → Tier background job (Sidekiq), tier routing (PgBouncer), tier distribution, dan lain-lain
    → Banyak tutorial membicarakannya seolah hanya 3-Tier, tetapi karena kita tidak tahu akan ada berapa banyak tier yang masuk, saya menyebutnya "n-Tier"

  • Dalam 50 tahun itu kita juga melihat CPU, memori, dan disk menjadi ratusan kali lebih cepat dan murah
    → Kata yang benar-benar mendefinisikan inovasi database era 2010-an adalah "big data"
    → Tetapi dengan peningkatan hardware, pada 2020 konsep itu pun makin sulit dipertahankan
    → Jika pada 1996 mengelola DB 1GB adalah pekerjaan besar, pada 2022 itu sudah cukup dijalankan bahkan di laptop atau t3.micro

  • Saat kita memikirkan arsitektur DB baru, kita sering terhipnosis oleh batas skalabilitas
    → Jika tidak bisa memproses data skala petabyte atau setidaknya terabyte, rasanya tidak layak masuk pembicaraan
    → Padahal kebanyakan aplikasi, bahkan jika sukses, sulit mencapai data skala terabyte
    → Kita seperti memakai jackhammer hanya untuk memaku paku

Rilis manis SQLite

  • Ada database yang sangat mencerminkan tren ini
  • Salah satu DB SQL paling terkenal di dunia, format arsip resmi Library of Congress Amerika Serikat, terkenal karena keandalannya, test suite yang ukurannya sulit dibayangkan, dan performanya yang luar biasa
  • Dengan petunjuk sebanyak ini, sebenarnya saya tak perlu menyebut namanya... tetapi untuk yang masih mengangkat tangan di belakang... ya, ini tentang SQLite
  • SQLite adalah DB embedded. Ia tidak hadir sebagai tier terpisah dalam arsitektur umum, melainkan hanya sebuah library yang ditautkan ke proses server aplikasi Anda
    → Sebuah "aplikasi proses tunggal" yang berjalan sendiri tanpa bergantung pada server lain
  • Karena saya orang yang membuat database, saya tertarik pada jenis aplikasi seperti ini
  • Saya membuat BoltDB, DB key/value embedded yang terkenal di ekosistem Go
  • BoltDB stabil, dan seperti yang diharapkan dari DB in-process, performanya seperti mobil mainan yang dipasangi Nitro
  • Tetapi BoltDB punya keterbatasan
    → Karena skemanya didefinisikan di kode Go, migrasi DB jadi sulit. Anda harus membuat tooling sendiri. Bahkan REPL pun tidak ada
  • Jika Anda berhati-hati, DB seperti ini bisa memberi performa yang luar biasa
  • Tetapi untuk penggunaan umum, Anda mungkin tidak ingin mengoperasikan DB seperti ini
  • Saya memikirkan apa yang harus dilakukan agar BoltDB bisa dipakai di lebih banyak aplikasi, dan kesimpulan saya adalah: "SQLite memang dibuat tepat untuk itu"
  • SQLite tentu juga punya batasan. Yang terbesar adalah aplikasi proses tunggal memiliki SPOF (Single Point of Failure): jika server hilang, database ikut hilang. Ini bukan cacat SQLite, memang desainnya seperti itu

Hadirlah Litestream

  • Ada dua alasan besar mengapa banyak orang tidak menjadikan SQLite sebagai default
    → Pertama, ketahanan terhadap kesalahan storage (resilience)
    → Kedua, konkurensi pada skala besar
  • Litestream punya sesuatu untuk dikatakan soal dua masalah ini
  • Litestream bekerja dengan mengendalikan journaling mode WAL (Write Ahead Log) milik SQLite
  • Dalam mode WAL, operasi tulis ditambahkan ke file log terpisah, bukan langsung ke file DB utama SQLite
  • Reader memeriksa baik file WAL maupun DB utama untuk memenuhi kueri
  • Biasanya SQLite otomatis menjalankan checkpoint dari WAL ke DB utama
  • Litestream menyela di tahap ini dengan membuka transaksi baca tanpa akhir untuk mencegah auto-checkpoint, menangkap dan mereplikasi update WAL secara langsung, lalu memicu checkpoint sendiri

    Hal terpenting yang perlu dipahami tentang Litestream adalah bahwa ini tetaplah SQLite biasa. Aplikasi memakai SQLite standar; Litestream tidak menambahkan dependensi, tidak menganalisis kueri, dan tidak bertindak sebagai proxy. Ia hanya memanfaatkan fitur journaling dan konkurensi yang sudah dimiliki SQLite. Dalam banyak kasus, kode Anda bahkan mungkin tidak menyadari keberadaan Litestream

  • Kelihatannya rumit, tetapi sebenarnya sangat sederhana. Saat dicoba, Anda akan tahu bahwa ini benar-benar "just works"
    $ litestream replicate fruits.db s3://my-bukkit:9000/fruits.db
    $ litestream restore -o fruits-replica.db s3://my-bukkit:9000/fruits.db
  • Umumnya orang memakainya untuk mereplikasi DB SQLite dan menyimpannya ke S3
  • Ini memberi keuntungan operasional yang besar. DB Anda menjadi tangguh dan mudah dipindahkan atau dimigrasikan
  • Tetapi dengan Litestream Anda bisa melakukan lebih banyak lagi
  • Pada versi berikutnya, replikasi real-time antar DB SQLite akan dimungkinkan, sehingga Anda bisa menyiapkan read replica terdistribusi dan DB write-leader
    → Read replica dapat menangkap write lalu mengarahkannya ke leader
    → Karena banyak aplikasi bersifat read-heavy, setup ini memungkinkan aplikasi memiliki DB yang dapat diskalakan secara global

Anda perlu lebih serius mempertimbangkan opsi ini (memakai SQLite sebagai DB aplikasi)

  • Salah satu pekerjaan IT saya di awal karier adalah sebagai Oracle DBA pada awal 2000-an
  • Saya menghabiskan banyak waktu membaca buku dan dokumen untuk mempelajari Oracle
  • Manual administratornya hampir seribu halaman, dan itu hanya salah satu dari ratusan dokumen
  • Jika Anda mempelajari apa yang harus dilakukan untuk mengoptimalkan kueri atau memperbaiki write, pada masa itu itu memang membuat perbedaan besar
  • Hard disk yang hanya mampu membaca puluhan megabyte per detik membuat indeks yang lebih baik bisa mengubah kueri 5 menit menjadi kueri 30 detik
  • Tetapi optimasi DB makin lama makin kurang penting untuk aplikasi umum
  • Jika Anda punya DB 1GB, disk NVMe dapat memuat semuanya ke memori dalam kurang dari 1 detik
  • Saya suka optimasi kueri SQL, tetapi bagi banyak pengembang aplikasi ini menjadi keterampilan yang mulai memudar
  • Bahkan kueri yang tidak dituning dengan baik pun di banyak database bisa selesai dalam kurang dari 1 detik
  • Postgres modern itu seperti keajaiban. Saya banyak belajar dengan membaca kode itu selama bertahun-tahun
  • Optimizer kueri, kebijakan keamanan tingkat baris, 6 jenis indeks, dan seterusnya
  • Jika Anda butuh fitur-fitur ini, ya memang perlu. Tetapi kebanyakan orang tidak
  • Dan jika Anda tidak menginginkan fitur-fitur Postgres tersebut, tanggung jawab operasional tetap ikut datang
  • Walaupun tidak memakai banyak akun, Anda tetap harus mengonfigurasi autentikasi berbasis host dan membuka firewall
  • Lebih banyak fitur berarti lebih banyak dokumentasi, sehingga lebih sulit benar-benar memahami perangkat lunak yang Anda operasikan
  • Dokumentasi Postgre14 hampir 3.000 halaman
  • SQLite memiliki subset dari fitur Postgres. Tetapi itu sudah mencakup 99,9% dari yang biasanya saya butuhkan
  • Dukungan SQL yang sangat baik, fungsi window, CTE, full-text search, dukungan JSON, dan sebagainya
  • Kalau ada fitur yang kurang, data berada tepat di samping aplikasi saya, jadi mengambilnya dan memprosesnya sendiri tidak menambah banyak overhead
  • Sementara itu, masalah kompleks yang benar-benar perlu diselesaikan tidak diselesaikan oleh fitur inti database
  • Sebaliknya, saya hanya ingin mengoptimalkan dua hal: latensi dan pengalaman pengembang
  • Jadi, salah satu alasan Anda harus serius mempertimbangkan SQLite adalah karena operasionalnya sangat sederhana
  • Anda bisa menghabiskan waktu untuk menulis kode aplikasi alih-alih mendesain lapisan database
  • Tetapi masih ada masalah lain

Cahaya terlalu lambat: The Light is Too Damn Slow

  • Kita mulai menabrak batas teoretis. Dalam ruang hampa, cahaya menempuh 186 mil dalam 1 milidetik (jarak pulang-pergi Philadelphia ke New York)
  • Tambahkan switch jaringan, firewall, dan lapisan protokol aplikasi, maka semuanya menjadi lebih lambat
  • Overhead latensi untuk kueri Postgres di dalam satu region AWS bisa sampai hampir 1 milidetik
  • Ini bukan berarti Postgres lambat, melainkan kita sudah mencapai batas kecepatan perpindahan data
  • Aplikasi modern memproses permintaan HTTP, dan sering kali sudah menghabiskan 10 ms untuk beberapa kueri database serta business logic atau rendering
  • Ada angka ajaib dalam latensi aplikasi: respons di bawah 100 ms terasa nyaris seketika
  • Aplikasi yang responsif membuat pengguna senang
  • 100 ms terdengar banyak, tetapi sangat mudah habis tanpa terasa
  • Karena ambang 100 ms ini sangat penting, orang rela melakukan prerender halaman dan menaruhnya di CDN untuk menurunkan latensi
  • Kita sebaiknya memindahkan data sedekat mungkin ke aplikasi. Seberapa dekat? Sangat dekat
  • SQLite bukan hanya berada di mesin yang sama dengan aplikasi Anda, tetapi berada di dalam proses aplikasi Anda
  • Dengan menaruh data di samping aplikasi, Anda bisa melihat latensi per kueri turun menjadi 10~20 mikrodetik (μ)
  • Artinya 50~100x lebih cepat daripada kueri Postgres di region yang sama
  • Tetapi bukan cuma itu. Kita pada dasarnya menghilangkan latensi per kueri. Aplikasi kita jadi lebih cepat sekaligus lebih sederhana
  • Kueri besar bisa dipecah menjadi kueri yang lebih kecil dan lebih mudah dikelola, dan kita bisa menghabiskan lebih banyak waktu membangun fitur baru tanpa sibuk mencari pola kueri N+1
  • Meminimalkan latensi bukan hanya untuk production. Menjalankan integration test dengan DB client/server tradisional sering meluas menjadi hitungan menit di lokal, dan penderitaannya tetap ada saat didorong ke CI
  • Jika Anda mengurangi feedback loop dari perubahan kode sampai tes selesai, Anda menghemat waktu dan bisa tetap fokus saat mengembangkan
  • Di SQLite, perubahan satu baris bisa dijalankan di memori sehingga integration test dapat selesai hanya dalam beberapa detik

Kecil, cepat, andal, dan terdistribusi global: pilih 4 sekaligus

  • Litestream bersifat terdistribusi, tereplikasi, dan yang paling penting, mudah dipahami
  • Serius, "coba saja sekali". Hampir tidak banyak yang perlu dipelajari
  • Inilah argumen saya:
    • Jika kita membangun replikasi yang stabil dan mudah digunakan untuk SQLite, maka aplikasi full-stack yang sepenuhnya berjalan di atas SQLite menjadi sangat menarik
    • Pada masa tutorial lama seperti "membuat blog dengan Rails" ditulis, opsi ini terlewat. Tetapi SQLite masa kini mampu menangani beban write kebanyakan aplikasi, dan dengan replika, read dapat diload-balance ke banyak instance
  • Litestream juga punya keterbatasan
    • Karena dibuat untuk aplikasi single-node, ia tidak bekerja baik di platform serverless atau rolling deployment
    • Karena semua perubahan harus dipulihkan secara berurutan, restore DB bisa memakan waktu beberapa menit
    • Kami sedang menyiapkan replikasi real-time, tetapi model proses terpisah membatasi kontrol detail terhadap jaminan replikasi
  • Kita bisa melakukan lebih baik
    • Selama setahun terakhir pekerjaan saya adalah menetapkan inti Litestream dan berfokus pada ketepatan
    • Saya puas dengan posisi kami saat ini
    • Ini dimulai sebagai alat backup streaming sederhana, tetapi perlahan berkembang menjadi database yang stabil dan terdistribusi
    • Pekerjaan saya di Fly.io adalah membuat ini lebih cepat dan lebih mulus
    • Terlepas dari Fly.io, lebih banyak peningkatan akan terus ditambahkan ke Litestream
  • Litestream memang menemukan rumah baru di Fly.io, tetapi akan tetap menjadi proyek open source
  • Rencana saya untuk beberapa tahun ke depan adalah membuatnya lebih berguna di mana pun aplikasi dijalankan, dan melihat sejauh mana model SQLite bisa dibawa

6 komentar

 
nicewook 2022-09-27

Saya jadi ingin membacanya lagi dengan saksama.

 
johngrib 2022-05-17

Saya pernah memikirkan hal serupa, tetapi ini jauh lebih matang dan serius. Saya terkesan saat membacanya. Sepertinya saya juga ingin mencoba Litestream.

 
japansea 2022-05-16

Akan lebih bagus kalau kueri bisa dijalankan secara remote... sniff

 
mrchypark 2022-05-16

Ini mengingatkan saya pada momen ketika Elixir mulai naik daun. Ini adalah alat yang menyediakan DB terdistribusi tersemat dan orkestrasi di level bahasa, tetapi saya tidak begitu yakin apakah itu masa depan.

 
nicewook 2022-05-16

Saya membacanya dengan sangat menyenangkan!

 
xguru 2022-05-16

Awalnya saya hanya ingin membaca singkat lalu merangkumnya, tetapi saat dikerjakan ternyata menarik jadi malah panjang.

Litestream - alat replikasi streaming SQLite

Akan bagus juga jika dibaca bersama pertanyaan Ada yang pernah menggunakan SQLite sebagai DB utama?.

Sepertinya ini juga punya kaitan dengan Cloudflare mengumumkan D1, database SQL untuk Workers yang dirilis beberapa hari lalu.

Lihat juga komentar di HN https://news.ycombinator.com/item?id=31318708