你能帮我解决我的问题吗?我有一些缓慢的 mysql 查询,所以我将其结果缓存到内存缓存中。
我做这样的事情:
$data = get_from_cache();
if (! $data) {
$data = get_from_mysql();
set_cache($data);
}
问题。 有时我每秒大约有 10 个请求。因此,当我的缓存过期时,我有 5-10 个 get-requests 同时启动这个缓慢的 mysql 查询。
你能为我推荐一种模式,让我在 php 中创建一个互斥体,或者类似的东西,只对 mysql 执行一个缓慢的请求。
最佳答案
这就是众所周知的狗堆问题。 Strategy: Break Up The Memcache Dog Pile 描述了两种方法:
解决方案一:
- 将缓存项的过期时间设置在未来。
- 嵌入用值序列化的“真实”超时。例如,将项目设置为 24 小时后超时,但嵌入的超时可能是 future 五分钟。
- 在从缓存中获取数据时,确定过时超时是否已过期,并在过期时立即设置 future 的时间并按原样重新存储数据。这关闭了风险窗口。
- 从数据库中获取数据并使用最新值更新缓存。
解决方案 2:
- 在 memcached 中创建两个 key :过期时间比正常时间稍长的 MAIN key + 一个提前过期的 STALE key 。
- 在读取 STALE key 时也是如此。如果stale已经过期,重新计算并重新设置stale key。
关于php - 并发写入内存缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17026858/