1 Redis单线程为什么这么快?
- 纯内存操作
- 基于非阻塞的IO多路复用机制
- 单线程避免多线程频繁上下文切换带来的性能问题
2 Redis持久化机制?
2.1 RDB
Redis DataBase将某个时刻的内存快照,以二进制的方式写入磁盘。
手动触发
- save命令,使redis处于阻塞状态,知道RDB持久化完成,才会响应客户端发出的命令。
- bgsave命令,fork出一个子进程进行RDB持久化操作。主线程可以正常向颖客户端的请求。
自动触发
- save m n:在m秒内,如果有n个键发生变化,自动通过bgsave触发持久化。
- flushall:清除redis所有的数据,并生成一个dump.rdb
- 主从同步:全量同步时会自动触发bgsave命令,生成RDB文件发送到从节点。
优点
- 只有一个RDB文件,方便持久化
- 容灾性好,方便备份
- 性能最大化
- 数据集大,备份效率快
缺点
- 数据安全性低,因为RDB是隔时间持久化,如果在节点之间宕机了,导致部分数据丢失。
- RDB通过fork子进程持久化,数据集大时,会导致整个服务宕机几百毫秒,会占用cpu
2.2 AOF
Append Of File以日志的形式记录服务器每一个增删改操作,查询不记录。
2.2.1 所有的写命令都会追加到AOF缓冲区。
2.2.2 AOF缓冲区根据对应的策略向硬盘进行同步操作
2.2.3 AOF越来越大,需要定时对AOF进行重写,达到压缩的目的。
2.2.4 当Redis重启时,可以加载AOF进行数据恢复。
优点
- 数据安全
- 通过append模式写文件,即使中途宕机也不会破坏已存在的内容。
- AOF机制的rewrite模式,定期对AOF文件进行重写,达到压缩的目的。
缺点
- AOF文件大
- 数据集大,启动效率慢
- 运行效率低。
区别
- AOF更新频率高,优先使用AOF更新
- AOF更安全更大
- RDB效率高
- 优先加载AOF
3 布隆过滤器
位图:初始化,每一个bit都是0
添加数据:计算数据的hash值,转换成对应的bit位,并把0改成1
查询数据:计算数据的hash值,对应的bit中,如果存在一个0,证明数据不存在bit中,如果都为1,则可能在bit中
优点:
- 占用内存小
- 增加和查询元素的时间复杂度为0(K)
- 哈希函数相互之间没有关系
- 布隆过滤器不需要存储元素本身,具备保密性
- 数据量很大时,布隆过滤器可以显示全集
- 使用同一组散列函数的布隆过滤器进行交,并,差运算
缺点:
- 误判率,不能准确判断元素是否在集合中
- 不能获取元素本身
- 一般情况下不能从布隆过滤器删除元素
4 缓存过期都有哪些策略
- 定时过期:定时清除过期的数据。清除大量的数据会占用CPU资源,降低响应速度和吞吐量。
- 惰性过期:当访问一个key时,才判断对应的数据是否过期,过期则删掉。占用大量内存。
- 定时过期和惰性过期的结合。定时清除一部分过期数据。使CPU和内存资源在较好的情况。
5 缓存雪崩,缓存穿透,缓存击穿
- 缓存雪崩:同一时间缓存大面积失效,大量请求到数据库端,导致宕机。
解决方案:
- 缓存数据过期时间设置随机,防止同一时间失效。
- 监控缓存数据是否失效,如果失效,即使更新。
- 缓存预热。提前把缓存数据加载好。
- 互斥锁。缓存排队。
- 缓存穿透:缓存和数据库都没有数据,短时间内,数据库承受大量请求而崩掉。
解决方案:
- 接口层增加校验
- 缓存和数据库没有数据,缓存key-value设置key-null,有效时间设置短点,30秒。
- 采用布隆过滤器,将所有可能存在的数据哈希到bitmap中,一定不存在的数据会被拦截掉,避免对底层存储系统的查询压力。
- 缓存击穿:缓存中没有数据,数据库有数据。跟缓存雪崩不同,缓存雪崩是很多数据失效,缓存击穿是一个数据失效。
- 设置热点数据永不过期
- 加互斥锁,缓存排队,CAS,自旋锁。
6 Redis分布式锁
- setnx保证如果key不存在,才获取锁,如果key存在,则获取不到锁。
- lua脚本保证多个redis操作的原子性
- 锁过期,定时任务判断锁是否需要续约
- redis节点挂掉的情况,需采用红锁的方式向N/2+1节点申请锁,都申请了才能证明获取锁成功,这样就算redis挂了,锁也不能被其他客户端获取。
7 Redis9大结构
- String 字符串
- List 列表
- Hash 哈希表
- Set 无序集合
- SortedSet 有序集合
- BitMap 布隆过滤器
- GeoHash 坐标
- HyperLogLog
- Streams
8 Redis集群方案
3种策略:
- 主从模式:
主库宕机,需手动修改ip,较难扩容,整个集群存储数据量收到某一台机器的内存容量的影响。 - 哨兵模式:
主库节点宕机,会在从库中选择一个作为主库。哨兵也可以是集群。不能很好扩容 - cluster模式:
常用,支持多主多从,根据key进行槽位的分配,可以使得不同的key分散到不同的节点上,可以使整个集群环境支持更大的数据容量。每一个主节点有自己的从节点。
数据量小-哨兵模式,数据量大,需支持扩容-cluster模式
- 哨兵模式+主从模式
解决高可用问题,无法解决数据量大。
- 集群监控:负责监控各个节点是否正常。
- 消息通知:如果某一个redis实例故障,那么哨兵负责发预警消息给管理员。
- 故障转移: 如果master节点宕机,会自动转移到slave节点。
- 配置中心:如果故障转移发生了,通知客户端新的master节点。
- Redis Cluster:是一种服务端sharing技术,采用slot槽的概念,一共分成16384个。将请求发送到任意节点,接受到请求的节点会将查询请求发送到正确的节点上执行。
实现原理:
- 通过哈希将数据分片,每一个节点根据内存配置一定的哈希槽区间的数据。
- 每一个数据分片,都会存储到互为主从的多节点上。
- 数据先写入主节点,再同步到从节点。
- 同一分片多节点间数据不包吃一致性。
- 读取数据时,当前客户端操作的key没有分配到该节点,会返回指令,自从正确的节点查询数据。
- 扩容时需要把旧节点的数据迁移一部分到新节点上。
9 Redis如何保持消息的一致性?
- 先更新MySQL,再更新Redis。如果Redis更新失败,可能仍然不一致。
- 先删除Redis缓存数据,再更新MySQL。可能在删除数据后,再查询数据库,把旧数据更新到缓存里。
- 延时双删,删完缓存,MySQL数据后,过几百毫秒,再删除缓存数据。
10 简述Redis事务实现
- 事务开始
Multi命令的执行,标志着一个事务的开始。Multi命令将客户端状态的flags属性中打开Redis_multi标识来完成。 - 命令入队
当一个客户端切换到事务状态后,服务器会根据这个客户端发送过来的命令执行不同的操作。
2.1 如果客户端发送的命令使exec,discard,watch,multi其中之一,那么服务器会立即执行命令
2.2 否则,把正确的命令放进事务队列中(FIFO),向客户端返回queued回复。 - 事务执行
客户端发送EXEC命令,执行队列中的命令。
11 Redis主从复制
-
全量复制
1.1 bgsave命令fork子进程进行RDB持久化,该过程非常消耗CPU,内存(页表复制),硬盘IO
1.2 RDB文件通过网络传输,消耗带宽。
1.3 从节点需要先清除老数据,再重新载入RDB文件,该过程是阻塞的,无法响应客户端的命令。 -
部分复制
2.1 复制偏移量
2.2 复制积压缓冲区,若主从节点的偏移量>缓冲区长度,将无法执行部分复制,只能全量复制
2.3 服务器运行id:
从节点断开重连,根据运行id判断同步的进度。若判断主id不同,则主节点也换了,需要全量复制。
网友评论