一、Redis基础数据类型与底层架构
在回答 Redis面试题答案 中的基础问题时,面试官通常关注Redis为何如此高效,以及其底层数据结构的设计哲学。Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
String(字符串)
String是Redis最基本的类型。你可以理解成与Memcached一模一样的类型,一个Key对应一个Value。
- 底层实现: SDS(Simple Dynamic String)。相比C语言的字符串,SDS提供了常数复杂度的长度获取、防止缓冲区溢出、减少修改字符串长度带来的内存重分配次数。
- 应用场景: 缓存、计数器(如点赞数)、分布式锁(setnx)、会话共享。
- 面试考点: 为什么SDS比C字符串好?(二进制安全、可缓存长度、减少内存重分配)。
示例:设置过期时间
SET key value EX 60示例:自增
INCR key
Hash(哈希)
Hash是一个键值对集合。Redis Hash是一个String类型的field和value的映射表,hash特别适合用于存储对象。
- 底层实现:
- 节点数据少于配置(hash-max-ziplist-entries 512)且值长度小于配置(hash-max-ziplist-value 64)时,使用ziplist(压缩列表)。
- 否则使用hashtable(哈希表)。
- 应用场景: 用户信息存储(ID、姓名、年龄),只需存储部分字段时比String更节省空间。
ZSet(有序集合)
ZSet和Set一样是String类型的集合,但不能重复。不同的是每个元素都会关联一个double类型的分数(score),集合通过score进行排序。
- 底层实现: 跳跃表(SkipList)+ 哈希表(Hash Table)。跳跃表提供了有序扫描能力,哈希表提供了快速查找能力。
- 应用场景: 排行榜(如视频热度榜)、延迟队列(利用score作为时间戳)。
- 面试考点: 为什么用跳表而不用红黑树?(跳表实现更简单,范围查询性能更好,CPU缓存命中率更高)。
二、Redis持久化机制:RDB与AOF深度解析
持久化是 Redis面试题答案 中的高频考点。Redis提供了两种持久化方式:RDB(快照)和AOF(追加文件)。现代Redis通常建议开启AOF,或者两者结合使用。
| 特性 | RDB (Redis Database) | AOF (Append Only File) |
|---|---|---|
| 原理 | 定期将内存中的数据集快照写入磁盘。 | 以日志形式记录每一个写操作,重启时重放日志。 |
| 恢复速度 | 快(文件小,加载快)。 | 慢(文件大,需重放大量命令)。 |
| 数据安全性 | 低(可能丢失最后一次快照后的数据)。 | 高(取决于fsync策略,最多丢失1秒数据)。 |
| 磁盘I/O | fork子进程进行写盘,可能引起主进程暂停。 | 持续写入,I/O操作频繁,但可通过rewrite优化。 |
1. RDB 触发机制
2. AOF 重写(Rewrite)
AOF文件会越来越大,Redis提供BGREWRITEAOF命令。原理是fork子进程,读取当前内存数据,用一条SET命令表示一个key的最终状态,生成新的AOF文件,替换旧文件。
三、缓存三大问题:穿透、击穿、雪崩
这是 Redis面试题答案 中最具实战意义的部分。面试官通常会追问解决方案及其底层原理。
① 缓存穿透
定义: 查询不存在的数据,请求直达数据库。
解决方案:
- 布隆过滤器: 在缓存前加一层过滤器,拦截不可能存在的数据。
- 缓存空对象: 将查询结果为null的key也缓存起来,设置较短过期时间。
② 缓存击穿
定义: 某个热点key在过期瞬间,大量请求并发访问,导致数据库压力剧增。
解决方案:
- 互斥锁: 获取数据时,如果缓存失效,先加锁,再查库回写,其他线程等待。
- 逻辑过期: 不设置TTL,在value中设置逻辑过期时间,异步更新缓存。
③ 缓存雪崩
定义: 大量key在同一时间过期,或Redis服务宕机。
解决方案:
- 随机TTL: 设置过期时间时加上一个随机值,避免集中过期。
- 高可用: 搭建Redis集群(Sentinel或Cluster)。
- 限流降级: 使用Hystrix或Sentinel进行服务降级。
四、Redis集群架构与主从复制
随着数据量增长,单机Redis无法满足需求,集群化部署成为必然。
1. 主从复制(Master-Slave)
- 作用: 数据冗余、故障恢复、读写分离(从节点只读)。
- 过程:
- 从节点连接主节点,发送SYNC命令。
- 主节点启动后台保存(RDB),并缓存新命令。
- 主节点发送RDB文件给从节点,从节点加载。
- 主节点发送缓存命令给从节点,完成同步。
2. Redis Cluster
Redis 3.0引入的分布式方案,去中心化,无代理层(No Proxy)。
数据分片
使用哈希槽(Hash Slot)。Redis Cluster有16384个槽,数据分布在槽中。通过 CRC16(key) % 16384 计算key属于哪个槽。
故障转移
基于Gossip协议。主节点宕机,从节点发现后发起选举,多数派同意则从节点晋升为主节点。
五、Redis分布式锁:Redlock与实现细节
分布式锁是 Redis面试题答案 中考察系统设计能力的重要环节。
1. 基础实现(SETNX + EXPIRE)
使用 SETNX key value 加锁,EXPIRE key seconds 设置过期时间。但这两个操作不是原子的,如果SETNX成功但EXPIRE失败,会导致死锁。
优化: 使用 SET key value NX EX seconds 一条命令完成加锁和设置过期时间。
2. 看门狗机制(Watchdog)
如果业务执行时间超过锁的过期时间,如何保证锁不释放?Redisson引入了看门狗机制,后台线程会定期检查锁是否被持有,如果持有则自动续期。
3. Redlock算法
为解决单点故障,Redis作者提出Redlock算法:向N个独立的Redis实例申请锁,只有当在超过半数实例获取成功且总耗时小于锁有效期时,才认为加锁成功。这提高了可用性,但增加了复杂性。