博客这类读多写少的站点,Redis 用对了收益很明显,用错了就是白白多一个要维护的服务。这篇讲三种真正值得做的用法。
用法一:整页或片段缓存
最直接也最有效的用法。对于首页、归档页这类「所有人看到的内容都一样」的页面,缓存整段 HTML:
$key = 'page:index:' . $page;
$html = $redis->get($key);
if ($html === false) {
$html = render_index($page);
$redis->setex($key, 300, $html); // 5 分钟过期
}
echo $html;关键是发布文章时主动删掉相关 key,而不是干等过期:
function on_post_publish($redis) {
foreach ($redis->keys('page:index:*') as $key) {
$redis->del($key);
}
}用法二:计数器
阅读量这类高频自增,用 Redis 顶住比直接写数据库友好得多:
INCR views:post:42再定期落库(比如每 5 分钟合并一次):
GETSET views:post:42 0这么做的好处是:即使 Redis 挂了,丢的也只是几分钟的计数,不会让页面打不开。
用法三:分布式锁
定时任务在多台机器上跑时,需要保证同一时刻只有一个在执行:
$ok = $redis->set('lock:backup', getmypid(), ['nx', 'ex' => 600]);
if (!$ok) {
exit("已有实例在运行
");
}
// ... 执行备份 ...
$redis->del('lock:backup');nx 保证只有一个能设置成功,ex 保证进程意外退出后锁会自动释放,不会永久卡死。
一个不该踩的坑
不要把 Redis 当成唯一数据源。 它默认是异步持久化的,进程崩掉可能丢最后几秒的写入。用它做缓存、计数、锁都没问题,但博客正文、评论这类数据必须落在 MySQL 里。
另外记得给 Redis 设置内存上限与淘汰策略:
maxmemory 256mb
maxmemory-policy allkeys-lru不设 maxmemory 的话,它会把宿主机内存吃光。
小结
- 缓存:读多写少,配上主动失效。
- 计数:高频自增,定期落库。
- 锁:
nx+ex组合,避免多实例冲突。
除此之外的用法,先问问自己是不是真的需要。