zoukankan      html  css  js  c++  java
  • Redis主备复制

         Redis 支持 Master-Slave(主从)模式,Redis Server 可以设置为另一个 Redis Server 的主机(从机),从机定期从主机拿数据。特殊的,一个从机同样可以设置为一个 Redis Server 的主机,这样一来 Master-Slave 的分布看起来就是一个有向无环图,形成 Redis Server 集群,无论是主机还是从机都是 Redis Server,都可以提供服务。

         在配置后,主机Master可负责读写服务从机Slave只负责读。Redis 提高这种配置方式,为的是让其支持数据的弱一致性,即最终一致性。redis 复制在 master 这一端是非阻塞的,也就是说在和 slave 同步数据的时候,master 仍然可以执行客户端的操作命令而不受其影响。

    二、redis主从复制特点

    1、同一个Master可以拥有多个Slaves。

    2、Master下的Slave还可以接受同一架构中其它slave的链接与同步请求,实现数据的级联复制,即Master->Slave->Slave模式;

    3、Master以非阻塞的方式同步数据至slave,这将意味着Master会继续处理一个或多个slave的读写请求;

    4、Slave端同步数据也可以修改为非阻塞是的方式,当slave在执行新的同步时,它仍可以用旧的数据信息来提供查询;否则,当slave与master失去联系时,slave会返回一个错误给客户端;

    5、主从复制具有可扩展性,即多个slave专门提供只读查询与数据的冗余,Master端专门提供写操作;

    6、通过配置禁用Master数据持久化机制,将其数据持久化操作交给Slaves完成,避免在Master中要有独立的进程来完成此操作。

    三、redis主从复制原理

     

    1、当启动一个Slave进程后,它会向Master发送一个SYNC Command,请求同步连接。无论是第一次连接还是重新连接,Master都会启动一个后台进程,将数据快照保存到数据文件中,同时Master会记录所有修改数据的命令并缓存在数据文件中;

    2、后台进程完成缓存操作后,Master就发送数据文件(dump.rdb)给Slave,Slave端将数据文件保存到硬盘上,然后将其在加载到内存中,接着Master就会所有修改数据的操作,将其发送给Slave端。

    3、若Slave出现故障导致宕机,恢复正常后会自动重新连接,Master收到Slave的连接后,将其完整的数据文件发送给Slave,如果Mater同时收到多个Slave发来的同步请求,Master只会在后台启动一个进程保存数据文件,然后将其发送给所有的Slave,确保Slave正常。

    Redis复制工作原理:

    1. 如果设置了一个Slave,无论是第一次连接还是重连到Master,它都会发出一个SYNC命令;

    2. 当Master收到SYNC命令之后,会做两件事:

        a) Master执行BGSAVE,即在后台保存数据到磁盘(rdb快照文件);

        b) Master同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类);

    3. 当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给Slave,而Slave则把内存清空后,加载该文件到内存中;

    4. 而Master也会把此前收集到缓冲区中的命令,通过Reids命令协议形式转发给Slave,Slave执行这些命令,实现和Master的同步;

    5. Master/Slave此后会不断通过异步方式进行命令的同步,达到最终数据的同步一致;

    6. 需要注意的是Master和Slave之间一旦发生重连都会引发全量同步操作。但在2.8之后版本,也可能是部分同步操作。

    部分复制 2.8开始,当Master和Slave之间的连接断开之后,他们之间可以采用持续复制处理方式代替采用全量同步。 Master端为复制流维护一个内存缓冲区(in-memory backlog),记录最近发送的复制流命令;同时,Master和Slave之间都维护一个复制偏移量(replication offset)和当前Master服务器ID(Master run id)。当网络断开,Slave尝试重连时: a. 如果MasterID相同(即仍是断网前的Master服务器),并且从断开时到当前时刻的历史命令依然在Master的内存缓冲区中存在,则Master会将缺失的这段时间的所有命令发送给Slave执行,然后复制工作就可以继续执行了; b. 否则,依然需要全量复制操作;

    rdb复制弊端请参见:http://my.oschina.net/hanruikai/blog/308007?fromerr=VJsCzCcq           

    四、redis主从配置

        实现主从复制仅需要修改Slave对应的redis.conf文件中的如下参数,Master中的此参数不需要修改:

    slaveof <master ip> <port>  

    slaveof 192.168.126.137   6379

    IP和端口为Master的IP和端口

         replication在redis.conf的配置选项:

         #slaveof [masterip] [masterport]  设置master的ip和port #masterauth [master-password]     如果master需要auth,在此设置password
         #slave-serve-stale-data yes       如果slave与master的连接断开,该选项决定slave是否继续提供服务
         #slave-read-only yes              slave是否是只读的 #repl-ping-slave-period 10        master端ping slave端的时间间隔,时刻检测slave连接的有效
         #repl-timeout 60                  replication连接的超时时间
         #slave-priority 100               slave的权重,用于redis sentinel模式中,如果master down,权重大的slave接替master

        replication是redis提供的复制功能,用于master提供给slave的数据同步。 slave在连接master后,master端会在后台启动一个进程进行rdb文件的建立,当文件建立完成后,发送给slave端,slave端收到后,会通过rdb文件完成对master的复制。

    具体示例如下:

    先打开三个终端,然后起三个实例,分别用三个 client 去连接它们:

    A:src $ ./redis-server --port 10000 --daemonize yes

    A:src $ ./redis-cli -p 10000

    端口10000的做 master。

    slave 01:

    A:src $ ./redis-server --port 10001 --daemonize yes

    A:src $ ./redis-cli -p 10001

    slave 02:

    A:src $ ./redis-server --port 10002 --daemonize yes

    A:src $ ./redis-cli -p 10002

    上面只是让它们的实例启动了并用客户端去连接它,并没有设置主从关系。在 slave 01 和 slave 02 上执行下面的命令:

    127.0.0.1:10001> slaveof 127.0.0.1 10000

    OK

    127.0.0.1:10001> 

    这样就设置好了主从关系。我们来试试有没有效果。

    127.0.0.1:10001> get testkey001

    (nil)

    127.0.0.1:10001> 

    这个时候是没有值的。

    master 上执行:

    127.0.0.1:10000> set testkey001 testvalue001

    OK

    127.0.0.1:10000> 

    然后看看 slave 上有没有:

    127.0.0.1:10001> get testkey001

    "testvalue001"

    127.0.0.1:10001> 

    127.0.0.1:10002> get testkey001

    "testvalue001"

    127.0.0.1:10002> 

    当你设置了主从关系后,slave 在第一次连接或者重新连接 master 时,slave 都会发送一条同步指令给 master ;

    master 接到指令后,开始启动后台保存进程保存数据,接着收集所有的数据修改指令。后台保存完了,master 就把这份数据发送给 slave,slave 先把数据保存到磁盘,然后把它加载到内存中,master 接着就把收集的数据修改指令一行一行的发给 slave,slave 接收到之后重新执行该指令,这样就实现了数据同步。

    slave 在与 master 失去联系后,自动的重新连接。如果 master 收到了多个 slave 的同步请求,它会执行单个后台保存来为所有的 slave 服务。

  • 相关阅读:
    两种图像缩放算法的对比与实现
    字节流与字符流
    自己的网站 首都易搜网 又修改了一下。。首页改变了
    序列化和反序列化 .NET
    关于 C#异步方法的使用
    vs2010 设计视图中控件无法加载,提示未将对象设置到对象的实例。
    .Net 中的反射(查看基本类型信息) Part.2
    URL重写
    .Net 中的反射(序章) Part.1
    数据库死锁问题 及 解决方法
  • 原文地址:https://www.cnblogs.com/moonandstar08/p/4979173.html
Copyright © 2011-2022 走看看