同时调用Memcache

时间:2015-02-14 10:11:26

标签: php mysql caching memcached high-load

我几天前接受过中/高级PHP开发人员的采访(我失败了)。我被问到一个棘手的问题仍困扰着我。

想象一下,我们使用 PHP + Memcached 和极其负载的项目(大约每秒100次点击或更多)。我们要执行巨大的SQL查询,因此我们决定将其缓存在Memcached中。现在缓存已经过期了,我们需要再次执行那个巨大的查询来缓存它,但问题是所有100个用户同时进入网站 ,所以理论上服务器会进行100次SQL查询同时将其缓存后,我认为服务器会停机。

我们怎么解决这个问题?我认为查询应该执行一次,另外99个人应该留下并等待Memcached中存在的数据。

2 个答案:

答案 0 :(得分:1)

  
    

我们有大量的SQL查询要执行,

  

多久(让我们假设每小时?)。 需要多长时间(假设30米)

首先,没有人(客户端,服务器,php,用户)应该触发使查询发生的事件。您不希望前端有任何与服务页面请求阻止有关的内容。

相反,您在后台,线程,另一台计算机,cron作业中执行查询(例如:每隔1小时运行一次查询以提供新的结果)。查询完成后,您可以在系统运行时写入内存缓存。

这样,没有页面请求会导致查询触发(从而阻止),此外,您可以稳定/一致地处理先前的100个请求。

此外,您不会在mysql中执行100个查询副本。它将并行执行一些(阻塞其余的),但是其他90个查询都将命中sql查询缓存,因此它不会真正运行查询100次。

我怀疑你是否想在这个地方工作。

希望这有意义!

答案 1 :(得分:1)

我的选择是添加额外的缓存状态(例如,#34; stale")以标记已过期且处于更新状态的缓存条目。

因此,如果php进程从memcached请求缓存数据并发现其状态为"已过期",则会将状态设置为" stale",从中获取新版本数据库并将其存储为"有效"在memcached中。

如果另一个php进程使用" stale"来访问缓存的数据状态,它将简单地使用陈旧版本,但不会从数据库中获取新版本。

现在,如果你想要挤出最后一点性能,第一个php进程本身并不会获取新数据,而是会将此任务委托给另一个实例(例如rabbitmq)并返回陈旧的数据。