基础概念
1. 什么是Redis?
回答:Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,可用作数据库、缓存和消息代理。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等,并提供持久化、复制、事务等功能。
2. Redis有哪些主要特点?
回答:
- 基于内存操作,读写速度快
- 支持丰富的数据结构
- 支持持久化(RDB和AOF)
- 支持主从复制
- 支持事务
- 支持Lua脚本
- 支持发布/订阅模式
- 支持键过期策略
数据结构
3. Redis支持哪些数据类型?
回答:
- String(字符串):最基本类型,可以包含任何数据
- Hash(哈希):键值对集合,适合存储对象
- List(列表):字符串列表,按插入顺序排序
- Set(集合):无序的字符串集合,不允许重复
- Sorted Set(有序集合):与Set类似,但每个元素关联一个分数用于排序
- Bitmaps(位图):通过特殊命令操作的字符串
- HyperLogLogs:用于基数统计
- Geospatial:地理空间索引
4. Redis的String类型最大能存储多大?
回答:Redis的String类型最大可以存储512MB的数据。
持久化
5. Redis有哪几种持久化方式?
回答:
RDB(Redis Database):定时将内存中的数据快照写入磁盘
- 优点:文件紧凑,恢复速度快,适合备份
- 缺点:可能丢失最后一次快照后的数据
AOF(Append Only File):记录所有写操作命令
- 优点:数据安全性高,最多丢失1秒数据
- 缺点:文件体积大,恢复速度慢
6. RDB和AOF如何选择?
回答:
- 如果对数据安全性要求不高,可以只使用RDB
- 如果既想保证数据安全又希望快速恢复,可以同时开启RDB和AOF
- 生产环境通常建议同时开启两种持久化方式
性能与优化
7. Redis为什么这么快?
回答:
- 完全基于内存操作
- 单线程模型避免了多线程的上下文切换和竞争条件
- 使用多路复用I/O模型(epoll/kqueue)
- 高效的数据结构设计
- 直接使用C语言编写,执行效率高
8. Redis如何实现高可用?
回答:
- 主从复制:一个主节点,多个从节点,主节点负责写,从节点负责读
- 哨兵模式(Sentinel):监控主从节点,自动故障转移
- Redis Cluster:分布式解决方案,数据分片存储,自动故障转移
高级特性
9. Redis事务与数据库事务有何区别?
回答:
Redis事务与数据库ACID事务的主要区别:
- Redis事务不支持回滚(没有Rollback)
- Redis事务是批量执行命令,中间不会被其他命令打断
- Redis事务没有隔离级别的概念
- Redis事务通过MULTI、EXEC、DISCARD和WATCH命令实现
10. Redis的过期策略有哪些?
回答:
- 定时删除:设置键过期时间时创建定时器,到期立即删除(对内存友好,但对CPU不友好)
- 惰性删除:访问键时检查是否过期,过期则删除(对CPU友好,但对内存不友好)
- 定期删除:每隔一段时间随机检查并删除过期键(折中方案)
Redis实际采用惰性删除+定期删除的组合策略。
实际应用
11. Redis如何实现分布式锁?
回答:
使用SET命令的NX(不存在才设置)和PX(设置过期时间)选项:
SET lock_key unique_value NX PX 30000
解锁时需要先比较unique_value再删除,可以使用Lua脚本保证原子性。
12. Redis的缓存雪崩、缓存穿透、缓存击穿是什么?如何解决?
回答:
缓存雪崩:大量缓存同时失效,请求直接打到数据库
- 解决方案:设置不同的过期时间,使用集群降低风险,加锁或队列
缓存穿透:查询不存在的数据,每次都打到数据库
- 解决方案:布隆过滤器过滤非法请求,缓存空值
缓存击穿:热点key过期瞬间大量请求打到数据库
- 解决方案:设置热点数据永不过期,加互斥锁
13. Redis的内存淘汰策略有哪些?
回答:
- noeviction:不淘汰,内存不足时返回错误(默认)
- allkeys-lru:从所有key中淘汰最近最少使用的
- volatile-lru:从设置了过期时间的key中淘汰最近最少使用的
- allkeys-random:从所有key中随机淘汰
- volatile-random:从设置了过期时间的key中随机淘汰
- volatile-ttl:从设置了过期时间的key中淘汰剩余时间最短的
集群相关
14. Redis Cluster如何实现数据分片?
回答:
Redis Cluster使用哈希槽(16384个槽)进行数据分片:
- 每个键通过CRC16算法计算后对16384取模得到槽位
- 集群中每个节点负责一部分哈希槽
- 客户端可以直接连接到正确的节点,或通过重定向获取数据
15. Redis主从复制的原理是什么?
回答:
- 从节点执行SLAVEOF命令建立复制关系
- 主节点执行BGSAVE生成RDB文件并发送给从节点
- 从节点接收并加载RDB文件
- 主节点将后续的写命令发送给从节点
- 从节点执行这些命令保持数据同步
其他问题
16. Redis为什么选择单线程模型?
回答:
- 避免多线程的上下文切换和竞争条件
- 基于内存操作,CPU通常不是瓶颈
- 使用I/O多路复用处理网络请求
- 单线程模型更简单,易于维护
注意:Redis 6.0引入了多线程I/O(处理网络请求),但命令执行仍然是单线程。
17. Redis的Pipeline有什么作用?
回答:
Pipeline可以将多个命令打包一次性发送给Redis服务器,减少网络往返时间(RTT),显著提高批量操作的性能。但Pipeline中的命令不是原子性的。
18. Redis和Memcached有什么区别?
回答:
| 特性 | Redis | Memcached |
|——|——-|———–|
| 数据类型 | 支持多种数据结构 | 仅支持字符串 |
| 持久化 | 支持 | 不支持 |
| 集群 | 原生支持 | 需要客户端实现 |
| 线程模型 | 单线程(6.0+多线程I/O) | 多线程 |
| 内存管理 | 原生支持 | 依赖Slab Allocation |
| 适用场景 | 复杂数据结构、持久化需求 | 简单键值缓存 |
19. Redis的发布订阅模式如何工作?
回答:
- 客户端可以订阅一个或多个频道
- 发布者向频道发送消息
- 所有订阅该频道的客户端都会收到消息
- 使用PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令实现
20. Redis的Lua脚本有什么优势?
回答:
- 减少网络开销:多个命令可以打包在一个脚本中执行
- 原子性:脚本执行期间不会被其他命令打断
- 复用:脚本可以存储在Redis中重复使用
- 灵活性:可以使用复杂的逻辑处理数据
最后编辑:admin 更新时间:2025-06-07 09:52