• 关于Redis中的Replication


    一、简介

    Redis的replication机制允许slave从master那里通过网络传输拷贝到完整的数据备份。具有以下特点:

    • 异步复制

    • 可以配置一主多从

    • 可以配置从服务器可以级联从服务器,既 M->S->S

    • M replication时是非阻塞的(在replication期间,M依然能够处理客户端的请求)

    • S replication期间也是非阻塞的(也可以接受来自客户端的请求,但是它用的是之前的旧数据)可以通过配置来决定S是否在进行replication时用旧数据响应客户端的请求,如果配置为否,那么slave将会返回一个错误消息给客户端。不过当新的数据接收完全后,必须将新数据与旧数据替换,即删除旧数据,在替换数据的这个时间窗口内,slave将会拒绝客户端的请求和连接

    • 能够通过replication来避免master每次持久化时都将整个数据集持久化到硬盘中。只需把master配置为不进行save操作,然后连接上一个slave,这个slave则被配置为不时地进行save操作的。不过需要注意的是,在这个用例中,必须确保master不会自动启动

    二、Master持久化功能关闭时Replication的安全性

    当有需要使用到replication机制时,一般都会强烈建议把master的持久化开关打开。即使为了避免持久化带来的延迟影响,不把持久化开关打开,那么也应该把master配置为不会自动启动的

    为了更好地理解当一个不进行持久化的master如果允许自动启动所带来的危险性。可以看看下面这种失败情形:

    假设我们有一个redis节点A,设置为master,并且关闭持久化功能,另外两个节点B和C是它的slave,并从A复制数据。

    • 如果A节点崩溃了导致所有的数据都丢失了,它会有重启系统来重启进程。但是由于持久化功能被关闭了,所以即使它重启了,它的数据集是空的。而B和C依然会通过replication机制从A复制数据,所以B和C会从A那里复制到一份空的数据集,并用这份空的数据集将自己本身的非空的数据集替换掉。于是就相当于丢失了所有的数据

    • 即使使用一些HA工具,比如说sentinel来监控master-slaves集群,也会发生上述的情形,因为master可能崩溃后迅速恢复。速度太快而导致sentinel无法察觉到一个failure的发生

    • 数据的安全很重要、持久化开关被关闭并且有replication发生的时候,应该禁止实例的自启动

    三、M/S replication的工作原理

    • 当master和slave启动时,不管这个slave是否是第一次连接上Master,它都会发送一个SYNC命令给master请求复制数据

    • master收到SYNC命令后,会在后台进行数据持久化,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份数据集发送给slave,slave会把接收到的数据进行持久化,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave

    • 当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,然后再把这一份持久化的数据发送给多个并发连接的slave

    • 当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,支持部分复制

    数据部分复制

    从2.8版本开始,slave与master能够在网络连接断开重连后只进行部分数据复制。

    master会在其内存中创建一个复制流的等待队列,master和它所有的slave都维护了复制的数据下标和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果进程id变化了,或者数据下标不可用,那么将会进行一次全部数据的复制。支持部分数据复制的命令是PSYNC

    不需硬盘参与的Replication

    一般情况下,一次复制需要将内存的数据写到硬盘中,再将数据从硬盘读进内存,再发送给slave。对于速度比较慢的硬盘,这个操作会给master带来性能上的损失。Redis2.8版本开始,实验性地加上了无硬盘复制的功能。这个功能能将数据从内存中直接发送到slave,而不用经过硬盘的存储。不过这个功能目前处于实验阶段,还未正式发布

    四、配置M/S

    slaveof <masterip> <masterport>
    slave实例需要配置该项,指向master的(ip, port)
    
    masterauth <master-password>
    如果master实例启用了密码保护,则该配置项需填master的启动密码;若master未启用密码,该配置项需要注释掉
    
    slave-serve-stale-data
    指定slave与master连接中断时的动作。默认为yes,表明slave会继续应答来自client的请求,但这些数据可能已经过期(因为连接中断导致无法从master同步)
    若配置为no,则slave除正常应答"INFO"和"SLAVEOF"命令外,其余来自客户端的请求命令均会得到"SYNC with master in progress"的应答,
    直到该slave与master的连接重建成功或该slave被提升为master。
    
    slave-read-only
    指定slave是否只读,默认为yes。若配置为no,这表示slave是可写的,但写的内容在主从同步完成后会被删掉
    
    repl-ping-slave-period
    Redis部署为Replication模式后,slave会以预定周期(默认10s)发PING包给master,该配置可以更改这个默认周期
    
    repl-timeout
    有2种情况的超时均由该配置指定:1) Bulk transfer I/O timeout; 2) master data or ping response timeout
    需要特别注意的是:若修改默认值,则用户输入的值必须大于repl-ping-slave-period的配置值,否则在主从链路延时较高时,会频繁timeout
    
    repl-disable-tcp-nodelay
    指定向slave同步数据时,是否禁用socket的NO_DELAY选项。
    若配置为yes,则禁用NO_DELAY,则TCP协议栈会合并小包统一发送,这样可以减少主从节点间的包数量并节省带宽,但会增加数据同步到slave的时间
    若配置为no,表明启用NO_DELAY,则TCP协议栈不会延迟小包的发送时机,这样数据同步的延时会减少,但需要更大的带宽
    通常情况下,应该配置为no以降低同步延时,但在主从节点间网络负载已经很高的情况下,可以配置为yes
    备注:socket的NO_DELAY选项涉及到TCP协议栈的拥塞控制算法—Nagle's Algorithm
    
    slave-priority
    指定slave的优先级。在不只1个slave存在的部署环境下,当master宕机时,Redis Sentinel会将priority值最小的slave提升为master
    需要注意的是,若该配置项为0,则对应的slave永远不会被Redis Sentinel自动提升为master

    replication相关的配置比较简单,只需要把下面一行加到slave的配置文件中

    slaveof 192.168.1.1 6379

    你也可以通过客户端发送SLAVEOF命令给slave。无硬盘复制功能可以通过repl-diskless-sync来配置,另外一个配置项repl-diskless-sync-delay用来配置当收到第一个请求时,等待多个slave一起来请求之间的间隔时间

    1、同时启动两个Redis服务器,可以考虑在同一台机器上启动两个Redis服务器,分别监听不同的端口,如6379和6380

    2、配置文件为6379.conf 6380.conf

    3、启动并配置

    ./src/redis-server  6380.conf 
    ./src/redis-server  6379.conf 
    

    4、测试

    [root@localhost redis]# ./src/redis-cli  -p 6379
    127.0.0.1:6379> flushdb
    OK
    127.0.0.1:6379> set aa 1
    OK
    127.0.0.1:6379> set bb 2
    OK
    127.0.0.1:6379> set cc 3
    OK
    127.0.0.1:6379> exit
    [root@localhost redis]# ./src/redis-cli  -p 6380
    127.0.0.1:6380> keys *
    1) "bb"
    2) "aa"
    3) "cc"
    127.0.0.1:6380> get aa 
    "1"
    127.0.0.1:6380> get bb 
    "2"

    五、only read slave

    从redis2.6版本开始,slave支持只读模式,而且是默认的。可以通过配置项slave-read-only来进行配置,并且支持客户端使用CONFIG SET命令来动态修改配置

    只读的slave会拒绝所有的写请求,只读的slave并不是为了防范不可信的客户端,毕竟一些管理命令例如DEBUGCONFIG在只读模式下还是可以使用的。如果确实要确保安全性,那么可以在配置文件中将一些命令重新命名。也许你会感到很奇怪,为什么能够将一个只读模式的slave恢复为可写的呢,尽管可写,但是只要slave一同步master的数据,就会丢失那些写在slave的数据。不过还是有一些合法的应用场景需要存储瞬时数据会用到这个特性。不过,之后可能会考虑废除掉这个特性。Setting a slave to authenticate to a master

    如果master通过requirepass配置项设置了密码,slave每次同步操作都需要验证密码,可以通过在slave的配置文件中添加以下配置项:

    masterauth <password>

    也可以通过客户端在运行时发送以下命令:

    config set masterauth <password>

    六、至少N个slave才允许向master写数据

    从redis2.8版本开始,master可以被配置为只有当master当前有至少N个slave连接着的时候才接受写数据的请求;由于redis是异步复制的,所以它并不能保证slave会收到一个写请求,所以总有一个数据丢失的时间窗口存在

    这个机制的工作原理如下所示:

    • slave每秒发送ping心跳给master,询问当前复制了多少数据

    • master会记录下它上次收到某个slave的ping心跳是什么时候

    • 使用者可以配置一个时间,来指定ping心跳的发送不应超过的一个超时时间

    如果master有至少N个slave,并且ping心跳的超时不超过M秒,那么它就会接收写请求。也许你会认为这情形好似CAP理论中弱化版的C(consistency),因为写请求并不能保证数据的一致性,但这样做,至少数据丢失被限制在了限定的时间内,即M秒

    如果N和M的条件都无法达到,那么master会回复一个错误信息。写请求也不会被处理

    有两个配置项用来配置上文中提到的N和M:

    min-slaves-to-write <number of slaves>
    min-slaves-max-lag <number of seconds>
    

    参考文章

    https://support.pivotal.io/hc/en-us/articles/205309278-How-to-setup-Redis-Master-and-Salve-replication

  • 相关阅读:
    个人永久性免费-Excel催化剂功能第31波-数量金额分组凑数功能,财务表哥表姐最爱
    个人永久性免费-Excel催化剂功能第30波-工作表快捷操作(批量创建、命名、排序、工作表目录)
    个人永久性免费-Excel催化剂功能第29波-追加中国特色的中文相关自定义函数
    发现用System.Net.Mail发邮件(代码附后),附件稍微大一点就会造成程序假死. 有没有什么简单的解决办法呢? 多谢!!
    上传文件 获取文件名 --360浏览器
    js中的json对象和字符串之间的转化
    chosen.jquery.js
    select 后台获取text 并根据text 设置value选中项
    iframe中有ajax,设置iframe自适应高度
    charme浏览器 jquery1.9.1min.js 报脚本错误 无jquery.min.map 文件
  • 原文地址:https://www.cnblogs.com/chenpingzhao/p/5167784.html
Copyright © 2020-2023  润新知