一、AOF持久化
1. AOF持久化是怎么实现的?
AOF会将Redis执行的每一条写操作都以追加的方式写入到一个文件中,重启Redis是先去执行整个文件就能恢复数据了;
Redis的AOF持久化功能默认是不开启的,因为与Redis的设计理念冲突。
修改conf文件中的appendonly字段 和 appendfilename字段开启AOF持久化
Redis先执行操作才会写入到AOF日志中,
好处:
· 只有语句正确执行,没有语法错误才会写入,避免了额外的检查开销。
· 不会阻塞当前写操作的命令
风险:
· 执行操作和记录日志不是原子性的,有丢失的风险
· 可能会阻塞下一个执行操作
2. 写回策略
· Always:每写入一条就从AOF日志中执行一条写回硬盘的操作
· Everysec:每秒写回硬盘一次
· No:不自动执行,由操作系统决定
3. AOF重写机制:
当AOF文件大小过大,就会启动重写机制
新AOF会记录最新的写key操作;
AOF重写是由后台的子进程完成的
二、RDB快照持久化
RDB快照就是记录某瞬间的内存数据,记录的是实际的数据,AOF记录的是命令操作
在恢复数据是直接把RDB文件读入到内存中就可以
Redis的RDB快照是全量快照,所以不可能随时记录数据,在发生故障时损失的数据也会更多;
RDB分为save模式和bgsave模式:
save模式就是使用主线程进行RDB,会阻塞主线程;
bgsave模式会创建一个子进程来生成RDB文件:
conf中的自动RDB使用的是bgsave
三、总结
尽管RDB比AOF的数据恢复快,但是频率不好把握
如果频率太低,两次快照间发生故障,可能会丢失过多数据
如果频率太高,频繁写入磁盘和创建子进程会带来额外的性能开销
混合持久化:
先以RDB的方式存储数据,然后在两次RDB之间,
用AOF的方式记录增量命令,然后将含有RDB格式和AOF格式的AOF文件替换旧的AOF文件
也就是说,AOF文件的前半部分是RDB格式的全量数据,后半部分是AOF的增量数据
重新加载时,前半段加载的速度会很快,后半段由AOF记录使得丢失的数据更少。
一、缓存雪崩、缓存击穿、缓存穿透
一般实际应用时会使用Redis作为mysql的缓存,避免mysql因为高并发的访问导致宕机。
应用优先从缓存中读取数据,缓存中不存在再向数据库中读取数据,读取完数据后将数据加载到缓存中。
1. 缓存雪崩
如果大量的缓存数据在同一时间按过期或者Redis宕机,全部请求直接访问数据库,造成数据库压力剧增,这就是缓存雪崩
· 大量缓存数据同时过期
a. 均匀设置过期时间:保证数据不会在同一时刻过期
b. 互斥锁:保证一个key同时只有一个线程用于更新缓存
c. 双key策略:使用两个key,主key设置过期时间,副key长期保存
d. 后台更新缓存:
缓存不设置有效期,根据负载量清理缓存,由后台负责更新缓存
两种方法:
频繁定时检查缓存是否有效(不推荐)
通过消息队列发送一条消息通知后台线程主动更新缓存(推荐)
· Redis宕机
a. 服务熔断或请求限流机制:
当Redis宕机,服务熔断,暂停也会对缓存服务的访问;
或者对请求流量限流,只处理少部分请求。
b. 构建Redis高可靠集群
通过主从节点的方式构建Redis高可靠集群,避免Redis缓存不可用
2. 缓存击穿
缓存中的数据过时了,大量数据无法匹配到缓存数据直接访问数据库,导致数据库压力过大
· 互斥锁和后台异步更新缓存可以解决
3. 缓存穿透
请求数据在缓存和数据库中都不存在,没办法构建缓存
· 非法请求的限制:
检查请求参数是否合法、请求字段是否存在..避免缓存和数据库的压力
· 缓存控制或者默认值
发现缓存击穿的现象,在缓存中设置一个控制或者默认值,避免数据库压力
· 使用布隆过滤器判断数据是否存在,减少数据库压力
二、主从复制
主从复制可以保证多台服务器的数据一致性,且主从服务器之间采用的是读写分离的方式
主服务器负责读写操作;从服务器负责只读操作,并同步主机的写操作;
所有的数据修改只在主服务器中进行,然后将最新的数据同步给从机。
1. 第一次同步
从机输入( slaveof IP地址 端口号 )建立主从关系,接着开始第一次同步
第一次同步可以分为三个阶段:
· 建立连接、协商同步:为券廊复制做准备
· 主服务器同步数据给从服务器:
主机执行bgsave命令生成RDB文件,然后把文件发送给从机;
从机收到RDB文件,会先清空当前数据,然后载入RDB文件;
主服务器会将在RDB文件生成后收到的写操作命令,写入到replication buffer缓冲区里
· 主句发送新写操作命令给从机
RDB文件发送之后,再把replication buffer中的写操作命令发送给从机
2. 语句长连接的命令传播
第一次同步之后,双方建立TCP连接;
后续主机可以通过这个连接继续将写操作命令传播给从机,然后从机执行命令,使得双方数据状态相同。
且这个连接时长连接,目的是避免频繁的TCP连接和断开带来的性能开销
3. 分摊主服务器的压力
在第一次同步中,主机需要给自己的从机发送RDB文件,这样会造成几个问题:
· bgsave会忙于创建子进程,如果内存数据庞大,会阻塞主线程
· 传输RDB文件会占用主机的网络带宽
Redis允许让从机拥有自己的从机,它不仅可以接收主机数据同步数据,还可以给自己的从机传输数据。
这样,主机生成RDB和传输RDB的压力可以分摊到充当经理角色的从服务器上。
4. 增量复制
如果主从服务器之间的服务器断开了,此时再重连,主机只会把网络断开期间收到的写操作命令同步给从机,而不是全量复制
通过一个环形缓冲区和主从服务器各自的偏移量来确定需要增量复制哪些内容
三、哨兵机制
基本的主从复制在主机宕机后需要手动监控工作情况,手动完成从机上位和主机恢复后恢复主从关系的过程;
哨兵机制可以实现自动检测、提醒、和故障处理
四、Redis-cluster集群
Redis官方提供的高可用集群方案
通过去中心化让每一个主机平均承担存储数据;
Redis-Cluster数据分片:
Redis cluster提出了基于哈希槽slot的概念,来实现数据分片;
每个key经过哈希函数取哈希值,再模上哈希槽的个数(16384)决定将key放置在哪一个主机上;
每个主机至少要有一个从机,避免某主机宕机导致某段哈希槽不可用;
当某个主机宕机时,会按照类似于哨兵机制选举出一个节点继续服务;
如果主节点和所有从机都不可用,则整个集群也不可用。