深色模式
Redis 与缓存设计
面向全栈岗位的语言无关基础。先口述定义与场景,再解释一致性、性能和故障边界;产品特有行为会明确标注。
1. Redis 常见数据类型如何映射业务?
展开答案与追问
参考答案: String 用于计数和简单值,Hash 表达字段集合,List 表达有序序列,Set 表达唯一集合,Sorted Set 表达带分数排序,Stream 表达可读取的事件流。选择取决于操作模式、数据规模和一致性要求。
追问与易错点: 类型对应内部编码会随大小及版本变化,不要把业务类型等同于唯一内部结构。数据类型
2. Redis 为什么常有较低延迟?
展开答案与追问
参考答案: 内存访问、合适的数据结构、网络处理与较少的协调开销共同起作用。常见核心命令执行路径以串行执行为主,但 I/O、持久化和后台工作可能使用其他线程或进程。
追问与易错点: “Redis 是单线程”不能推导为全部工作只有一个线程;大命令、脚本和慢网络仍可能增加延迟。
3. 过期策略与内存淘汰有什么区别?
展开答案与追问
参考答案: TTL 表达数据在时间上的有效期,系统通过访问时检查及后台清理等方式处理过期键;淘汰是在内存压力下按策略移除数据。未到 TTL 的键也可能被淘汰,过期并不要求那一毫秒立即物理回收。
追问与易错点: TTL 不是可靠的精确定时任务服务。淘汰策略
4. LRU、LFU 与 noeviction 如何选择?
展开答案与追问
参考答案: LRU 倾向淘汰较久未访问的数据,LFU 倾向低频数据,noeviction 达到限制后可能拒绝需要新增内存的写入。还需区分 allkeys 与仅带过期时间键的策略范围,基于命中率与内存指标选择。
追问与易错点: Redis 的相关策略存在近似采样实现,不能默认每次都维护精确全局排序。
5. 缓存穿透、击穿、雪崩有什么区别?
展开答案与追问
参考答案: 穿透是查询无效数据持续落到数据库;击穿是热点键失效引发集中回源;雪崩是大量键失效或缓存服务故障导致广泛回源。可分别评估输入校验/短期空值、请求合并/热点刷新、TTL 抖动/限流降级。
追问与易错点: 布隆过滤器存在假阳性,并需处理数据更新;不能用它作为最终存在性与权限判断。
6. Cache Aside 如何更新缓存?
展开答案与追问
参考答案: 读取先查缓存,未命中查数据库再填充;写入常先提交数据库,再使缓存失效。这个流程简单但不是强一致协议,还会遇到并发旧值回填、失效失败和副本延迟。
追问与易错点: 可按一致性目标引入版本、可靠失效事件、TTL 和补偿;延迟双删不能保证所有竞态消失。
7. 如何处理缓存失效失败?
展开答案与追问
参考答案: 提交数据库后删除缓存失败,可能留下旧值。可用事务内写出的 outbox 事件驱动可靠重试,辅以缓存 TTL、版本校验和监控;要求强一致的数据不应仅凭可能过期的缓存做最终决策。
追问与易错点: 先明确允许陈旧多久,再设计修复窗口;数据库与 Redis 之间普通两条命令不是原子事务。
8. RDB 与 AOF 如何取舍?
展开答案与追问
参考答案: RDB 在时间点保存快照,AOF 记录写入以恢复状态;两者在恢复时间、写入与重写成本、数据丢失窗口上有不同取舍,常可组合使用。实际持久性取决于 fsync 策略、部署及故障类型。
追问与易错点: 不能说启用 AOF 就绝不丢数据,也不能把重写简单等同于清空日志。持久化
9. Redis 复制、Sentinel 与 Cluster 各负责什么?
展开答案与追问
参考答案: 复制维护主副本关系;Sentinel 提供主从部署中的监控与故障切换协调;Cluster 通过槽位分片并提供相关故障处理。复制常为异步,故障切换可能丢失部分已确认写入。
追问与易错点: Cluster 多键操作需要关注键槽约束;高可用不等于无限可用或强一致。复制
10. Pipeline、MULTI/EXEC 与 Lua 有什么不同?
展开答案与追问
参考答案: Pipeline 批量发送以减少往返,不提供事务隔离;MULTI/EXEC 将排队命令集中执行,WATCH 可检测冲突;Lua 可在服务端执行相关逻辑并避免命令间被其他客户端插入。脚本应短小,错误也不自动回滚之前的写入。
追问与易错点: Redis 事务不是关系数据库式任意错误自动回滚。事务语义
11. Redis 分布式锁的最低要求是什么?
展开答案与追问
参考答案: 获取锁应使用带唯一持有者标记和过期时间的原子条件写入;解锁需原子检查标记再删除。租约过期后旧持有者可能仍在运行,关键资源应考虑可被目标系统验证的 fencing token 或其他强约束。
追问与易错点: 单主异步复制切换可能破坏互斥;续租和 Redlock 都需要明确故障假设,不能当作无条件正确。锁的边界
12. 大 key 与热 key 如何发现和治理?
展开答案与追问
参考答案: 大 key 指体积或元素数量造成高资源成本,热 key 指访问过于集中;应结合命令延迟、采样、键大小和访问分布定位。按访问方式拆分数据、限制单次操作、控制热点刷新,必要时使用本地缓存或请求合并。
追问与易错点: 拆分可能损失原子性;生产环境不应为排查而全量阻塞扫描,删除大值也需考虑异步释放能力。
13. Redis 能不能直接当消息队列?
展开答案与追问
参考答案: List、Pub/Sub、Streams 提供不同模型。Pub/Sub 不保留离线补收能力,通常是至多一次投递;Streams 可结合消费组、确认与待处理记录建立重试流程,但业务仍需处理重复、积压与毒消息。
追问与易错点: “已读到”不等于“业务已成功”;可靠性需求高时还要比较专门消息系统。Pub/Sub
14. 如何用 Redis 做限流?
展开答案与追问
参考答案: 固定窗口计数容易在边界放出突发,滑动窗口更平滑但存储/计算成本更高,令牌桶允许受控突发。计数与过期等组合操作应保证必要原子性,并确定按用户、租户还是接口限流。
追问与易错点: 缓存不可用时选择放行还是拒绝取决于业务,不能给所有接口统一策略。
15. 缓存命中率很高,为什么接口仍然慢?
展开答案与追问
参考答案: 可能是网络 RTT、连接池排队、序列化、大响应、热点单节点或命中后的其他依赖耗时。应拆分端到端耗时与 Redis 服务端命令耗时,同时查看尾延迟、错误和流量分布。
追问与易错点: 只看平均值或总命中率可能掩盖少量热点请求;用链路追踪连接前后端证据。