• redis cluster集群


    Redis集群工作原理:

    Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念。 Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个 节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么: 节点 A 包含 0 到 5460号哈希槽. 节点 B 包含5461到10922号哈希槽. 节点 C 包含10923到16383号哈希槽. 这种结构很容易添加或者删除节点,比如如果我想新添加个节点D,我需要从节点 A, B, C中得部分槽到 D上。如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除 即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节 点的哈希槽的数量都不会造成集群不可用的状态。

    Redis 集群的主从复制模型:

    为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型, 每个节点都会有N-1个复制品。 在上面具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就 会以为缺少5461到10922这个范围的槽而不可用。 然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个 集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点 继续服务,整个集群便不会因为槽找不到而不可用了,不过当B和B1 都失败后,集群是不可用的。

    redis cluster集群部署:
    环境:
    centos 7.X
    redis 5.0.7
    创建redis实例:
    #创建redis-cluster 存放目录:
    mkdir -p /usr/local/redis-cluster
    
    #用初始化脚本方式,快速创建实例配置文件,日志目录:
    cd /usr/src/redis-5.0.7
    root@localhost redis-5.0.7]# ./utils/install_server.sh
    Welcome to the redis service installer
    This script will help you easily set up a running redis server
    
    Please select the redis port for this instance: [6379] 7001
    Please select the redis config file name [/etc/redis/7001.conf] /usr/local/redis-cluster/7001.conf     
    Please select the redis log file name [/var/log/redis_7001.log] /usr/local/redis-cluster/7001.log
    Please select the data directory for this instance [/var/lib/redis/7001] /usr/local/redis-cluster/7001
    Please select the redis executable path [/usr/local/redis/bin/redis-server] /usr/local/redis/bin/redis-server
    Selected config:
    Port           : 7001
    Config file    : /usr/local/redis-cluster/7001.conf
    Log file       : /usr/local/redis-cluster/7001.log
    Data dir       : /usr/local/redis-cluster/7001
    Executable     : /usr/local/redis/bin/redis-server
    Cli Executable : /usr/local/redis/bin/redis-cli
    Is this ok? Then press ENTER to go on or Ctrl-C to abort.
    Copied /tmp/7001.conf => /etc/init.d/redis_7001
    Installing service...
    Successfully added to chkconfig!
    Successfully added to runlevels 345!
    Starting Redis server...
    Installation successful!
    
    #以上是创建7001实例: 用相同的方式创建剩余的5个redis cluster实例;

    开启Redis集群模式:

    #在每个redis 实例的配置文件中,开启如下参数;
    #将 cluster-enabled yes 前面的#去掉,意味着开启 redis-cluster
    cluster-enabled yes 
    #将前面的#去掉,并且将配置文件改为 7001.conf,Redis Cluster 记录的启动信息文件, 文件由 cluster 自动生成,不需要用户编辑 
    cluster-config-file nodes-7001.conf 
    #Redis 群集节点可以不可用的最长时间,而不会将其视为失败。
    cluster-node-timeout 5000 
    #开启 AOF 持久化 
    appendonly yes

     

     启动Redis实例:

    #启动实例服务:
    /etc/init.d/redis_7001 restart
    /etc/init.d/redis_7002 restart
    /etc/init.d/redis_7003 restart
    /etc/init.d/redis_7004 restart
    /etc/init.d/redis_7005 restart
    /etc/init.d/redis_7006 restart
    
    #批量启动实例服务:
    for i in `seq 1 6`;do /etc/init.d/redis_700$i start;sleep 2;done
    
    #查看服务进程:
    netstat -nutlp
    ps -ef|grep redis-server

    搭建集群:

    现在已经有了6个redis实例了,接下来可以直接用这些实例创建集群,并为每个节点编写配置文件, redis5版本可以直接使用redis-cli命令创建集群,检查或重新新硬化现有集群等等。
    #创建集群:
    redis-cli --cluster create 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 127.0.0.1:7006  --cluster-replicas 1
    
    --cluster-replicas 1 表示为集群中的每个主节点创建一个从节点。
    其中指定了6个redis的ip:port,3个master3个slave。 
    以上命令回车后,当我们输入yes,redis-cli就会将这份配置应用到集群当中,让各个节点开始互相通讯,
    最 后可以得到如下信息: 
    ... [OK] 
    All 16384 slots covered

    系统就开始执行 cluster 的相关配置,最终 哈希槽均被配置完 毕,且配置好每个主节点和和从节点的对应关系。

     执行完毕后,所有主机的 redis 实例数据目录下,都会自动生成 dump.rdb 和 nodes7000.conf 文件

     

    #查看集群信息或状态:
    [root@localhost redis-5.0.7]# redis-cli -p 7001 cluster info

    #查看集群节点:
    [root@localhost redis-5.0.7]# redis-cli -p 7001 cluster nodes

    添加新的节点:

    # 重新初始化一个节点:
    [root@localhost redis-5.0.7]# ./utils/install_server.sh 
    Welcome to the redis service installer
    This script will help you easily set up a running redis server
    
    Please select the redis port for this instance: [6379] 7007
    Please select the redis config file name [/etc/redis/7007.conf] /usr/local/redis-cluster/7007.conf
    Please select the redis log file name [/var/log/redis_7007.log] /usr/local/redis-cluster/7007.log
    Please select the data directory for this instance [/var/lib/redis/7007] /usr/local/redis/7007
    Please select the redis executable path [/usr/local/redis/bin/redis-server] /usr/local/redis/bin/redis-server
    Selected config:
    Port           : 7000
    Config file    : /usr/local/redis-cluster/7000.conf
    Log file       : /usr/local/redis-cluster/7000.log
    Data dir       : /usr/local/redis/7000
    Executable     : /usr/local/redis/bin/redis-server
    Cli Executable : /usr/local/redis/bin/redis-cli
    Is this ok? Then press ENTER to go on or Ctrl-C to abort.
    Copied /tmp/7000.conf => /etc/init.d/redis_7007
    Installing service...
    Successfully added to chkconfig!
    Successfully added to runlevels 345!
    Starting Redis server...
    Installation successful!
    [root@localhost redis-5.0.7]# 
    #修改配置文件添加如下或开启:
    cluster-enabled yes 
    cluster-config-file nodes-7000.conf 
    cluster-node-timeout 5000 
    appendonly ye
    #启动服务:
        /etc/init.d/redis_7000 restart
    #添加新节点:
    redis-cli  --cluster add-node 127.0.0.1:7000 127.0.0.1:7001

    重新分片:

    虽然节点添加成功,但是还没有分配散列槽,需要重新分片,就是将其他节点上的部分散列槽移动到该 节点上。

    # 可以看到虽然7000新节点添加成功,但是没有分配散列槽: 
    [root@localhost redis-5.0.7]# redis-cli --cluster check 127.0.0.1:7001 
     127.0.0.1:7001 (e8cf1e59...) -> 0 keys | 5461 slots | 1 slaves.
    127.0.0.1:7000 (1186fbcb...) -> 0 keys | 0 slots | 0 slaves.
    127.0.0.1:7002 (b02a78af...) -> 0 keys | 5462 slots | 1 slaves.
    127.0.0.1:7003 (dd351704...) -> 0 keys | 5461 slots | 1 slaves.
    [OK] 0 keys in 4 masters.
    0.00 keys per slot on average.
    >>> Performing Cluster Check (using node 127.0.0.1:7001)
    M: e8cf1e5955caba283e843a57b01f3d5bf04a3f77 127.0.0.1:7001
       slots:[0-5460] (5461 slots) master
       1 additional replica(s)
    M: 1186fbcb65016b5ce42fa95c77de872b4e9c7e6b 127.0.0.1:7000
       slots: (0 slots) master
    M: b02a78af5e9106cb1100e5feff1d56146c911bb1 127.0.0.1:7002
       slots:[5461-10922] (5462 slots) master
       1 additional replica(s)
    S: db67bfb7580ee7f6067f381e8ddd92ebb27044bc 127.0.0.1:7004
       slots: (0 slots) slave
       replicates dd3517043af0ae6f936ae820036079101b61b2b4
    S: a1e53727be8fdb39485427d5054c70e9964cddbc 127.0.0.1:7006
       slots: (0 slots) slave
       replicates b02a78af5e9106cb1100e5feff1d56146c911bb1
    M: dd3517043af0ae6f936ae820036079101b61b2b4 127.0.0.1:7003
       slots:[10923-16383] (5461 slots) master
       1 additional replica(s)
    S: fd471711e0d771b22e63dad5e4312aff0144b066 127.0.0.1:7005
       slots: (0 slots) slave
       replicates e8cf1e5955caba283e843a57b01f3d5bf04a3f77
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.

      重新分配,只需指定一个节点,redis-cli将自动找到其他节点:

    #重新分配
    redis-cli --cluster reshard 127.0.0.1:7001
    
    首先指定分配多少散列槽:
    # 重新分配多少个散列槽,这里尝试重新设置2048个散列槽: 
    How many slots do you want to move (from 1 to 16384)? 2048
    
    指定接收哈希槽的节点ID:
    # 指定接受的redis节点ID,注意不是指定ip地址: (7000实例的ID)
    What is the receiving node ID? 1186fbcb65016b5ce42fa95c77de872b4e9c7e6b
    
    指定从哪些节点获取散列槽:
    
    Please enter all the source node IDs.  
    Type 'all' to use all the nodes as source nodes for the hash slots.  
    Type 'done' once you entered all the source nodes IDs. 
    Source node #1: all
    # all:  表示自动在所有节点进行分配。 
    # done: 表示指定节点结束,一般用在移除节点时,指定完Source node #1: 节点ID,再输入done, 表示输入结束

     是否确定分配:yes

    在最终确认之后,redis-cli开始执行重新分配:
    重新分片正在进行中时,程序不受影响地运行。
    检查集群的运行状态:
    # 可以看到散列槽已经分配了 
    [root@node5 ~]# redis-cli --cluster check 127.0.0.1:7000 127.0.0.1:7001
    [root@localhost redis-5.0.7]#  redis-cli -h 127.0.0.1 -p 7000 cluster nodes

     

     免交互重新分片脚本:

    可以自动执行重新分片,而无需以交互方式手动输入参数。这可以使用如下命令行:
    redis-cli reshard <host>:<port> --cluster-from <node-id> --cluster-to <node-id> --cluster-slots <number of slots> --cluster-yes
    删除节点:
    删除节点与添加节点类似,就是一定要注意,删除节点之前一定要先将数据移到其他节点,不能直接删 除,不过也不用担心,即使有数据,不小心执行了删除节点指令,也会报有数据存在,不可以删除的错 误。
    # 通过重新分片,将散列槽移到其他节点: 
    redis-cli  --cluster reshard 127.0.0.1:7000
    
    How many slots do you want to move (from 1 to 16384)? 2047 
    # 用来接受散列槽的节点,可以任意指定: 
    What is the receiving node ID? b02a78af5e9106cb1100e5feff1d56146c911bb1 
    Please enter all the source node IDs.  
     Type 'all' to use all the nodes as source nodes for the hash slots.  
      Type 'done' once you entered all the source nodes IDs.  
      # 7000节点的id(意思是把该节点的散列槽分配给其他节点): 
      Source node #1: 1186fbcb65016b5ce42fa95c77de872b4e9c7e6b 
      Source node #2: done
    
    # 查看状态: 
    [root@node5 ~]# redis-cli --cluster check 127.0.0.1:7000 
    127.0.0.1:7001 (aa04c256...) -> 0 keys | 4779 slots | 1 slaves. 
    127.0.0.1:7002 (f6838a0e...) -> 0 keys | 4779 slots | 1 slaves. 
    # 已经没有了散列槽: 
    127.0.0.1:7006 (44124bd9...) -> 0 keys | 0 slots | 0 slaves. 
    127.0.0.1:7004 (e4f85202...) -> 1 keys | 6826 slots | 1 slaves.

     

     

     

     以下删除节点:

    # 确定没问题了,执行下面命令,可以实现删除节点: 127.0.0.1:7000
    [root@node5 ~]# redis-cli --cluster del-node 127.0.0.1:7000 1186fbcb65016b5ce42fa95c77de872b4e9c7e6b 
    >>> Removing node 1186fbcb65016b5ce42fa95c77de872b4e9c7e6b from cluster 127.0.0.1:7000 
    >>> Sending CLUSTER FORGET messages to the cluster... 
    >>> SHUTDOWN the node

  • 相关阅读:
    从零实现一个功能完善的迷你区块链
    Merkle Tree理解起来并不难
    微信、支付宝个人收款的一种实现思路
    PostgreSQL的登录、创建用户、数据库并赋权
    java list 按照多字段排序
    2019年最新全国省市区街道共46462条数据(统计局MySQL数据库)
    一份非常值得一看的Java面试题
    spring scope prototype与singleton
    http请求与响应,TCP三次握手&四次分手
    HTTP协议三次握手过程
  • 原文地址:https://www.cnblogs.com/fengyuanfei/p/13830794.html
Copyright © 2020-2023  润新知