Redis学习路径、面试
2022-04-12 10:21:50 57 举报
AI智能生成
Redis学习路径、读书笔记、面试题
作者其他创作
大纲/内容
掌握数据结构和缓存使用方法
基础数据类型
String
适用简单键值对,常用语计数场景,例如点赞次数、访问次数、转发次数
Hash
适用于存储对象,需要对对象属性进行单独操作的场景
List
适合存储可重复的集合、FIFO队列场景
Set
适合存储不可重复的集合,可做交集、并集、差集运算
Sorted Set
适合存储排序类集合,例如热门排行榜、带权重评论
扩展数据类型
Bitmap
适合是否签到等场景。集合元素的取值就只有0和1
优点:节约空间
HyperLogLog
适合做基数较大统计
优点:节约空间
缺点:有一定误差
GEO
记录经纬度形式的地理位置信息
Redis用作缓存的方法
只读缓存
读写缓存
事务
原子性
MULTI命令开始;EXEC命令结束
命令会一起执行,若中途出现宕机则无法保证原子性
Lua脚步
命令
multi
事务开始
exec
事务结束
discard
取消事务,放弃执行事务块内的所有命令
watch
监视key变化,发生变化时会取消事务
unwatch
取消 WATCH 命令对所有 key 的监视
典型问题解决方案
缓存和数据库数据不一致如何解决
系统故障
产生原因
先更新数据库再更新缓存或先更新缓存再更新数据库时,其中一方更新失败
解决方案
失败时写入MQ,采用重试机制
并发
产生原因
操作数据库和缓存间隙其他线程读取数据
解决方案
先操作数据库再删除缓存情况。非强一致情况不用处理,发生概率极低。推荐
先删除缓存再操作数据库情况。采用延迟双删
缓存雪崩
含义
大量请求访问Redis未生效,直接访问到后端数据库,给数据库造成较大压力
原因
大量缓存同时过期
Redis宕机
解法
缓存过期时间加上随机数,避免缓存同时过期
搭建高可用集群
熔断、限流、降级,优先保证核心业务
缓存击穿
含义
热点数据访问Redis未生效,直接访问后端数据库,给数据库造成较大压力
原因
缓存过期
解法
针对热点数据不设置过期时间
后台通过Job更新缓存
缓存穿透
含义
Redis缓存和数据库中都没有的数据被访问
原因
后台误删数据
恶意攻击
解法
设置缺省值
使用布隆过滤器
前端进行请求检测
掌握支撑Redis实现高性能、高可用的技术
持久化机制
AOF
RDB
高可用机制
主从模式+哨兵
哨兵机制
机制
监听
选主
通知
故障自动恢复
哨兵监控
哨兵选出新主库
哨兵通知其他从库和客户端
切片集群
方案
官方Redis Cluster
通过哈希槽管理数据和实例关系
第三方Codis
精通Redis底层实现原理
数据结构实现原理
全局Hash表
Redis键值对存储在全局Hash表中,查询效率极快,时间复杂度为O(1)
通过Rehash解决因Hash冲突导致的查询效率降低的问题
String
简单动态字符串
优点
是一个种“万金油”数据结构,什么类型都可以放
缺点
元数据(记录数据长度、空间使用)占用内存较多
Hash
压缩列表
哈希表
List
压缩列表
双向链表
Set
哈希表
整数数组
Sorted Set
跳表
底层数据结构
简单动态字符串
整数数组
时间复杂度O(N)。目的是节省空间
压缩列表
时间复杂度O(N)。目的是节省空间,只有数据量少的时候才会使用
双向链表
时间复杂度O(N)
哈希表
时间复杂度O(1)
跳表
时间复杂度O(logN)。在链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位
高性能、高可用原理
持久化机制
AOF日志
记录Redis操作命令
三种写回策略
Always:写完数据马上写AOF日志,并落地到磁盘
优点:可靠性最高
缺点:性能最差
Everysec:写完数据后先写到AOF缓冲区,每秒异步线程写到磁盘
优点:对性能几乎无影响
缺点:极端情况可能有1秒数据丢失
No:写完数据后先写到AOF缓冲区,由操作系统写到磁盘
优点:性能最好
缺点:数据丢失风险最高
AOF重写
目的:减少AOF日志体量,去除已无效或重复命令
做法:从内存中拷贝一份数据,回写成新的一份AOF文件
RDB快照
记录数据
优点:恢复速度快
缺点:丢失数据较多
写回策略:固定时间内操作次数达到上线触发增量快照
Redis4.0引入混合日志
RDB固定时间做全量
AOF做增量
主从模式
目的
增加数据冗余,达到高可用
读写分离,提升性能
同步机制
第一次同步
从库清空所有数据
从库给主库发送 psync 命令
runID:从库ID
offset:偏移量,第一次为-1,表示全量复制
主库执行 bgsave 命令,生成 RDB 文件并发送给从库
主库生成replication buffer,记录 RDB 文件生成后收到的所有写操作。
主库将replication buffer中命令发送给从库,从库再执行命令以保持同步
增量同步
replication buffer
主库记录所有操作命令
repl_backlog_buffer
环形缓冲区,主库会记录自己写到的位置,从库则会记录自己已经读到的位置。
主库写入位置:master_repl_offset
从库已复制的偏移量 slave_repl_offset
哨兵机制
目的
实现Redis故障自动切换
机制
监控:监控主库和从库的状态
主观下线:一个哨兵认为实例下线
客观下线:N/2+1哨兵认为下线,执行下线操作
选主:主库故障时选出最新的主库
管理员设置的优先级
从库复制进度
最小ID
通知:通知所有从库和客户端新的主库
切片集群
目的
存储更多数据
方案
官方出品:Redis Cluster
哈希槽
目的:
处理数据和实例关系
映射过程
根据键值对的 key,按照CRC16 算法计算一个 16 bit 的值
用这个 16bit 值对 16384 取模,得到 0~16383 范围内的模数,每个模数代表一个相应编号的哈希槽。
每个实例上对应槽个数:16384/N
Redis客户端自己计算键值对对应哈希槽,从而确定该访问哪个实例
Redis 实例会把自己的哈希槽信息发给和它相连接的其它实例,来完成哈希槽分配信息的扩散
重定向
路由重定向原因
新增/删除实例
负载均衡
部分迁移完
实例返回包含了新实例地址的ASK命令响应结果,客户端对新地址发起访问
全部迁移完
实例返回包含了新实例地址的MOVED 命令响应结果,客户端对新地址发起访问并更新客户端缓存
第三方:Codis
缓存过期策略以及过期缓存删除
过期缓存删除
每 100 毫秒会删除一些过期 key
超过 25% 的 key 过期,则重复删除的过程,直到过期 key 的比例降至 25% 以下
淘汰策略
noeviction
不淘汰,内存写满后报错
volatile-ttl
越早过期的越早被淘汰
volatile-random
设置了过期时间的键值对随机被淘汰
volatile-lru
设置了过期时间的最近未访问的被淘汰
volatile-lfu
设置了过期时间的键值对访问次数少的被淘汰
allkeys-random
所有键值对随机淘汰
allkeys-lru
所有键值对最近未访问的被淘汰
allkeys-lfu
所有键值对访问次数少的被淘汰
Redis中LRU算法
每个键值对中保存最近被访问的时间戳(RedisObject中保存)
第一次会随机选出 N 个数据,把它们作为一个候选集合,把 lru 字段值最小的数据从缓存中淘汰出去
第N次淘汰,筛选新的数据进入候选集合,并进行淘汰。能进入候选集合的数据的 lru 字段值必须小于候选集合中最小的 lru 值
Redis中LFU算法
LFU 缓存策略是在 LRU 策略基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时,首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。如果两个数据的访问次数相同,LFU 策略再比较这两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出缓存。Redis4.0版本新增淘汰策略
实现原理
RedisObject中保存最近访问时间戳和访问次数
ldt 值:lru 字段的前 16bit,表示数据的访问时间戳
counter 值:lru 字段的后 8bit,表示数据的访问次数,最大值255。通过设置参数,概率性累计访问次数,避免很宽达到255
相比LRU更加关注访问次数
使用策略建议
allkeys-lru 策略:业务数据中有明显的冷热数据区分
allkeys-random 策略:业务应用中的数据访问频率相差不大,没有明显的冷热数据区分
volatile-lru 策略:业务中有置顶的需求,比如置顶新闻、置顶视频,同时不给这些置顶数据设置过期时间。这样一来,这些需要置顶的数据一直不会被删除,而其他数据会在过期时根据 LRU 规则进行筛选。
allkeys-lfu策略:针对有扫描查询的场景
常见面试题
为什么要用 Redis
高性能
从内存中读取数据,更快响应用户
高并发
一般像 MySQL 这类的数据库的 QPS 大概都在 1w 左右(4 核 8g) ,但是使用 Redis 缓存之后很容易达到 10w+
Redis为什么快
内存数据库,大部分操作在内存上完成
使用IO多路复用,即一个线程处理多个 IO 流
高效的数据结构,例如采用Hash表和跳表
Redis为什么使用单线程
Redis是内存数据库,CPU并非瓶颈
避免由多线程带来共享资源并非的问题
降低代码复杂度和维护复杂度
单线程指网络IO和键值对操作是单线程,持久化、集群数据同步、异步删除都是由异步线程完成。Redis 6.0中网络IO可使用多线程完成
Redis6.0之后为什么引入多线程
提高网络 IO 读写性能,命令执行任然是单线程,默认关闭。
Redis常见数据结构及使用场景
见基础数据类型
过期的数据的删除策略
惰性删除
只会在取出key的时候才对数据进行过期检查。这样对CPU最友好,但是可能会造成太多过期 key 没有被删除。
固定删除
每隔一段时间抽取一批 key 执行删除过期key操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响。
采用的是 定期删除+惰性/懒汉式删除 。
Redis 内存淘汰机制
noeviction
不淘汰,内存写满后报错
volatile-ttl
越早过期的越早被淘汰
volatile-random
设置了过期时间的键值对随机被淘汰
volatile-lru
设置了过期时间的最近未访问的被淘汰
volatile-lfu
设置了过期时间的键值对访问次数少的被淘汰
allkeys-random
所有键值对随机淘汰
allkeys-lru
所有键值对最近未访问的被淘汰
allkeys-lfu
所有键值对访问次数少的被淘汰
Redis 持久化机制
AOF日志
记录Redis操作命令
三种写回策略
Always:写完数据马上写AOF日志,并落地到磁盘
优点:可靠性最高
缺点:性能最差
Everysec:写完数据后先写到AOF缓冲区,每秒异步线程写到磁盘
优点:对性能几乎无影响
缺点:极端情况可能有1秒数据丢失
No:写完数据后先写到AOF缓冲区,由操作系统写到磁盘
优点:性能最好
缺点:数据丢失风险最高
AOF重写
目的:减少AOF日志体量,去除已无效或重复命令
做法:从内存中拷贝一份数据,回写成新的一份AOF文件
RDB快照
记录数据
优点:恢复速度快
缺点:丢失数据较多
写回策略:固定时间内操作次数达到上线触发增量快照
Redis4.0引入混合日志
RDB固定时间做全量
AOF做增量
Redis 事务
Redis事务提供了一种将多个命令请求打包的功能。然后,再按顺序执行打包的所有命令,并且不会被中途打断。
multi
事务开始
exec
事务结束
discard
取消事务,放弃执行事务块内的所有命令
watch
监视key变化,发生变化时会取消事务
unwatch
取消 WATCH 命令对所有 key 的监视
缓存和数据库数据不一致如何解决
系统故障
产生原因
先更新数据库再更新缓存或先更新缓存再更新数据库时,其中一方更新失败
解决方案
失败是写入MQ,采用重试机制
并发
产生原因
操作数据库和缓存间隙其他线程读取缓存
解决方案
先操作数据库再删除缓存情况。非强一致情况不用处理,发生概率极低。推荐
先删除缓存再操作数据库情况。采用延迟双删
缓存雪崩
含义
大量请求访问Redis未生效,直接访问到后端数据库,给数据库造成较大压力
原因
大量缓存同时过期
Redis宕机
解法
缓存过期时间加上随机数,避免缓存同时过期
搭建高可用集群
熔断、限流、降级,优先保证核心业务
缓存击穿
含义
热点数据访问Redis未生效,直接访问后端数据库,给数据库造成较大压力
原因
缓存过期
解法
针对热点数据不设置过期时间
后台通过Job更新缓存
缓存穿透
含义
Redis缓存和数据库中都没有的数据被访问
原因
后台误删数据
恶意攻击
解法
设置缺省值
使用布隆过滤器
前端进行请求检测
IO多路复用
含义
IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制
原理
该机制允许内核中同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。
监听有连接请求或数据请求时,将这些事件放入队列,Redis主线程来消费这些队列
0 条评论
下一页