Redis淘汰策略与性能优化

一、Redis基础知识

1. Redis是什么?
  • 基于内存的键值数据库(NoSQL),支持持久化。

  • 单线程模型(6.0+支持多线程I/O),高性能(10万+ QPS)。

  • 支持多种数据结构:字符串、列表、哈希、集合、有序集合、Stream等。

2. Redis核心数据类型与使用场景
  • String(字符串):缓存、计数器、分布式锁。

  • Hash(哈希):存储对象(如用户信息)。

  • List(列表):消息队列、最新文章列表。

  • Set(集合):去重、共同好友(交集)。

  • Sorted Set(有序集合):排行榜、带权重的队列。

  • Bitmaps/HyperLogLog/Geo:特定场景优化(如UV统计)。

  • Stream(5.0+):消息队列(类似Kafka)。

3. Redis持久化
  • RDB(快照)

    • 定时生成内存快照,文件紧凑,恢复快。

    • 缺点:可能丢失最后一次快照后的数据。

  • AOF(追加日志)

    • 记录写操作命令,支持每秒同步/每次同步。

    • 缺点:文件大,恢复慢。

  • 混合持久化(4.0+):结合RDB和AOF,重启时先加载RDB再重放AOF。

4. Redis高可用
  • 主从复制

    • 主节点(Master)写,从节点(Slave)读,异步复制。

    • 数据不一致窗口期问题。

  • 哨兵(Sentinel)

    • 监控主从节点,自动故障转移(Master选举)。

    • 解决高可用问题,但扩容困难。

  • Cluster模式

    • 分片(16384个槽),自动数据分片和故障转移。

    • 客户端直连节点,支持动态扩缩容。


二、Redis进阶知识

1. 缓存问题与解决方案
  • 缓存穿透(查不存在的数据):

    • 解决方案:布隆过滤器(Bloom Filter)、缓存空值。

  • 缓存击穿(热点Key过期):

    • 解决方案:互斥锁(分布式锁)、永不过期(逻辑过期)。

  • 缓存雪崩(大量Key同时过期):

    • 解决方案:随机过期时间、集群部署、降级熔断。

2. 内存管理与淘汰策略
  • 内存淘汰策略(8种):
    1. noeviction(默认策略)

    • 行为:内存不足时,新写入操作直接报错(OOM command not allowed when used memory > 'maxmemory')。

    • 适用场景:数据绝对不能丢失的场景(如金融核心数据),需确保内存足够或由其他机制处理溢出。

    1. volatile-lru

    • 行为:从设置了过期时间(TTL)的 Key 中,淘汰最近最少使用(LRU)的 Key。

    • 适用场景:缓存场景,允许部分数据丢失,但希望保留热点数据。

    1. volatile-lfu(4.0+)

    • 行为:从设置了过期时间的 Key 中,淘汰最不经常使用(LFU)的 Key。

    • 适用场景:需要更精确的淘汰逻辑(LFU 比 LRU 更关注访问频率)。

    1. volatile-ttl

    • 行为:从设置了过期时间的 Key 中,淘汰剩余存活时间最短(TTL 最小)的 Key。

    • 适用场景:优先淘汰即将过期的 Key,适合短期缓存数据。

    1. volatile-random

    • 行为:从设置了过期时间的 Key 中,随机淘汰一个 Key。

    • 适用场景:对淘汰逻辑无特殊要求,简单快速。

    1. allkeys-lru

    • 行为:从所有 Key 中,淘汰最近最少使用(LRU)的 Key(无论是否设置 TTL)。

    • 适用场景:纯缓存系统,所有数据都可被淘汰。

    1. allkeys-lfu(4.0+)

    • 行为:从所有 Key 中,淘汰最不经常使用(LFU)的 Key。

    • 适用场景:需要基于访问频率淘汰数据的缓存系统。

    1. allkeys-random

    • 行为:从所有 Key 中,随机淘汰一个 Key。

    • 适用场景:数据无冷热区分,淘汰任意 Key 对业务影响小。

  • 如何选择淘汰策略?
    1. 明确需求

    • 是否允许数据丢失

      • 不允许 → noeviction(需确保内存足够或使用持久化+扩容)。

      • 允许 → 其他策略。

    • 数据是否有冷热区分

      • 有 → LRULFU

      • 无 → randomTTL

    1. 典型场景推荐

    • 缓存系统(所有数据可淘汰):

      • 优先选择 allkeys-lruallkeys-lfu(保留热点数据)。

    • 混合型数据(部分数据永久有效):

      • 使用 volatile-lruvolatile-lfu,并为可淘汰的 Key 设置 TTL。

    • 短期缓存(数据自然过期):

      • 使用 volatile-ttl,自动淘汰即将过期的 Key。

    • 简单场景

      • allkeys-randomvolatile-random(性能高,但可能误删重要数据)。

    1. LRU vs LFU

    • LRU(最近最少使用):

      • 适合数据访问模式随时间变化(如新闻热点)。

    • LFU(最不经常使用):

      • 适合长期稳定的访问模式(如用户画像数据)。

  • 内存优化

    • 使用合适的数据类型(如用Hash代替多个String)。

    • 控制Key生命周期,避免BigKey(单Key数据过大)。

  • 配置方式
    maxmemory 8gb
    maxmemory-policy allkeys-lfu
3. 事务与Lua脚本
  • 事务

    • MULTI/EXEC命令,不支持回滚(非原子性)。

  • Lua脚本

    • 原子执行复杂逻辑,替代事务。

    • 示例:限流、秒杀扣库存。

4. 分布式锁
  • 实现方式

    • SET key value NX EX(原子操作设置过期时间)。

    • 避免锁误删:检查唯一标识(如UUID)。

  • RedLock算法

    • 多节点部署,半数以上节点加锁成功才算成功。


三、Redis性能优化

1. 性能瓶颈分析
  • 网络延迟、BigKey、复杂命令(如KEYS *)、持久化阻塞。

  • 监控工具:redis-cli --statINFO命令、slowlog

2. Pipeline与批量操作
  • Pipeline批量发送命令,减少RTT(Round Trip Time)。

  • 示例:Jedis的pipelined()方法。

3. 集群优化
  • 数据分片均匀,避免热点Key集中在某节点。

  • 合理设置hash tag(如{user}:1)强制Key分配到同一槽。


四、Redis常见面试题

  1. Redis为什么快?

    • 内存操作、单线程避免上下文切换、I/O多路复用。

  2. 如何保证缓存与数据库一致性?

    • 旁路缓存模式(Cache Aside)、延迟双删、订阅Binlog。

  3. Redis集群如何动态扩缩容?

    • 添加节点后使用redis-cli --cluster reshard重新分配槽。

  4. Redis的过期策略?

    • 定期删除(随机抽查)+惰性删除(访问时检查)。


五、学习建议

  1. 动手实践:部署Redis集群、模拟高并发场景。

  2. 源码阅读:单线程模型、RDB/AOF实现。

  3. 场景设计:结合业务设计缓存方案(如电商秒杀)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值