- Son 1 yıldır SQLite kullanarak Rails uygulamalarını yüksek performanslı ve kararlı şekilde çalıştırmanın yollarını derinlemesine anlamaya çalışıyordu
- Bu süreçte çeşitli dersler çıkardı ve bunları paylaşmak istiyor
- Sorunların nedenlerini ve çözüm yöntemlerini açıklayacak
SQLite ve Rails'in sorunları
- Varsayılan olarak SQLite kullanan bir Rails uygulaması kutudan çıktığı gibi kullanıma hazır değil
- Biraz ayar ve ince ayarla yüksek performanslı ve kararlı bir uygulama oluşturulabilir
- Rails 8'de hedef, yalnızca varsayılan ayarlarla bile üretime hazır bir duruma gelmek
Demo uygulama "Lorem News"
- Sorunları ve çözümleri açıklamak için "Lorem News" adlı demo uygulama kullanılacak
- Bu uygulama Hacker News'in bir klonu ve kullanıcılar gönderi ile yorum yazabiliyor
Performans testi
- Performans,
oha yük testi CLI aracı ve uygulama içindeki benchmark yolu kullanılarak test ediliyor
- Tekil istekler ve eşzamanlı isteklerle performans ölçülüyor
Ana sorun: SQLITE_BUSY istisnası
- SQLite, aynı anda yalnızca tek bir yazma işlemine izin vermek için yazma kilidi kullanır
- Birden fazla bağlantı aynı anda yazma kilidini almaya çalıştığında
SQLITE_BUSY istisnası oluşur
- Bu sorunu çözmek için immediate transaction kullanılmalı
Immediate transaction
- Varsayılan olarak SQLite deferred transaction modunu kullanır
- Immediate transaction kullanıldığında yazma kilidi hemen alınmaya çalışılır ve başarısız olursa yeniden denenebilir
sqlite3-ruby gem'i kullanılarak varsayılan transaction modu immediate moda ayarlanabilir
Timeout ayarı
database.yml dosyasındaki timeout ayarıyla SQLITE_BUSY istisnaları azaltılabilir
- SQLite'ın
busy_timeout ayarı kullanılarak yazma kilidi yeniden denenebilir
GVL (Global VM Lock) sorunu
sqlite3-ruby gem'i, SQLite'ın C kodunu çağırırken GVL'yi serbest bırakmaz
- Bu durum eşzamanlılık performansını düşürür
busy_handler kullanılarak GVL serbest bırakılabilir ve performans iyileştirilebilir
busy_timeout yeniden uygulaması
busy_timeout yeniden uygulanarak tüm sorguların aynı sıklıkta yeniden denenmesi sağlanır
- Bu, daha eski sorguların timeout'a düşmesini engeller
Performans iyileştirmeleri
- Performansı artırmak için şu ayarlar uygulanmalı
- Immediate transaction kullanımı
- Timeout ayarı
busy_handler kullanımı
- WAL (Write-Ahead Logging) modu kullanımı
- Okuma/yazma bağlantı havuzlarının ayrılması
GN⁺ özeti
- SQLite kullanan Rails uygulamalarındaki performans sorunları ve çözümleri ele alınıyor
- Immediate transaction, timeout ayarı, GVL'nin serbest bırakılması, WAL modu kullanımı ve okuma/yazma bağlantı havuzlarının ayrılması gibi yöntemlerle performans artırılabilir
- Bu yazı, SQLite ve Rails kullanan geliştiriciler için oldukça faydalı olacaktır
- Benzer özelliklere sahip diğer projeler olarak PostgreSQL ve MySQL öneriliyor
1 yorum
Hacker News yorumları
Oldmoe'nin Litestack projesine giriş
Ayrıntılı makale için teşekkür
SQLite ile çalışanlara tavsiye
FOSS analitik sistemi hakkında soru
sqlite3-ruby gem'inin GVL sorunu
Kişisel web hizmeti ayarları
PRAGMA journal_mode = WALPRAGMA busy_timeout = 5000PRAGMA synchronous = NORMALPRAGMA cache_size = 1000000000PRAGMA foreign_keys = truePRAGMA temp_store = memoryBEGIN IMMEDIATEtransaction kullanımıDjango hakkında soru
busy_timeoutvarsayılan ayarı üzerine sorubusy_timeoutyönteminin neden eski sorguları cezalandıran bir gecikmeye sahip olduğunu merak ediyorumSQLite ve Rails kullanımı hakkında görüş
Rails entegrasyon sorunlarının çözülmesine teşekkür