Redis高可用

发布于:2024-04-08 ⋅ 阅读:(127) ⋅ 点赞:(0)

  持久化:持久化是最简单的高可用方法,主要作用:数据备份,即将数据存储在硬盘保证数据不会因进程退出而丢失

  主从模式:主从复制时高可用Redis的基础。主动复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复

  哨兵:在主从复制的基础上实现了自动化的故障恢复

  Cluster集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题

一、Redis持久化

  1.1 redis的功能

redis是内存数据库,数据都是存储在内存中,为了避免下次断电而导致数据丢失,需要定期将数据从内存保存到硬盘;当下次重启时,利用持久化完成数据备份。以防万一还可以将持久化文件拷贝到远端。

  1.2 实现持久化的方式

  • RDB持久化:原理是将Redis在内存中数据库记录定时保存到磁盘上。
  • AOF持久化:原理是将Redis的操作日志以追加的方式写入文件(主流)

  1.2.1 RDB持久化

    指定的时间间隔内将内存中当前进程中的数据生成快照保存到硬盘,用二进制压缩存储,保存的文件后缀是rdb;当redis重启时,可以读取快照中的文件恢复数据

  1.2.1.1触发条件

    RDB持久化的触发条件分为手动触发自动触发

  • 手动触发

    save命令和bgsave命令都可以生成RDB。

    save命令会阻塞redis服务器进程,直到RDB文件创建完毕为止。在阻塞期间,服务器无法处理任何请求、bgsave会创建一个子进程,子进程来负责创建RDB文件,父进程会处理该请求。在命令执行过程中,只有fork子进程会阻塞服务器。

  • 自动触发

    在自动触发RDB持久化时,redis会选择bgsave来进行持久化

1.2.1.2 其他自动触发机制

除了save m n以外,还有一些其他情况也会触发bgsave

  • 在主从复制的情况下,如果从节点执行全量复制操作,则主节点会执行bgsave命令,并将rdb文件发送给从节点。

  • 执行shutdown命令时,自动执行rdb持久化

1.3 执行流程

  1. Redis父进程首先判断当前是否在执行save,bgsave或者bgrewriteaof的子进程,如果在执行bgsave命令直接返回。bgsave/bgrewriteaof子进程不能同时执行,如果两个子进程同时执行大量的磁盘读写操作,会引起性能的问题。
  2. 父进程执行fork操作创建子进程,这个进程父进程处于阻塞状态,Redis不能接收任何从客户端发来的命令
  3. 父进程fork后,bgsave命令返回"Background Saving started"信息不再阻塞父进程
  4. 子进程创建RDB文件。根据父进程内存快照生成临时快照文件,完成后在原有文件进行原子进程替换
  5. 子进程发送信号给父进程表示完成,父进程更新统计信息

1.4 启动时加载

  RDB文件载入服务器时自动执行。但是AOF的优先级更高,当载入AOF时,Redis会优先载入AOF来恢复数据。只有当AOF关闭后,服务器才会检测RDB文件并载入Redis载入RDB文件时,会对RDB文件校验如果文件损坏,在日志中打印错误,进入Redis启动失败

二、AOF持久化

  2.1 AOF功能

    将Redis执行的写、删操作记录到单独的日志文件中,查询操作不会记录。当Redis重启时再次执行AOF来恢复数据

  2.2 执行流程

    执行流程包括

  • 文件追加:将redis的写命令追加到缓冲区aof_buf
  • 文件写入和文件同步:根据不同的同步策略将aof_buf中的内容同步到硬盘
  • 文件重写:定期重写AOF文件,来达到压缩的目的

  2.2.1 命令追加

    Redis现将写命令追加到缓冲区,主要为了避免每次有写命令都直接写入硬盘,导致因IO成为Redis负载的瓶颈。追加的格式是Redis命令请求的协议格式。 在AOF除了用于指定数据库的select命令是由redis添加的,其余的都是客户端发来的写命令。

    特点:

  1. 读写性强
  2. 兼容性强
  3. 易处理
  4. 操作简单
  5. 避免二次开销

  2.2.2 文件写入和文件同步

    当用户调用write写入文件时,操作系统通常会将数据暂存到一个内存缓冲区里,当缓冲区被填满后,才将缓冲区的数据写入到硬盘中,但会代理一个安全问题,一旦计算机停机,内存缓冲区的数据会丢失。因此提供了fsync,fdatasync,而可以强制将缓冲区中的数据写到硬盘中,来确保安全性

  2.2.2.1 缓冲区同步文件策略存在三种同步方式
  • appendfsync always:总是触发持久化
  • appendfsync no: 不进行持久化
  • appendfsync everysecond:每秒会触发一次持久化

  2.2.3 文件重写

    目的:将所有的数据进行解压再压缩,为了节省空间

    文件重写的原因:

  • 过期的数据不在写入文件
  • 无效的命令不再写入文件:例如重复数据、删除数据
  • 多余的命令可以合并为一个

  2.2.3.1 文件触发规则
  • 手动触发:直接调用bgrewriteaof命令。都是fork自进程能进行具体的工作,且都只有在fork时阻塞
  • 自动触发:通过设置auto-aof-rewrite-min-size选项和auto-aof-rewrite-percentage满足来执行bgrewriteaof

  2.2.3.2 文件重写的注意事项
  1. 重写由父进程fork子进程进行
  2. 重写期间redis执行写的命令,需要追加到新的AOF文件中,为此引入了aof_rewrite_buf缓存

  2.2.3.3 文件重写的流程

(1)Redis父进程首先判断当前是否存在正在执行bgsave/bgrewriteaof子进程,如果存在bgrewriteaof直接返回,存在bgsave命令会等它执行完后再执行

(2)父进程执行fork操作创建子进程,整个过程中父进程是阻塞的

(3.1)父进程fork后,bgrewriteaof命令返回"background append only file rewrite started"信息不在阻塞父进程,并可以响应其他的命令。redis所有写命令写入AOF缓冲区,并根据appendsync策略同步到硬盘中,使得原有AOF机制正确

(3.2)由于fork操作使用写时,子进程只能共享fork操作时的内存数据。但是父进程响应命令,因此Redis使用AOF重写缓冲区保存着部分数据防止AOF生成期间再丢失。再bgrewriteaof执行期间,redis写命令同步追加到aof_buf(原数据区)和auf_rewrite_buf(重写数据区)

(4)子进程根据内存快照,会将规则合并到新的AOF文件

(5.1)子进程写完新的AOF文件后,想父进程发送信号来更新统计信息,具体可以通过info persistence查看

(5.2)父进程把AOF重写缓冲区的数据写到新的AOF文件,可以保证新的AOF数据库状态和服务器当前状态一致

(5.3)使用新的AOF文件替换老文件,完成AOF重写

三、 RDB和AOF优缺点

优点 缺点
RDB
  1. RDB文件紧凑
  2. 体积小
  3. 传输速率块
  4. 适合全量复制
  5. 恢复速度快
  • 不能实施持久化
  • 兼容性差
  • 不能满足特定格式
  • 在操作时Redis主进程会阻塞;写数据也会带来IO压力
AOF
  1. 支持秒级持久化
  2. 兼容性好
  3. 具有重写功能
  • 文件大
  • 回复速度慢
  • 性能影响大
  • 硬盘写数据的频率大大提高,可能会造成AOF追加阻塞


网站公告

今日签到

点亮在社区的每一天
去签到