Memcached Bu ok?

2 Cevap php

I'm new to memcached. Is this code vulnerable to the expired cache race condition? How would you improve it?

$memcache = new Memcache;
$memcache->connect('127.0.0.1');
$arts = ($memcache===FALSE) ? FALSE : $memcache->get($qparams);
if($arts===FALSE) {
	$arts=fetchdb($q, $qparams);
	$memcache->add($qparams, $arts, MEMCACHE_COMPRESSED, 60*60*24*3);
}
if($arts<>FALSE) {
	// do stuff
} else {
	// empty dataset
}
  • $ Qparams sorguya parametreleri içeren, bu yüzden anahtar olarak kullanıyorum.
  • $ Sanatlar olsun her madde için gereken tüm alanları ile bir dizi var.

Kullanıcının bu sorgu X 100 satır alır diyelim. Satır 50. başka bir işlem tarafından değiştirilen biraz sonra (perakende fiyatı artmış olur söylüyorlar sağlar).

  • Ben önbelleği hakkında ne yapmalıyım?
  • Nasıl 50. önbelleğe üste bilebilir?
  • Ben önbellek TÜM girdileri geçersiz kılmalıdır? (Bana overkill gibi geliyor).

2 Cevap

Bu kod önbellek süresi dolan yarış durumu savunmasız mı? Bunu nasıl artıracak?

Yes. Iki (veya daha fazla) aynı anda müşterilerine önbellek aynı anahtarı alıp veritabanından çekerek sonuna kadar deneyin. Sen veritabanında sivri olacak ve zaman dönemleri için veritabanı ağır yük altında olacak. Bu önbellek izdiham denir. Bu işlemek için yollar bir çift vardır:

  • Önbellek ön ısıtma yeni öğeler için (temelde size site canlı gitmeden önce gerektiren nesneleri önceden yüklenmesi anlamına gelir).
  • Periyodik sona öğeler için gerçek daha ileride biraz zaman (5-10 dakika diyelim) sona bir sona zaman yaratmak. Eğer önbellekten nesneyi çekin zaman aşımına zaman yakın ise o zaman, veritabanından önbelleği ve güncelleştirme güncellenmesi herhangi bir başka müşteri önlemek için geleceğe, önbelleği denetler. Bu önbellek stampedes ile çalışmak için anahtar kilitleme uygulamak veya cas belirteçleri kullanabilirsiniz (çalışmak için son istemci kütüphanesi gerektirir) ya gerekir.

Daha fazla bilgi için memcached faq edin.

Kullanıcının bu sorgu X 100 satır alır diyelim. Satır 50. başka bir işlem tarafından değiştirilen biraz sonra (perakende fiyatı artmış olur söylüyorlar sağlar).

Siz önbellek veri üç tip var:

  1. Nesneler
  2. Nesnelerin listeleri
  3. Oluşturulan veri

Ne genellikle yapmak ayrı tuşları gibi nesneleri tutmak ve daha sonra listelerde önbellek "işaretçileri" kullanmaktır. Sizin durumunuzda bir yere önbellek N objets var (tuşlar 1,2..N söylüyorlar sağlar), ve daha sonra bir dizi nesnelerin listenizi var array(1,2,3,10,42...). Nesnelerle listesini yüklemek için karar verdiğinizde, size önbellek liste anahtarı yükleyin, sonra (isteklerini azaltmak için getMulti kullanarak) önbellekten gerçek nesneleri yüklemek. Nesnenin herhangi güncellenmiş alırsa, bu durumda, sadece tek bir noktada güncellemek ve otomatik olarak (söz değil bu teknikle alanı büyük miktarda tasarruf) her yerde güncellenir.

Edit: lookahead time expiration ile ilgili biraz daha bilgi eklemek için karar verdi.

Sen bir son verilerine x ile nesneyi kurmak ve x+5minutes bir son kullanma tarihi ile veritabanına kaydetmek. Bu önbellekten nesne yüklemek zaman alabilir adımlar şunlardır:

  1. Güncellemek için zaman olup olmadığını kontrol edin (time() - x < 0)
  2. Öyleyse öğeyi serinletici ise kimse güncelleme böylece, tuş kilidi. Eğer tuşunu kilitlemek yapamıyorsanız, o zaman başkası zaten anahtarı güncelliyor ve bir Eylül (Somebody Else Sorunu) olur. Memcached kilitleri için bir çözüm olduğundan, kendi mekanizmasını geliştirmek zorunda. Ben genellikle sonunda orijinal tuşlarına değeri + ":lock" ile ayrı bir anahtar ekleyerek bunu. Sen must (1 saniye memcached için) mümkün olan kısa sürede sona erecek bu anahtarı ayarlayın.
  3. Eğer anahtar üzerinde bir kilit aldıysanız, önce yeni bir zaman aşımı süresi (Eğer başka müşteri tuşunu kilitlemek için çalışacağız eminiz bu şekilde) ile nesneyi kaydetmek, sonra iş hakkında gitmek ve veritabanından anahtarını güncellemek ve tasarruf Uygun ileri yönlü sona ermesi ile tekrar yeni bir değer (1 noktasına bakınız).

Bu her şeyi temizler umuyoruz :)

Değiştirilmiş bir öğeyi içeren herhangi bir önbelleğe nesne geçersiz zorunda. Eğer daha ayrıntılı bir düzeyde öğeleri saklamak veya tüm girişi geçersiz önbellek mekanizması değiştirmek zorunda ya.

Bu temelde tek bir önbellek-girişte tüm DB önbelleğe konum söyleyerek aynı. Bunu sona ya da yoktur.