Büyük siteler için bellek tasarrufu sağlayan önbellek temizleme stratejileri?


30

Drupal 7 sitelerimden birinde binlerce alan, bir sürü içerik türü, 25 görünümden fazlası ve yüzlerce (yakında binlerce) profil türü var. Bu nedenle, varlık alanı bilgilerini daha iyi önbelleğe alan bir çekirdek düzeltme eki (http://drupal.org/node/1040790) ve görünümleri görüntüleyerek daha iyi önbelleğe alan Görünümlerin -dev sürümünü kullanıyorum (bir HUGE'a sahip olmak yerine) önbellek satırını, içindeki tüm görünüm verileriyle birlikte görüntüler).

Bu, sitedeki çoğu sayfanın 160 MB + yerine 20 - 30 MB RAM kullanmasına yardımcı oldu (10 MB + olan alanlar ve görünümler için önbellek_ * tablo satırları almak yerine yamalar önbellek_ * verilerinin çok daha verimli tutulmasına yardımcı oldu).

Ancak bu, önbellek yeniden oluşturma işlemlerinin gerçekten çok uzun sürdüğü bir sorunu ortaya koyuyor . Genellikle bir iki dakikadan fazla. Ve bu süre zarfında, Drupal basitçe herhangi bir sayfa yüklemeyecektir (okumaya çalıştığı önbelleklerin henüz oluşturulmadığı için diğer isteklerin beklemesi gerekir).

Düşük trafik döngüsü sırasında bu önemli bir şey değil; Yüzlerce kullanıcı sadece sayfa yüklenmeden önce bir dakika beklemek zorunda kalacak. Ancak, yoğun trafik sırasında Apache sunucusu 40+ CPU yüküyle çıldırmaya başlar ve tüm çalışan iş parçacıkları beklemeye girip belleklerini değiştirerek bellek değiştirmeye neden olur. Bir çeşit ölüm spirali. Bir httpd yeniden başlatılması işleri temizleyecektir, ancak işlerin normale dönmesi 5-10 dakika sürer.

Amacım, önbelleklerin siteyi dizlerine çekmemesi için temizlemektir. Birincisi, admin_menu'nun bireysel önbellek temizleme işlevlerini kullanırsam ("CSS ve JS", sonra "Menü", sonra "Tema kayıt defteri", vb.), "Sayfa ve diğer" seçeneğine basana kadar işler düzgün gider. Bu, görünümlerin önbelleği sıfırlandığında (önbelleklenmesi gereken görünüm sayısıyla çok CPU ve veritabanı yoğun bir işlem) ve alan bilgisi önbelleği sıfırlandığında (bu site de CPU ve veritabanı yoğun olur).

Yani ... benim soru / fikirlerim:

  • Sarhoş ve / veya diğer kabuk komut dosyalarını kullanarak, önbellekleri "tüm önbellekleri bir kerede patlatmak ve temiz bir yeniden oluşturma umudundan" daha akıllıca temizlemek mümkün mü?
  • Önbellek temizliği yapılırken http isteklerini engelleyebilir miyim, böylece apache bir miktar önbellek damgalama isteğiyle tıkanmaz.
  • Drupal / normal httpd isteğinin dışındaki önbellekleri temizleyebilirsem, önbellek temizleme işlemi için daha yüksek bir PHP memory_limit ayarlayabilirim ve evrensel memory_limit'imi devre dışı bırakabilirim (şu anda herhangi bir httpd iş parçacığının önbelleğe alınması gerekiyorsa, şimdi 256 MB olarak ayarlanmış olabilir) ...).

Temel olarak: Kullanıcı arayüzündeki düğmeye tıklamanın yanı sıra Drupal ile tüm önbellekleri temizlemenin akıllıca ve zarif bir yolu var mı drush cc all?

[ Açıklama için düzenle : Sahip olduğum ana sorun , (a) biraz zaman alan ve (b) yeniden yapılanmalar tamamlanana kadar diğer tüm istekleri engelleyen önbellek yeniden yapılandırmalarıdır. Bunu yapmanın bir yolunu bulmak istiyorum, böylece yeniden yapılanmalar yüksek trafik zamanlarında ölümcül olmayacak.]


2
İlginç soru. Önbelleğe almayı devre dışı bırakırsanız, site performansınız yeterli mi? IOW, Apache / PHP / MySQL'i, önbelleğe alma etkin olmadan çalıştırabileceği şekilde çalışacak şekilde optimize ettiniz mi? Açıkçası, sisteminizi görmedim, ancak apc.stat = 0 ayarının yapılması ve APC için yeterli belleğe sahip olduğunuzdan emin olmanız disk kullanımını azaltmanıza yardımcı olacaktır. Mysqltuner.pl kullanmak ayrıca MySQL'in darboğaz olup olmadığına dair bir gösterge verecektir. Sonra önbelleğe alma ve ince ayar yapabilirsiniz (bazı DB kullanımını artıracak, bu yüzden MySQL parametrelerini ayarlamanız gerekebilir).
mpdonadio

Görünüm önbellek tablolarını bellekte tutmak için Redis'i (memcache'ye benzer) kullanırım. Bu, yükleme sürelerini büyük ölçüde iyileştirdi. Kararlı bir sürümde "görüntüleyerek önbelleği görüntüle" özelliğine sahip olmayı dört gözle bekliyoruz, bu çok mantıklı.
uwe

@MPD - Önbelleğe almanın devre dışı bırakılması hızlıca tüm siteyi öldürür; genellikle 100-500 kimliği doğrulanmış kullanıcı ve sitenin bazı bölümleri oldukça ağırdır. Benim için en büyük sorun, önbellek okumaları değil (bunun için Memcached, Redis ve APC kullanıcı önbelleğini denedim) değil, çok fazla CPU yoğunluğuna sahip önbellek yeniden inşası.
geerlingguy

İdeal olarak, yeni önbellek yeniden oluşturulurken eski önbellek verilerini kullanmak istiyorsunuz. Bu doğru mu?
mikeytown2

@ mikeytown2 - doğru - bu ideal olurdu.
geerlingguy

Yanıtlar:


9

Kullanıcı arayüzündeki düğmeye tıklamanın yanı sıra drush cc all kullanmanın yanı sıra Drupal ile tüm önbellekleri temizlemenin akıllı ve zarif bir yolu var mı?

Önbellek eylemleri modül bunu yapmaz. Bu kurala bağlı. Örnek olarak, "x" tipi bir düğüm eklendiğinde veya güncellendiğinde belirli bir görünümü silmek için bir kural ayarlayabilirsiniz. Daha fazla bilgi için dokümanları kontrol ediniz .

Ayrıca zarif önbellek modülüne bir göz atın - henüz denemedim ama ilginç görünüyor.


Zaten drush cc [type]belirli önbellek temizliği için kullanıyorum (önbellek işlemlerine benzer), ancak önbelleği daha zarif bir şekilde temizlemenin yollarını bulmak ve diğer httpd iş parçacıklarının Apache sunucusunu öldürmediğinden emin olmakla daha fazla ilgileniyorum.
geerlingguy

1
Drush cc gibi görünüyor tüm görünümleri önbellekleri temizler. Önbellek eylemleriyle, yalnızca belirli bir görünümü veya ekranı temizleyebilirsiniz. Gösterim sürümünde muhtemelen bir hata vardır, aksi halde önbellekleri yeniden oluşturmak bir iki dakika sürmez. 7.x-3.5 görünümlerini kullanırken aynı problem mi yaşıyorsunuz? Ayrıca bir göz atın drupal.org/project/cache_graceful - henüz denemedim ama ilginç görünüyor
uwe

Views dev, önbellek okuma performansına yardımcı olmak için görünümü kendi önbellek satırlarına böler. Bu, görünümlerin önbellek oluşturmak için muhtemelen 5 kat daha fazla zaman harcadığı anlamına gelir (ancak bu, önbellekleri okurken çok fazla bellek kullanımının azaltılmasına yardımcı olur!).
geerlingguy

Özgün cevabınıza Cache Graceful hakkındaki bilgileri ekleyebilir misiniz? Belirli modül biraz yardımcı olduğu için kabul edeceğim (ancak sorunu tamamen benim için çözmüyor). Sanırım sorunumu gerçekten çözmek için daha az alan ve varlık türü kullanmak için siteyi yeniden arama yapmak zorunda kalacağım.
geerlingguy

tamam. Cache_graceful ile ilgili deneyiminizi öğrenmek isterim. Hangi kısmı tamir etmedi?
uwe

2

Asıl sorun, önbellek verilerini depolamak için MySQL kullanmanızdır - yüksek yüklenen siteler için bu çok etkili bir çözümdür.

Bunun yerine Memcache kullanmanızı öneririm . Bu, önbellek sisteminin performansını önemli ölçüde artıracak ve size 2 büyük avantaj sağlayacaktır:

  1. Memcache, MySQL'in tüm önbellek işlemlerinde (ve tam önbellek yeniden oluşturma) daha hızlı çalışacağı okuma ve yazma işlemleri için çok daha hızlıdır.
  2. Çünkü önbellek verileri artık DB’de depolanmıyor - önbellek temizliği diğer MySQL sorgularını engellemeyecek.

İşte Drupal 7 için Memcache yapılandırması örneği .


Hem memcached hem de APC'yi çeşitli şekillerde kullandım ve önbellek okumalarına büyük ölçüde yardımcı olurken, asıl sorun asıl yeniden oluşturma; web sunucusu (çok yavaş / uzun) yeniden oluşturma işlemi sırasında önbelleği damgalarken veritabanı neredeyse hiçbir şey yapmıyor.
geerlingguy

APC ve Memcached farklı şeyler yapar. Memcached'in doğru yapılandırılmasının size yardımcı olacağını düşünüyorum. BTW, sitenizi çoğunlukla isimsiz kullanıcılar ziyaret ettiğinde - Vernik kullanabilirsiniz. Bu durumda Varnish kendi önbellek sistemini kullanacak ve isimsiz istekler için Apache çalıştırılmayacak.
Eugene Fidelin

Site neredeyse% 100 kimliği doğrulanmış bir trafiğe sahip, aksi takdirde Varnish kullanmayı düşünüyorum. Bu noktada Cache Graceful modülüne bakabilirim.
geerlingguy

0

Sarhoş ve / veya diğer kabuk komut dosyalarını kullanarak, önbellekleri "tüm önbellekleri bir kerede patlatmak ve temiz bir yeniden oluşturma umudundan" daha akıllıca temizlemek mümkün mü?

Tüm önbellekleri patlatmak istemiyorsanız, şunu kullanın: drush cc type_of_cachebelirli birini silmek veya kendinizinkini tanımlamak için.

Alternatif olarak tüm önbellek benzeri tabloları manuel olarak temizleyin, örn.

echo "SHOW TABLES LIKE 'cache%'" | $(drush sql-connect) | tail -n +2 | xargs -L1 -I% echo "DELETE FROM %;" | $(drush sql-connect) -v 

Memcached (Bash sözdizimi) kullanıyorsanız, şunu deneyin:

pgrep memcached && echo flush_all > /dev/tcp/127.0.0.1/11211

Önbellek temizliği yapılırken http isteklerini engelleyebilir miyim, böylece apache bir miktar önbellek damgalama isteğiyle tıkanmaz.

drush -y vset maintenance_mode 1İnsanların siteye erişmesini önlemek için bakım modunu ( ) etkinleştirin . Veya ön ucu başka bir yere yönlendirmek için yapılandırın (örn. Varnish, Apache'ye yönlendirmek veya değiştirmek .htaccess).

Drupal / normal httpd isteğinin dışındaki önbellekleri temizleyebilirsem, muhtemelen memory_limitönbellek temizleme işlemi için daha yüksek bir PHP memory_limitayarlayabilirim ve herhangi bir bireysel httpd iş parçacığının önbellekleri temizlemesi gerekmesi durumunda evrenselimi geri alabilirim (şu anda 256 MB olarak ayarlanmış .. .).

Önbelleği temizlemek daha fazla bellek gerektirmez, ancak temizledikten sonra önbelleği yeniden oluşturmak daha fazla zaman alır. Önbellekleri her zaman cron çalıştırarak veya herhangi bir sayfayı açarak ısıtabilirsiniz, örn.

time php -n -d memory_limit=-1 time $(which drush) cc registry
PHP_OPTIONS='-d memory_limit="2G"' drush cron
php -d memory_limit=1G ./scripts/drupal.sh http://localhost/

Önbellek temizleme işlemini ek olarak hızlandırabilecek işlemi -nyoksaymayı belirtin php.ini.


-1

Muhtemelen parasal bir maliyet söz konusudur, ancak Varnish gibi bir önbellek sunucusu kurulumunu kullanabilirsiniz. Sonunda, Varnish sitenizi, kullanıcı bilgili olmadan önbellekiniz üretim sunucusundan temizlerken hizmet verecek.

Dezavantajı: VCL zaman aşımı ayarlarına göre üretim sunucusunun kaç saniye / dakika kapalı kalma süresine bağlı olarak, Varnish bu süre içinde güncellenebilir ve bir Varnish 503 hata ekranı göreceksiniz.

Ancak Redis veya Memcache ile birlikte bu yaklaşım yardımcı olabilir.


Bu soru yalnızca dahili Drupal önbellekleriyle ilgilidir; Drupal’ın önbelleklerinin yeniden yapılandırılması sonsuza dek sürdü ve Drupal’ın önündeki / önündeki ek önbellek katmanları, gerçek önbellek verilerinin yeniden oluşturulmasına yardımcı olmak için çok fazla bir şey yapmaz (web sunucusu, önbellek sırasında bir süre bekletmek için gereken bazı trafiği boşaltmanın yanı sıra) yeniden inşa edildi).
geerlingguy

Bu durumda, Zend OpCache'nin iyi çalıştığını gördüm. :-)
mulderjoe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.