Redis-集群

  • 哈希槽
    Redis集群没有采用一致性hash,而是引入了哈希槽的概念。

    Redis集群有16384个哈希槽,每个key通过CRC16校验后,对16384取模,来决定放置到哪个哈希槽中。

    集群的每个节点都负责一部分的哈希槽。
    比如当前有3个接点时,

    • 节点 A 包含 0 到 5500号哈希槽.
    • 节点 B 包含5501 到 11000 号哈希槽.
    • 节点 C 包含11001 到 16384号哈希槽.

    这种结构很容易进行插入或者删除节点
    插入节点D时,只需要将A、B、C节点的部分哈希槽移动到节点D
    移除节点A时,只需要将A的哈希槽分给B、C

  • 集群的主从复制
    为了在部分节点无法通信的情况下,集群仍能使用,给集群使用主从复制模型,即给A、B、C分别创建A1、B1、C1三个Slave节点,可以通过在创建集群时通过 --cluster-replicas指定

  • redis哨兵(sentinel),主从自动切换
    sentinel(哨兵)是Redis的高可用性解决方案,由一个或多个sentinel实例组成的sentinel系统,可以监视任意多个主服务器,以及主服务器属下的所有从服务器,并在监视的主服务器处于下线状态时,自动将下线主服务器属下的从服务器,升级为新的主服务器。

    哨兵(sentinel)是一个分布式系统,你可以在一个系统中,运行多个哨兵进程,这些进程使用留言协议(gossipprotocols)来接收主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障转移,以及选择哪一个slave作为新的Mater。

    每个哨兵会定时向其他哨兵、Master、Slave发送消息,以确认对方是否还“活着”,如果发现,在指定的时间(可配置)内,未得到回应,就暂时认为对方已下线,即所谓的“主观认为宕机”。当哨兵群中的多数都认为Master主服务器SDOWN(Subjective Down: 主观认为宕机)。并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”,英文名称是:Objectively Down, 简称 ODOWN。

    通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)

    • 配置哨兵
      在redis目录中,有一个sentinel.conf,这个是哨兵的配置文件。修改其中的几个配置项,如下:

      port 26379    # 默认的端口号
      daemonize     # 是否后台启动
      pidfile       # pid文件路径
      logfile       # log日志地址
      sentinel monitor mymaster 127.0.0.1 6379 2 # 设置哨兵监控的主服务器,端口号,以及多少个哨兵确认后,才认为主服务器宕机了(How many replicas we can reconfigure to point to the new replica simultaneously)
      sentinel down-after-milliseconds mymaster 5000
      
    • 启动哨兵
      可以在启动redis-server时,加上--sentinel启动

      src/redis-server redis.conf --sentinel
      

      也可以单独启动

      src/redis-sentinel sentinel.conf
      
  • 实践

    1. 下载redis

       wget http://download.redis.io/releases/redis-5.0.3.tar.gz
       tar zxf redis-5.0.3.tar.gz
       mv redis-5.0.3 7000
       cd 7000 && make
      
    2. 修改配置文件

       vim 7000/redis.conf
       # cluster-enabled no => cluster-enabled yes
       # cluster-config-file nodes.conf
       # 打开appendonly持久化 appendonly yes
       # 打开后台运行 daemonize yes
       # 修改端口号port 7000
      
    3. 复制多份

       cp -R 7000 7001  #修改7001/redis.conf端口号为7001,下同
       cp -R 7000 7002
       cp -R 7000 7003
       cp -R 7000 7004
       cp -R 7000 7005
      
    4. 启动多个server

       cd 7000 && src/redis-server redis.conf 
       cd 7001 && src/redis-server redis.conf 
       cd 7002 && src/redis-server redis.conf 
       cd 7003 && src/redis-server redis.conf 
       cd 7004 && src/redis-server redis.conf 
       cd 7005 && src/redis-server redis.conf 
      
    5. 创建集群

       cd 7000/src
       redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replacas 1
       # --cluster-replacas 设置后三个节点分别问前三个节点的从节点
      

      以下为输出:

       # >>> Performing hash slots allocation on 6 nodes...
       # Master[0] -> Slots 0 - 5460
       # Master[1] -> Slots 5461 - 10922
       # Master[2] -> Slots 10923 - 16383
       # Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
       # Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
       # Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
       # >>> Trying to optimize slaves allocation for anti-affinity
       # [WARNING] Some slaves are in the same host as their master
       # M: fa57c564cc8449b82869fe1c1c97b2f55bad294b 127.0.0.1:7000
       #    slots:[0-5460] (5461 slots) master
       # M: c71a7933530d15032e625517de3d706bb29b462d 127.0.0.1:7001
       #    slots:[5461-10922] (5462 slots) master
       # M: d84b060378130f42023d3c6006a44b2970f7c96b 127.0.0.1:7002
       #    slots:[10923-16383] (5461 slots) master
       # S: aee483c4ec738fb10e48e894d299d9eb32bd3372 127.0.0.1:7003
       #    replicates c71a7933530d15032e625517de3d706bb29b462d
       # S: 265ca55f05999079d903496f58674afdc3b51b18 127.0.0.1:7004
       #    replicates d84b060378130f42023d3c6006a44b2970f7c96b
       # S: 2d136c50a4483ee0b7242cbdb29aeeee5aa4973f 127.0.0.1:7005
       #    replicates fa57c564cc8449b82869fe1c1c97b2f55bad294b
       # 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 127.0.0.1:7000)
       # M: fa57c564cc8449b82869fe1c1c97b2f55bad294b 127.0.0.1:7000
       #    slots:[0-5460] (5461 slots) master
       #    1 additional replica(s)
       # S: 265ca55f05999079d903496f58674afdc3b51b18 127.0.0.1:7004
       #    slots: (0 slots) slave
       #    replicates d84b060378130f42023d3c6006a44b2970f7c96b
       # M: d84b060378130f42023d3c6006a44b2970f7c96b 127.0.0.1:7002
       #    slots:[10923-16383] (5461 slots) master
       #    1 additional replica(s)
       # S: aee483c4ec738fb10e48e894d299d9eb32bd3372 127.0.0.1:7003
       #  slots: (0 slots) slave
       #    replicates c71a7933530d15032e625517de3d706bb29b462d
       # S: 2d136c50a4483ee0b7242cbdb29aeeee5aa4973f 127.0.0.1:7005
       #   slots: (0 slots) slave
       #   replicates fa57c564cc8449b82869fe1c1c97b2f55bad294b
       # M: c71a7933530d15032e625517de3d706bb29b462d 127.0.0.1:7001
       #    slots:[5461-10922] (5462 slots) master
       #    1 additional replica(s)
       # [OK] All nodes agree about slots configuration.
       # >>> Check for open slots...
       # >>> Check slots coverage...
       # [OK] All 16384 slots covered.
      
    6. 查看

      redis-cli -h 127.0.0.1 -p 7000
      info # 查看主从信息
      # Replication
      # role:master
      # connected_slaves:1
      # slave0:ip=127.0.0.1,port=7005,state=online,offset=17726,lag=1
      
      redis-cli -h 127.0.0.1 -p 7001
      info # 查看主从信息
      # Replication
      # role:master
      # connected_slaves:1
      # slave0:ip=127.0.0.1,port=7003,state=online,offset=17985,lag=1
      
      redis-cli -h 127.0.0.1 -p 7002
      info # 查看主从信息
      # Replication
      # role:master
      # connected_slaves:1
      # slave0:ip=127.0.0.1,port=7004,state=online,offset=3474,lag=1
      
    7. 操作

      1. 添加key,获取key


        Redis-集群_第1张图片
        image.png
      2. kill掉7002之后,主动将7004提升为了Master


        image.png
      3. 连接7004查看其信息


        Redis-集群_第2张图片
        7004主动提升为Master
      4. 重新启动7002后,查看7004信息,发现7002变成了7004的从库


        Redis-集群_第3张图片
        7002变为7004的从库
      5. 添加新的节点
        先启动一个新的节点,修改其配置文件类似之前启动的节点,端口号为7006。

         src/redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
         # >>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000
         # >>> Performing Cluster Check (using node 127.0.0.1:7000)
         # M: fa57c564cc8449b82869fe1c1c97b2f55bad294b 127.0.0.1:7000
         #    slots:[0-5460] (5461 slots) master
         #    1 additional replica(s)
         # M: 265ca55f05999079d903496f58674afdc3b51b18 127.0.0.1:7004
         #    slots:[10923-16383] (5461 slots) master
         #    1 additional replica(s)
         # S: d84b060378130f42023d3c6006a44b2970f7c96b 127.0.0.1:7002
         #    slots: (0 slots) slave
         #    replicates 265ca55f05999079d903496f58674afdc3b51b18
         # S: aee483c4ec738fb10e48e894d299d9eb32bd3372 127.0.0.1:7003
         #    slots: (0 slots) slave
         #    replicates c71a7933530d15032e625517de3d706bb29b462d
         # S: 2d136c50a4483ee0b7242cbdb29aeeee5aa4973f 127.0.0.1:7005
         #    slots: (0 slots) slave
         #   replicates fa57c564cc8449b82869fe1c1c97b2f55bad294b
         # M: c71a7933530d15032e625517de3d706bb29b462d 127.0.0.1:7001
         #    slots:[5461-10922] (5462 slots) master
         #    1 additional replica(s)
         # [OK] All nodes agree about slots configuration.
         # >>> Check for open slots...
         # >>> Check slots coverage...
         # [OK] All 16384 slots covered.
         # >>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
         # [OK] New node added correctly.
        
      6. 查看集群

         redis-cli -c -p 7000 cluster nodes  #查看集群中的所有节点
         ./src/redis-cli --cluster reshard 127.0.0.1:7000 # 重新分配集群中的插槽,将一部分插槽手动移动到新加的节点中
         redis-cli -c -p 7006 cluster replicate 0b00721a509444db793d28448d8f02168b94bd38 # 将7006作为7000的从库
        

你可能感兴趣的:(Redis-集群)