结论:点赞接口必须用 redis 抗并发、异步落库,禁止直写 mysql;article:like_count:{id} 用 string 原子计数,article:liked_by:{id} 用 set 管理用户状态,php 用 predis pipeline 实现原子操作,定时同步需校验、分批、带时间戳,redis 不可替代 mysql 持久化。

直接说结论:不要在点赞接口里同步写 MySQL,必须用 Redis 先扛住并发,再异步落库;否则热门文章一上首页,数据库连接池就爆了。
Redis 用什么结构存点赞数和用户状态
两个 key 分开管,别塞进一个 Hash 里硬扛所有逻辑:
-
article:like_count:{article_id}:用INCR/DECR做原子计数,类型是 String。这是你前端显示的“XX 人点赞”来源,快且线程安全 -
article:liked_by:{article_id}:用 Redis Set 存已点赞的user_id,比如SADD article:liked_by:123 456。查“我点没点”就SISMEMBER article:liked_by:123 456,O(1) 响应
不用 Hash 存状态,是因为 Hash 的 field 不能做成员存在性判断(HGET 返回 null 不代表没点过,可能是点过又取消),而 Set 天然支持 SISMEMBER + SREM + SCARD,语义清晰、操作原子。
PHP 怎么连 Redis 并做点赞/取消的原子操作
用 Predis 客户端(比原生 Redis 扩展更易处理 pipeline 和事务):
$redis = new Predis\Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => 'your_pass',
'database' => 0,
]);
<p>// 点赞(带防重)
$pipe = $redis->pipeline();
$pipe->sAdd('article:liked_by:'.$article_id, $user_id);
$pipe->incr('article:like_count:'.$article_id);
$result = $pipe->execute();</p><p>// 取消点赞(同样原子)
$pipe = $redis->pipeline();
$pipe->sRem('article:liked_by:'.$article_id, $user_id);
$pipe->decr('article:like_count:'.$article_id);
$result = $pipe->execute();
</p>
注意:pipeline 不等于事务,但对这两个操作足够了;真要强一致性(比如防止超赞),得用 WATCH + MULTI,但实际中 SADD/SREM 本身已幂等,够用。
定时把 Redis 数据写回 MySQL 的坑在哪
不是简单地 SELECT * FROM article WHERE id IN (...) 再 UPDATE 就完事:
- 别用
SCARD当最终点赞数 —— Redis 可能有脏数据(如用户删号后没清理 Set),要以数据库为准做校验 - 写回时用
INSERT ... ON DUPLICATE KEY UPDATE,主键设为(article_id, user_id),避免重复插入或丢失取消动作 - 定时任务别卡死:用
SCAN游标分批读article:liked_by:*,每次最多取 1000 个 key,防止 Redis 阻塞 - 记录最后同步时间戳到 MySQL 表里,下次只扫新增的点赞 key,别全量扫
示例 SQL:
INSERT INTO article_like (article_id, user_id, created_at) VALUES (?, ?, NOW()) ON DUPLICATE KEY UPDATE updated_at = NOW();
为什么不能只靠 Redis 持久化
Redis 是缓存,不是数据库。哪怕开了 AOF + RDB,以下情况仍会丢数据:
- 服务器断电且 AOF 未刷盘(默认每秒刷一次,可能丢 1 秒数据)
- 内存淘汰策略触发
maxmemory-policy,误删了点赞 key(尤其用allkeys-lru时) - 运维误操作
FLUSHALL或配置错误导致 DB 编号错乱
所以点赞关系表(article_like)必须存在,且字段要有 created_at 和 updated_at,用于对账和补漏 —— 这不是备胎,是底线。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











