- Selama satu tahun terakhir, penulis berupaya memahami secara mendalam cara menjalankan aplikasi Rails dengan SQLite agar berkinerja baik dan stabil
- Dalam prosesnya, ada banyak pelajaran yang didapat dan ingin dibagikan
- Artikel ini akan menjelaskan penyebab masalah dan cara mengatasinya
Masalah SQLite dan Rails
- Secara default, aplikasi Rails yang menggunakan SQLite belum benar-benar siap dipakai begitu saja
- Dengan sedikit penyesuaian dan fine-tuning, aplikasi bisa dibuat memiliki performa yang baik dan stabil
- Di Rails 8, targetnya adalah agar konfigurasi bawaan saja sudah cukup untuk siap produksi
Aplikasi demo "Lorem News"
- Penjelasan masalah dan solusi akan menggunakan aplikasi demo bernama "Lorem News"
- Aplikasi ini adalah klon Hacker News, tempat pengguna bisa membuat postingan dan komentar
Pengujian performa
- Performa diuji menggunakan CLI load test
oha dan rute benchmarking di dalam aplikasi
- Kinerja diukur lewat permintaan tunggal dan permintaan konkuren
Masalah utama: pengecualian SQLITE_BUSY
- SQLite menggunakan write lock untuk memastikan hanya satu operasi tulis yang diizinkan pada satu waktu
- Jika beberapa koneksi mencoba mengambil write lock secara bersamaan, akan muncul pengecualian
SQLITE_BUSY
- Untuk mengatasi masalah ini, perlu menggunakan immediate transaction
Immediate transaction
- Secara default, SQLite menggunakan mode deferred transaction
- Dengan immediate transaction, upaya mengambil write lock dilakukan segera dan bisa diulang jika gagal
- Gem
sqlite3-ruby dapat digunakan untuk mengatur mode transaksi default menjadi mode immediate
Pengaturan timeout
- Pengaturan timeout di file
database.yml dapat mengurangi pengecualian SQLITE_BUSY
- Pengaturan
busy_timeout milik SQLite dapat digunakan untuk mencoba ulang write lock
Masalah GVL (Global VM Lock)
- Gem
sqlite3-ruby tidak melepaskan GVL saat memanggil kode C milik SQLite
- Hal ini menurunkan performa konkurensi
- Dengan
busy_handler, GVL bisa dilepas dan performa dapat ditingkatkan
Implementasi ulang busy_timeout
busy_timeout diimplementasikan ulang agar semua kueri mencoba ulang dengan frekuensi yang sama
- Ini mencegah kueri yang lebih lama mengalami timeout
Peningkatan performa
- Untuk meningkatkan performa, perlu menerapkan pengaturan berikut
- menggunakan immediate transaction
- mengatur timeout
- menggunakan
busy_handler
- menggunakan mode WAL (Write-Ahead Logging)
- memisahkan connection pool baca/tulis
Ringkasan GN⁺
- Membahas masalah performa aplikasi Rails yang menggunakan SQLite beserta solusinya
- Performa dapat ditingkatkan melalui immediate transaction, pengaturan timeout, pelepasan GVL, penggunaan mode WAL, dan pemisahan connection pool baca/tulis
- Artikel ini akan sangat berguna bagi pengembang yang menggunakan SQLite dan Rails
- Untuk proyek lain dengan fungsi serupa, PostgreSQL dan MySQL direkomendasikan
1 komentar
Komentar Hacker News
Memperkenalkan proyek Litestack dari Oldmoe
Terima kasih untuk artikel yang ditulis dengan rinci
Direkomendasikan bagi siapa pun yang bekerja dengan SQLite
Pertanyaan tentang sistem analitik FOSS
Masalah GVL pada gem sqlite3-ruby
Pengaturan layanan web pribadi
PRAGMA journal_mode = WALPRAGMA busy_timeout = 5000PRAGMA synchronous = NORMALPRAGMA cache_size = 1000000000PRAGMA foreign_keys = truePRAGMA temp_store = memoryBEGIN IMMEDIATEPertanyaan tentang Django
Pertanyaan tentang pengaturan default
busy_timeoutbusy_timeoutdefault memiliki penundaan yang menghukum kueri yang lebih lamaPendapat tentang penggunaan SQLite dan Rails
Terima kasih atas penyelesaian masalah integrasi Rails