一. 复制环境准备

  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. Android进阶:一、日志打印和保存策略

    前言: 项目开始没有做好日志统计工作,每次有问题后端都得找前端对接,严重影响工作效率.最近特地在项目中加上日志保存策略,在此分享,供需要的人学习. 一.更详细的日志信息 既然决定自定义一个log,那我 ...

  2. python 判断连个 Path 是否是相同的文件夹

    python 判断连个 Path 是否是相同的文件夹 import os os.path.normcase(p1) == os.path.normcase(p2) normcase() 在 windo ...

  3. git ignore 总结

    git ignore 总结 忽略和 ! 不忽略的先后顺序 gitignore的规则是有从上到下的顺序的,所以当我们使用 ! 不忽略的时候,这个顺序会对结果产生影响 例如: # 忽略所有 folder ...

  4. TCP/IP详解 卷一学习笔记(转载)

    https://blog.csdn.net/cpcpcp123/article/details/51259498

  5. Django“少折腾”

    1.Django中文语言.时区 修改项目setting文件 LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'

  6. bs4库学习

    # -*- coding:utf-8 -*- import bs4 import requests def tags_val(tag, key='', index=0): ''' tag指HTML元素 ...

  7. 开始食用grpc(之一)

    开始食用grpc(之一) 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9501353.html ```   记一次和一锅们压马路,路过一咖啡厅(某巴克),随口 ...

  8. python多线程和多进程使用

    # 多线程 from concurrent.futures import ThreadPoolExecutor # 多进程 from concurrent.futures import Process ...

  9. [微信小程序]在应用地图时,如何设置满屏(高度)

    微信小程序在做地图功能时 用常规的办法height:100%:来设置高度来占满屏幕是不行的 它不会生效 应该改用单位vh 例如 height:100vh 这样就可以是地图占满整个屏幕高度

  10. linux下tomcat服务器的启动和关闭以及查看实时打印日志

    本页面中的操作都在tomcat的bin目录下 <一> 一般我都是使用: ./shutdom.sh //关闭tomcat ./startup.sh //开启tomcat服务 <二> ...