您当前的位置: 首页 >  redis

Charge8

暂无认证

  • 0浏览

    0关注

    447博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Redis 持久化与主从复制配置

Charge8 发布时间:2020-05-05 13:36:14 ,浏览量:0

一、Redis 持久化

       Redis是一种内存数据库,所以它的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”)。由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启 redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

       持久化主要作用就是在redis重启后的数据恢复.

Redis有两种方式进行持久化:

1)RDB持久化(默认的持久化方式)(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),

2)AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。

1、RDB 持久化(默认的持久化方式)

     RDB持久化是指在指定的时间间隔内定时将内存中的数据集快照写入磁盘。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为 dump.rdb。

[root@centos7 redis]# ll
总用量 68
drwxr-xr-x 2 root root   134 4月  27 21:24 bin
-rw-r--r-- 1 root root   184 5月   4 22:24 dump.rdb
-rw-r--r-- 1 root root 61808 5月   4 19:49 redis.conf

1) 在redis.conf 配置文件中的默认配置如下,如果要关闭RDBR持久化时,只需要注释掉save配置就可以了

     

     表示在多少秒内如果超过多少个key被修改,则发起快照保存。#300秒内如果超过10个key被修改,则发起快照保存。 

2)在客户端判断是否启动了RDB:

127.0.0.1:6379> config get save
1) "save"
2) "900 1 300 10 60 10000"

   查看持久化信息:info  persistence

127.0.0.1:6379> config get save
1) "save"
2) "900 1 300 10 60 10000"
127.0.0.1:6379> info  persistence
127.0.0.1:6379> info sistence
127.0.0.1:6379> info persistence
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1588642242
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0

3)手动执行RDB,会阻塞的命令save,不会阻塞的命令bgsave

命令描述SAVE同步数据到磁盘上,会阻塞当前Redis服务器BGSAVE异步数据到磁盘上,不会阻塞当前Redis服务器
127.0.0.1:6379> bgsave
Background saving started
2、AOF(append only file)持久化

      将 Reids 的操作日志以追加的方式写入文件中,默认的文件名为appendonly.aof,AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令。

默认是no关闭的,开启的方式又两种:关闭操作把yes改no即可

1) 命令的方式:> config set appendonly yes

2) 配置文件中(记得重启):配置 appendonly yes

           

[root@centos7 redis]# ll
总用量 72
-rw-r--r-- 1 root root    52 5月   5 09:51 appendonly.aof
drwxr-xr-x 2 root root   134 4月  27 21:24 bin
-rw-r--r-- 1 root root   190 5月   5 09:50 dump.rdb
-rw-r--r-- 1 root root 61809 5月   5 09:42 redis.conf
[root@centos7 redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
kjj
$2
vjj

 1)AOF持久化的可靠性,通过 appendfsync 选项来控制,

     RDB持久化的可靠性,取决于save设置,也就是说它保存快照的频率。

(1)设置 appendfsync no 时

       Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作系统的调试了。对大多数Linux操作系统,是每30秒进行一次写,将缓冲区中的数据写到磁盘上。

(2)设置 appendfsync everysec 时(默认的)

       Redis会每隔一秒进行一次写操作调用,将缓冲区中的数据写到磁盘。但是当这一次的写,调用时长超过1秒时。Redis会采取延迟写的策略,再等一秒钟。也就是在两秒后再进行下一次写,这一次的写就不管会执行多长时间都会进行。这时候由于在写文件,客户端会被阻塞,所以当前的写操作就会阻塞。

所以,在绝大多数情况下,Redis会每隔一秒进行一次写。在最坏的情况下,两秒钟会进行一次写操作。

(3)设置 appednfsync always 时

      Redis会每一次写操作都会调用一次写操作,这时数据是最安全的。由于每次都会执行写操作,所以其性能也会受到影响。

 

3、RDB和AOF的优缺点

RDB:

优点:全量数据快照,文件小,恢复快

缺点:无法保存最近一次快照之后的数据,数据量大会由于I/O严重影响性能

AOF“”

优点:可读性搞,适合保存增量数据,数据不一丢失

缺点:文件体积大,恢复时间长

4、RDB和AOF该如何选择

如果你非常重视数据安全性, 那可以同时使用两种持久化功能。

如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那可以只使用 RDB 持久化。

其余情况建议选择AOF

    

   

二、Redis 主从复制

       Redis的持久化功能在一定程度上保证了数据的安全性,即便是服务器宕机的情况下,也可以保证数据的丢失非常少。但是如果单个服务器系统崩溃了,磁盘损坏了等,保存的数据就完蛋了,所以为了应对这样的问题,通常,为了避免服务的单点故障,会把数据复制到多个副本放在不同的服务器上,且这些拥有数据副本的服务器可以用于处理客户端的读请求,扩展整体的性能,即主从复制。

 主从复制的好处:

  1. 数据冗余,实现数据的热备份
  2. 故障恢复,避免单点故障带来的服务不可用
  3. 读写分离,负载均衡。主节点负载读写,从节点负责读,提高服务器并发量
  4. 高可用基础,是哨兵机制和集群实现的基础
1、主从复制的配置

这里使用 3 台虚拟机(CentOS 7.6)来搭建一下,两个从服务器是虚拟机克隆来的,

主服务器的ip:192.168.198.5,两个从服务器的ip分别为:192.168.198.10 和 192.168.198.11,端口号都为6379。

注意:启动后修改从服务器 ip 和 bind。

     

1)具体的配置如下:

     主服务器不用配置,如果主服务器设置redis登录密码(requirepass 选项),那么从服务器就要设置masterauth来认证(masterauth  选项)。

在从服务器中添加配置 slaveof 选项,在5.0版本中使用了 replicaof 代替了 slaveof。slaveof 还可以继续使用。

     两个从服务器 在redis.conf 中配置:

 293 # masterauth 
masterauth 123456
slaveof 192.168.198.5 6379

  配置好之后,主从服务器的数据就同步了。

    

2)实验的步骤:

  1. 主服务器上新建一个key-value
  2. 在从服务器上获取这个key的值,可以拿到
  3. 尝试在从服务器上新建一个key-value,新建不了,默认从服务器是只读的
  4. 关闭从服务器10,在主服务器上新建一个key-value
  5. 重启从服务器10,获取刚刚在主服务器上创建的key的值,可以拿到

     

     通过实验可以看出 主从服务器之间数据的同步,即使,其中一个从服务器挂了(重启又可以同步漏掉的数据);要是主服务器挂了,只有有一个从服务器数据正常,数据就还在。

     主从复制的配置使用还是比较简单的,但是,更应该了解主从复制的实现原理。    

2、主从复制的工作原理:

      Redis的主从复制的实现过程大体上分3个阶段:建立连接、数据同步、命令传播。

     

1)建立连接 -- slaveof 命令

这个阶段主要是从服务器发出 slaveof 命令之后,与主服务器如何建立连接,为数据同步做准备的过程。

      1. 在 slaveof 命令执行之后,从服务器根据设置的 master 的 ip 地址和端口,创建连向主服务器的 socket 套接字连接,连接成功后,从服务器会为这个套接字关联一个专门的处理器,用于处理后续的复制工作

      2. 建立连接之后,从服务器会向主服务器发送 ping 命令,确认主服务器是否可用,以及当前是否可用接受处理命令。如果收到主服务器的 pong 回复说明是可用的,否则有可能是网络超时或主服务器阻塞,从服务器会断开连接发起重连

      3.身份验证。如果主服务器设置了 requirepass 选项,那么从服务器必须配置 masterauth 选项,且保证密码一致才能通过验证

      4. 身份验证完成之后,从服务器会发送自己的监听端口,主服务器会保存下来

2)数据同步 -- PSYNC 命令

      在主从服务器建立连接确认各自身份之后,就开始数据同步,从服务器向主服务器发送 PSYNC 命令,执行同步操作,并把自己的数据库状态更新至主服务器的数据库状态。Redis的主从同步分为:完整重同步(full resynchronization)和 部分重同步(partial resynchronization)。即:

      PSYNC 命令具有完整重同步(full resynchronization)和 部分重同步(partial resynchronization)两种模式。

(1)完整重同步(full resynchronization):

1、主服务器需要执行 BGSAVE 命令来生成 RDB 文件,这个生成操作会耗费主服务器大量的CPU、内存和磁盘I/O资源;

2、主服务器需要将自己生成的 RDB 文件发送给从服务器,这个发送操作会耗费主从服务器大量的网络资源(带宽和流量),并对主服务器响应命令请求的时间产生影响;

3、接收到RDB文件的从服务器需要载入主服务器发来的RDB文件,并且在载入期间,从服务器会因为阻塞而没办法处理命令请求。

(2)部分重同步(partial resynchronization):

部分重同步用于处理断线后重 复制情况:

      当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。

部分重同步功能由以下三个部分构成:

  • 主服务器的复制偏移量(replication offset)和从服务器的复制偏移量;
  • 主服务器的复制积压缓冲区(replication backlog);
  • 服务器的运行ID(run ID)。

(2.1)复制偏移量:

执行复制的双方——主服务器和从服务器会分别维护一个复制偏移量:

  • 主服务器每次向从服务器传播N个字节的数据时,就将自己的复制偏移量的值加上N;
  • 从服务器每次收到主服务器传播来的N个字节的数据时,就将自己的复制偏移量的值加上N;

通过对比主从服务器的复制偏移量,程序可以很容易地知道主从服务器是否处于一致状态:

  • 如果主从服务器处于一致状态,那么主从服务器两者的偏移量总是相同的;
  • 相反,如果主从服务器两者的偏移量并不相同,那么说明主从服务器并未处于一致状态。

    

 

       假设从服务器A在断线之后就立即重新连接主服务器,并且成功,那么接下来,从服务器将向主服务器发送 PSYNC 命令,报告从服务器A当前的复制偏移量为10086,那么这时,主服务器应该对从服务器执行完整重同步还是部分重同步呢?如果执行部分重同步的话,主服务器又如何补偿从服务器A在断线期间丢失的那部分数据呢?

      以上问题的答案都和复制积压缓冲区有关。

 

(2.2)复制积压缓冲区:

复制积压缓冲区是由主服务器维护的一个固定长度(fixed-size)先进先出(FIFO)队列,默认大小为 1MB。

和普通先进先出队列随着元素的增加和减少而动态调整长度不同,固定长度先进先出队列的长度是固定的,

当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列。

当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区里面,如图所示。

    

因此,主服务器的复制积压缓冲区里面会保存着一部分最近传播的写命令,

并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量,就像下表所示的那样。

    

当从服务器重新连上主服务器时,从服务器会通过 PSYNC 命令将自己的复制偏移量 offset 发送给主服务器,

主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作:

  • 如果offset偏移量之后的数据(也即是偏移量offset+1开始的数据)仍然存在于复制积压缓冲区里面,

那么主服务器将对从服务器执行部分重同步操作;

  • 相反,如果offset偏移量之后的数据已经不存在于复制积压缓冲区,那么主服务器将对从服务器执行完整重同步操作。

根据需要调整复制积压缓冲区的大小

Redis为复制积压缓冲区设置的默认大小为1MB,如果主服务器需要执行大量写命令,又或者主从服务器断线后重连接所需的时间比较长,那么这个大小也许并不合适。如果复制积压缓冲区的大小设置得不恰当,那么PSYNC命令的复制重同步模式就不能正常发挥作用,因此,正确估算和设置复制积压缓冲区的大小非常重要。

复制积压缓冲区的最小大小可以根据公式 second*write_size_per_second 来估算:

  • 其中 second 为从服务器断线后重新连接上主服务器所需的平均时间(以秒计算);
  • 而 write_size_per_second 则是主服务器平均每秒产生的写命令数据量(协议格式的写命令的长度总和);

例如,如果主服务器平均每秒产生1 MB的写数据,而从服务器断线之后平均要5秒才能重新连接上主服务器,那么复制积压缓冲区的大小就不能低于5MB。

为了安全起见,可以将复制积压缓冲区的大小设为 2*second*write_size_per_second,这样可以保证绝大部分断线情况都能用部分重同步来处理。

复制积压缓冲区大小的修改方法:

修改 redis.conf 配置文件中 repl-backlog-size 的参数即可。

      

 

(2.3)服务器运行ID

除了复制偏移量和复制积压缓冲区之外,实现部分重同步还需要用到服务器运行ID(run ID):

  • 每个Redis服务器,不论主服务器还是从服务,都会有自己的运行ID;
  • 运行ID在服务器启动时自动生成,由40个随机的十六进制字符组成,

    

当从服务器对主服务器进行初次复制时,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来(注意:是从服务器保存了主服务器的ID)。

当从服务器断线并重新连上一个主服务器时,从服务器将向当前连接的主服务器发送之前保存的运行ID:

  • 如果从服务器保存的运行ID和当前连接的主服务器的运行ID相同,

那么说明从服务器断线之前复制的就是当前连接的这个主服务器,主服务器可以继续尝试执行部分重同步操作;

  • 相反地,如果从服务器保存的运行ID和当前连接的主服务器的运行ID并不相同,

那么说明从服务器断线之前复制的主服务器并不是当前连接的这个主服务器,主服务器将对从服务器执行完整重同步操作。

 

3)命令传播

当完成数据同步之后,主从服务器的数据暂时达到一致状态,当主服务器执行了客户端的写命令之后,主从的数据便不再一致。为了能够使主从服务器的数据保持一致性,主服务器会对从服务器执行命令传播操作,即每执行一个写命令就会向从服务器发送同样的写命令。

在命令传播阶段,从服务器会默认以每秒一次的频率向主服务器发送心跳检测 REPLCONF ACK 其中replication_offset 是当前从服务器的复制偏移量,该命令的作用有三个:

  1. 检测主从服务器的网络连接状态
  2. 辅助实现min-slaves选项
  3. 检测命令丢失

    

     主从复制的配置使用还是比较简单的,主从复制的工作实现原理还需要我们掌握。    

参考文章:

     Redis主从复制的配置和实现原理

     详解Redis中两种持久化机制RDB和AOF(面试常问,工作常用)

 

 —— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。

关注
打赏
1664721914
查看更多评论
立即登录/注册

微信扫码登录

0.0402s