Önbellek temizlemeyi takmanın bir yolu var mı?


16

Büyük bir kurum web sitesi için, ağır önbelleklerle, mümkün olan en kısa sürede önbellek oluşturmak istiyorum, böylece hiçbir kullanıcı önbellek üretimine ulaşamaz ...

Birkaç dakika çalıştırarak ve kritik sayfalar talep ederek bunu yapan her dakika ayarlanmış bir cronum var, ancak aradığım şey önbelleğin ne zaman temizlendiğini , tercihen bir kanca olduğunu bilmenin bir yoludur , bu yüzden bunu başlatabilirim üretme fonksiyonları.

Herhangi bir fikir ?


Neyi başarmaya çalıştığınıza bağlı olarak, phayes'in sayfadaki cevabı, önbellekler temizlendikten sonra kodu atmak için güzel bir çözümdür.
Lester Peabody

Yanıtlar:


7

Drupal 7.x'te yok ama bu yeterli bir kişi istedikten sonra çekirdek bir kanca olarak eklendi , Drupal 8.x'de hook_rebuild . Sorununuzu 7.x'te çözmenin daha iyi bir yolu olabilir - cron önbelleği temizledikten hemen sonra bir tür önbellek ısınma işlevi başlatmaya çalışıyorsunuz, değil mi? Buna yaklaşmanın bir başka yolu, cronun nasıl çalıştığı konusunda önemli iyileştirmelere sahip olan ancak kullanım durumunuzla ilgili olabilecek iki tane olan Elysia cron'u kullanmak olacaktır :

Elysia Cron, Drupal standart cronunu genişleterek her görev üzerinde ince bir tahıl kontrolü ve sitenize özel cron işleri eklemenin çeşitli yollarını sağlar.

  • Her cron görevinin zamanlamalarını ve sıklıklarını ayarlayın (her gün belirli bir saatte bazı işleri, diğerlerini sadece aylık vb. Çalıştırabilirsiniz ...). Her görev için, sık kullanılan bazı seçenekler ("günde bir kez", "ayda bir kez") arasından seçim yapabilir veya doğru zamanlamaları ayarlamak için güçlü bir "linux crontab" benzeri sözdizimi kullanabilirsiniz. Site yapılandırmasını hızlandırmak için sık kullandığınız seçenekleri bile tanımlayabilirsiniz. ...
  • Görev yürütme önceliğini / sırasını değiştirin. ...

Eski önbellek sorununu çözmeye yardımcı olmak için cron'unuzun nasıl çalıştığı üzerinde daha iyi kontrol sahibi olmak için bu modülü kullanabilirsiniz. Özellikle, yeniden oluşturma işlevlerinize cron'a bir kanca ekleyebilir ve daha sonra Elysia cron'u kullanarak bu işlemleri önbellek temizleme işleminden hemen sonra çalışacak şekilde ayarlayabilirsiniz.

Ayrıca, sık sık önbelleğin çok sık yeniden oluşturulmasına yol açan cron ile ilgili sorunlar yaşıyor olabilirsiniz gibi geliyor. Bu durumda, Elysia cron'daki belirli önbellek temizleme işlemini, cron işlemlerinizin geri kalanından farklı bir hızda çalışacak şekilde ayarlayabilirsiniz; örneğin, arama dizine ekleme her 5 dakikada bir güncellenir, ancak tam önbellek temizliği yalnızca her 6 saat vb.

Cron önbellek yönetimine ince ayar yapın: drupal cron, her cron çalıştırmasında değişken önbelleği geçersiz kılacaktır ve sık aranan bir göreviniz varsa bu büyük bir performans sorunudur. Elysia cron önbellek yönetimini optimize eder ve önbelleği geçersiz kılmak zorunda değildir.


Bu gerçek bir serseri. Çabuk D8! Aslında, sana dediğim gibi, elysia_cron'lu bir cron her dakika koşuyorum, ihtiyacım olanı ısıtıyor. Ancak sitemin 10.000'den fazla ziyaret / saat olacağı için, sbdy'nin boş önbelleklere düşeceğinden eminim ... Her neyse, şimdi bir D7 sınırlaması olduğunu biliyorum!
Gregory Kapustin

12

Bunu yapmanın yolu hook_flush_cachesile birlikte kullanmaktır register_shutdown_function. Örnek kod:

/**
 * Implements hook_flush_caches().
 */
function mymodule_flush_caches() {
   // After caches are cleared we will run mymodule_cache_rebuild()
   register_shutdown_function('mymodule_cache_rebuild');

   // We don't want to add any custom cache-tables, so just return an empty array
   return array();
}

/**
 * Rebuild expensive cache items that need to be rebuilt immediately.
 */
function mymodule_cache_rebuild() {
  // Do the cache rebuild work here
}

Kullanmak , önbellek temizlendikten sonra önbellek register_shutdown_functionyeniden oluşturma işlevimizin çağırılacağı anlamına gelir . Asla kullanılmayacak şekilde kötüye kullanıyoruz, ancak bu tam olarak ihtiyacınız olanı yapmalı.hook_flush_caches


Bu çözümü gerçekten çok seviyorum. Kendim kullanmadan önce, Drupal'da kullanarak bilinen herhangi bir sorunu / çatışmayı aradım register_shutdown_function()ve Drupal çekirdeğinin drupal_register_shutdown_function () : "Bilinmeyen bir yığın çerçevesi olmadan atılan istisna" önlemek için atılan istisnaları yakalayan Wrapper . I yapar biliyorum beni daha iyi hissediyorsun abusing hook_flush_cachesbunu yapmak için sadece Drupal çekirdek işlevlerini kullanıyorum eğer.
runswithscissors

11

Hayır, yok. Pek sayılmaz. En azından 6 veya 7'de değil.

Eğer drupal_flush_all_caches()bakacaksanız onu çağırdığını göreceksiniz hook_flush_caches(). Bu kanca:

"Performans sayfasındaki Temizle düğmesiyle veya drupal_flush_all_caches çağrıldığında temizlenecek önbellek tabloları listesine önbellek tablosu adları ekleyin."

Modülünüzün kancasını sonlandırmak ve oraya kod yazmak cazip olurdu. Ama tekrar bakalım drupal_flush_all_caches(). Gerçek silme şu şekilde gerçekleşir:

  $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
  foreach ($cache_tables as $table) {
    cache_clear_all('*', $table, TRUE);
  }

Bu, herhangi bir şey gerçekten temizlenmeden önce tüm kancaların ateşlendiği anlamına gelir . Orada, fiili silindikten sonra denilen tek fonksiyonudur _system_update_bootstrap_status(), ancak yalnızca aramaları hook_boot, hook_exit, hook_watchdogve hook_language_init- önbellek-net bağımlı işlevsellik sağlamak için sadece uygulamak istemiyoruz kanca.


Lanet olsun, tüm bu bağlantıları eklemem uzun sürdü;) Neden yapılamadığını açıklamak için çok fazla zaman geçirdikten sonra kendimi silmeye zorlayamadığım için şimdilik bırakacağım .
Mołot

3
Bırakın, iyi bir cevap.
mpdonadio

Evet bırakın, tüm iyi cevapları kontrol edemiyorum ama ben yükselttim :)
Gregory Kapustin

8

Burada geniş vuruşlar:

D8 öncesi bir kanca olmasa da, standart olana dayalı olarak kendi veritabanı arka ucunuzu DrupalDatabaseCacheyazabilir ve daha sonra clear()işlevinize her türlü mantığı yazabilirsiniz . Hızlı bir bakış module_invoke_all(), bunun D7'de makul bir şekilde basit olmasını önerir (sadece özel adınıza sınıfı kopyalayın ve uygun şekilde atarak vb. Değiştirin ) ve cache_backport modülü ile D6'da bile çalışacaktır. Ardından, süslenmesini istediğiniz önbellek kutularını net bir şekilde işaretleyin ve yola çıkmalısınız.


3
Bu muhtemelen en iyi çözümdür, sadece 'sorun' birden fazla önbellek bölmesine (memcache, redis, vb.) Sahipseniz birkaç önbellek sınıfını genişletmenizdir. Yine de buna değer
Clive

Memcached, apc veya diğer db olmayan çözümlerde önbellek ile çalışmaz mı?
Mołot

Redis kullanıyorum, işe yarayacağından emin değilim.
Gregory Kapustin

Eğer drupal.org/project/redis kullanıyorsanız , özel bir modülde sağlanan sınıfları vb. Kopyalayabilir veya başka bir şekilde değiştirebilmeniz ve bunun yerine bunları kullanabilmeniz gerekir. Yine de, Pantheon platformunun çizgileri boyunca, redis için tüm ağır kaldırmayı sağladıkları bir şey kullanıyorsanız, evet, tüm bunlar hakkında onlarla koordinasyon yapmanız gerekir.
Jimajamma

3

Eğer için kaynak bakarsak drupal_flush_all_caches()veclear_cache_all() , hiçbir kanca oldukça böcek çekilir gibi değil sonrası takas çağrılan olduğunu göreceksiniz.

Bir kullanıcının hiçbir zaman bazı önbellek girişlerinin oluşturulmasını beklemek zorunda kalmayacağını garanti etmek çok zordur, bu yüzden mümkün olduğunca tam önbellek temizlemelerinden kaçınmaya çalışırım.

Gerçekten yardımcı olan bir yöntem, yalnızca ileriye dönük önbellekleri temizleyen ve menülere, kayıt defterine ve benzer çekirdek önbelleklere dokunmayan bir gönderme işleyicisini bağlamak için performans sayfasını değiştirmektir. Menü ve kayıt defteri yeniden oluşturma tam bir önbellek yeniden oluşturmak için yaklaşık yarım zaman alır gibi, bu ile iyi sonuçlar elde ettim.

Başka bir şey drupal_http_request()tüm URL'lerimi (sadece önemli olanlar değil) yapan bir drush betiği var, böylece her şey önbelleğe alınır. Bunun nasıl yapılacağı siteye göre değişir. Bazen sadece yayınlanan düğümleri EFQ yapabilir ve URL'leri bu şekilde oluşturabilirim. Diğer durumlarda, URL'nizi almak için XML site haritası tablolarını sorgulayabilirsiniz. Sonra bunu sistem cronumdan istediğim sıklıkta çağırıyorum.


1

Birkaç seçenek:
https://www.drupal.org/project/cache_graceful tam olarak istediğiniz şey olabilir.

https://www.drupal.org/project/apdqc , önbelleği temizleyen ve açıklığı değiştirmenize drupal_alter('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);izin veren ve açıklığa tepki vermenize izin veren 2 kancaya sahiptir module_invoke_all('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);. APDQC'nin düzgün çalışmasını $conf['apdqc_call_hook_on_clear'] = TRUE;sağlayın ve settings.php dosyanızda ayarlayın ve önbellek temizliği yapıldığında kancalar çağrılmalıdır.


1

Bu herkes için uygun olmayabilir ve OP için yeterince hızlı olmayabilir - çünkü sadece bir sonraki sayfa başlangıcında tetiklenir. Ancak, zaman duyarlı olmayan bir "önbellek tümünü temizle" hemen sonra kodu tetiklememe yardımcı oldu.

Açıkçası HOOKkendi modül adınızla değiştirilmesi gerekiyor.

/**
 * Implements hook_init().
 */
function HOOK_init(){
  // if there is no cache_not_empty defined, define it 
  // and then trigger our cache cleared code
  if ( !cache_get('HOOK_cache_not_empty') ) {
    cache_set('HOOK_cache_not_empty', TRUE);
    foreach (module_implements('cache_cleared') as $module) {
      module_invoke($module, 'cache_cleared');
    }
  }
}

/**
 * Implements hook_cache_cleared().
 */
function HOOK_cache_cleared(){
  // do what you need here, in which ever module.
}

Hedeflemeniz gereken belirli bir bölmeniz varsa, tüm bölme önbelleğinizin temizlendiği noktada boşaldığı sürece yukarıdakiler bunu destekleyecek şekilde değiştirilebilir.

hook_inityalnızca önbelleğe alınmamış sayfalar için yürütülür. Tam bir önbellek temizliği önbelleğe alınmış sayfa olmaması anlamına gelmesine rağmen, bu bir soruna neden olmamalıdır. Bununla birlikte, Vernik gibi harici önbellek sistemleri bu tetiklemenin önüne geçecek ve sadece bir sonraki uygun istek Drupal'a geri döndüğünde gerçekleşeceği anlamına gelecektir.

Ayrıca, önbellek sisteminize bağlı olarak - tam olarak cache_seteşzamanlı kullanıcılar için tam olarak kullanılabilir olduğunda - bu çağanozun, özellikle çok sayıda kullanıcınız varsa, aynı anda birden çok kez tetiklenebileceğine dikkat edilmelidir.


0

Bir müşterinin "tüm önbellekleri temizle" düğmesine bastığında hem Drupal hem de Vernik önbelleklerini temizlemek istediği benzer bir ihtiyacım vardı. Bunu yapmak için o menü öğesini kaçırdım.

Bu, cron veya başka herhangi bir yerde önbellek temizliğini etkilemez - sadece menü bağlantısında.

/**
 * Implements hook_menu_alter().
 */
function mymodule_menu_alter(&$items) {
  if (isset($items['admin_menu/flush-cache'])) {
    $items['admin_menu/flush-cache']['page callback'] =
      "_mymodule_custom_flush_cache";
  }
}

/**
 * Hijacks the "flush all caches" button in menu
 */
function _mymodule_custom_flush_cache() {
  /**
   * Clear varnish, or other logic here
   */
  admin_menu_flush_cache(); //Run the normal cache clearing stuff
}

Thx Travis, ama ben sadece bir kullanıcı tarafından volontarly tetiklenen değil, herhangi bir açık önbellek kanca bir yol arıyorum.
Gregory Kapustin

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.