Skip to content

banalord/FindFood

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

  • 此源码为FindFood点赞缓存更新策略(Redis 增量同步方案)

    一、背景与目标

    在社交系统中,点赞操作频繁,若每次点击都直接更新数据库,将导致严重的数据库压力,尤其在高并发场景下可能引发性能瓶颈甚至服务雪崩。

    本方案通过 Redis 缓存点赞增量 + 阈值触发/定时同步数据库 实现点赞数据的弱一致性缓存,以此提高系统吞吐量、降低数据库压力,并兼顾数据一致性和系统可用性。


    二、核心策略说明

    1. 弱一致性缓存设计

    点赞操作不直接更新数据库,而是先更新 Redis 中的“点赞增量”值,并在满足以下条件之一时将其同步至数据库:

    • 增量值达到指定阈值(如 50 次);
    • 定时任务每 10 分钟 检查并将现有增量统一入库。

    2. Redis Key 结构设计

    Redis Key 类型 说明
    post:{id}:like_count_delta String 帖子 {id} 点赞的增量
    post:{id}:like_count String 帖子 {id} 点赞总数缓存
    lock:post:{id} String 用于并发写入加锁

    三、具体实现机制

    1. 点赞触发逻辑 incrementLikeCount(postId)

    • 使用 Lua 脚本将以下 3 步操作合并为原子操作:
      1. INCRBY 点赞增量;
      2. EXPIRE 设置过期时间(如 12 分钟);
      3. 判断是否超过阈值;
    • 若增量达到阈值(例如 50 次),尝试加 Redis 锁(key: lock:post:{id});
    • 加锁成功后,读取增量并写入数据库;
    • 最后更新总点赞数缓存并清空 delta 增量键。

    原始版本中 incrementLikeCount0() 存在三步操作非原子性问题,可能导致重复写库或数据错乱,故已弃用。

    2. 点赞数读取逻辑 getLikeCount(postId)

    • 优先读取缓存键 post:{id}:like_count
    • 若无缓存,则读取数据库原始值 + 当前 Redis 中的点赞增量;
    • 结果写入总点赞缓存,设置过期时间(如 12分钟);
    • 返回总点赞数。

    ⚠️ 注:缓存过期策略需结合同步频率综合设置,避免频繁失效导致穿透。

    3. 定时任务:定期同步点赞增量 syncLikeCountsToMysql()

    • 每隔 10 分钟 执行一次;
    • 扫描所有 post:*:like_count_delta 的键(使用 keys);
    • 尝试为每个 postId 获取写锁;
    • 获取成功后同步 Redis 增量到数据库,并删除该增量键;
    • 最后同步总点赞数缓存。

    四、同步写入数据库逻辑

    统一调用方法 redisToMysql() 完成以下操作:

    • 使用 MyBatis-Plus UpdateWrapper 实现点赞字段自增;
    • 删除点赞增量缓存(DEL key);
    • 更新 Redis 中点赞总数缓存。
    java复制编辑updateWrapper.eq("id", postId)
                 .setSql("like_count = like_count + " + likeCountDelta);
    

    五、Redis的Key

    参数名 数值 说明
    LIKE_COUNT_DELTA 50(个点赞数) 点赞增量阈值,达到后触发入库
    LIKE_COUNT_UPDATE_INTERVAL 10 分钟 定时任务入库间隔
    LIKE_COUNT_DELTA_EXPIRE_TIME 12 分钟 点赞增量键过期时间,避免空键长期保留

    六、优缺点分析

    ✅ 优点:

    • 有效减轻数据库压力,适用于高并发场景;
    • 使用 Redis 锁+Lua 脚本,解决并发一致性问题;
    • 可拓展性强,支持分布式部署;

    ⚠️ 缺点:

    • 弱一致性:点赞数在短时间内存在延迟;
    • Redis 异常/丢失会造成增量丢失(建议搭配 AOF 或 RDB 持久化);
    • 使用 keys 命令会阻塞 Redis,后续可替换为 SCAN

    七、优化思路

    • 持久化方案增强:开启 AOF 持久化降低数据丢失风险;
    • 性能优化:定时任务使用 SCAN 替代 keys
    • 精细锁粒度:可以将 lock:post:{id} 替换为 Redisson 分布式锁;

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages