我几天前接受过中/高级PHP开发人员的采访(我失败了)。我被问到一个棘手的问题仍困扰着我。
想象一下,我们使用 PHP + Memcached 和极其负载的项目(大约每秒100次点击或更多)。我们要执行巨大的SQL查询,因此我们决定将其缓存在Memcached中。现在缓存已经过期了,我们需要再次执行那个巨大的查询来缓存它,但问题是所有100个用户同时进入网站 ,所以理论上服务器会进行100次SQL查询同时将其缓存后,我认为服务器会停机。
我们怎么解决这个问题?我认为查询应该执行一次,另外99个人应该留下并等待Memcached中存在的数据。
答案 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)并返回陈旧的数据。