Skip to content

使用Redis实现朋友圈点赞功能的步骤说明

1. 数据结构设计

  • 每条朋友圈的点赞用户集合
    键名格式:post:{post_id}:likes,类型为Set,存储所有点赞用户的ID。
    示例

    • post:123:likes → 存储用户ID user1, user2, user3
  • 每个用户点赞的朋友圈集合
    键名格式:user:{user_id}:liked_posts,类型为Set,存储用户点过赞的朋友圈ID。
    示例

    • user:456:liked_posts → 存储朋友圈ID post:123, post:456

2. 核心操作实现

2.1 用户点赞
bash
# 原子化操作:使用Lua脚本确保两个集合同时更新
EVAL "redis.call('SADD', KEYS[1], ARGV[1]); redis.call('SADD', KEYS[2], KEYS[3]); return 1;" 3 post:123:likes user:456:liked_posts post:123 456

步骤解释

  1. 将用户ID添加到朋友圈的点赞用户集合(SADD post:123:likes 456)。
  2. 将朋友圈ID添加到用户的点赞记录集合(SADD user:456:liked_posts post:123)。
  3. 使用Lua脚本保证原子性,避免部分操作失败导致数据不一致。
2.2 用户取消点赞
bash
# 原子化操作:使用Lua脚本移除两个集合中的数据
EVAL "redis.call('SREM', KEYS[1], ARGV[1]); redis.call('SREM', KEYS[2], KEYS[3]); return 1;" 3 post:123:likes user:456:liked_posts post:123 456

步骤解释

  1. 从朋友圈的点赞用户集合中移除用户ID(SREM post:123:likes 456)。
  2. 从用户的点赞记录集合中移除朋友圈ID(SREM user:456:liked_posts post:123)。
2.3 获取点赞用户列表
bash
SMEMBERS post:123:likes  # 返回集合中所有用户ID

示例输出
1) "user1" 2) "user2" 3) "user3"

2.4 统计点赞数量
bash
SCARD post:123:likes  # 返回集合元素数量

示例输出
(integer) 3

2.5 检查用户是否已点赞
bash
SISMEMBER post:123:likes 456  # 返回1(已点赞)或0(未点赞)

示例输出
(integer) 1

3. 性能优化与扩展

  • 分片存储
    若朋友圈数量极大,按post_id哈希分片(如post_shard:{hash}:{post_id}:likes)分散键存储。

  • 缓存热点数据
    高频访问的朋友圈点赞列表(如热门帖子)可缓存到本地或Redis的String类型(需序列化)。

  • 异步持久化
    通过消息队列(如Kafka)将点赞操作异步写入数据库,降低Redis压力。

4. 数据结构对比

操作命令时间复杂度适用场景
添加/取消点赞SADD/SREMO(1)快速单次操作
获取点赞列表SMEMBERSO(N)小规模数据(建议分页)
统计点赞数SCARDO(1)实时统计
检查用户是否点赞SISMEMBERO(1)动态判断

5. 完整流程图

用户点击点赞 → 调用API → Redis Lua脚本(SADD两集合) → 返回成功  
用户取消点赞 → 调用API → Redis Lua脚本(SREM两集合) → 返回成功  
前端展示 → 查询SCARD(计数)和SMEMBERS(列表) → 渲染界面

6. 异常处理

  • 网络重试
    客户端在超时后重试点赞操作,服务端通过SISMEMBER检查避免重复处理。

  • 数据一致性校验
    定时任务扫描post:*:likesuser:*:liked_posts,修复不一致数据。

总结

通过Redis的Set数据结构,结合Lua脚本保证原子性操作,能够高效实现朋友圈的点赞、取消、计数及列表展示功能。针对高并发场景,可通过分片和缓存优化性能,同时通过异步持久化和定时任务确保数据最终一致性。

文章来源于自己总结和网络转载,内容如有任何问题,请大佬斧正!联系我