Smart (?) Veritabanı Önbellek

6 Cevap php

Ve elle bir INSERT / {[(2 sonra bütün önbellek depo silmek gerektirir: Ben hepsini çok aptal vardır (keep this query cached for X minutes yani), birkaç veritabanı önbellek motorları gördüm )]} / DELETE sorgu idam edilmiştir.

Yaklaşık 2 veya 3 yıl önce üzerinde çalıştığım bir proje için alternatif bir DB önbellek sistemi geliştirdi, fikir belirli bir SQL Sorguda tablo (ler) bulmak için normal ifadeler kullanmak temelde:

$query_patterns = array
(
    'INSERT' => '/INTO\s+(\w+)\s+/i',
    'SELECT' => '/FROM\s+((?:[\w]|,\s*)+)(?:\s+(?:[LEFT|RIGHT|OUTER|INNER|NATURAL|CROSS]\s*)*JOIN\s+((?:[\w]|,\s*)+)\s*)*/i',
    'UPDATE' => '/UPDATE\s+(\w+)\s+SET/i',
    'DELETE' => '/FROM\s+((?:[\w]|,\s*)+)/i',
    'REPLACE' => '/INTO\s+(\w+)\s+/i',
    'TRUNCATE' => '/TRUNCATE\s+(\w+)/i',
    'LOAD' => '/INTO\s+TABLE\s+(\w+)/i',
);

Ben bu regexs muhtemelen bazı kusurları (benim regex becerileri sonra geri oldukça yeşil idi) var ve tabii ki iç içe geçmiş sorguları eşleşmiyor biliyorum, ama onları kullanmak asla beri bu benim için bir sorun değildir.

Neyse, ilgili tablolar bulduktan sonra ben bunları alfabetik olarak sıralamak istiyorum ve aşağıdaki adlandırma kuralı ile önbellek deposunda yeni bir klasör oluşturun:

+table_a+table_b+table_c+table_...+

Bir SELECT sorgu durumda, ben, veritabanından sonuçlar almak istiyorum serialize() onları ve uygun önbellek klasöründe saklayabilirsiniz böylece örneğin aşağıdaki sorgu sonuçları:

SELECT `table_a`.`title`, `table_b`.`description` FROM `table_a`, `table_b` WHERE `table_a`.`id` <= 10 ORDER BY `table_a`.`id` ASC;

Saklanır olacaktır:

/cache/+table_a+table_b+/079138e64d88039ab9cb2eab3b6bdb7b.md5

MD5 sorgu kendisidir. Müteakip bir SELECT sorgusu üzerine sonuç almak için önemsiz olacaktır.

Yazma sorgu başka tür durumunda (INSERT, REPLACE, UPDATE, DELETE ve benzeri) I olacaktır {[( kendi adına +matched_table(s)+ vardı 4)]} tüm klasörleri tüm dosya içeriğini silin. Bu şekilde, etkilenen ve ilgili tablolar tarafından kullanılan, sadece önbellek tüm önbelleğini silmek için gerekli olmaz.

Sistem oldukça iyi çalıştı ve performans farkı görünür oldu - Proje sorguları yazmak çok daha fazla okuma sorguları vardı rağmen. O zamandan beri ben işlemleri, FK CASCADE UPDATES / DELETES kullanmaya başladı ve bu özellikleri ile çalışması için sistem mükemmel zaman yoktu.

Ben geçmişte MySQL Query Cache kullandım ama ben bile performansı karşılaştırmak değil söylemeliyim.

Ben merak ediyorum: Ben bu sistemde güzelliği görür tek ben miyim? Ben farkında olmayabilir herhangi darboğazları var mı? Neden CodeIgniter ve Kohana (I Zend Framework farkında değilim) gibi popüler çerçeveler gibi ilkel DB önbellek sistemleri var mı?

Daha da önemlisi, takip değer bir özellik olarak bunu görüyor musun? Evet, ben / make it even faster (benim ana kaygıları disk I/O and (de)serialization sorgu sonuçlarının vardır) için kullanabilirsiniz yapabileceği bir şey var mı?

Ben, teşekkürler katkılarınıza teşekkür ederiz.

6 Cevap

Ben bu çözümde güzelliğini görebilirsiniz, ancak ben sadece uygulamaların çok özel bir set için çalışıyor inanıyoruz. Bu geçerli değildir Senaryoları şunlardır:

  • Basamaklı siler / güncelleştirmeleri veya tetikleyiciler her türlü kullanmak Veritabanları. Örneğin, sizin tablo A DELETE neden olabilir regex bu asla tutmaz masa B. SİL.

  • Örneğin, size önbellek invalidation program aracılığıyla gitmez noktalardan veritabanına erişen vb crontab komut Hiç (salt okunur köleler tanıtmak) makineler arasında çoğaltma uygulamaya karar verirseniz, o da (önbellek invalidation vb yoluyla gitmez çünkü) önbelleği rahatsız edebilir

Bu senaryolar davanız için gerçekçi olmasa bile yine çerçeveler önbellek bu tür uygulama yok neden sorusuna cevap vermez.

Bu takip değer olup olmadığını ilgili olarak, tüm uygulama bağlıdır. Belki daha fazla bilgi sağlamak için bakım?

Özellikle kaynakları sınırlı ve kolayca paylaşılan barındırma gibi, genişletilmiş edilemez ortamlar için - - Ben bu güzelliği görmek yaparken ben şahsen gelecekte komplikasyonları korku olur: Ya birisi, yeni işe alınan ve önbelleğe alma mekanizmasının habersiz, iç içe geçmiş sorguları kullanmaya başlar? Ne bazı dış hizmet önbellek fark ile değil, tablo güncelleme başlarsa?

Acilen işlemci güç ya da RAM ekleyerek yardımcı edilemez bir hıza ihtiyacı bir uzman, tanımlanmış bir proje için, bu büyük bir çözüm gibi görünüyor. Genel bir bileşeni olarak, ben çok titrek bulmak ve farkında olmak bir önbellek olduğunu unutmadan insanlardan kaynaklanıyor uzun vadede ince sorunları korku olacaktır.

Çözümü, bunu açıklamak gibi, eşzamanlılık sorunları için risk altındadır. Saniyede sorguları yüzlerce alma olduğunuzda, bir UPDATE deyimi çalışan bir dava vurmak uğrarsınız, ancak önbelleği temizlemek için önce, bir SELECT ondan okur, ve bayat verileri alır. Birkaç UPDATE'ler kısa bir süre içinde satır aynı seti vurduğunuzda Ayrıca, sorunları çalışabilir.

Daha geniş anlamda, önbelleğe alma ile en iyi uygulama mümkün büyük nesneleri önbelleğe almaktır. Örneğin, yerine "kullanıcı" ile ilgili her yerde önbelleğe satır bir grup olan daha, sadece kendisi nesne "kullanıcı" önbelleğe daha iyidir.

Eğer bütün sayfaları önbelleğe eğer daha iyi, (ör., herkese aynı ana gösterir; bir profil sayfası hemen hemen herkes, vb özdeş görünen), bu daha da iyidir. Bir önbellek bir bütün için getirme, önceden işlenen sayfa dramatik önbellek sayfasını yeniden paralayan ardından satır / sorgu seviye cache getirir onlarca geride bırakacaktır.

Uzun lafın kısası: profili. Bazı ölçüm yapmalısınız zaman varsa, büyük olasılıkla büyük nesneler, hatta sayfaları ziyade bu şeyler inşa etmek için kullanılan küçük sorgularını önbelleğe çok büyük bir performans kazan olduğunu göreceksiniz.

Kesinlikle onlar temel tablo adlarını ve tablolar kendilerini karıştırma senaryo ile başa çıkmak için görünmüyor - Ben regexes her durumda sağlamak olmayabilir şüpheleniyoruz. örneğin düşünmek

güncelleme stats.measures = 50 where id = 1 miktarını ayarlamak;

ve

use stats; update measures set amount=50 where id=1;

Sonra PL / SQL var.

Sonra tüm veritabanı erişimi paylaşılan bir dosya sistemi üzerinde önbelleğe kontrol mekanizmasını uygulama makineleri olduğunu önceden varsayar yani her müşteri bir danışma denetim mekanizması gözle bağlı olduğu gerçeği var.

(Küçük bir nokta gibi - sadece tablolar tanımlanmış bir dizi üzerinde bir sorgu önbelleğe alınan sürümün hala geçerli ise, ziyade tespit etmeye çalışıyoruz belirlemek için veri dosyaları üzerinde değişiklik zamanlarını denetlemek için kolay olmaz ise önbellek denetim mekanizması bir güncelleştirme tespit etti - kesinlikle çok daha sağlam olurdu)

Stepping back a bit, implementing this from scratch using a robust architecture would mean that all queries would have to be intercepted by the control mechanism. The control mechanism would probably need a more sophisticated query parser. It certainly requires a common storgae substrate for all the instances of the control mechanism. It probably needs an understveing of the data dictionary - all things which are already implemented by the database itself.

Sen "Ben geçmişte MySQL Query Cache kullandım ama ben bile performansı karşılaştırmak değil söylemeliyim." Devlet

Ben bu oldukça tuhaf buluyorum. Sorgulardan Büyük sonuç kümeleri ile uğraşırken Kesinlikle, benim deneyim bir veritabanından yığın veri yükleme büyük diziler unserializing çok daha hızlı olmasıdır - Büyük sonuç kümeleri web tabanlı uygulamalar oldukça atipik olmasına rağmen.

When I've tried to speed up database access (after fixing everything else of course) then I've gone down the route of replicating ve partitioning data across multiple DBMS instances.

C.

Bir master-slave konfigürasyonunda çoklu veritabanları ile çalışırken bu oturum bölme sorunu ile ilgilidir. Temel olarak, düzenli ifadeler benzer bir dizi tablo (hatta hangi satırların) okumak veya yazılı edildiği belirlemek için kullanılır. Sistem tabloları için yazılmış ve hangi izler ve bu tablolardan biri bir okuma kadar geldiğinde, o ana yönlendirilir oluyor. Bir sorgu sonucunda veri-to-the-ikinci doğru, o zaman köle yönlendirilir var olması gerekmeyen bir tablodan okuyor. Genellikle, bilgi sadece gerçekten bir kullanıcı (bir kullanıcının profil düzenleme yani) kendilerini değişti şey olduğunda geçerli olması gerekir.

Onlar O'Reilly kitabının geri gün böler oturumu işleme için bir sistem geliştirirken High Performance MySQL. Ben bunu biraz kullanılan bu konuda iyi bir biraz konuşmak.

Eğer tarif iyileşme farklı bir tablodan veri çekmek için bir güncelleştirme tarafından etkilenmiş değil garantili önbelleklerini geçersiz kaçınmaktır.

Bu güzel tabii ki, ancak ince taneli gerçek bir fark yaratmak için yeterli olup olmadığından emin değilim. Eğer gerçekten hala (güncelleme masaya çünkü, ancak farklı satırlarda) olması gerek yoktu önbelleklerini çok invaliding olacaktır.

Ayrıca, hatta bu "basit" şeması SQL sorgu dizesi bakarak ilgili tabloları tespit edememek dayanır. Bunun nedeni manzaralı, masa adlar ve çoklu katalog, genel durumda yapmanız zor olabilir.

Otomatik olarak (ve verimli) bir önbellek geçersiz gerekip gerekmediğini tespit etmek çok zordur. Bu nedenle, (pek çok güncellemeler olduğunda çok iyi çalışmaz, hangi sistem içinde olduğu gibi, bu tür her güncellemede geçersiz, ya da masa başına gibi) çok basit bir düzeni kullanın, ya da bir çok el yapımı önbellek için ya sorgu mantığı (muhtemelen yazmak zor ve korumak zor), ya da içine derin kanca ile özel uygulama önbellek bayat verileri içeren ve sadece periyodik olarak yenileyebilirsiniz kabul ediyorum.