Model düzeyinde önbelleğe uygulanması

8 Cevap php

Ben geldi MVC önbelleğe alma ve fiili uygulama ile ilgili bazı sorular hakkında bir related question bazı yorum gönderme yapıldı. Nasıl bir el önbellek, henüz hala etkili olmaya devam gerek geliştirici olmadan şeffaf çalışır Model-seviye önbellek uyguluyor?

I would keep my caching responsibilities firmly within the model. It is none of the controller's or view's business where the model is getting data. All they care about is that when data is requested, data is provided - this is how the MVC paradigm is supposed to work.

(Kaynak: Post by Jarrod)

Önbelleğe gerçek bir ihtiyaç olmadıkça genellikle yapılmamalı ve arama sonuçları gibi şeyler için yapılmamalı çünkü şüpheci nedenidir. Yani bir şekilde Model kendisi kendisine tanzim edilmekte SELECT deyimi önbelleğe layık olup olmadığını bilmek zorundadır. Model çoğunlukla doğru bir karar yapmak için uzun bir süre boyunca sorgulanan ediliyor ne istatistikleri astronomik akıllı, ve / veya mağaza olmak zorunda değil misiniz? Ve tüm bu yükü zaten önbelleğe alma yararsız yapmaz mı?

Nasıl benzersiz (daha doğrusu, başka bir sonuç kümesindeki sonucu) başka bir sorgudan sorgu belirlemek istiyorsunuz? Ne kullanıcı girişine göre değişen sadece parametreleri ile, hazırlanmış deyimleri kullanarak eğer hakkında?

Başka bir poster bu dedi:

I would suggest using the md5 hash of your query combined with a serialized version of your input arguments.

Çarpışma ufacık şans endişesi değer mi?

Kavramsal olarak, Modeli'nde önbelleğe alma benim için iyi bir fikir gibi görünüyor, ama pratiklik görünüyor nedeniyle geliştirici önbelleğe doğası kontrolör mantığı içine doğrudan denetimini ve explicity kodu o olmalıdır.


Update for Bounty

Ben gerçekten ActiveRecord biraz benzer bir derece hafif ORM kullanarak ancak karmaşık n^2 sorun olmadan katılır ve alt sorgular yapma yeteneğine sahip olduğunu duyuyorum. Ben kendim inşa edilmiş, böylece esnek ve ilişkiler veya sütun adları açısından kısıtlayıcı değil, ve ben sadece önbelleğe alma mekanizması uygulamaya nasıl anlamak istiyorum.

Yardımsever insanların tavsiyesine uyarak, ben onun bir parametre listesi ile birleştirilmiş sorgu bir karma (muhtemelen md5) alacağını ve söz konusu veri deposu için anahtar olarak kullanabilirsiniz. Bunu gerektiren Model sınıfların ayrı ayrı önbelleğe alma uygulamak gerektiğini, ya da ORM katmanın parçası olmalıdır?

Bunun geçersiz gerektiği zaman nasıl anlarım? Ben GÜNCELLEME ayrıştırmak gerekir / manuel hangi kayıtların modifiye ediliyor öğrenmek için parametreleri / INSERT sorguları ve alt SİL? Ya da daha kötüsü, veri işler değişti ve ne geçersiz gereken izlemek için ek sorgular değiştirilmiş mı ne zaman?

Bana (bu şeffaf yapılacak verimli / gerçekten gerekli olup olmadığını) açık kavramsal bir açıklama verebilir kim için lütuf ödül, ve eğer öyleyse, Model önbelleğe alma için bazı uygulama ayrıntılarını vardır olacaktır. Sizin odak daraltmak için yardımcı olur, ben PHP ve MySQL kullanıyorum.

8 Cevap

Modeli önemsiz bir ORM olup olmadığını sonrası sadece herhangi bir mantıklı. Ve bu kötü bir şey neden birçok nedeni vardır. Bir web hizmeti sanki modeli düşünmeye çalışın.

Modelin önbelleğe alma is sorumluluğudur.

Nasıl benzersiz (daha doğrusu, başka bir sonuç kümesindeki sonucu) başka bir sorgudan sorgu belirlemek istiyorsunuz? Ne kullanıcı girişine göre değişen sadece parametreleri ile, hazırlanmış deyimleri kullanarak eğer hakkında?

Ama modele girdileri benzersiz çıktısı tanımlar.

Bir alışveriş sepetinin içeriği almak ve ürün kataloğu üzerinde bir arama çalıştırmak için aynı model kullanıyorsanız o kod ile yanlış bir şey var.

Hatta alışveriş sepetinin durumunda, için eşleşen ürünlerin listesini önbelleğe alma, katalog arama durumunda, içeriğini değiştirecek bir işlem süreci için alınan zaman daha az bir TTL ile önbelleğe alma veri hak olabilir birkaç saat muhtemelen satış ile ilgili herhangi ölçülebilir bir etkisi var, ama ticaret-off de veritabanı yükünü azaltmada olacaktır.

Eğer kutunun dışında önemsiz bir ORM kullanıyor olması, kendi kodu sararak sizi dışlamaz.

Model istatistik astronomik akıllı, ve / veya mağaza olmak zorunda değil

Hayır önbelleğe konusunda kararlılık yapmak ve önbellek tutarlı olduğundan emin olamaz eğer isteğin türüne göre bir TTL zorlamak.

Genel bir kural olarak, herhangi bir değişken ve bu tasarım zamanında uygulanması gerekmektedir bağlama SELECT sorgusu before dayalı uygun TTLS'de tahmin etmek mümkün olmalı - ama açıkçası sonuç dayalı endeksli olmalıdır bağlanmasından sonra sorgula.

Bunu gerektiren Model sınıfların ayrı ayrı önbelleğe alma uygulamak gerektiğini, ya da ORM katmanın parçası olmalıdır?

Tercihi için ben model sınıf bir dekoratör olarak uygulamak - doğrusu önemsiz ORM daha bir fabrika uygulamak modellerine kolayca bağlantı yapabilirsiniz bu şekilde.

C.

Orada vb karma, hükümsüzlük gibi önbelleğe alma ile düşünmek oldukça birkaç faktör vardır Ama önbelleğe hedefi her zaman aynıdır: yanıt süreleri ve kaynak tüketimini azaltmak için.

İşte sistemleri için kafamın üst kapalı hızlı düşünceler bir çift do not kullanımı ORM şunlardır:

  • Eğer bunun için bir bellek varsa memcache kullanarak bir şey önbelleğe acıyor asla
  • Diğer türleri verileri sadece hiç önbellek SELECT sorguları etkileyecek beri
  • Tüm önbelleğe sorgular parametized edilmelidir
  • Önbellek anahtar parametrelerin bir serialize() 'd sürümü ile birleştirilmiş sorgu bir md5 olmalıdır (bu eşsiz sorguları tanımlar. Parametrelerin boyutu genellikle sorguları seçmek geçti çünkü parametreleri Seralizing bir sorun değil genellikle oldukça önemsiz). Dizgeleştirme düşündüğünüz kadar pahalı değildir. Eğer dinamik params ile birleştirilmiş statik sorgu karma çünkü, çarpışmalar konusunda endişelenmenize gerek asla.
  • Değişiklikler (INSERT / UPDATE / DELETE) bir model satır geçersiz (veya TTL set) bu model için önbelleğe alınan tüm öğeler üzerinde olmalıdır
  • Modeli bir sorgu ile birlikte gönderilmek üzere önbellek TTL değerlerini izin uzatılmalıdır
  • Sizin modeli (muhtemelen sorgu ile birlikte 0 TTL geçerek) önbellek atlama için destek olmalıdır
  • Bir temel sorgu önbelleğe alınmış olsa bile, genellikle ORDER BY / LIMIT yeni (değiştirilmiş) sorgusunda operasyonlarını yazmak yerine önbellek tüm bir satır kümesi çekmek için uygulamak daha verimli ve (Lütfen web ve veritabanı sunucuları arasında çok yüksek gecikme olmadığı sürece) aynı şeyi elde etmek için PHP aracılığıyla manipüle.

Bir ORM sistemi için önbellek doğrulama yönetmek için çalışılıyor (nedeniyle ilişkilerin) tamamen farklı bir canavar, ve muhtemelen (denetleyicisi) bir vaka ile ayrı ayrı ele alınmalıdır. Eğer performansı ile gerçekten ilgili iseniz, şans ile başlamak için bir ORM kullanarak olmaz vardır.

UPDATE:

Tek bir iş parçacığı içinde aynı modeli sınıfının birden çok örneğini kullanarak kendiniz bulursanız, ben senin örneği modeli (Yapıcınızda bağlı deserializing ve bir nesne oluşturarak daha verimli bazen bir nesne olduğu uyanma) memcaching potansiyel de öneririm. Bir intialized nesne (inşa veya serisi olsun) var, bir nesnenin worlds more efficient to clone() temel bir örneğidir ve PHP bir nesneyi yeniden yeni devlet yerine ayarlayın.

The reason I am skeptical is because caching should usually not be done unless there is a real need, and shouldn't be done for things like search results. So somehow the Model itself has to know whether or not the SELECT statement being issued to it worthy of being cached. Wouldn't the Model have to be astronomically smart, and/or store statistics of what is being most often queried over a long period of time in order to accurately make a decision? And wouldn't the overhead of all this make the caching useless anyway?

Başka kim herhangi izlemek için daha uygundur? Birden kontrolörleri ihtiyaç duydukları veri getirmek için aynı modeli kullanarak olacaktır. Peki dünyada bir kontrolör rasyonel bir karar vermek mümkün olacaktır?

Hiçbir sert ve hızlı kurallar vardır - bir akıllı önbelleğe alma stratejisi neredeyse tamamen bağlam tarafından tahrik edilir. Iş mantığı (yine, modelleri!) Şeyler ne tür vb önbellek geçersiz gereken önbellek, olması gerektiğini dikte edecek

Sen önbelleğe alma arama sonuçları kötü bir fikir gibi görünüyor kesinlikle haklısın. Ben genellikle eminim. Bu arama sonuçları üretmek için çok pahalı ve sayfalama gibi bir şey yapıyorsanız, arama parametreleri ile birlikte, en son sonuçlarını tutan bir kullanıcı başına önbellek isteyebilirsiniz mümkündür. Ama bu oldukça özel bir durum olduğunu düşünüyorum.

Bu bağlamda olmadan daha spesifik bir tavsiye vermek zor, ama burada senaryolar bir çift vardır:

1) Bir kategori atanmış olabilir iş nesneleri var. Kategoriler nadiren değişir. Sizin Kategori modeli okuma işlemleri için kategorilerin tam set önbelleğe gerek. Nadir sağ işlemler olduğunda, onlar önbellek geçersiz kılabilir. Sistemdeki her œkod önbelleği ile kendisini ilgili olmadan (seçme kutularını render için, diyelim) şimdi modeli sorgulamak ve geri akım kategorileri alabilirsiniz. Sisteminde herhangi denetleyicisi şimdi önbelleği hakkında bilmeden kategorileri silme / güncelleme / ekleyebilirsiniz.

2) Birden fazla girişleri tüketir ve "ürün" bazı tür bir popülerlik derece oluşturur bazı karmaşık bir formül var. Sayfa düzeni bazı Widget özet şeklinde en popüler 5 nesneleri gösterir. Sizin Ürün modeli önbellek güvenmek hangi bir getPopular () yöntemini sağlayacaktır. Model önbelleğe her X dakikada geçersiz olabilir, ya da bazı arka plan işlemi yeniden / geçersiz düzenli aralıklarla çalıştırmak olabilir. Olursa olsun popüler ürünler istiyor sisteminin hangi bölümünün, onlar şeffaf önbelleği modeli aracılığıyla bunu talep.

Kesin önbelleğe alma uygulaması tipik kullanım durumları ile birlikte, size manipüle konum verilerinin tür üzerinde son derece bağlıdır.

Burada ihtar ActiveRecord kötüye, ve / veya denetleyicileri SQL sorguları (veya eşdeğerleri) beste yapıyorsanız, muhtemelen sorunları için gidiyoruz olmasıdır. Eğer sadece veritabanı tabloları yerine çürük modellerinin doğru modeller sizin etki, şal, güzel, zengin, model katmanı var ise akıllı önbelleğe alma yapmak çok daha kolaydır.

Bu modeller akıllı olmak, bu developer akıllı olmak değil.

Ne yaptığını, MVC yükleme fonksiyonu için bir yedek olarak bir önbellek katmanı inşa edildi. Bu şekilde, yalnızca gerçek modeli istediğimiz aramaları, önbelleğe alınır. Hiçbir önbelleğe alma gerekli ya da istenmeyen ise, denetleyici bir model çağrı normal şekilde kullanılıyor.

Bir model cachelayer aracılığıyla davet ediliyor ise, bu nihai parametreler bulunuyor birlikte, önbellek katmanı ilk önbellek havuzun karşı istenen verileri doğrulamak ve hala geçerli ise iade. Bu durumda, gerçek model verileri yüklenir ve önbelleğe sadece kontrol döndürülür. Eğer değilse o normal şekliyle, model olarak adlandırılır.

Hatta daha da sunucu yükleri azaltmak için, bir sorgu başına / başına modeline düzeyde semafor kilitleri kullanımını tanıtmak için çok kolay hale geldi çünkü, modelin üstünde bir tabaka içinde bunu yapmanın imkanı olması gerçekten harika.

Benim için en büyük avantajı olsa modelleri amaçlanan olarak tasarlanmış ve saf veritabanı sorgularını ama hiçbir şey içerir olduğu gerçektir. Bu şekilde, hatta fark son kullanıcılar olmaksızın üretimin bir modelini değiştirmek mümkündür (tabii, bir model sunar istenen veri güncelleme süresinde recreation gerek olmadığını varsayarak ..)

Güncelleme: Biz de iki düzeyde, bir başına bir model bazında ve isteğe bağlı grup temelinde bizim cachelayer içinde Namespacing hayata geçirdik. Bunun sayesinde, kolayca önceden veritabanında güncelleme veya silme üzerine bir modeli geliyor tüm önbelleğe alınmış veriler geçersiz tüm geçersiz kılabilir.

Eğer aktif kayıtları kütüphanesi için daha şeffaf önbellek sistemi ile ilgilenen nerede varsa. Siz sonucu ilişkilendirilebilir bir dizi oluşturmak daha sonra her bir sorgu için bir id atayabilirsiniz. Bir veritabanında statik veya ironik bu ilişki gemi saklayabilirsiniz. (Bu bazen daha az bilgisayar güç kullanmak böylece daha bilgisayar güç kullanmak zorunda önbelleğe arasında ticaret tür)

Sonuç karma yeni karma güncellenir farklı ise sorgu çıkan karma çalıştırmak her zaman takip etmek. Karma aynı ise, o zaman, yinelenen sonuç sayısı ekler. Tekrar sonuçların istenilen sayıda gelip, o zaman sonuçları önbelleğe ve zaman veya sorgunun izleyen çalıştırır bir ayrılan miktar için tablo denetimi durdurun.

Bu gidiş ons tüm kontrollü bir sınıf olurdu. Fonksiyonlar gibi şeyler içerebilir

-start cache checking
-set threshold
-cache always
-cache time life
-force clear all cache
-clear this cache for this query
-we have been death hit with the death laser and need to catch everything(The I hate you wordpress I'm never using you again function I shouldn't have been so lazy and made my own website function)

Bu sürecin çok otomatikleştirmek için yardımcı olacaktır. Ayrıca önbellek kuralları modeli bazında ya da bir bütün olarak tüm uygulamada bir model üzerinde uygulanabilir.

Bu daha sonra bazı önbellek sistemleri biraz daha masraf olabilir ama sadece önbelleğe kendi şeyi yapıyor olmasını istiyorsanız ben de işe yarayacağını düşünüyorum; dışarı ile çok amok çalışan.

Bu gerçekten bir cevap değil, ama soru seni Symfony ile Doctrine ORM kullanarak ne yapmak istediğinizi nasıl, sanırım, açıklar this chapter hangi görmüştü hatırlattı. Siz bu yaklaşım / uygulama ile karşılaştırmak isteyebilirsiniz.

Temel olarak, bir yaklaşım var "astronomik akıllı" için çalışın ama elle sonuç belirtmek için programcı verileri ve performans etkisi dalgalanmalara göre önbelleğe ayarlar verir vermez ... Ben bu kararı yaklaştığı ve gece yeniden hesaplamak olabilir varsayalım Gerçek ölçümler falan dayanmaktadır.

Ben ORM en uygulanabilir sorunlar ve çözümleri de dahil olmak üzere önbelleğe alma kapsamlı bir göz için here bakmak tavsiye ederim.

Bir ORM verileri önbelleğe alma ile uğraşırken, genellikle çözmek için aşağıdaki 3 sorunları var:

  1. Birçok ORM uygulamaları mağaza ya veritabanı kaynak veya serileştirilemez bir sonuç gerçek ORM nesneleri ayarlamak ya da her ikisi. Önbelleğe alma tüm nesneleri seri hale gerektirdiğinden, bu yolumuza ciddi bir yol blok koyar.
  2. Nasıl önbellek diğerine karşı tek bir veri kümesi izlerim?
  3. Nasıl belirli bir veri seti değişti önbellek bildiririm?

SQL, örneğin, doğrudan arabirim yok ayrı modeli olmalıdır. Müşteriler tablosunda için: $CustomerModel->GetCustomers($parameter); vesaire. Sonra, bu modellerde, varolan MAK'lerde herhangi bir düzenlemeye gerek kalmadan şeffaf önbelleğe uygulayabilirsiniz.