一、redis性能
1.redis是单线程吗?
redis的主要工作线程,也就是负责网络IO、数据存储和查询的工作是由一个线程来完成的,但是数据持久化、数据异步删除、集群数据的同步是是有额外的线程来完成的,所以redis并非真正意义上所有的工作都是单线程完成,单线程只能说是相对的。
2.redis主要工作线程是单线程,为什么还那么快
因为redis的数据都存在内存中,数据的运算都是内存级别的,所以性能非常快,另外正因为redis的主要工作线程是单线程的,减少了多线程互相切换产生的性能损耗。
3.redis单线程怎么处理客户端的并发连接
redis使用IO多路复用模型,利用epoll来实现,将连接信息和事件放到队列中,依次交给文件事件分配器,然后再分发到事件处理器处理。
二、redis持久化
1.RDB快照
默认情况下redis是开启rdb数据持久化的方式,也就是在满足N秒内有多少数据集改变的情况下会触发RDB快照(save N number),将内存中所有的数据都以二进制的方式存在dump.rdb的文件中,在这个过程中,会非常消耗性能,所以应尽量避免频繁的RDB持久化操作。在使用RDB持久化这种数据保存的方式安全性不高,会有部分数据丢失的情况,但是数据恢复的速度会非常快(因为保存的是二进制文件,直接加载到内存)。
2.bgsave写时复制(COW)机制
redis借助操作系统的写时复制机制(copy-on-write),就是在生成快照的同时,依然可以执行写命令。bgsave线程是由主线程fork生成的子线程,共享主线程的内存,可以直接将主内存的数据写入RDB文件,当此时正好有客户端发送写命令请求时,主线程不会阻塞,而是正常执行,并且将新写的数据备份一份,然后bgsave线程会将备份的数据写入RDB文件。
save | bgsave | |
IO类型 | 同步 | 异步 |
主线程是否阻塞 | 阻塞 | 非阻塞 |
复杂度 | O(n) | O(n) |
优点 | 没有额外内存消耗 | 异步非阻塞 |
缺点 | 阻塞主线程工作 | 需要fork子线程,消耗内心 |
3.AOF
rdb快照的方式并不能安全的保证内存中数据完全被持久化,而aof则可以尽可能少的丢失数据,通过配置参数appendfsync 给不同的配置(always-每次持久化、everysec-每秒、no-自动)达到想要的效果(通常情况下会用没秒持久化一次,效率会高,并且保存的数据更全,最多只丢失1秒钟的数据),aof方式的持久化会将每一条resp命令写入到appendonly.aof文件中,在恢复数据的时候再一条一条命令执行,效率会比rdb快照的方式低很多。如果两种方式都做了持久化,redis默认会使用aof的方式恢复数据,因为这个数据会更全。
4.AOF重写
因为aof文件记录的是一条条的命令,所以存在多条命令可以合并成一条命令的情况,这样可以增大恢复缓存的效率,所以redis会对aof文件进行重写,可以通过配置(auto-aof-rewrite-min-size 100mb)文件大小超过多少后进行重写。
5.RDB与AOF比较
RDB | AOF | |
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
速度 | 快 | 慢 |
数据安全性 | 容易丢数据 | 根据策略决定 |
6.混合持久化
aof因为恢复数据的时候需要执行所有的resp命令,效率太低,所以redis 4.0之后新增了一种混合持久化的方式,就是在aof重写的时候,不再是写入resp的命令,而是直接在内存做rdb快照处理,后续有新增的持久化命令,再继续在文件后面写入,恢复数据的时候先加载rdb的内容,再执行resp命令。
三、redis主从架构
1.redis主从架构原理
当我们为master配置了一个从节点slave,slave第一次去请求master会发送psync命令要求同步数据,master接收到命令后会进行RDB持久化数据,持久化完成后发送给slave节点同步数据,slave首先会生成自己的rdb文件,然后加载到自己的内存中。master在持久化的过程中,还可以继续处理客户端发送过来的写操作,它会在自己的内存中复制一份出来,最后会发送给从节点将持久化期间的数据变动完全实现主从一致,最终达到数据的一致性。
2.redis数据部分复制(断点续传)
当从slave和master断开连接一段时间后,重新连接上时,slave会记下最后同步数据的下标offset和master的进程id,slave会将这两个参数发送给master,master接收到slave发送的psync命令后,会在自己内存中缓存的数据查找到下标offset,如果能找到,并且进程id一致,则会将offset后面的命令全部发送给slave,如果找不到或者进程id不一致,master则会全量复制数据给slave。
3.redis主从复制风暴
一个master节点,有很多个slave节点,会导致多个slave同时从master复制数据,导致master压力过大,为了解决这个问题,可以让部分slave从slave同步数据,从而缓解master的压力,如下图:
四、redis哨兵
1.redis哨兵高可用架构
client第一次访问的是sentinel,sentinel会返回master节点的信息,后续client不用再访问sentinel,而是直接访问master,当master挂掉的时候,sentinel会从slave中选举出新的master,随后会更新并发布集群的信息,client实现了订阅功能,所以会获取到最新的master信息,请求会发到新的master那里,当挂掉的master节点服务恢复正常的时候,会加入到集群中,变成其中的一个slave。