Php 当缓存过期时,如何防止应用程序对数据库进行DDoS攻击?
我们有一个高流量的网站,很像StackOverflow,在memcache中有对象缓存。该网站是用PHP(CodeIgniter)和MySQL构建的 每次作为每个页面加载一部分的缓存对象上的TTL(生存时间)过期时,此时的所有页面加载都会导致对数据库的查询,从而有效地对数据库执行DDOS 是否有某种方式只让一个页面加载重新获取数据,而让其他页面加载等待第一个页面加载更新缓存Php 当缓存过期时,如何防止应用程序对数据库进行DDoS攻击?,php,mysql,codeigniter,caching,memcached,Php,Mysql,Codeigniter,Caching,Memcached,我们有一个高流量的网站,很像StackOverflow,在memcache中有对象缓存。该网站是用PHP(CodeIgniter)和MySQL构建的 每次作为每个页面加载一部分的缓存对象上的TTL(生存时间)过期时,此时的所有页面加载都会导致对数据库的查询,从而有效地对数据库执行DDOS 是否有某种方式只让一个页面加载重新获取数据,而让其他页面加载等待第一个页面加载更新缓存 我的第一个想法是使用随机化器,让一些页面加载获取数据,让其他页面在重新检查缓存之前等待一秒钟。但是肯定有更好的方法。如果您
我的第一个想法是使用随机化器,让一些页面加载获取数据,让其他页面在重新检查缓存之前等待一秒钟。但是肯定有更好的方法。如果您可以控制后台任务,例如cronjobs,那么您可以安排在要求的时间之前完成工作并获取数据,以便最近的数据永远不会从缓存中出来
例如,您可以让作业每20分钟运行一次(或者每分钟运行一次),更新缓存的值。当该作业运行时,不需要其他数据库查询来获取数据。您可以从以下代码中使用我的算法:
因此,只有一个进程将从DB中读取新值。为了澄清我的答案,我将编写一些代码来说明我的想法(无论如何,这可能是一个解决方案……):
所涉及的唯一风险是在同一时间出现两次页面点击,这可能会使缓存重新生成两次。这是非常不可能的,但如果发生这种情况,至少所有其他请求仍在等待 +1用于缓存考虑!但是,这会导致多个额外的查询,因为您会让其他请求轮询数据库,直到您将页面标记为“重新链接到缓存”为止。请参见。@eggyal这里有很多有趣的想法,谢谢。这是个好主意。实际上,我们已经在为页面加载时间太长而无法接受的请求执行此操作。事实上,我可以让一个cronjob定期检查每个缓存项的TTL,并提前几秒钟刷新它们。谢谢。缓存锁定的概念对我来说是新概念。我会看看是否可以将此解决方案应用到我们的应用程序中。谢谢,如果我理解正确,这与其他人所说的缓存锁定基本相同。
if ($this->cacheExpired()){
if (!$this->isMarkedAsRegenerating())
{
$this->markAsRegenerating(); //..ing
$this->regenerateCache();
$this->markAsCacheRegenerated(); //..ed
} else {
while ( $this->isMarkedAsRegenerating() )
{
sleep(1); //sleep 1 second to decrease database-queries, we are preventing a DDOS you know...
}
}
}
$this->output(); //at this point, we always have a cached version of the page