redis-主从复制

发布时间:2018-11-15  栏目:NoSQL  评论:0 Comments

1、主从复制简而言之呢以主redis的数量并到由redis,达到基本数据一致。主从复制应用:

复制

  1. Redis 采用异步复制。从
    Redis 2.8始发,从服务器会周期性地告知由复制流中处理的数据量。
    一个主服务器可以拥有多个从服务器。
  2. 从今服务器可以领任何从服务器的连续。除了连多个自服务器到跟一个主服务器,从服务器也足以接连至其他的打服务器,形成图状结构。
  3. Redis 的复制在主服务器上是非阻塞的。
    这象征,当一个要么多单从服务器执行初始化同步(initial
    synchronization)时,主服务器能够继续处理要。
  4. Redis 的复制在从服务器上也是非阻塞的。
  5. redis.conf
    中展开了对应安排,也能持续运用原本子的数据集处理要。另外,你还足以配备当复制流宕(dowm)掉的上,从服务器返回给客户端一个荒谬。然而,初始化同步结束后,旧的数据集需要被删除,新的数据集需要被载入。在这个简短的窗口期内,从服务器会阻塞到来的连接。
  6. 复制可就此来支撑可伸缩性,用多个从服务器处理只读查询(例如,繁重的
    SORT 操作可以分配到由服务器上),也足以只是看做数据冗余。
  7. 得动用复制来避免主服务器将合数目集写到磁盘的开支:只需要安排你的主服务器的
    redis.conf 来严防保存(所有的” 保存”
    指令),然后连一个连发复制的从服务器。但是,这种设置下而保证主服务器无见面自行还开(阅读下同样省得到更多信息)。
  • 诵读写分离
  • 容灾备份

主服务器关闭持久化时的安全性(Safety of replication)

当用了 Redis
的复制时,强烈建议在主服务器上打开持久化,或者,当不容许打开持久化时,例如由于关注延迟,实例应该吃部署为避自动重新开
为了更好之喻为什么关闭了持久化的主服务器被安排也活动重新开是好凶险的,查看下的挫折模型,数据从主服务器和该具有自服务器上吃免除:

  1. 咱俩安节点 A 作为主服务器,关闭了持久化,节点 B 和节点 C 从节点 A
    复制。
  2. A
    崩溃了,但是其富有某个自动重新开系统,重开了这个进程。但是,由于持久化是于关的,这个节点以空的多寡集重启。
  3. 节点 B 和节点 C 从空的 A 复制,于是她了绝迹了他们的数目拷贝。

当 Redis Sentinel
被用来高可用时,主服务器关闭了持久化,并打开了经过又开也是很危险的。例如,主务器非常快捷的重启,以至于
Sentinel 没有检测到破产,于是点描述的挫折模型就有了。

任何时刻数据安全还是老重大的,要禁止主服务器配置也关门持久化并自行重新开。

2、怎样设置基本?

Redis 复制如何行事(How works)

  1. 当您建一个打服务器,连接时便会见发送一个 SYNC
    命令。不管是首先软连续达还是再度连接上。
  2. 然后主服务器开始在后台保存,并且开始缓冲所有新吸纳的相会窜数据集的通令。当后台保存好之后,预告服务器传输数据库文件于起服务器,从服务器将那个保存至磁盘上,然后加载到内存中。然后主服务器开始发送缓冲的通令深受从服务器。这是经过命令流完成的,和
    Redis 的情商是相同的格式。

若得据此 telnet 试试。连上同一华在工作的 Redis 的端口,然后发送 SYNC
命令。你晤面看到大量之传导,还有主服务器收到的各级条命令于还发送给了
telnet 会话。

当主从链路出于某些原因断开时,从服务器可以活动重连。如果主服务器收到多单冒出的从服务器的一块请求,只会履行一个后台保存来服务有自服务器。

当主服务器和自服务器断开后还连上,总是执行同一次完整重共(full
resynchronization)。然而,从 Redis 2.8
以后,可以挑选执行有再共(partial resynchronization)。

  • 规格:配从不配主
  • 方式:

一些重新共(partial resynchronization)

自 Redis 2.8
开始,在复制链接断开后,主服务器和自服务器通常可以连续复制过程,而无需要一致不善完整的双重共。
当下是由此在主服务器上始建一个复制流的内存缓冲区(in-memory
backlog)
贯彻之。主服务器和颇具自服务器都记录一个复制偏移量(offset)和一个主服务器运行
ID(run
id)
,当链接断掉时,从服务器会重连接,并且请求主服务器继续复制。假设主服务器的运作
ID
还是同的,并且指定的偏移量在复制缓冲区中可用,复制会由中断的接触持续。如果当时半独标准化有不满足,将会晤尽总体重共(2.8
版之前的正常行为)。

初的一对重新共特性应用的凡里 PSYNC命令,老的实现利用的凡SYNC
命令。注意,Redis 2.8 的从服务器可以检测主服务器是否非支持
PSYNC,然后使用 SYNC 代替。

       a、在自redis中利用执行命令 slaveof host port  [slaveof no
one命令表示禁止与主机的一块儿]

无盘复制(Diskless replication)

便,一赖完整的双重共需要以磁盘上创造一个 RDB
文件,然后起磁盘重新加载与一个 RDB 来服务由服务器。

由于低速的磁盘,这对主服务器来说是老大可怜压力之操作。Redis 2.8.18
版本是率先独对无盘复制提供试验性支持之版本。在这种装置下,旁进程一直通过线(wire)发送
RDB 文件于起服务器
,而休需要动用磁盘作为中存储。

     b、在由redis的配置文件被配备slaveof host port

配置(Configuration)

布复制简直小菜一碟:只待丰富下一行到打服务器配置文件:

slaveof  192.168.1.1  6379  

当,你得把 192.168.1.1 6379 替换成你自己的主服务器 IP
地址(或主机名)和端口。或者,你可以调用 SLAVEOF
命令和主服务器主机,开始和自服务器的等同涂鸦联袂。

起诸多参数可以用来调动执行有再同步主服务器的达标之内存复制缓冲区。可以省
Redis 发布版中于带的样例文件 redis.conf 以取得更多之音讯。

  • 查询主从信:info replication

独读由服务器(Read-only slave)

从 Redis 2.6 开始,从服务器支持默认开启的只读模式。斯作为由
redis.conf 文件被的 slave-read-only 选项决定,可以当运转时采取
CONFIG SET 来开启同关闭。

单单念由服务器会拒绝所有写命令,所以写副数据到自服务器就会滋生错误。这并无代表,这个特点打算暴露于服务器实例到互联网,或者到网被无信赖的客户端,因为像
DEBUG 和 CONFIG 这样的田间管理命令等以可用。但是,可以由此以 redis.conf
中使用 rename-command 指令来禁止命令,从而改善只读实例的安全性。

君或许坏愕然,为什么要会反转只念设置,使得从服务器实例能够变成写操作的靶子。尽管这些写副的数据会在从服务器和主服务器重同步时,或者由服务器又启时被废弃,还是来局部囤积一些短命之数及可写的起服务器的客体场景。例如,客户端可储存一些预示服务器的可达性信息来调整故障转移(failover)策略。

 3、主从复制原理

认证主服务器(Authenticate to a master)

一旦你的主服务器通过 requirepass
而有一个密码,很爱配置起服务器在装有同步操作中采用是密码。

如果就这个,在一个运行的实例上,使用 redis-cli 并键入:

config  set  masterauth  <password>  

设若永久设置是,添加这个倒你的部署文件中:

masterauth  <password>  

图片 1

N 独副本才能够写(Allow writes only with N attached replicas)

自打 Redis 2.8 开始,可以装 Redis 主服务器在当下起码有 N
个从服务器的总是的状况下,才能够接受写请求。

不过,由于 Redis
使用异步复制,不可知管从服务器真正接受了一个加以的刻画请求,于是连续发出一个多少丢失的窗口期。

脚是这个特性是怎运行的:

  • Redis 从服务器每秒种 ping 主服务器,上报处理了的复制流的数据量。
  • Redis 主服务器记录及等同涂鸦从各级一个起劳动收取 ping 的岁月。
  • 用户可以配备最小由服务器数量,每令由服务器拥有一个无浮最深秒数的后退(lag)。

假定来起码 N 个低于 M 秒滞后的从服务器,写请求才会受接受。

你或许会见以为此像 CAP
理论被较宽大版本的”C”,不能保证指定写的一致性,但是至少数据丢失的时间窗口被限制在一个指定的秒数内。

若基准不饱,主服务器会返回一个荒唐,并且不见面经受写请求。

其一特点产生少单布局参数:

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

吁查看随 Redis 源码发布版自带的 redis.conf 文件获取更多信息。

全量复制:slave连接上master时候,master将整个快照发给slave,slave加载快照的数据,此时也全量复制

增量复制:master每次接到至于温馨数据库的抒写操作,同时会拿写命令传给slave

  • 主从复制存在的题目:

出于具备的描摹操作都是先期在Master上操作,然后一起创新至Slave上,所以打Master同步到Slave机器有早晚之推,当系统特别忙碌的时段,延迟题材会见尤其严重,Slave机器数量之增多为会见使之问题越来越严重。

4、常见问题

  • 切入点问题?slave1、slave2是开端开始复制还是于切入点开始复制?比如从k4进来,那之前的123是否也得以复制

–>从头开始复制,不是起切入点(创建于之日子),主从数据保持一致了

  • 从机是否好描绘?set可为?

–>从机一般配备为slave-read-only yes,即为不可set,只可以读

  • 长机shutdown后状况怎么样?从机是上位还是原地待命

–>从机不上位,原地待命

  • 主机同时回来了继,主机新增加记录,从机还能否如愿复制?

–>主机回来晚或主机身份,主机新增,从机仍然顺利复制

  • 中间同样宝由机down后状况怎么样?依照原来它亦可跟达到大部队吗?

–>如果由此命令slaveof设置的核心,从新启动由机后身份会变成主机,需要打新用命令设置为原主机的从机,那么此时数码就是伙同了;

假设是由此时从机的布局文件配置的,那么启动后仍旧是从机,且数额是合的

  • 若是打机中途变更主机,数据变动?

–>清空所有数据,并和新主机的数并

5、哨兵模式

  • 哎呀是哨兵模式?

督查主机是否有故障,如果来了故障,根据投票数自动将于机切换为主机。一个哨兵可以而且监控多单主机。

  • 怎启动哨兵?

新建配置sentinel.conf文件,并累加内容(这里是极度简化的配备):

sentinel monitor 被监督主机名字(随意) 127.0.0.1(主机的IP)
6379(主机redis的端口号) 1(至少1 单 Sentinel 同意才开展故障切换)

起先哨兵:redis-sentinel sentinel.conf

  • 每个哨兵(sentinel)定期执行之任务

a、每个 Sentinel 以每秒钟一蹩脚的频率为其所知之主服务器、从服务器和另
Sentinel 实例发送一个 PING 命令。

b、如果一个实例(instance)距离最后一差有效恢复 PING 命令的年月越
down-after-milliseconds 选项所指定的价, 那么这实例会给 Sentinel
标记为主观下线。 一个有效恢复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN

c、如果一个主服务器被记为主观下线, 那么正在监视这主服务器的拥有
Sentinel 要盖每秒一不行的频率肯定主服务器的确进入了主观下线状态。

d、如果一个主服务器被标记为主观下线, 并且有足数量之 Sentinel
(至少要达到布局文件指定的多少)在指定的岁月范围外允许就同一判定,
那么这个主服务器被记为客体下线。

e、在形似情形下, 每个 Sentinel 会以各 10
秒一糟的效率为她就清楚之具有主服务器和于服务器发送 INFO 命令。
当一个主服务器被 Sentinel 标记为客体下线时, Sentinel
向下线主服务器的富有由服务器发送 INFO 命令的频率会从 10
秒一不善变动吧各国秒一不善。

f、当没有足够数量之 Sentinel 同意主服务器已下线,
主服务器的合理性下线状态就会被移除。 当主服务器再于 Sentinel 的 PING
命令归来有效恢复时, 主服务器的司下线状态就会为移除。

  • 一个实例:

设若127.0.0.1 6379  6380
6381叔独端口分别启动了redis服务,6380吗master,其它为slave,然后启动哨兵(只监控一个master)

哨兵的日记:

2793:X 19 Aug 02:02:42.868 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2793:X 19 Aug 02:02:42.883 # Sentinel ID is bfbd85c34ae2f4d8f0cd584dda8a90bb44ebe7af
2793:X 19 Aug 02:02:42.883 # +monitor master host6379 127.0.0.1 6380 quorum 1 【监视主机】
2793:X 19 Aug 02:02:42.884 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380 【sentinel识别到的从机6379】
2793:X 19 Aug 02:02:42.885 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6380 【sentinel识别到的从机6381】

关闭6380的服务,日志:

2820:X 19 Aug 02:21:32.136 # +sdown master host6379 127.0.0.1 6380                  【主观下线】
2820:X 19 Aug 02:21:32.136 # +odown master host6379 127.0.0.1 6380 #quorum 1/1    【客观下线】
2820:X 19 Aug 02:21:32.136 # +new-epoch 2
2820:X 19 Aug 02:21:32.136 # +try-failover master host6379 127.0.0.1 6380
2820:X 19 Aug 02:21:32.147 # +vote-for-leader bfbd85c34ae2f4d8f0cd584dda8a90bb44ebe7af 2
2820:X 19 Aug 02:21:32.147 # +elected-leader master host6379 127.0.0.1 6380
2820:X 19 Aug 02:21:32.147 # +failover-state-select-slave master host6379 127.0.0.1 6380  【故障转移操作现在处于select-slave状态-sentinel选择可以升级为主的从机】
2820:X 19 Aug 02:21:32.206 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6380 【已经找到可以升级为主的从机】
2820:X 19 Aug 02:21:32.207 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6380【故障转移操作现在处于send-slaveof-noone状态-执行slaveof no one命令将从升级为主】
2820:X 19 Aug 02:21:32.292 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6380【故障转移操作现在处于wait-promotion状态-等待从升级为主】
2820:X 19 Aug 02:21:32.853 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6380
2820:X 19 Aug 02:21:32.853 # +failover-state-reconf-slaves master host6379 127.0.0.1 6380【故障转移操作现在处于reconf-slaves状态-重新配置院主机的所有从机】
2820:X 19 Aug 02:21:32.906 * +slave-reconf-sent slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380
2820:X 19 Aug 02:21:33.863 * +slave-reconf-inprog slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380
2820:X 19 Aug 02:21:33.863 * +slave-reconf-done slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380
2820:X 19 Aug 02:21:33.939 # +failover-end master host6379 127.0.0.1 6380【故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了】
2820:X 19 Aug 02:21:33.939 # +switch-master host6379 127.0.0.1 6380 127.0.0.1 6381【配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息】
2820:X 19 Aug 02:21:33.940 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6381
2820:X 19 Aug 02:21:33.940 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6381
2820:X 19 Aug 02:22:03.944 # +sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6381

自日记可以看出,主机从6380切换到了6381。上面日志也得看成一不善故障转移的步子。

这时候,启动6380端口底劳动,日志:

2820:X 19 Aug 02:30:57.570 # -sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6381
2820:X 19 Aug 02:31:07.500 * +convert-to-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6381

自打日记可以望,原主机down机后,再过来时候,哨兵会将该看成当前主机(6381)的从机使用

流淌:在故障切换的时各个实例的布置文件以及sentinel.conf配置文件会自行做出相应的改

  • 差不多哨兵模式(来源博客https://blog.csdn.net/enlyhua/article/details/80544135)

哨兵+主从复制保证了redis的胜可用,通常为保哨兵的健壮性,将哨兵部署为集群,至少3独节点

a、为什么redis哨兵集群不克吧2单节点?

 如果哨兵集群仅仅部署了单2独哨兵实例,Configuration: quorum = 1

+—-+          +—-+

| M1 |———| R1 |

| S1 |            | S2 |

+—-+         +—-+

master宕机,s1(哨兵1)和s2中只要发生1单哨兵认为master宕机就可推行切换,同时s1和s2中见面选出产生一个哨兵来推行故障转移。同时这个时,也尽管是多数(majority)哨兵都是运作的,但是若尽M1和S1运行的机器宕机了,那么哨兵只生1个了,此时就算没majority来允许实施故障转移,虽然另外一光机器还有一个R1,但是故障转移不会见尽。

b、经典的3节点哨兵模式:Configuration: quorum
= 2,majority

  +—-+

   | M1 |

   | S1 |

  +—-+

 +—-+          +—-+

 | R2 |            | R3 |

 | S2 |            | S3 |

+—-+           +—-+

假若M1所当机械宕机了,那么三独哨兵还剩下2个,S2和S3可以一如既往觉得master宕机,然后推产生一个来实行故障转移。同时3只哨兵的majority是2,所以还剩余的2个哨兵运行在,就好允许实施故障转移

c、小结:每次一个哨兵要开主备切换,首先需要quorum数量的哨兵认为odown,然后推出一个哨兵来举行切换,这个哨兵还得得majority哨兵的授权,才会规范实施切换。如果quorum
< majority,比如5单哨兵,majority就是3,quorum设置为2,那么就算3独哨兵授权就好实施切换。但是若quorum
>= majority,那么要quorum数量之哨兵都授权,比如5独哨兵,quorum是5,那么要5个哨兵都同意授权,才能够执行切换

6、客户端API连接使用redis

  • 直连redis

先是仔细读redis.conf文件以下说明,正确配置redis.conf的bind、protect-mode并确认防火墙,否则会造成连日不达标redis。

图片 2

图片 3

直连redis代码:

package com;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main(String[] args) {

        JedisPool jedisPool=new JedisPool("192.168.1.113", 6381);
        Jedis jedis=jedisPool.getResource();
        Set<String> out=jedis.keys("*");
        System.out.println(out);
        jedis.set("zhongguo","weida");

    }
} 
  • 通过哨兵连接redis

率先仔细读sentinel.conf文件以下说明,正确配置redis.conf的bind、protect-mode并肯定防火墙,否则会造成连日不达到redis。

图片 4

经过哨兵连接redis代码:

package com;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main(String[] args) {

        Set<String> sentinels=new HashSet<String>();
        sentinels.add("192.168.1.113:26379");//如果有多个哨兵,可继续添加
        JedisSentinelPool jedisSentinelPool=new JedisSentinelPool("host6379", sentinels);
        Jedis jedis=jedisSentinelPool.getResource();
        Set<String> out=jedis.keys("*");
        System.out.println(out);
        jedis.set("shoudu","beijing");
    }
}

 

留下评论

网站地图xml地图