zoukankan      html  css  js  c++  java
  • redis(4)--redis集群之主从复制

    集群

    先来简单了解下redis中提供的集群策略, 虽然redis有持久化功能能够保障redis服务器宕机也能恢复并且只有少量
    的数据损失,但是由于所有数据在一台服务器上,如果这台服务器出现硬盘故障,那就算是有备份也仍然不可避免数据丢失的问题。

    在实际生产环境中,我们不可能只使用一台redis服务器作为我们的缓存服务器,必须要多台实现集群,避免出现单点故障;

    主从复制

    复制的作用是把redis的数据库复制多个副本部署在不同的服务器上,如果其中一台服务器出现故障,也能快速迁
    移到其他服务器上提供服务。 复制功能可以实现当一台redis服务器的数据更新后,自动将新的数据同步到其他服务器上

    主从复制就是我们常见的master/slave模式, 主数据库可以进行读写操作,当写操作导致数据发生变化时会自动将
    数据同步给从数据库。而一般情况下,从数据库是只读的,并接收主数据库同步过来的数据。 一个主数据库可以有多个从数据库

    配置

    在redis中配置master/slave是非常容易的,只需要在从数据库的配置文件中加入slaveof 主数据库地址 端口。 而master 数据库不需要做任何改变
    准备三台服务器,分别安装redis , server1(192.168.25.129) server2(192.168.25.130) server3(192.168.25.131)
    1. 在server2的redis.conf文件中增加 slaveof server1-ip 6379 (即:slaveof 192.168.25.129 6379)

     在server3的redis.conf文件中增加 slaveof server1-ip 6379 (即:slaveof 192.168.25.129 6379)
    2. 启动server1,然后启动server2,server3
    3. 访问server2的redis客户端,输入 INFO replication

    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:192.168.25.129
    master_port:6379
    master_link_status:down
    master_last_io_seconds_ago:-1
    master_sync_in_progress:0
    slave_repl_offset:1
    master_link_down_since_seconds:1556958915
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0

    则证明从服务器没有起来,可以yum install telnet安装telnet命令,安装成功后,用telnet 192.168.25.129 6379 试一下能不能访问,如果不能访问则查看主节点配置(server1 的redis.config)

    vim redis.config 查找下图标黄的配置

    # Examples:
    #
    # bind 192.168.1.100 10.0.0.1
    # bind 127.0.0.1 ::1
    #
    # ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
    # internet, binding to all the interfaces is dangerous and will expose the
    # instance to everybody on the internet. So by default we uncomment the
    # following bind directive, that will force Redis to listen only into
    # the IPv4 lookback interface address (this means Redis will be able to
    # accept connections only from clients running into the same computer it
    # is running).
    #
    # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
    # JUST COMMENT THE FOLLOWING LINE.
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bind 127.0.0.1
    
    # Protected mode is a layer of security protection, in order to avoid that
    # Redis instances left open on the internet are accessed and exploited.
    #
    # When protected mode is on and if:
    #
    # 1) The server is not binding explicitly to a set of addresses using the
    #    "bind" directive.
    # 2) No password is configured.
    #
    # The server only accepts connections from clients connecting from the
    # IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
    # sockets.
    #
    # By default protected mode is enabled. You should disable it only if
    # you are sure you want clients from other hosts to connect to Redis
    # even if no authentication is configured, nor a specific set of interfaces
    # are explicitly listed using the "bind" directive.
    protected-mode yes
    
    # Accept connections on the specified port, default is 6379 (IANA #815344).
    # If port 0 is specified Redis will not listen on a TCP socket.
    port 6379
    
    # TCP listen() backlog.
    #
    # In high requests-per-second environments you need an high backlog in order
    # to avoid slow clients connections issues. Note that the Linux kernel
    

      

      redis3.2版本后新增protected-mode配置,默认是yes,即开启。设置外部网络连接redis服务,设置方式如下:

      1、关闭protected-mode模式,此时外部网络可以直接访问

      2、开启protected-mode保护模式,需配置bind ip或者设置访问密码

      

      而bind 127.0.0.1 限制访问地址,设置为 0.0.0.0 表示都可以访问,如果是127.0.0.1 表示localhost访问 

      修改后配置从新启动主、从服务器。可以看到:

      

    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:192.168.25.129
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:7
    master_sync_in_progress:0
    slave_repl_offset:57
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0

    4. 通过在master机器上输入命令,比如set foo bar 、 在slave服务器就能看到该值已经同步过来了

     在server1主节点上,设置key,并且get key

    127.0.0.1:6379> set lf 1994
    OK
    127.0.0.1:6379> get lf
    "1994"
    在server2、server3从节点上get key,一样可以拿到值

    127.0.0.1:6379> get lf
    "1994"

    原理

    全量复制

    Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤

     在server2上设置监听:replconf listening-port 6379

     返回ok后,再输入:sync进行监听:

     在server1主节点,设置一个key和value 

    127.0.0.1:6379> set hello helloword
    OK
    

     观察server2

    127.0.0.1:6379> replconf listening-port 6379
    OK
    127.0.0.1:6379> sync
    Entering slave output mode...  (press Ctrl-C to quit)
    SYNC with master, discarding 88 bytes of bulk transfer...
    SYNC done. Logging commands from master.
    "PING"
    "SELECT","0"
    "set","hello","helloword"
    "PING"
    "PING"
    "PING"
    "PING"
    "PING"
    

      

    完成上面几个步骤后就完成了slave服务器数据初始化的所有操作,savle服务器此时可以接收来自用户的读请求。
    master/slave 复制策略是采用乐观复制,也就是说可以容忍在一定时间内master/slave数据的内容是不同的,但是两者的数据会最终同步。
    具体来说,redis的主从同步过程本身是异步的,意味着master执行完客户端请求的命令后会立即返回结果给客户端,然后异步的方式把命令同步给slave。
    这一特征保证启用master/slave后 master的性能不会受到影响。

    但是另一方面,如果在这个数据不一致的窗口期间,master/slave因为网络问题断开连接,而这个时候,master是无法得知某个命令最终同步给了多少个slave数据库。
    不过redis提供了一个配置项来限制只有数据至少同步给多少个slave的时候,master才是可写的:
    min-slaves-to-write 3 表示只有当3个或以上的slave连接到master,master才是可写的
    min-slaves-max-lag 10 表示允许slave最长失去连接的时间,如果10秒还没收到slave的响应,则master认为该slave以断开

    增量复制

    从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份
    master node会在内存中创建一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制
    但是如果没有找到对应的offset,那么就会执行一次全量同步

    无硬盘复制

    前面我们说过,Redis复制的工作原理基于RDB方式的持久化实现的,也就是master在后台保存RDB快照,slave接收到rdb文件并载入,但是这种方式会存在一些问题
    1. 当master禁用RDB时,如果执行了复制初始化操作,Redis依然会生成RDB快照,当master下次启动时执行该RDB文件的恢复,但是因为复制发生的时间点不确定,所以恢复的数据可能是任何时间点的。
    就会造成数据出现问题

    2. 当硬盘性能比较慢的情况下(网络硬盘),那初始化复制过程会对性能产生影响因此2.8.18以后的版本,Redis引入了无硬盘复制选项,
    可以不需要通过RDB文件去同步,直接发送数据,通过以下配置来开启该功能
    repl-diskless-sync yes
    master**在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了

  • 相关阅读:
    [JSOI2010]满汉全席 2sat
    (转)MongoDB实战开发 【零基础学习,附完整Asp.net示例】
    (转)ASP.NET的Cookie跨域问题
    (转)发一个自己写的账号管理软件
    (转)Silverlight学习点滴之一——使用WCF RIA构建应用
    (转)再议依赖注入
    (转)【探索发现】winform 网络传输时候封包与解包心得
    (转)使用Entity Framework和WCF Ria Services开发SilverLight之1:简单模型
    (转)LINQ to Entities 多条件动态查询
    (转)最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用15
  • 原文地址:https://www.cnblogs.com/flgb/p/10808848.html
Copyright © 2011-2022 走看看