Redis常见面试题总结(下)
大约 5 分钟
Redis常见面试题总结(下)
1. Redis 事务
1.1 什么是 Redis 事务?
Redis 事务是一组命令的集合,可以一次性按顺序执行。
- 事务特点:
- 批量操作按顺序执行。
- 不支持部分回滚:即使某个命令失败,其他命令仍然会执行。
1.2 如何使用 Redis 事务?
- 开启事务:
MULTI - 执行命令:事务中的命令会被加入队列,暂不执行。
- 提交事务:
EXEC,批量执行命令。 - 放弃事务:
DISCARD,清空队列。
示例:
MULTI
SET key1 "value1"
SET key2 "value2"
INCR key3
EXEC1.3 Redis 事务支持原子性吗?
- 单个命令是原子的:Redis 保证单个命令的原子性。
- 事务整体不是原子的:如果某条命令失败,其他命令仍然会执行。
优化建议:可以使用 Lua 脚本来实现原子操作。
1.4 Redis 事务支持持久性吗?
- Redis 事务的执行依赖于内存,不具备持久性。
- 需要结合 RDB 或 AOF 持久化机制,才能保证数据安全。
1.5 如何解决 Redis 事务的缺陷?
使用 Lua 脚本:
- Lua 脚本在 Redis 中是原子的,可以替代事务处理。
- 示例:
-- Lua 脚本,检查 key 是否存在后设置值 if redis.call("EXISTS", KEYS[1]) == 0 then return redis.call("SET", KEYS[1], ARGV[1]) else return nil end
合理设计业务逻辑:
- 减少事务中命令的复杂度,避免失败。
2. Redis 性能优化(重要)
2.1 使用批量操作减少网络传输
- Redis 性能的瓶颈之一是网络传输。
- 使用批量操作(如
MSET、MGET)代替多次单条命令。
示例:
-- 多条命令
SET key1 "value1"
SET key2 "value2"
-- 批量操作
MSET key1 "value1" key2 "value2"2.2 大量 Key 集中过期问题
问题:大量 Key 同时过期会导致 Redis 卡顿。
解决方案:
- 过期时间随机化:
- 设置 Key 时,过期时间加入随机值:
SET key "value" EX 300 + RAND
- 设置 Key 时,过期时间加入随机值:
- 分批删除:
- 通过业务层分散过期时间。
2.3 Redis bigkey(大 Key)
问题:大 Key(单个 Key 存储过多数据)会导致操作时间过长。
解决方案:
- 避免大 Key:拆分大 Key 为多个小 Key。
- 操作前先检查 Key 大小:
DEBUG OBJECT key_name - 逐步删除大 Key:
- 如果需要删除大 Key,可以使用
SCAN或分批操作。
- 如果需要删除大 Key,可以使用
2.4 Redis hotkey(热 Key)
问题:某些 Key 被频繁访问,导致 Redis 性能下降。
解决方案:
- 分散热 Key:
- 为热 Key 添加随机前缀。
- 使用本地缓存:
- 对热 Key 使用本地缓存(如 Guava Cache)。
2.5 慢查询命令
查看慢查询:
CONFIG SET slowlog-log-slower-than 10000 -- 设置慢查询阈值(10 毫秒)
SLOWLOG GET 10 -- 查看最近 10 条慢查询优化建议:
- 使用索引或分片,减少慢查询。
2.6 Redis 内存碎片
问题:频繁的内存分配和回收会产生碎片。
解决方案:
- 定期优化内存:
MEMORY PURGE - 合理配置内存管理参数:
jemalloc是 Redis 默认的内存分配器,可以高效管理内存。
3. Redis 生产问题(重要)
3.1 缓存穿透
问题:请求大量不存在的 Key,直接打到数据库,导致压力过大。
解决方案:
- 缓存空值:
- 将不存在的 Key 缓存为特殊值。
- 布隆过滤器:
- 提前过滤掉不存在的 Key。
3.2 缓存击穿
问题:热点 Key 过期时,瞬间大量请求打到数据库。
解决方案:
- 设置热点 Key 永不过期:
- 使用定时任务更新缓存。
- 加分布式锁:
- 只允许一个请求更新缓存,其余请求等待。
3.3 缓存雪崩
问题:大量缓存同时过期,导致请求直接打到数据库。
解决方案:
- 过期时间随机化:
- 避免大量 Key 同时过期。
- 双缓存机制:
- 使用两个缓存,互为备份。
3.4 如何保证缓存与数据库的一致性?
问题:更新数据库后,缓存未及时更新。
解决方案:
- 先更新数据库,再删除缓存:
- 缓存中的旧数据可被删除,保证一致性。
- 消息队列同步更新:
- 使用 MQ 保证数据一致性。
3.5 哪些情况可能会导致 Redis 阻塞?
- 大 Key 操作:如
DEL或LRANGE大 Key。 - 慢查询:复杂命令如
SORT或ZUNIONSTORE。 - 内存不足:Redis 频繁触发内存回收。
解决方案:
- 避免大 Key,优化慢查询,合理设置内存。
4. Redis 集群
4.1 Redis 集群模式
Redis 提供两种集群模式:
- 主从模式:
- 一个主节点多个从节点,主节点负责写,从节点负责读。
- 分片集群:
- 将数据分片存储在多个节点,适合大规模数据场景。
示例:
# 查看节点状态
CLUSTER NODES
# 添加从节点
CLUSTER REPLICATE <master-node-id>4.2 Redis 使用规范
- 使用合适的淘汰策略:
- 如
allkeys-lru或volatile-lru。
- 如
- 避免频繁大操作:
- 拆分大 Key,分批操作。
- 设置过期时间:
- 避免数据长期占用内存。
- 监控和报警:
- 监控慢查询、内存使用等关键指标。
总结
- Redis 事务:事务不具备完全的原子性,但可以用 Lua 脚本解决。
- 性能优化:通过批量操作、分散过期时间、热 Key 处理等提高性能。
- 生产问题解决:
- 缓存穿透:使用布隆过滤器。
- 缓存击穿:加分布式锁。
- 缓存雪崩:随机化过期时间。
- 集群使用:主从模式适合读写分离,分片模式适合大规模数据场景。
- 内存管理:避免大 Key 和热 Key,监控内存碎片。
