当前位置: 首页 > news >正文

Redis不同场景下的注意事项

Redis常见的 使用场景:

  • 缓存系统(核心场景)
    • 存储热点数据,减少数据库访问压力。提升接口响应速度。
    • 技术点:
      • 用String/Hash 存储结构化数据
      • 结合过期时间(TTL)和缓存淘汰策略(如LRU)管理内存。
      • 解决缓存问题:穿透(布隆过滤器)、击穿(互斥锁)、雪崩(随机过期时间)。
  • 计数器与限流
    • 实时统计高频变动的值,或限制接口访问访问频率。
    • 技术点:
      • 用String存储单计数器(INCR )。
      • 用HASH存储多维计数器(HINCRBY user:100 stats:likes 1)
      • 限流可结合Expire自动重置技术(如 INCR limit:ip:192.168.1.1 + EXPIRE … 60)。
  • 消息队列
    • 实现简单的异步通信,解耦生产者和消费者。
    • 技术点:
      • 用List模拟队列:LPUSH(生产)+ RPOP(消费),或阻塞版本BRPOP避免空轮询。
      • 缺点:无消息确认机制,需要结合确认机制,需结合AOF持久化减少丢失风险;高级需求(如延时队列)需要额外设计。
  • 排行榜与实时排名
    • 作用:根据分数动态排序,商品销量榜,用户贡献榜。
    • 技术点:
      • 用Sorted Set存储:ZADD rank:game user:100 95(用户 100 分数 95),ZRANGE rank:game 0 9 WITHSCORES 取前 10 名。
      • 支持分数自增(ZINCRBY),适合动态更新排名。
  • 分布式锁
    • 作用:在分布式系统中保证临界资源的互斥访问(如库存扣减、订单创建)
    • 优化:使用Redisson框架,支持自动续期、公平锁、可重入等高级特性。
  • 用户行为分析
    • 记录用户行为状态,快速统计群体特征。
    • 技术点:
      • 用BitMap存储每日登录状态:SETBIT login:20201001 user:100 1(用户100在20201001登录)通过BITOP作位运算统计活跃用户。
      • 用SET存储用户标签:SADD tag:view:goods100 :100,通过交集(SINTER)找共同标签用户。
  • 地理信息服务
    • 作用:存储地理位置,实现附近搜索,距离计算等功能;
    • 技术点:
      • 用Geospatial命令:GEOADD shops 116.40 39.90 shop:1 存储经纬度,GEORADIUS shops 116.40 39.90 5 km 查找 5 公里内的商家。
  • 会话存储
    • 作用:存储用户登录状态(如Session、Token),支持分布式系统共享会话。
    • 技术点:
      • 用String存储Session/Token:SET session:user100 ”xxx“EX 7200(2小时过期)。
      • 结合EXPIRE自动销毁过期会话,减轻服务器存储压力。

缓存场景

缓存关键问题:数据一致性、可用性、内存效率。同时规避缓存常见风险(如穿透、击穿、雪崩)。

  1. 缓存穿透:避免”不存在的数据“,穿透到数据库。
    问题本质:请求查询 不存在的数据,导致缓存无法命中。所有请求都直接打到数据库,导致数据库压力骤增。
    解决方案

    • 空值缓存:数据库给查询为空时,可以将空值存入缓存。并设置较短的过期时间。避免重复穿透。 恶意攻击会导致内存膨胀。
    • 布隆过滤器:在缓存前加一层布隆过滤器,将数据库中存在的key提前存入过滤器,请求先过过滤器。
    • 参数校验:接口层直接拦截非法参数(如id<0,非预期格式的key),从源头阻断无效请求。
  2. 缓存击穿:避免热点key过期,导致数据库瞬间过载。

    • 问题本质:某个高频访问的热点key过期瞬间大量请求同时命中失效的缓存,全部穿透到数据库,造成数据库“瞬间峰值”。
    • 解决方式:
      • 互斥锁(分布式锁):缓存未命中时,只有一个请求能获取锁并查询数据库,其他请求自选等待(或直接返回默认值),避免“并发穿透。注意:锁过期时间需要大于数据库查询时间,防止锁提前释放导致并发问题;同时注意避免死锁。
      • 热点key永不过期
        • 业务层不设置TTL,通过后台定时任务(如Cron脚本主动更新(如每小时更新商品信息)。
        • 若数据需要实时更新,壳子啊数据变更时主动SET命令覆盖缓存,而非TTL过期。
      • 过期时间错开:对同类热点key设置随机过期时间(如基础过期时间+5~8分钟随机值)。
  3. 缓存雪崩问题,避免大量key集体过期/集群宕机导致数据库崩溃
    问题本质
    同一时间段内大量缓存key集中过期,请求全部穿透到数据库。
    Redis缓存集群整体宕机,缓存层整体失效。所有请求直接打向数据库。
    解决方法

    • 针对大量key同时过期:给每个key设置随机过期时间。分散过期时间。
    • 针对集群宕机:
      • 缓存使用集群高可用
      • 多级缓存:在Redis之前使用本地缓存(如:Caffeine、GuavaCache),即使Redis宕机本地缓存也可以暂代部分请求,减轻数据库压力。
      • 熔断降级:通过监控工具(如Prometheus+Grafana)实时检测数据库压力。当压力超过指定阈值时,出发熔断(直接返回默认值或错误提示),避免数据库崩溃。
      • 流量控制:结合网关做接口限流,限制单位时间内的请求量。

数据一致性

缓存与数据库 尽量保持一致,避免缓存存旧数据,数据库存新数据 的矛盾场景。

  1. 选择合适的 更新策略
  2. 处理缓存更新失败问题:
    • 若数据库更新成功,但删除缓存失败,会导致缓存残留旧数据。解决方案:
      • 重试机制:删除缓存失败后,通过 本地重试机制或消息队列 异步重试(如将”删除缓存任务存入队列中,失败后重新消费),确保缓存最终被删除。
      • 版本号+时间戳:缓存中存储“数据+版本号”,查询时对比数据库版本号,若缓存版本低则主动更新。

相关优化

Redis是内存数据库,需合理管理内存,避免内存溢出 性能下降。

  1. 缓存key的设计:
    • 简洁且唯一:用“业务前缀+唯一标识”格式(如user:session:1001、goods:detail:abc123)避免key冲突
    • 避免过长:key过长会增加内存占用。
    • 避免大量小key,大量零散的小key会浪费内存(如 user💯name、user💯age)建议使用Hash合并(如 user:100 {name: “xxx”, age: 20})。
  2. 合理配置淘汰策略:当Redis内存到达maxmemory阈值时,需通过淘汰策略释放内存,避免OOM内存溢出。需根据业务选择策略:
    • 核心策略推荐:
      • LRU:淘汰 最近最少使用的key(适合热点数据场景,如商品详情),对应配置 maxmemory-policy allkeys-lru(所有 key 中选 LRU)或 volatile-lru(只在设置了 TTL 的 key 中选 LRU)。
      • LFU:淘汰最近访问频率最低的key(适合长期低频访问数据,如历史订单)。对应配置:allkey-lfu或volatile-lfu。
    • 避免使用的策略:
      • noeviction(默认):内存满时,直接拒绝写请求,会导致业务报错,除非是只读场景。
      • random:随即淘汰,可能淘汰热点数据,不推荐。
  3. 控制缓存粒度与过期时间。
    • 缓存粒度不宜过粗过细:
      • 过粗:导致缓存数据冗余,更新世需全量替换,浪费带宽和内存。
      • 过细:将对象每个属性单独存储,导致 key数量增加,和查询次数增多。
      • 建议:按“业务查询维度”设计粒度,缓存对象采用聚合数据。
    • 过期时间合适

监控与运维

  • 核心指标:需要实时监控Redis的缓存命中率(目标>=95%),内存使用率、key过期数量、数据库访问量等。当指标异常时(如命中率骤降、内存超阈值) 及时告警。
    • 工具推荐:Prometheus+Grafana、Redis Insight。
  • 持久化配置:若缓存数据需要重启后恢复(如热点商品缓存),需要开启AOF和RDB持久化‘
    • 优先使用AOF+RDB混合持久化。AOF保证数据不丢失(每秒刷盘),RDB用于数据快速恢复。
    • 若缓存数据可重建(如数据库重新加载),可关闭持久化,减少IO操作。
http://www.dtcms.com/a/357132.html

相关文章:

  • 如何在FastAPI中玩转全链路追踪,让分布式系统故障无处遁形?
  • 【golang长途旅行第34站】网络编程
  • c++ template
  • Vue2+Element 初学
  • LRU 内存淘汰策略
  • 【51单片机定时1秒中断控制流水灯方向】2022-11-14
  • Geocodify 的 API
  • 以技术赋能强化消费者信任,助推餐饮服务质量提质增效的明厨亮灶开源了
  • 有鹿机器人:用智能清洁重塑多行业工作方式
  • Centos卸载anaconda
  • 微服务Eureka组件的介绍、安装、使用
  • 音频转音频
  • 数据结构:快速排序 (Quick Sort)
  • 数据结构(C语言篇):(五)单链表算法题(上)
  • Linux笔记13——shell编程基础-7
  • More Effective C++ 条款16:牢记80-20准则(Remember the 80-20 Rule)
  • Java泛型使用常见报错
  • Stream API 讲解
  • 上传文件到本地
  • LeetCode Hot 100 第8天
  • 医疗 AI 的 “破圈” 时刻:辅助诊断、药物研发、慢病管理,哪些场景已落地见效?
  • 174. Java 注释 - 声明注释类型
  • 《AI智脉速递》2025 年 8 月22 日 - 29 日
  • VS2022+QT6.7+NetWork(TCP服务器多客户端助手)
  • Rust 登堂 之 深入Rust 类型(六)
  • 如何打造团队协作型 IP,而非单人依赖型?
  • BugKu Web渗透之file_get_contents
  • Kotlin中回调函数的使用示例
  • Git-Git和TortoiseGit的安装以及使用
  • 云渲染云推流助力WebGL应用网页端无负担推流,摆脱终端加载缓慢问题