zoukankan      html  css  js  c++  java
  • Redis主从架构核心原理

    Redis-Cluster工作原理:

      redis集群内置了16384个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

      例如三个节点:槽分布的值如下:

        SERVER1:  0-5460

        SERVER2:  5461-10922

        SERVER3:  10923-16383

    容错机制: 

       选举过程是所有的主节点(master)参与,如果过半数的master认为故障节点挂掉了,就会将它踢出集群就像狼人杀一样,故障节点所对应的从节点(slave)就会自动升级为主节点。因为每个节点只存储部分信息,所以当主节点挂掉之后,又没有从节点替补的情况下集群就会挂掉,因为它不是一个完整的集群了。

    master slave通信原理

      节点之间通信方式一般有两种,一种是集中式,还一种是gossip协议。
      集中式的代表有springcloud config、zookeeper,它们是将集群元数据(节点信息,故障,等等)集中存储在某个节点上,而是互相之间不断通信,保持整个集群所有节点的数据是完整的。这样做的好处在于元数据的更新和读取,时效性非常好,一旦元数据出现了变更,立即就更新到集中式的存储中,其他节点读取的时候立即就可以感知到; 不好在于,所有的元数据的更新压力全部集中在一个地方,可能会导致元数据的存储有压力。
      gossip协议是redis cluster节点采取通信的方式。每个节点都有一个专门用于节点间通信的端口,每隔一段时间都会往另外几个节点发送ping消息,同时其他几点接收到ping之后返回pong。元数据更新时,请求会陆陆续续打到所有节点上去更新,有一定的延时,降低了压力; 缺点,元数据更新有延时,可能导致集群的一些操作会有一些滞后。

    gossip协议
      gossip协议包含多种消息,包括ping,pong,meet,fail,等等
      meet: 某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信。像redis-trib.rb add-node 其实内部就是发送了一个gossip meet消息,给新加入的节点,通知那个节点去加入我们的集群
      ping: 每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据。cluster_node_timeout是可以调节的,如果调节太长,那么会降低发送的频率可能元出现数据不一致的情况;如果太短,ping很频繁,所以可能会加重网络负担
      pong: 返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新
      fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了


    主从复制的断点续传
      从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份。
    master会在内存中产生一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制,但是如果没有找到对应的offset,那么就会执行一次resynchronization.
    slave对过期key的处理
      slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。

    ------------------------------------------------------------------------------------------------

      1台以上的节点就能搭建一个redis集群,我们这里搭建3个节点来组建一个集群,为了防止节点死掉而导致集群崩溃,我们这里还需要搭建3台从节点保证高可用!所以一共是6个节点!

    【搭建过程】

    1. RedisC语言开发的,我们首先安装C的编译环境。 yum install gcc-c++
    2. 安装ruby命令,用它来实现脚本搭建。 yum install ruby    yum install rubygems
    3. 创建文件夹 mkdir /usr/local/wulei/redis_cluster , redis-3.0.0.tar.gz传上来并解压  tar -zxvf redis-3.0.0.tar.gz
    4. make命令编译源码 cd /usr/local/wulei/redis_cluster/redis-3.0.0 在目录里面直接执行 make

           

      5. 现在我们可以用编译好的文件安装6个服务。

          cd /usr/local/wulei/redis_cluster/redis-3.0.0

          make install PREFIX=/usr/local/wulei/redis_cluster/redis1

          make install PREFIX=/usr/local/wulei/redis_cluster/redis2

          make install PREFIX=/usr/local/wulei/redis_cluster/redis3

          make install PREFIX=/usr/local/wulei/redis_cluster/redis4

          make install PREFIX=/usr/local/wulei/redis_cluster/redis5

          make install PREFIX=/usr/local/wulei/redis_cluster/redis6

      6. 安装好之后它们还差配置文件, 我们这个时候需要去把redis-3.0.0/redis.conf配置文件复制到它们bin目录下。

          cp redis.conf /usr/local/wulei/redis_cluster/redis1/bin

          cp redis.conf /usr/local/wulei/redis_cluster/redis2/bin

          cp redis.conf /usr/local/wulei/redis_cluster/redis3/bin

          cp redis.conf /usr/local/wulei/redis_cluster/redis4/bin

          cp redis.conf /usr/local/wulei/redis_cluster/redis5/bin

          cp redis.conf /usr/local/wulei/redis_cluster/redis6/bin

    【经过上面6步我们就搭建完成了,接下来我们要开始配置了】

    1. 修改6redisredis.conf文件   我们是伪集群所以要修改默认端口,并开启集群。

              45行的6379分别改为7001 ~ 7006         632行前面的井号和空格删掉(打开集群开关)

         

      2. 分别启动6个服务  cd /usr/local/wulei/redis_cluster/redis1/bin    ./redis-server redis.conf  前面是启动命令,后面是配置文件路径。

            

      3. 上传脚本: 全部启动成功之后,我们用ruby脚本将集群连接起来

          

      4. 安装脚本文件   gem install redis-3.0.0.gem

      5. 进入redis源码包,使用redis-trib.rb来连接集群。

    重新开一个窗口:
    进入这个原生目录
    cd /usr/local/wulei/redis_cluster/redis-3.0.0/src
    执行下面语句 .
    /redis-trib.rb create --replicas 1 192.168.25.100:7001 192.168.25.100:7002 192.168.25.100:7003 192.168.25.100:7004 192.168.25.100:7005 192.168.25.100:7006
    create --replicas:创建集群  值表示slave节点比例, 1表示1主1备; 2表示1主2备。

       这个时候我们可以看它的执行信息

    1.先检测每个节点成功启动
      ......

    >>> Performing hash slots allocation on 6 nodes...
    2.设置masters Using
    3 masters: 192.168.25.100:7001 192.168.25.100:7002 192.168.25.100:7003
    3.分配从节点 Adding replica 192.168.25.100:7004 to 192.168.25.100:7001 Adding replica 192.168.25.100:7005 to 192.168.25.100:7002 Adding replica 192.168.25.100:7006 to 192.168.25.100:7003
    4.可以看到16384个槽平均分给了3个主节点 M: 023c652a892d056ffe3b01ffba859ebfa4646acd 192.168.25.100:7001 slots:0-5460 (5461 slots) master M: 5e5f5b031aa82d0c3235cc135d9f76f06867a08b 192.168.25.100:7002 slots:5461-10922 (5462 slots) master
    从节点是没有槽的, 但是它会把主节点的数据复制过来 M: 96a22d58016ae41229a12b84adf5a0e3dd91c1e9
    192.168.25.100:7003 slots:10923-16383 (5461 slots) master S: 873e8f4d87b76bad2c2072a9936ac114d8adae49 192.168.25.100:7004 replicates 023c652a892d056ffe3b01ffba859ebfa4646acd S: 79e0bc90b114fdbf31178eecb9f0b83a05897130 192.168.25.100:7005 replicates 5e5f5b031aa82d0c3235cc135d9f76f06867a08b S: 80348137885573d23d523e0bb86a972721180937 192.168.25.100:7006 replicates 96a22d58016ae41229a12b84adf5a0e3dd91c1e9
    是否确定配置规则: 直接输入yes Can I
    set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.... >>> Performing Cluster Check (using node 192.168.25.100:7001) M: 023c652a892d056ffe3b01ffba859ebfa4646acd 192.168.25.100:7001 slots:0-5460 (5461 slots) master M: 5e5f5b031aa82d0c3235cc135d9f76f06867a08b 192.168.25.100:7002 slots:5461-10922 (5462 slots) master M: 96a22d58016ae41229a12b84adf5a0e3dd91c1e9 192.168.25.100:7003 slots:10923-16383 (5461 slots) master M: 873e8f4d87b76bad2c2072a9936ac114d8adae49 192.168.25.100:7004 slots: (0 slots) master replicates 023c652a892d056ffe3b01ffba859ebfa4646acd M: 79e0bc90b114fdbf31178eecb9f0b83a05897130 192.168.25.100:7005 slots: (0 slots) master replicates 5e5f5b031aa82d0c3235cc135d9f76f06867a08b M: 80348137885573d23d523e0bb86a972721180937 192.168.25.100:7006 slots: (0 slots) master replicates 96a22d58016ae41229a12b84adf5a0e3dd91c1e9 [OK] All nodes agree about slots configuration.
    设置ok
    >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.

       这个时候重新看redis服务器节点信息,发生了变化。并且我们可以用win来连接测试!

  • 相关阅读:
    springboot项目启动成功后执行一段代码的两种方式
    ELK相关资料整理
    Golang指针解析
    Golang文件操作
    Go Channel介绍
    Go语言new和make的区别
    SpringBoot+AOP实现记录操作日志和异常日志,并保存到数据库
    【面试专栏】Java 阻塞队列
    Linux安装Jenkins并构建SpringBoot工程
    Linux安装git
  • 原文地址:https://www.cnblogs.com/wlwl/p/9660261.html
Copyright © 2011-2022 走看看