1

几天前我参加了中/高级PHP开发人员的面试(我失败了)。有人问我这个棘手的问题仍然困扰着我。

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

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

4

2 回答 2

2

我的选择是添加额外的缓存状态(例如“陈旧”)来标记已过期且处于更新状态的缓存条目。

因此,如果一个 php 进程从 memcached 请求缓存数据并发现其状态为“过期”,它会将状态设置为“陈旧”,从数据库中获取一个新版本并将其作为“有效”存储在 memcached 中。

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

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

于 2015-02-14T11:36:54.570 回答
2

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

多久一次(假设每小时一次?)。需要多长时间(假设30m)

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

相反,您在后台、线程、另一台机器、cron 作业中执行查询(例如:每 1 小时运行一次查询以提供新结果)。查询完成后,您可以在系统运行期间一直写入 memcache。

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

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

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

希望这是有道理的!

于 2015-02-14T10:20:48.807 回答