携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
前言
本系列主要从基础知识,而后进阶,再逐步深入 Redis 的原理分析,以保证对 Redis 的学习深入浅出,学以致远并输出自己对 Redis 学习和了解的成果。本系列将划分四个部分:
为什么使用 Redis
- 提高服务性能,因 redis 的操作基本都是在内存中,从 redis 中获取数据比从数据库更快
- 并发情况下,直接操作数据库可能出现问题。将 redis 作为缓冲作用。
使用 Redis 的缺点
- 缓存和数据库双写一致性问题
- 缓存雪崩问题
- 缓存击穿问题
- 缓存的并发竞争问题
单线程的 Redis 为什么这么快
- 操作都是在内存中
- 拥有高效的数据结构,如哈希表,跳表
- 单线程避免了因多线程之间竞争或切换产生性能开销,且无死锁问题
- Redis 采用的非阻塞 I/O 多路复用机制,从而使得读写不再阻塞
单线程的处理能力应该比多线程差,但 Redis 因以上原因所以反而会更快
其实在 redis 6.0 之后增加了多线程
Redis 的数据类型,以及每个数据类型使用场景
- 字符串类型 string,场景:常规使用,也支持一些复杂的记述功能的缓存
- 列表类型 list,场景:简单消息队列功能, 利用 lrange 命令做基于 redis 的分页功能
- 哈希类型 hash,场景:存储结构化对象
- 集合类型 set ,场景:存储不重复值的集合
- 有序集合类型 zset ,有序集合多了 score 可按 score 进行排序。 场景:排行榜,排序使用
Redis 与数据库双写一致性
数据一致性问题,若要求强一致性,则不能放在缓存内。如果没有要求强一致性场景下,采用正确的更新策略:先更新数据库,再删除缓存。
缓存穿透、缓存击穿、缓存雪崩
-
缓存穿透
- 查询某个 key 时不存在,缓存不命中,则需要在数据库中查询,若数据库中不存在则将无法更新缓存(某key 缓存无,数据库也没有)
- 解决方案:预设值 null ,若为null 则无需查询数据库,避免请求访问到数据库的情况
-
缓存击穿
- 某热点 key 在并发且高峰期环境时,突然失效,将导致所有请求都请求到数据库,从而导致数据库压力增大
- 解决方案:后台异步监控该热点key ,若过期了,重新设置该 key的值
-
缓存雪崩
- 缓存过期时间集体失效,导致大量数据无缓存,请求时直接请求到数据库
- 解决方案:1、失效时间随机,每个缓存失效时间再加个随机值;2、设置缓存不过期
Redis 并发竞争问题
Redis 中提供事务机制,仅针对是同一服务下进行批量命令操作时使用事务机制,保证操作的原子性。在微服务环境下,若多个服务都去 set 某 key的值,事务就不合适。
所以可以使用分布式锁,服务抢到锁就进行 set 操作
Redis 过期策略以及内存淘汰机制
过期策略:Redis 采用的是定期删除+惰性删除策略
默认每 100ms 随机抽查 key 是否过期,过期就会删除。但只有定期删除无法保证所有的 key 都被删除,所以再加上惰性删除,每次你获取某个 key 的值都会检查其是否过期,如果过期了就会删除。
当然也会出现 key 定期删除没有被删除,也没有再被访问 ,这样就会一直留在内存中,就会导致内存越来越高,所以又使用内存淘汰机制。
maxmemory-policy volatile-lru
Redis 提供多种内存淘汰机制配置,不同的淘汰机制。比较推荐的是 allkeys-lru :内存不足写入新数据是,在所有 key 中,移除最近最少使用的
volatile-lru: 内存不足写入新数据时,在设置里过期时间的 key 中移除最近最少使用的。
主从复制的原理详解
- 从库启动时会向主库发送 sync 命令
- 主库收到命令就会执行 RDB 持久化,后续的指令缓存起来
- 快照完后就会将快照和缓存的指令都发送给从库
- 从库接收到指令后就会载入快照文件并执行缓里的命令
- 之后主库接收到写命令都会同步给从库
RDB 和 AOF 持久化的原理
RDB 快照方式
- redis 使用 fork 函数从主进程复制并创建一个子进程
- 子进程进行持久化工作,将内容写入硬盘
- 子进程写入所有数据后会用该临时文件替换旧的 RDB 文件
AOF 持久化,是将 redis 执行的那个命令都追加到磁盘文件中,恢复的时候只需要执行该命令文件完成持久化
Redis 哨兵机制,如何实现故障恢复自动化
哨兵的作用
- 监控主库和从库的状态
- 通知其他各哨兵主从库和自身的消息状态
- 当主库出现奔溃时,就会自动实现恢复
自动化恢复故障步骤:
- 将从库升级为主库
- 通知客户端主库变更
- 其他从库重新指向新的主库
- 将之前主库变更为从库,并执行新的主库
参考资料:
- cnblogs.com/rjzheng/p/9096228.html
- [准备面试|Redis]- 主从复制 - 掘金
- [准备面试|Redis]- 哨兵模式 - 掘金