一. 复制环境准备

  1.1 主库环境(172.168.18.201)

环境

说明

操作系统版本 CentOS  7.4.1708 
IP地址 172.168.18.201
网关Gateway 172.168.18.1
DNS 172.168.16.11
Redis版本和端口 4.0.6  和 6379
Redis 密码 123456
是否RDB持久化 开启
是否 AOF持久化 开启

  1.2 从库环境(172.168.18.203)

环境

说明

操作系统版本 CentOS  7.4.1708 
IP地址 172.168.18.203
网关Gateway 172.168.18.1
DNS 172.168.16.11
Redis版本和端口 4.0.6  和 6379
Redis密码 123456
是否RDB持久化 开启
是否 AOF持久化 开启
是否只读库 只读

二. 复制配置

  2.1 主库环境密码设置

    在201主库上,找到redis目录下的redis.conf文件,打开文件找到requirepass,在500行,下面脚本修改,密码为:123456

    -- 原脚本
# requirepass foobared
-- 修改后
requirepass

    修改后,设置防为墙,重启redis服务,重新登录主服务器,客户端连接成功,脚本如下:

    [root@hsr bin]# iptables -F
[root@hsr bin]# ./redis-cli -h 172.168.18.201 -p -a
172.168.18.201:> config get requirepass
) "requirepass"
) ""

    在slave从库203上,使用203从库的redis客户端连接201主库redis服务器,主从网络连接没有问题,连接成功,脚本如下:

    [root@hsr bin]# ./redis-cli -h 172.168.18.201 -p  -a
172.168.18.201:> config get requirepass
) "requirepass"
) ""

  2.2 主库设置RDB持久化和AOF持久化

    redis服务器默认是使用的RDB持久化,下面是save自动保存的触发条件点,以及rdb文件名, 脚本如下:

    172.168.18.201:> config get save
) "save"
) "900 1 300 10 60 10000"
172.168.18.201:> config get dbfilename
) "dbfilename"
) "dump.rdb"

    修改redis.conf文件,开启AOF持久化,在配置文件中找到appendonly将no改为yes, appendonly.aof 文件路径默认产生在启动所在的目录,为./dir。缓冲区数据写入磁盘也是默认模式Everysec ,相关脚本如下:

    -- 在672行开启AOF
appendonly yes
-- 263行文件默认路径
dir ./ --- 关闭redis服务,重启后查看
172.168.18.201:> config get appendonly
) "appendonly"
) "yes" 172.168.18.201:> config get appendfsync
) "appendfsync"
) "everysec"
    -- 开启后,持久化文件生成如下列表:
[root@hsr bin]# ls -l
总用量
-rw-r--r-- root root 12月 : appendonly.aof
-rw-r--r-- root root 12月 : dump.rdb

  2.3 从库配置

    从库也一样,设置密码为123456, 设置防火墙,开启AOF持久化,从库默认是只读模式。参考主库设置,这里就不再介绍,最后查看脚本如下:

    [root@xuegod64 redis]# redis-cli -h 172.168.18.203 -p  -a
172.168.18.203:> config get appendonly
) "appendonly"
) "yes"
172.168.18.203:> config get requirepass
) "requirepass"
) ""
172.168.18.203:> config get slave-read-only
) "slave-read-only"
) "yes"

  2.4 启动复制

    在从库203上设置slaveof参数,让一个从服务器去复制主服务器。下面修改从库配置文件,先不用重启redis服务,脚本如下:

    -- 将280行配置
# slaveof <masterip> <masterport>
-- 修改后如下,设置好对应的主库ip和端口
slaveof 172.168.18.201

  2.5 设置身份验证

    在从库203上设置身份验证 masterauth选项(slave 对 master 进行验证),在需要进行身份验证时,从服务器将向主服务器发送一条auth命令,命令的参数为从服务器masterauth选项的值。

    -- 将287行配置修改
# masterauth <master-password>
-- 修改后如下, 设置主库的密码为123456
masterauth
    -- 最后客户端关闭从库服务,重启服务
[root@xuegod64 redis]# redis-cli -h 172.168.18.203 -p -a
172.168.18.203:> shutdown
not connected> exit
[root@xuegod64 redis]# redis-server redis.conf

  

三.复制数据同步测试

  3.1 测试主从数据同步

    -- 在主库201设置一个kev value, 脚本如下:
172.168.18.201:> set repl "hello"
OK
-- 在从库203上读取主库该key成功,脚本如下:
172.168.18.203:> get repl
"hello" -- 在主库删除该key,脚本如下:
172.168.18.201:> del repl
(integer)
--在从库上读取该key,脚本如下:
172.168.18.203:> get repl
(nil)

  3.2 测试从库是否只读

    --下面在从库写入一个key,错误信息如下:
172.168.18.203:> set msg1 "hello"
(error) READONLY You can't write against a read only slave.

  3.3 在从库开启了日志记录,查看redis.log文件,相关复制的信息如下:

:S  Dec ::18.610 * Connecting to MASTER 172.168.18.201:
:S Dec ::18.610 * MASTER <-> SLAVE sync started
:S Dec ::18.611 * Non blocking connect for SYNC fired the event.
:S Dec ::18.612 * Master replied to PING, replication can continue...
:S Dec ::18.613 * Partial resynchronization not possible (no cached master)
:S Dec ::18.615 * Full resync from master: 0c208c84b99e1970721404abf88a92d80c50d0d2:
:S Dec ::18.708 * MASTER <-> SLAVE sync: receiving bytes from master
:S Dec ::18.708 * MASTER <-> SLAVE sync: Flushing old data
:S Dec ::18.708 * MASTER <-> SLAVE sync: Loading DB in memory
:S Dec ::18.708 * MASTER <-> SLAVE sync: Finished with success
:S Dec ::18.710 * Background append only file rewriting started by pid
:S Dec ::18.748 * AOF rewrite child asks to stop sending diffs.
:C Dec ::18.748 * Parent agreed to stop sending diffs. Finalizing AOF...
:C Dec ::18.749 * Concatenating 0.00 MB of AOF diff received from parent.
:C Dec ::18.749 * SYNC append only file rewrite performed
:C Dec ::18.749 * AOF rewrite: MB of memory used by copy-on-write
:S Dec ::18.812 * Background AOF rewrite terminated with success
:S Dec ::18.812 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
:S Dec ::18.812 * Background AOF rewrite finished successfully

四. 复制运行状态参数信息

  4.1 主库缓冲队列信息

    缓冲队列的大小默认是1MB,可以在redis.conf中的配置项repl-backlog-size进行设置,还有一个配置项repl-backlog-ttl,表示当主从断开后,缓冲队列的缓存时间。

    172.168.18.201:> config get repl-backlog-ttl
) "repl-backlog-ttl"
) "" 172.168.18.201:> config get repl-backlog-size
) "repl-backlog-size"
) ""

  4.2 info replication命令查看主库当前复制状态信息

172.168.18.201:> info replication
# Replication
role:master
connected_slaves:
slave0:ip=172.168.18.203,port=,state=online,offset=,lag=
master_replid:0c208c84b99e1970721404abf88a92d80c50d0d2
master_replid2:
master_repl_offset:
second_repl_offset:-
repl_backlog_active:
repl_backlog_size:
repl_backlog_first_byte_offset:
repl_backlog_histlen:

  4.3  info replication命令查看从库当前复制状态信息

172.168.18.203:> info replication
# Replication
role:slave
master_host:172.168.18.201
master_port:
master_link_status:up
master_last_io_seconds_ago:
master_sync_in_progress:
slave_repl_offset:
slave_priority:
slave_read_only:
connected_slaves:
master_replid:0c208c84b99e1970721404abf88a92d80c50d0d2
master_replid2:
master_repl_offset:
second_repl_offset:-
repl_backlog_active:
repl_backlog_size:
repl_backlog_first_byte_offset:
repl_backlog_histlen:

  注意:上一篇讲到主从偏移量相同时,表示主从服务器处于一致状态,反之则不一致。但这里显示的主从偏移量不一致,以后再了解。

  4.4  role命令查看主库和从库信息

    ROLE命令它提供 master 和 slave 的复制状态以及它们的复制偏移量,连接的 slaves 列表等等。role输出一个数组,第一个参数是 master, slave, sentinel 三个中的一个。

172.168.18.201:> role
) "master"
) (integer)
) ) ) "172.168.18.203"
) ""
) "" 172.168.18.203:> role
) "slave"
) "172.168.18.201"
) (integer)
) "connected"
) (integer)

  

五. 复制的内部实现步骤

  5.1 客户端设置主服务器的地址和端口

    从服务器首先将主服务器IP地址和端口保存到服务器状态的redisserver结构下masterhost和masterport属性中。

  5.2 建立套接字连接

    在slaveof命令执行之后,从服务器将根据命令所设置的ip地址和端口,创建连向主服务器的套接字连接:

    (1)如果从服务器成功连接到主服务器,那么从服务器将为这个套接字关联一个专门用于处理复制工作的文件事件处理器。执行的工作包括如接收RDB文件,主服务器传播的写命令等。

    (2)如果主服务器成功接受从服务器,将为该套接字创建相应的客户端状态,并将从服务器看作是一个连接到主服务器的客户端来对待。这时从服务器将同时具有服务器和客户端两个身份。

  5.3 发送ping命令

    从服务器成为主服务器客户端之后,做的第一件事就是向主服务器发送一个ping命令。该命令有两个作用:

    (1) 虽然主从服务器成功建立起了套接字连接,但双方并未使用该套接字进行过任何通信,通过发送ping命令可以检查套接字的读写状态是否正常。

    (2) 通过发送ping命令可以检查主服务器能否正常处理命令请求。

    从服务器发送ping命令之后将遇到三种情况的其中一种:

    (1) 如果主服务器向从服务器返回了一个命令回复,但从服务器却不能在规定的时限(timeout)内读出命令回复内容,那么表示主从服务器之间的网络连接状态不佳,这种情况,从服务器会断开重新创建连向主服务器的套接字。

    (2) 如果主服务器向从服务器返回了一个错误,那么从服务器会断开并重新创建连向主服务器的套接字。

    (3) 如果主服务向从服务器成功回复,那么网络正常并且主服务器可以正常处理从服务器发送的命令请求。

  5.4 身份验证

    从服务器收到主服务器返回的ping 回复后,接着决定是否进行身份验证:

    (1) 如果从服务器设置了masterauth选项,那么进行身份验证。

    (2) 如果从服务器没有设置masterauth选项,那么不进行身份验证。

    从服务器在身份验证阶级可以遇到的情况有以下几种:

    (1)如果主服务器没有设置requirepass选项, 从服务器也没有设置masterauth选项,那么复制工作可以继续进行。

    (2)如果从服务器的masterauth选项设置的密码与主服务器密码不相同,那么主服务器返回一个invalid password错误。

    (3)主服务器没有设置requirepass选项,但从服务器设置了masterauth选项,那么主服务器将返回一个no password  is set 错误。

  5.5 发送端口信息

    从服务器在身份验证后,从服务器将执行replconf listening-port port_number,向主服务器发送从服务器的监听端口号。

    主服务器在接受到这个命令之后,会将端口号记录在从服务器所对应的客户端状态的slave_listening_port属性中。通过info replication命令查看从服务器端口号。

  5.6 数据同步

    从服务器将向主服务器发送psync命令,执行同步操作,并将自己的数据库更新到主服务器数据库当前所处的状态。

  5.7 命令传播

    当完成了同步之后,主从服务器就会进入命令传播阶段,这时主服务器只要一直将自己执行的命令发送给从服务器,而从服务器只要一直接收并执行主服务器发来的写命令,就可以保证 主从一致了。

      

六. 复制的心跳检测

  在命令传播阶级,从服务器默认会以每秒一次的频率,向主服务器发送命令:replconf ack  offset。 发送replconf ack命令对于主从服务器有三个作用:

(1) 检测主从服务器的网络连接状态。

(2) 辅助实现min-slaves选项。

(3) 检测命令丢失。

  6.1 检测主从服务器的网络连接状态

    主从服务器可以通过发送和接收replconf ack 命令来检查两者之间的网络连接是否正常:如果主服务器超过一秒钟没有收到从服务器发来的replconf ack命令,那么主服务器就知道主从服务器之间的连接出现问题了。

    通过向主服务器发送info replication命令,在列出的从服务器列表的lag一栏中,我们可以看到相应从服务器最后一次向主服务器发送replconf ack 命令距离现在过了多少秒。 

    172.168.18.201:> info replication
# Replication
role:master
connected_slaves:
  slave0:ip=172.168.18.203,port=,state=online,offset=,lag=

    上面lag=0 表示刚刚发送过 replconf ack命令。       在一般情况下,lag的值应该在0秒或者1秒之间跳动,如果超过1秒的话,那么说明主从服务器之间的连接出现了故障。

  6.2 辅助实现min-slaves配置选项

    redis的min-slaves-to-write和min-slaves-max-lag两个选项可以防止主服务器在不安全的情况下执行写命令。意思是:至少有 N 个 slave ,并且滞后小于 M 秒,则写入将被接受,反之写入不被接受,master 将会回复一个 error。

    --例如:在主库配置如下:
min-slaves-to-write
min-slaves-max-lag

    如果从服务器的数量少于3个,或者三个从服务器的延迟(lag)值都大于或等于10秒时,主服务器将拒绝执行写命令,这里的lag延迟值就是上面提到的INFO replication命令的lag值。

  6.3 检测命令丢失

    如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么当从服务器向主服务器发送replconf ack命令时,主服务器将发觉从服务器当前的复制偏移量小于自己的复制偏移量,然后主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里面找到从服务器缺少的数据,并将这些数据重新发送给从服务器。

    注意:主服务向从服务器补发缺失数据这一操作的原理和部分重同步操作的原理非常相似,区别在于,补发缺失数据操作在主从服务器没有断线的情况下执行,而部分重同步操作则在主从服务器断线并重连之后执行。

  

7  Redis复制如何处理 key 的过期

  (1) slave 不会让 key 过期,而是等待 master 让 key 过期。当一个 master 让一个 key 到期(或由于 LRU 算法将之驱逐)时,它会合成一个 DEL 命令并传输到所有的 slave。

  (2) 由于这是 master 驱动的 key 过期行为,master 无法及时提供 DEL 命令,所以有时候 slave 的内存中仍然可能存在在逻辑上已经过期的 key 。为了处理这个问题,slave 使用它的逻辑时钟以报告只有在不违反数据集的一致性的读取操作(从主机的新命令到达)中才存在 key。

  (3) 当一个Lua脚本运行时,master 中的时间是被冻结的,这样脚本运行的时候,一个给定的键要么存在要么不存在。这可以防止 key 在脚本中间过期,保证将相同的脚本发送到 slave ,从而在二者的数据集中产生相同的效果。

  一旦一个 slave 被提升为一个 master ,它将开始独立地过期 key,而不需要任何旧 master 的帮助。

8.启动复制的其它方法

  (1)在从库启动Redis服务的时候,可以指定主服务器信息,命令:redis-server --slaveof masterip masterport。 例如:redis-server --slaveof 172.168.18.201 6379 。

(2)在从库客户端指定主服务器信息,命令:redis> SLAVEOF masterip masterport。这样SLAVEOF命令会停止与原有主服务器的同步,转而向新主服务器进行同步。

 

redis 系列22 复制Replication (下)的更多相关文章

  1. redis 系列21 复制Replication (上)

    一.   概述 使用和配置主从复制非常简单,每次当 slave 和 master 之间的连接断开时, slave 会自动重连到 master 上,并且无论这期间 master 发生了什么, slave ...

  2. redis系列二: linux下安装redis

    下面介绍在Linux环境下,Redis的安装与配置 一. 安装 1.首先上官网下载Redis 压缩包,地址:http://redis.io/download 下载稳定版3.0即可. 2.通过远程管理工 ...

  3. redis系列一: windows下安装redis

    一. 下载Redis Redis 支持 32 位和 64 位.这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 red ...

  4. redis 系列25 哨兵Sentinel (高可用演示 下)

    一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS  7.4.1708  IP地址 172.168.18.200 网关Gateway 1 ...

  5. 【目录】redis 系列篇

    随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...

  6. redis系列--主从复制以及redis复制演进

    一.前言 在之前的文章已经详细介绍了redis入门基础已经持久化相关内容包括redis4.0所提供的混合持久化. 通过持久化功能,Redis保证了即使在服务器宕机情况下数据的丢失非常少.但是如果这台服 ...

  7. Redis系列(四):Redis的复制机制(主从复制)

    本篇博客是Redis系列的第4篇,主要讲解下Redis的主从复制机制. 本系列的前3篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装 Redis系列(二):Redis的5种数据 ...

  8. redis 系列1 linux下安装说明

    一. 安装环境 操作系统:centos 7 ,redis版本4.06,客户端windows 7 ,vs2015. 1.1 安装前的条件 yum -y install gcc-c++ 判断是否安装了gc ...

  9. Redis 系列之CentOS下Redis的安装

    前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么redis版本就不能低于3.2版本,由于这个特性是3.2版本才有的.另外需要注意的是 ...

随机推荐

  1. 源生API解析XML文档与dom4j解析XML文档

    一.XML语言 XML是一种可扩展的标记语言,是一种强类型的语言,类似HTML(超文本标记语言,是一种弱类型的语言).XML是一种通用的数据交换格式(关系型数据库),综上所诉:XML可以传输数据,也可 ...

  2. 关机,重启BAT命令

    关机命令shutdown -s -t 重启命令 shutdown -r -t

  3. MySQL数据库的定时备份

    1. 创建shell脚本 vim backupdb.sh 创建脚本内容如下: #!/bin/sh db_user="root" db_passwd=" db_name=& ...

  4. [Git]2018-10 解决git cmd中文乱码问题

    2018年10月12日 莫名其妙出现cmd下git log中文乱码问题,显示一堆<E4><A8>之类的乱码.git bash却一切正常. 怀疑是Windows系统升级出现的不兼 ...

  5. 发现Chrome 浏览器 JavaScript Date对象的几个Bug

    打开浏览器F12 Console 输入: 第一个 位数影响 new Date("2018-06-9") Sat Jun 09 2018 00:00:00 GMT+0800 (中国标 ...

  6. XIX Open Cup named after E.V. Pankratiev. GP of Poland(AMPPZ-2018)

    A. Drone With a Camera 三分套三分. #include<cstdio> #include<cmath> #include<algorithm> ...

  7. Chrome_高亮显示当前改变的区域

  8. RCNN论文细节

    写在前面: 本系列笔记主要记录本人在阅读过程中的收获,尽量详细到实现层次,水平有限,欢迎留言指出问题~ 这篇文章被认为是深度学习应用于目标检测的开山之作,自然是要好好读一下的,由于文章是前些日子读的, ...

  9. 弄懂CNN,然后提升准确率4.21-4.27

    英语: 1.每天背单词,75起步.(这周没怎么背,考虑调整了) 2.并背王江涛图画作文一:传统文化(这周没背,但肯定要做) 学校: 0.吴恩达ML 1.毕设一:可视化,肺癌基因突变,深度学习(那么作图 ...

  10. ES6-个人学习大纲

    1,let   const学习补充 1.1,let的知识点: 01-作用域只限制在当前代码块内,代码块形式如下: { var str = '张三'; console.log(str); let str ...