Peringatan: mungkin ada ketidakakuratan di bawah ini. Saya telah belajar tentang banyak hal ini saat saya berjalan, jadi bawa dengan sedikit garam. Ini cukup panjang, tetapi Anda bisa membaca parameter yang kami mainkan, lalu lewati ke Kesimpulan di bagian akhir.
Ada beberapa lapisan di mana Anda bisa khawatir tentang kinerja penulisan SQLite:
Kami melihat yang disorot dalam huruf tebal. Parameter tertentu adalah
- Cache tulis disk. Disk modern memiliki cache RAM yang digunakan untuk mengoptimalkan penulisan disk sehubungan dengan disk yang berputar. Dengan ini diaktifkan, data dapat ditulis dalam blok out-of-order, jadi jika terjadi kerusakan, Anda dapat berakhir dengan file yang ditulis sebagian. Periksa pengaturan dengan hdparm -W / dev / ... dan atur dengan hdparm -W1 / dev / ... (untuk menyalakannya, dan -W0 untuk mematikannya).
- penghalang = (0 | 1). Banyak komentar online yang mengatakan "jika Anda menjalankan dengan penghalang = 0, maka tidak ada caching penulisan disk yang diaktifkan". Anda dapat menemukan diskusi tentang hambatan di http://lwn.net/Articles/283161/
- data = (jurnal | ordered | writeback). Lihatlah http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html untuk deskripsi opsi ini.
- komit = N. Memberitahu ext3 untuk menyinkronkan semua data dan metadata setiap N detik (default 5).
- SQLite pragma synchronous = ON | MATI. Ketika ON, SQLite akan memastikan bahwa transaksi "ditulis ke disk" sebelum melanjutkan. Mematikan ini pada dasarnya membuat pengaturan lain sebagian besar tidak relevan.
- SQLite pragma cache_size. Mengontrol berapa banyak memori yang akan digunakan SQLite untuk cache di dalam memori. Saya mencoba dua ukuran: satu di mana seluruh DB akan muat dalam cache, dan satu di mana cache adalah setengah dari ukuran DB maksimum.
Baca lebih lanjut tentang opsi ext3 dalam dokumentasi ext3 .
Saya menjalankan tes kinerja pada sejumlah kombinasi parameter ini. ID adalah nomor skenario, sebagaimana dimaksud di bawah ini.
Saya mulai dengan menjalankan konfigurasi default pada mesin saya sebagai skenario 1. Skenario 2 adalah apa yang saya anggap sebagai "paling aman", dan kemudian mencoba berbagai kombinasi, jika perlu / diminta. Ini mungkin yang paling mudah dipahami dengan peta yang saya gunakan:
Saya menulis skrip pengujian yang menjalankan banyak transaksi, dengan menyisipkan, memperbarui, dan menghapus, semua di atas meja dengan hanya INTEGER, TEXT saja (dengan kolom id), atau dicampur. Saya menjalankan ini beberapa kali pada masing-masing konfigurasi di atas:
Dua skenario terbawah adalah # 6 dan # 17, yang memiliki "pragma syncous = off", sehingga tidak mengejutkan bahwa mereka adalah yang tercepat. Cluster tiga berikutnya adalah # 7, # 11, dan # 19. Ketiganya disorot dengan warna biru pada "peta konfigurasi" di atas. Pada dasarnya konfigurasi adalah cache tulis pada, penghalang = 0, dan data diatur ke sesuatu selain 'jurnal'. Mengubah komit antara 5 detik (# 7) dan 60 detik (# 11) tampaknya membuat sedikit perbedaan. Pada tes ini sepertinya tidak ada banyak perbedaan antara data = dipesan dan data = penulisan kembali, yang mengejutkan saya.
The pembaruan campuran uji puncak tengah. Ada sekelompok skenario yang lebih jelas lebih lambat pada tes ini. Ini semua adalah data = jurnal . Kalau tidak, tidak ada banyak di antara skenario lainnya.
Saya memiliki tes pengaturan waktu lain, yang melakukan campuran sisipan, pembaruan, dan penghapusan yang lebih heterogen pada berbagai jenis kombinasi. Ini membutuhkan waktu lebih lama, itulah sebabnya saya tidak memasukkannya dalam plot di atas:
Di sini Anda dapat melihat bahwa konfigurasi writeback (# 19) sedikit lebih lambat daripada yang dipesan (# 7 dan # 11). Saya berharap penulisan kembali menjadi sedikit lebih cepat, tapi mungkin itu tergantung pada pola tulis Anda, atau mungkin saya belum cukup membaca di ext3 :-)
Berbagai skenario agak mewakili operasi yang dilakukan oleh aplikasi kita. Setelah memilih daftar skenario pendek, kami menjalankan tes pengaturan waktu dengan beberapa suite pengujian otomatis kami. Mereka sejalan dengan hasil di atas.
Kesimpulan
- The berkomitmen parameter tampaknya membuat sedikit perbedaan, jadi kita meninggalkan bahwa pada 5s.
- Kita akan melanjutkan dengan cache penulisan disk, penghalang = 0 , dan data = dipesan . Saya membaca beberapa hal secara online yang menganggap ini adalah pengaturan yang buruk, dan yang lain berpikir bahwa ini harus menjadi pengaturan default dalam banyak situasi. Saya kira yang paling penting adalah Anda membuat keputusan yang tepat, mengetahui apa yang Anda lakukan.
- Kita tidak akan menggunakan pragma sinkron dalam SQLite.
- Mengatur pragma SQLite cache_size sehingga DB akan masuk dalam memori meningkatkan kinerja pada beberapa operasi, seperti yang kami harapkan.
- Konfigurasi di atas berarti kita mengambil risiko yang sedikit lebih besar. Kami akan menggunakan API cadangan SQLite untuk meminimalkan bahaya kegagalan disk pada penulisan sebagian: mengambil snapshot setiap N menit, dan menjaga M terakhir tetap ada. Saya menguji API ini saat menjalankan tes kinerja, dan memberi kami keyakinan untuk melakukannya.
- Jika kita masih menginginkan lebih, kita bisa melihat penyia-nyiaan dengan kernel, tetapi kita cukup meningkatkan hal-hal tanpa pergi ke sana.
Terima kasih kepada @Huygens untuk berbagai tips dan petunjuk.