Uyarı: Aşağıda yanlışlıklar olabilir. Ben ilerlerken bu şeylerin çoğunu öğreniyorum, bu yüzden bir tutam tuz ile alın. Bu oldukça uzun, ama sadece oynadığımız parametreleri okuyabilir ve sonunda Sonuca geçebilirsiniz.
SQLite yazma performansı hakkında endişelenebileceğiniz birkaç katman vardır:
Koyu renkle vurgulanmış olanlara baktık. Belirli parametreler
- Disk yazma önbelleği. Modern diskler, disk yazma işlemlerini dönen diske göre optimize etmek için kullanılan RAM önbelleğine sahiptir. Bu etkinleştirildiğinde, veriler sıra dışı bloklarda yazılabilir, böylece bir kilitlenme meydana gelirse, kısmen yazılı bir dosya elde edebilirsiniz. Hdparm -W / dev / ... ile ayarı kontrol edin ve hdparm -W1 / dev / ... ile ayarlayın (açmak için -W0 kapatmak için).
- Bariyer = (0 | 1). "Bariyer = 0 ile çalıştırırsanız, disk yazma önbelleği etkin değilse" diyen çok sayıda yorum var. Engellerle ilgili bir tartışmayı http://lwn.net/Articles/283161/ adresinde bulabilirsiniz.
- data = (günlük | sipariş edilen | geri yazma). Bu seçeneklerin açıklaması için http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html adresine bakın .
- taahhüt = N. Ext3'e tüm verileri ve meta verileri her N saniyede bir senkronize etmesini söyler (varsayılan 5).
- SQLite pragma senkronize = AÇIK | KAPALI. ON olduğunda, SQLite devam etmeden önce bir işlemin "diske yazılmasını" sağlar. Bunu kapatmak, diğer ayarları büyük ölçüde ilgisiz kılar.
- SQLite pragma cache_size. SQLite'ın bellek içi önbellek için ne kadar bellek kullanacağını kontrol eder. İki boyutu denedim: biri tüm DB önbelleğe sığacak ve diğeri önbellek maksimum DB boyutunun yarısı idi.
Ext3 belgelerindeki ext3 seçenekleri hakkında daha fazla bilgi edinin .
Bu parametrelerin bir dizi kombinasyonu üzerinde performans testleri yürüttüm. Kimlik, aşağıda belirtilen bir senaryo numarasıdır.
Senaryo 1 olarak makinemdeki varsayılan yapılandırmayla çalışarak başladım. Senaryo 2, "en güvenli" olduğunu düşündüğüm şeydir ve sonra uygun / istenirse çeşitli kombinasyonları denedim. Bu, muhtemelen kullandığım harita ile anlaşılması en kolay:
Yalnızca INTEGER, yalnızca TEXT (id sütunu ile) veya karışık olan tablolarda, ekler, güncellemeler ve siler ile çok sayıda işlem yürüten bir test komut dosyası yazdım. Bu yukarıdaki yapılandırmaların her biri üzerinde birkaç kez koştu:
En alttaki iki senaryo "pragma senkronize = kapalı" olan # 6 ve # 17'dir, bu yüzden en hızlı olmaları şaşırtıcı değildir. Üçlü sonraki küme # 7, # 11 ve # 19'dur. Bu üçü yukarıdaki "yapılandırma haritası" nda mavi renkle vurgulanmıştır. Temel olarak yapılandırma disk yazma önbelleği açık, bariyer = 0 ve veri 'günlük' dışında bir şeye ayarlanmıştır. İşlemi 5 saniye (# 7) ile 60 saniye (# 11) arasında değiştirmek çok az fark yaratıyor gibi görünüyor. Bu testlerde veri = sıralı ve veri = geri yazma arasında herhangi bir fark varsa beni şaşırtmıştı.
Karışık güncelleme testi orta zirvedir. Bu testte daha yavaş bir senaryo kümesi var. Bunların hepsi data = günlüğü olanlardır . Aksi takdirde, diğer senaryolar arasında fazla bir şey yoktur.
Farklı tip kombinasyonlarda daha heterojen ekler, güncellemeler ve siler karışımı yapan başka bir zamanlama testi yaptım. Bunlar çok daha uzun sürdü, bu yüzden yukarıdaki arsaya dahil etmedim:
Burada geri yazma yapılandırmasının (# 19) sıralı olanlardan (# 7 ve # 11) biraz daha yavaş olduğunu görebilirsiniz. Geri yazımın biraz daha hızlı olmasını bekledim, ama belki de yazma desenlerinize bağlıdır, ya da henüz ext3'te henüz yeterince okumadım :-)
Çeşitli senaryolar, başvurumuzun yaptığı işlemleri bir şekilde temsil ediyordu. Kısa bir senaryo listesi seçtikten sonra, bazı otomatik test takımlarımızla zamanlama testleri gerçekleştirdik. Yukarıdaki sonuçlarla aynı çizgideydi.
Sonuç
- Taahhüt biz 5s o terk ediyoruz, böylece parametre, küçük fark yaratmak için görünüyordu.
- Disk yazma önbelleği açık, bariyer = 0 ve veri = sıralı olarak devam ediyoruz . Çevrimiçi olarak bunun kötü bir kurulum olduğunu düşündüğüm bazı şeyleri okudum ve birçok durumda bunun varsayılan olması gerektiğini düşünen diğerleri. En önemlisi, hangi ödünleşimleri yaptığınızı bilerek bilinçli bir karar vermenizdir.
- SQLite'de senkron pragmayı kullanmayacağız.
- SQLite cache_size pragma'nın DB'nin bellekte sığacağı şekilde ayarlanması beklediğimiz gibi bazı işlemlerde performansı artırdı.
- Yukarıdaki yapılandırma, biraz daha fazla risk aldığımız anlamına gelir. Kısmi yazma işleminde disk arızası riskini en aza indirmek için SQLite yedekleme API'sini kullanacağız: N dakikada bir anlık görüntü alma ve son M'yi çevresinde tutma. Performans testlerini yaparken bu API'yı test ettim ve bize bu şekilde gitmemize güven verildi.
- Hâlâ daha fazlasını isteseydik, çekirdeği karıştırmaya bakabilirdik, ama oraya gitmeden işleri yeterince geliştirdik.
Çeşitli ipuçları ve işaretçiler için @Huygens'e teşekkürler.