一、Redis是单线程的?先别急着下结论!(🚨易错点预警)

很多同学张口就来"Redis是单线程模型",这其实是个经典误区!!!Redis 6.0之后其实引入了多线程网络IO处理(注意是网络IO部分!)。主流程还是单线程处理命令的(划重点),这样既保证了原子性,又提升了网络吞吐量。

(面试坑点)当面试官问"Redis为什么快"时,千万别只说单线程,要展开说:

  1. 基于内存操作
  2. IO多路复用模型
  3. 高效的数据结构
  4. 6.0后的多线程网络处理

二、五大基础数据结构:别只会用String!

1. String(最常用但最容易被轻视)

  • 常规用法:缓存验证码、计数器
  • 高级玩法:SET key value EX 60 NX 实现分布式锁(注意要配合Lua脚本保证原子性!)

2. Hash(对象存储神器)

  • 用户信息存储经典案例:
HSET user:1001 name "王大力" age 28 tags "java,redis"
  • 千万注意字段数量控制!!!超过500个要考虑分拆(内存优化重点)

3. List(消息队列的备胎方案)

  • 左进右出做队列:LPUSH + BRPOP
  • 右进右出做栈:RPUSH + BRPOP
  • (注意)生产环境建议用专业的MQ,别拿Redis当主力队列!

4. Set(共同好友统计利器)

  • SINTER 求交集:共同关注的好友
  • SUNIONSTORE 并集存储:合并标签
  • 突发奇想:用 SPOP 实现随机抽奖功能

5. ZSet(排行榜必备)

  • 经典操作:ZINCRBY hotNews:202311 1 "某明星离婚"
  • 范围查询:ZREVRANGE hotNews:202311 0 9 WITHSCORES 取TOP10
  • 冷知识:底层是跳表+字典,插入时间复杂度O(logN)

三、持久化方案:RDB和AOF的相爱相杀

1. RDB快照(内存快照)

  • 优势:紧凑二进制文件,恢复速度快
  • 致命伤:可能丢失最近一次快照后的数据
  • 配置建议:save 900 1 表示900秒内1次修改就触发

2. AOF日志(追加写操作)

  • 写后日志设计:先执行命令再记录(可能丢失一个命令)
  • 重写机制:BGREWRITEAOF 瘦身AOF文件
  • 同步策略:
    • always:每个命令都刷盘(安全但性能差)
    • everysec:每秒刷盘(折中方案)
    • no:交给操作系统(危险但快)

3. 混合持久化(Redis 4.0+)

  • 结合RDB和AOF优势:AOF文件包含RDB头+AOF日志
  • 重启加载时先加载RDB部分,再重放AOF
  • 开启方式:aof-use-rdb-preamble yes

四、缓存三大经典问题:穿透、雪崩、击穿

1. 缓存穿透(查询不存在数据)

  • 解决方案:
    1. 布隆过滤器拦截(存在误判率)
    2. 缓存空值:SET null 60
    3. 接口校验(比如ID<0直接拦截)

2. 缓存雪崩(大量key同时失效)

  • 预防措施:
    • 随机过期时间:EXPIRE key 3600 + random(600)
    • 热点数据永不过期 + 后台更新
    • 集群部署避免单点故障

3. 缓存击穿(热点key突然失效)

  • 终极方案:互斥锁
if redis.call('exists', KEYS[1]) == 0 then
    if redis.call('setnx', 'lock_key', 1) == 1 then
        redis.call('expire', 'lock_key', 10)
        -- 查数据库
        return db.query()
    else
        -- 等待重试
        return redis.call('get', KEYS[1]) 
    end
end

五、分布式锁的进阶玩法

1. 基础版SETNX方案

SET lock:order 1 EX 30 NX

(常见坑点)一定要设置过期时间!防止死锁

2. RedLock算法(分布式版)

  • 获取多数节点锁才算成功
  • 需要至少3个独立Redis实例
  • 时钟同步问题可能导致锁失效(争议点)

3. 锁续期方案

  • 看门狗机制:获取锁后启动线程定期续期
  • 推荐使用Redisson客户端(内置看门狗)

六、高频灵魂拷问:Redis如何保证高可用?

1. 主从复制

  • 异步复制存在数据丢失风险
  • repl-backlog-size 配置复制缓冲区大小

2. 哨兵模式

  • 至少3个哨兵节点
  • 主观下线和客观下线机制
  • 故障转移时的配置纪元(config epoch)

3. Cluster集群

  • 数据分片采用CRC16算法
  • 每个节点维护部分slot(16384个)
  • MOVED重定向和ASK重定向的区别

七、性能优化实战技巧

1. 内存优化三把斧

  • 使用ziplist编码的Hash/List
  • 控制key长度(别用超长业务字段)
  • 启用内存淘汰策略:maxmemory-policy allkeys-lru

2. 慢查询定位

  • slowlog get 10 查看最近10条慢查询
  • 配置阈值:slowlog-log-slower-than 10000(单位微秒)

3. 管道化操作(Pipeline)

  • 网络往返次数从N次降为1次
  • 但要注意单个Pipeline的命令数量(建议不超过1000)

八、扩展题:当面试官突然抛出…

Q1:Redis事务为什么不支持回滚?

(神回答)因为作者觉得:

  1. 命令错误在入队时就能发现
  2. 运行时错误通常是业务逻辑问题
  3. 保持简单高效的设计哲学

Q2:Redis怎么实现延时队列?

  • 方案1:ZSET + 时间戳做score
  • 方案2:BRPOPLPUSH 备份队列
  • 方案3:Stream 数据类型(Redis5.0+)

Q3:大Key问题怎么处理?

  • 发现工具:redis-cli --bigkeys
  • 拆分方案:Hash分拆成多个key
  • 删除技巧:UNLINK替代DEL(异步删除)

看完这篇还拿不下Redis面试?建议直接把这篇文章打印出来贴在床头(开玩笑)!最后提醒:理论结合实践才是王道,赶紧动手搭个Redis集群试试吧~

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐