大型站点的节省内存的缓存清除策略?


30

我的Drupal 7站点中有一个拥有数千个字段,一堆内容类型,超过25个视图以及数百个(很快成千上万个)配置文件类型。因此,我正在使用一个更好地缓存实体字段信息的核心补丁(http://drupal.org/node/1040790),以及-dev版本的Views,它可以通过显示更好地缓存视图(而不是一个HUGE)视图缓存中包含所有视图数据的行)。

这已帮助站点上的大多数页面加载了20-30MB的已用RAM,而不是160MB +(不是为10MB +的字段和视图拉出cache_ *表行,这些补丁有助于使cache_ *数据保持更高的效率)。

但是,这带来了一个问题,即缓存重建需要很长时间。通常超过一两分钟。在这段时间内,Drupal根本不会加载任何页面(因为它尚未尝试读取的缓存尚未建立,因此其他请求必须等待)。

在低流量周期中,这没什么大不了的。一百个左右的用户只需等待一分钟,即可加载页面。但是在高流量周期中,Apache服务器开始发疯,CPU负载超过40,并且由于所有工作线程都处于等待状态并最大程度地占用了内存,从而导致交换,内存很快就装满了。这有点像死亡螺旋。重新启动httpd可以清除问题,但是恢复正常需要5到10分钟。

我的目标是做到这一点,以使缓存清除不会使站点瘫痪。首先,如果我使用admin_menu的单个缓存清除功能(例如“ CSS和JS”,然后是“菜单”,然后是“主题注册表”,等等),事情进展顺利,直到我点击了“ Page and else”选项。那是在重置视图的缓存时(一个非常占用CPU和数据库的操作,需要缓存视图的数量),并且在重置字段信息缓存时(在此站点上也是CPU和数据库的消耗)。

所以...我的问题/想法:

  • 使用drush和/或其他shell脚本,是否有可能比“一次清理所有缓存并希望进行干净的重建”更加智能地清除缓存?
  • 我可以在清除缓存时阻止HTTP请求,以使apache不会被一堆带有缓存标记的请求所阻塞吗?
  • 如果我可以清除Drupal /正常httpd请求之外的缓存,则可以为缓存清除操作设置更高的PHP memory_limit,并退出我的通用memory_limit(现在设置为256MB,以防任何单个httpd线程需要清除缓存) ...)。

基本上:除了单击UI中的按钮或使用之外,是否有任何智能,优雅的方式使用Drupal清除所有缓存drush cc all

[ 编辑说明:我的主要问题是缓存重建,这(a)需要一段时间,并且(b)阻止所有其他请求,直到重建完成。我想找到一种方法来使它在高流量时不会那么致命。]


2
有趣的问题。如果禁用缓存,站点性能是否足够?IOW,您是否优化了Apache / PHP / MySQL以使其能够运行并且不启用缓存?显然,我还没有看到您的系统,但是设置apc.stat = 0并确保您有足够的内存供APC使用将有助于减少磁盘使用率。使用mysqltuner.pl还可以指示MySQL是否是瓶颈。然后,您可以打开缓存并进行调整(这将增加一些数据库的使用,因此您可能需要调整MySQL参数)。
mpdonadio

我使用Redis(类似于memcache)将视图缓存表保留在内存中。这大大缩短了加载时间。期望在稳定版本中具有“按显示缓存视图”功能,这很有意义。
uwe 2012年

@MPD-禁用缓存将迅速杀死整个站点;通常有100-500个经过身份验证的用户,并且网站的某些部分非常繁琐。对我而言,最大的问题不是缓存读取(我已经尝试过使用Memcached,Redis和APC用户缓存),而是使用缓存重建功能,这非常占用CPU资源。
geerlingguy 2012年

理想情况下,您要在重建新缓存时使用旧缓存数据。它是否正确?
mikeytown2

@ mikeytown2-正确-那将是理想的选择。
geerlingguy 2012年

Answers:


9

除了单击UI中的按钮或使用drush cc all之外,是否有任何智能而优美的方法可以使用Drupal清除所有缓存?

高速缓存操作模块做到这一点。这取决于规则。例如,您可以设置规则以在添加或更新类型为“ x”的节点时清除特定视图。查看文档以获取更多详细信息。

还请看一下缓存优美的模块-尚未尝试过,但看起来很有趣。


我已经drush cc [type]用于特定的缓存清除(类似于缓存操作),但是我对寻找更优雅地清除缓存并确保其他httpd线程不会杀死Apache服务器的方法感兴趣。
geerlingguy 2012年

1
看起来drush cc将清除所有视图缓存。使用缓存操作,您仅可以清除特定的视图或显示。views开发版中可能存在一个错误,否则重建缓存将不需要一两分钟。使用View 7.x-3.5是否有相同的问题?还可以看看drupal.org/project/cache_graceful-尚未尝试过,但看起来很有趣
uwe

Views开发人员将视图显示分为自己的缓存行,以帮助提高缓存读取性能。这意味着视图可能会花费5倍以上的时间来构建缓存(但是,当大量读取缓存时,这有助于减少内存使用!)。
geerlingguy 2012年

您能否在原始答案中添加有关“缓存优美”的信息?我会接受的,因为该特定模块会有所帮助(但不能完全为我解决问题)。我认为我将不得不对站点进行一些重新配置,以使用更少的字段和实体类型来真正解决我的问题。
geerlingguy 2012年

好。我很想听听您使用cache_graceful的经历。它没有修复哪一部分?
uwe 2012年

2

主要问题是您正在使用MySQL存储缓存数据-对于高负载站点,这是非常无效的解决方案。

我建议改用Memcache。这将大大提高缓存系统的性能,并为您带来2大好处:

  1. 与MySQL相比,Memcache的读写操作要快得多-您所有的缓存操作(以及完整的缓存重建)都可以更快地工作。
  2. 由于缓存数据不再存储在数据库中-清除缓存不会阻止任何其他MySQL查询。

这是Drupal 7 的Memcache配置示例。


我已经以各种方式使用了memcached和APC,尽管它们确实对缓存读取有很大帮助,但我遇到的主要问题是实际的重建。当Web服务器在(非常慢/长)重建过程中标记高速缓存时,数据库几乎什么也不做。
geerlingguy 2012年

APC和Memcached的作用不同。我认为正确配置Memcached将对您有所帮助。顺便说一句,如果您的网站主要是由匿名用户访问的,则可以使用Varnish。在这种情况下,Varnish将使用其自己的缓存系统,并且不会对匿名请求执行Apache。
尤金·菲德林

该网站的身份验证流量几乎达到100%,否则我会考虑使用Varnish。此时,我可能会研究Cache Graceful模块。
geerlingguy 2012年

0

使用drush和/或其他shell脚本,是否有可能比“一次清理所有缓存并希望进行干净的重建”更加智能地清除缓存?

如果您不想爆炸所有缓存,请使用:drush cc type_of_cache清除特定的缓存,或定义自己的缓存。

或者,手动清除所有类似缓存的表,例如

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

如果您使用的是memcached(Bash语法),请尝试:

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

我可以在清除缓存时阻止HTTP请求,以使apache不会被一堆带有缓存标记的请求所阻塞吗?

启用维护模式(drush -y vset maintenance_mode 1)以防止人们访问该网站。或将前端配置为重定向到其他地方(例如,在Varnish中重定向,在Apache中重定向或更改.htaccess)。

如果我可以在Drupal / normal httpd请求之外清除缓存,则可memory_limit以为缓存清除操作设置更高的PHP ,并退出通用memory_limit(现在设置为256MB,以防任何单个httpd线程需要清除缓存。) )。

清除缓存不会占用更多的内存,但是清除后重建缓存会占用更多的内存。您始终可以通过运行cron或打开任何页面来预热缓存,例如

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/

指定-n忽略php.ini将进一步加快缓存清除过程的处理。


-1

可能涉及金钱成本,但是您可以使用诸如Varnish之类的缓存服务器设置。好处是,在生产服务器上清除缓存时,Varnish将为您的站点提供服务,而用户不会变得更明智。

缺点:根据生产服务器停机的秒数/分钟与您的VCL超时设置的不同,Varnish可能会在这段时间内进行更新,您会看到Varnish 503错误屏幕。

但是,这种方法与Redis或Memcache一起使用可能会有所帮助。


这个问题仅与内部Drupal缓存有关。Drupal缓存的重建花了永久的时间,Drupal外部/前面的额外缓存层对实际缓存数据的重建没有多大帮助(除了减轻网络服务器在缓存时需要保留的流量)重建)。
geerlingguy 2015年

在那种情况下,我发现Zend OpCache可以很好地工作。:-)
mulderjoe 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.