Redis持久化、复制

Redis持久化、复制

持久化

RDB

把当前进程数据生成快照保存到硬盘

触发机制

  • 手动触发:
    • save :阻塞Redis,知道RDB完成,线上环境不建议使用
      • bgsave :Redis进程fork子进程,RDB由子进程完成,阻塞发生在fork阶段
  • 自动触发:
    • save m n配置,m秒内数据集存在n次修改时触发bgsave
    • 从节点执行全量复制,主节点自动执行bgsave并将RDB文件发给从节点
    • debug reload命令重新加载redis
    • 默认执行shutdown时,如果没有开启AOF,则自动执行bgsave

执行流程

  • 执行bgsave,父进程判断是否存在正在执行的子进程,存在则直接返回
  • 父进程fork子进程,父进程阻塞,info stats可查看latest_fork_usec选项,获取最近fork耗时微秒
  • fork结束,bgsave命令返回“Background saving started”,不阻塞父进程,继续响应其他命令
  • 子进程创建RDB文件,根据父进程内存生成临时快照,完成后对原有文件原子替换。lastsave可获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项
  • 进程发送信号给父进程表示完成,父进程更新统计信息,info Persistence下的rdb_*选项

RDB文件处理

RDB文件保存在dir配置铺路下,文件名为dbfilename

可通过如下命令动态执行

  • config set dir {newDir}
  • config set dbfilename {newFileName}

遇到坏盘或磁盘写满的情况,可以用上述命令在线修改文件路径到可用磁盘路径,然后bgsave进程磁盘切换

redis默认使用LZF算法压缩RDB文件,压缩后远小于内存,默认开启,通过config set rdbcompression{yes|no}动态修改,压缩会消耗CPU,但便于保存和发送,线上建议开启

RDB文件损坏,可使用redis-check-dump工具检测

RDB优缺点

  • 优点:
    • 紧凑压缩的二进制文件,代表某个时间点上的数据快照,适用于备份,全量复制
    • RDB加载恢复远远快于AOF方式
  • 缺点:
    • 没法做到实时持久化/秒级持久化。bgsave每次运行都要fork子进程,属于重量级操作
    • RDB使用特定二进制格式,老版本Redis可能无法兼容新的RDB格式

AOF

AOF:append only file

以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。

AOF主要解决了数据持久化的实时性

使用

配置

  • appendonly yes 默认不开启
  • appendfilename AOF文件名,默认appendonly.aof

工作流程

graph TB
    a1(命令写入) -- append --> a2(AOF缓冲)
    a2 -- sync --> a3(AOF文件)
    a3 -- rewrite/load --> a3
    a3 -- load --- a4(重启)
  1. 所有的写入命令追加到aof_buf缓冲区中
  2. AOF缓冲区根据对应的策略向硬盘做同步操作
  3. 随着AOF越来越大,需要定期对AOF文件重写达到压缩目的
  4. redis重启时,加载AOF文件进行数据恢复

命令写入

AOF命令直接写入文本协议格式

*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n
  • 使用文本协议格式
    • 文本协议兼容性好
    • 开启AOF后,所有写入命令都包含追加操作,直接用协议格式,避免二次处理开销
    • 可读性好,便于直接修改
  • 命令追加到aof_buf中
    • 减轻硬盘负载
    • redis可以提供多种缓冲区同步硬盘的策略,平衡性能和安全

文件同步

AOF缓冲区同步文件策略,由appendfsync控制,不同的值对应命令写入aof_buf后不同的处理方式:

说明
always调用系统fsync同步到AOF文件,fsync完成后线程返回
everysec调用系统write,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次
no调用系统write,不对AOF文件做fsync同步,同步硬盘由OS负责,通常同步周期最长30秒

write出发延迟写(delayed write)机制

fsync针对单个文件做强制硬盘同步,阻塞直到写入硬盘完成后返回

everysec是建议的同步策略也是默认配置,兼顾性能和数据安全。理论上只有在系统突然宕机的情况下丢失1秒的数据。

重写机制

AOF引入重写来压缩文件体积。

AOF文件重写,是把Redis进程内额数据转化为写命令同步到新AOF文件的过程

重写后变小原因如下:

  1. 进程内已超时的数据不再写入文件
  2. 旧的AOF文件含有无效命令,重写使用进程内数据直接生产,新的AOF文件只保留最终数据的写入命令
  3. 多条写命令可以合并为一个

AOF重写触发:

  • 手动触发: bgrewriteaof
  • 自动触发: 根据配置确定
    • auto-aof-rewrite-min-size:运行AOF重写时文件最小体积,默认64MB
    • auto-aof-rewrite-percentage:当前AOF文件空间(aof_curremt_size)和上一次重写后AOF文件空间(aof_base_size)的比值

AOF详细流程:

重启加载

  1. AOF开启且存在AOF文件,优先加载AOF
  2. AOF关闭或者AOF文件不存在,加载RDB文件
  3. 加载AOF/RDB成功后,Redis启动
  4. AOF/RDB文件存在错误时,Redis启动失败

文件校验

加载损坏的AOF文件拒绝启动

错误的AOF文件,先备份,然后redis-check-aof –fix进行修复,修复后diff-u对比差异,找出丢失数据,有些可以人工补全。

机器突然掉电可能导致AOF尾部文件命令写入不全。Redis提供aof-load-truncated配置兼容之,默认开启

复制

配置

建立复制

参与复制的Redis划分为master节点和slave节点。默认都是master节点,每个salve只能有一个master。

复制的数据流只能从master复制到slave

配置方式:

  • 配置文件中加入slaveof {masterHost} {masterPort}随Redis启动生效
  • redis-server启动加入命令行 –slaveof {masterHost} {masterPort}
  • 直接使用命令 slaveof {masterHost} {masterPort}

slaveof配置都是在从节点发起

主从节点复制成功建立后,使用info replication 查看复制相关状态

复制断开

命令:slave节点执行 slaveof no one

  • 断开与master节点复制关系
  • slave节点晋升为master节点

切换master节点:slaveof {newMasterIp} {newMasterPort}

切换master节点会清空之前所有的数据

安全性

master节点设置requirepass参数进行密码验证,这是客户端必须使用auth命令校验。

slave与master的复制连接通过一个特殊标识的客户端完成,需要配置slave节点的masterauth参数与master密码一致。

只读

默认slave使用slave-read-only=yes配置为只读模式。

修改slave节点会造成主从数据不一致。线上建议不要修改slave的只读模式

传输延迟

repl-disable-tcp-nodelay参数用于控制是否关闭TCP_NODELAY,默认关闭

关闭时,master数据无论大小都及时发给slave,这样主从延迟变小,但增加了带宽消耗,适用主从网络良好

开启时,master合并较小的TCP包节省带宽,发送间隔取决于Linux内核,一般默认40ms。

拓扑

Redis复制拓扑结果支持单层或多层复制关系。

一主一从

用于master宕机时slave提供故障转移支持。

如果只在slave节点开启AOF,需要注意主节点脱机避免自动重启,因为master没开启持久化重启后数据位空。

可以在slave执行slaveof no one断开复制,然后重启master

一主多从

也称星形拓扑

使得应用端利用多个slave节点实现读写分离。对于读占比大的场景,把读发送到slave分担master压力

树状主从

slave可以做为其他slave的master继续向下层复制

树状主从可以降低主节点压力

原理

复制过程

在slave执行slaveof命令后,复制过程便开始运作

  1. 保存master信息

    master的ip和port被保存下来,但是master的连接状态是下线状态

    master_link_status:down

  2. 主从建立网络连接

    slave内部的定时任务发现存在新的master节点,则尝试建立网络连接

    如果无法建立连接,则定时任务无限重试直到连接成功或者取消复制

    失败可以在slave执行info replication查看master_link_down_since_seconds指标

  3. 发送ping命令

    连接建立后slave发送ping请求首次通信

    ping用于检测主从sockect是否可用以及master当前是否可接受处理命令

    如果slave没收到master的pong回复或超时,则断开复制下次定时任务发起重连

  4. 权限验证

    如果master设置了requirepass参数,slave必须配置masterauth参数保存密码相同

    验证失败则复制终止,slave重新发起复制流程。

  5. 同步数据集

    连接正常后,对于首次建立复制的场景,master把持有的数据全部发送给slave(耗时)

    redis 2.8以后采用psync进行数据同步

  6. 命令持续复制

    完成复制的建立流程后,接下来master持续把命令发送给slave,保证主从数据一致

数据同步

同部分全量复制部分复制

全量复制:一般用于初次复制

部分复制:用于处理复制中因网络闪断等原因造成的数据丢失场景,当slave再次连上master后,如果条件允许,master会补发丢失数据给slave

psync命令运行需要以下组件支持:

  • 主从节点各自复制偏移量
  • master复制积压缓冲区
  • master运行id

复制偏移量

参与复制的主从节点维护自身复制偏移量

info replication中的master_repl_offset指标中

slave每秒钟上报自身复制偏移量给master,master也会保存slave的复制偏移量

slave收到master发送的命令后,累计记录自身偏移量于info replication中的slave_repl_offset指标中

通过对比主从复制偏移量,判断主从数据是否一致

复制积压缓冲区

保存在主节点上的一个固定长度的队列,默认1MB

主节点运行ID

每个Redis节点启动后会动态分配一个40bit的16禁止字符串作为运行ID,唯一识别Redis节点。

运行ID变化后,从节点将做全量复制

info server命令查看当前节点运行ID

redis关闭再启动后,运行ID随之改变

debug reload可以重新加载RDB保持运行ID不变,避免不必要的全量复制。但是该命令会阻塞当前Redis节点主线程。谨慎使用。

psync命令

slave节点使用psync完成部分复制和全量复制。

psync {runId} {offset}

runId表示要复制的master的运行id

offset表示当前slave已复制数据的偏移量

全量复制
部分复制
心跳
异步复制

开发运维中的问题

  1. 读写分离
  2. 主从配置不一致
  3. 规避全量复制
  4. 规避复制风暴
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值