• Redis(1.11)Redis4.0.11 cluster 分布式集群搭建


    概念与了解:Redis(1.7)Redis高可用架构(理论篇)

    【0】试验环境

    结构图如下:

      

    (这里试验没有那么多机器,就用3台机器搭建试验)

    redis1是redis集群的一个节点A,上面运行了两个redis实例,7001 7004

    redis2是redis集群的一个节点B,上面运行了两个redis实例,7002 7005

    redis3是redis集群的一个节点C,上面运行了两个redis实例,7003 7006

    -- 试验集群包含 A/B/C A1/B1/C1 6个节点

      A、B、C 为主节点对应Redis实例:7001 7002 7003

      A1、A2、A3 为主节点的从库,对应Redis实例:7004 7005 7006

    -- 交叉构建主从节点,对应关系为

      【A > B】  【B>C】  【C>A1】

        A:192.168.135.173

        B:192.168.135.174

        C:192.168.135.175

    -- IP与端口分布:

    redis4.0.11版本

    cluster1:

      主:192.168.135.173 7001 /data/redis/redis-cluster/nodes-7001/redis.conf

      备:192.168.135.174 7005 /data/redis/redis-cluster/nodes-7005/redis.conf

    cluster2:

      主:192.168.135.174 7002 /data/redis/redis-cluster/nodes-7002/redis.conf

      备:192.168.135.175 7006 /data/redis/redis-cluster/nodes-7006/redis.conf

    cluster3:

      主:192.168.135.175 7003 /data/redis/redis-cluster/nodes-7003/redis.conf

      备:192.168.135.175 7004 /data/redis/redis-cluster/nodes-7004/redis.conf

    -- 外界连接策略

      外端可以用F5、keepalived+haproyx结果,实现2个负载均衡(3台主的写,3台备的读)

    【1】安装redis

      详细参考:Redis(1.1)linux下安装redis

      快速安装:

    #【1.1】构建目录
    #173 mkdir -p /data/redis/7001data mkdir -p /data/redis/7001log mkdir -p /data/redis/7001conf mkdir -p /data/redis/7004data mkdir -p /data/redis/7004log mkdir -p /data/redis/7004conf #174 mkdir -p /data/redis/7002data mkdir -p /data/redis/7002log mkdir -p /data/redis/7002conf mkdir -p /data/redis/7005data mkdir -p /data/redis/7005log mkdir -p /data/redis/7005conf #175 mkdir -p /data/redis/7003data mkdir -p /data/redis/7003log mkdir -p /data/redis/7003conf mkdir -p /data/redis/7006data mkdir -p /data/redis/7006log mkdir -p /data/redis/7006conf

    #【1.2】安装(其实这一步可以省略,多实例不过是用不同的配置文件启动redis而已)
    cd /soft/redis-4.0.14 && make PREFIX='/data/redis/7001data' install 
    cd /soft/redis-4.0.14 && make PREFIX='/data/redis/7004data' install  
    cd /soft/redis-4.0.14 && make PREFIX='/data/redis/7002data' install 
    cd /soft/redis-4.0.14 && make PREFIX='/data/redis/7005data' install 
    cd /soft/redis-4.0.14 && make PREFIX='/data/redis/7003data' install 
    cd /soft/redis-4.0.14 && make PREFIX='/data/redis/7006data' install 
    #【1.3】配置文件
    vim /data/redis/7001conf/7001redis.conf
    vim /data/redis/7004conf/7004redis.conf
    vim /data/redis/7002conf/7002redis.conf
    vim /data/redis/7005conf/7005redis.conf
    vim /data/redis/7003conf/7003redis.conf
    vim /data/redis/7006conf/7006redis.conf

    然后目录和名字对应改一下即可(参数参考:Redis配置文件(4.0.14)
    daemonize yes
    logfile "/data/redis/7001log/redis.log"
    #requirepass 123456
    #masterauth 123456 bind 192.168.135.173 127.0.0.1 pidfile /data/redis/7001conf/redis.pid dbfilename redis.rdb dir /data/redis/7001conf/
    port 7001
    appendonly yes
    appendfilename "appendonly.aof"
    appendfsync always
    cluster-enabled yes 
    cluster-config-file nodes-7001.conf 
    cluster-node-timeout 15000
    appendonly yes

     【1.4】全部启动起来

    redis-server /data/redis/7001conf/7001redis.conf

    .....以此为例

     【1.5】构建的启动脚本 /data/redis/startall.sh,举例如下(每个机器根据自身情况修改)

    #!/bin/bash
    if [ $1 == 'start' ]; then
    redis-server /data/redis/7002conf/7002redis.conf
    redis-server /data/redis/7005conf/7005redis.confelse
    redis-cli -p 7002 -h 192.168.135.174 shutdown
    redis-cli -p 7005 -h 192.168.135.174 shutdownfi

    【2】安装redis-trib所需的 ruby脚本

      注意(本文用的4.0.11 所以需要用ruby等一系列很麻烦的操作。redis 5.0以后的版本 可以直接使用 redis-cli的方式搭建(redis-cli --cluster create 192.168.80.131:7001 192.168.80.131:7002 192.168.80.131:7003 192.168.80.131:7004 192.168.80.131:7005 192.168.80.131:7006 --cluster-replicas 1),省去了第【2】步,直接到【3】

      一台机器装即可

       3.0以上的redis才支持cluster,且需要 ruby 2.2以上版本才支持 redis-trib命令,而Centos7中默认的是2.0版本

      ruby下载:http://www.ruby-lang.org/zh_cn/downloads/

      ruby安装:http://www.ruby-lang.org/zh_cn/documentation/installation/#yum

      如果是直接下的tar.gz,一般是源码。

      yum源配置:Yum源配置

      离线安装:https://blog.csdn.net/zhanaolu4821/article/details/99750304


    #[2.1] 查看ruby是否存在
    ruby -v
    #如果存在则需要卸载原来的老版本
    rpm -e ruby-2.0.0.648-33.el7_4.x86_64 --nodeps
    rpm -e ruby-irb-2.0.0.648-33.el7_4.noarch --nodeps
    rpm -e ruby-libs-2.0.0.648-33.el7_4.x86_64 --nodeps

    #【2.2】安装依赖包
    yum install -y zlib-devel curl-devel openssl-devel httpd-devel apr-devel apr-util-devel 

    #【2.3】源码安装ruby
    #不存在可以去官网下载安装
    #源码安装
    ./configure
    make 
    make install
    ruby -v #检查是否安装成功

    #默认情况下,Ruby 安装到 /usr/local 目录,并且已经在usr/local/bin/下面加了环境变量。
    #如果想使用其他目录,可以把 --prefix=DIR 选项传给 ./configure 脚本。如果命令还是没用则退出登录用户再重登试试。

    #【2.4】ruby-redis.gem安装(必须联网)
    #这一步如果报错参考:gem install redis报错
    #添加国内源命令
    #gem source -l #查看当前gem源
    #gem source -a https://gems.ruby-china.com/

    #删除国外源并添加国内源
    gem sources --add gem source -a https://gems.ruby-china.com/ --remove https://rubygems.org/
    #要是自己下载的包就直接这样既可 gem install /soft/redis-4.1.3.gem
    #要是网络安装
      gem install redis
        

    【3】创建redis cluster

    前置核心:

      (1)要先启动redis服务端

      (2)设置集群的时候密码必须为空,可以设计好集群后再配置密码

      (3)配置文件中的 bind 127.0.0.1  必须要改,改成 bind youripv4    127.0.0.1  ,这样其他机器和本机都可以直接访问

      (4)如果redis数据库数据不为空,则删除掉所有的数据(比如 aof,rdb 等,还不赶紧则 flushall)

    #【3.1】切换到源码目录下
    cd /soft/redis-4.0.14/src/
    cp ./redis-trib.rb /usr/bin #添加环境变量


    #【3.2】开始创建集群
    redis-trib.rb create --replicas 1 192.168.135.173:7001 192.168.135.173:7004 192.168.135.174:7002 192.168.135.174:7005 192.168.135.175:7003 192.168.135.175:7006

    #5.0以后可以直接用 redis-cli --cluster create 192.168.80.131:7001 192.168.80.131:7002 192.168.80.131:7003 192.168.80.131:7004 192.168.80.131:7005 192.168.80.131:7006 --cluster-replicas 1
    --cluster-replicas 1表示希望为集群中的每个主节点创建一个从节点(一主一从)。
    --cluster-replicas 2表示希望为集群中的每个主节点创建两个从节点(一主二从)。
    输完命令后,集群相关信息会展现出来如下图:(这个主从是自动判断分配的
      

    构建成功如下图:

       

    #【3.3】创建失败

    参考:Redis(1.12)Redis cluster搭建常见错误

    【4】连接集群及核验

    #【4.1】去任意节点登录集群 redis-cli -c
    redis-cli -c -h 192.168.135.173 -p 7001

    #【4.2】使用的时候会自动分布
    set 和 get 都会跳到对应的实例上去。
      
    
    

     #【4.3】核验检查

     (1)redis-trib.rb check 192.168.135.173:7001 #(任意节点的IP:端口 即可)

        

         
    
    

      (2)任意节点 redis-cli -c 登录上去之后,使用 CLUSTER 命令(按tab 可以自动补全)

      redis -c -h 192.168.135.173 -p 7001

        (2.1)CLUSTER NODES

            

              

       (2.2)CLUSTER INFO

          

    【5】添加删除集群节点

    注意,千万不要cluster增删节点命令与 redis-trib.rb 增删节点混用!!!

    【5.0】新增节点规划与操作

    cluster 相关命令参考:https://www.cnblogs.com/kevingrace/p/7910692.html

    192.168.135.174:7007
    192.168.135.175:7008
    
    192.168.135.174:      cd /data/redis      mkdir -p 7007{conf,log}     cp 7002conf/7002redis.conf 7007conf/7007redis.conf     #修改配置文件中的7002为7007即可
    192.168.135.175:       cd /data/redis     mkdir -p 7008{conf,log}     cp 7003conf/7003redis.conf 7008conf/7008redis.conf     #修改配置文件中的7003为7008即可

    【5.1】cluster meet 命令增删节点

    【5.1.1】Cluster meet 增加节点(不建议使用这种办法,建议使用【5.2】)

    #在任意节点登录都可以,我这里用 173:7001 节点登录了
    redis-cli -c -h 192.168.135.173 -p 7001

    #添加节点命令(用这个命令添加进来默认是没有分配槽位的,会在需要的时候自动把其他MSTER的槽位转移过来用的
    cluster meet 192.168.135.174 7007
    cluster meet 192.168.135.175 7008
    #效果如下图,默认是以主节点的身份添加进来的
      

     #把其中一个设置为从,这里设置192.168.135.175:7008为7007的从

      A:比如要登录7008

        redis-cli -p 7008 -h 192.168.135.175 -c 

       B: 在A的登录环境下, cluster replicate 7007node_id

        cluster replicate d80a9c494633a6d84697ac5330dfb024e4a0866d

        #这是在没进行任何操作的情况,如果已经进行了set相关

        Node 192.168.135.173:7001 is not empty  

          

        查看了一下,原来是7008因为我之前set了一下,自动给它分配了一个槽位,所以如上图操作,我把该槽位释放掉就可以执行让其变成从库了!

        但如上图所示,并没有自动分配槽位给新增的主节点,而是等到使用的时候才会按需分配,且我们的13026槽位也并没有分配给某个具体master节点.所以,检查报错如下:

          

        出现新的错误:[ERR] Not all 16384 slots are covered by nodes

        修复:redis-trib.rb fix 192.168.135.175:7008 即,把这个槽从新分配一下给master

            

    【5.1.2】cluster forget 命令移除节点

    #登录
      redis-cli -p 7001 -h 192.168.135.173 -c

    #(1)移除节点命令(移除7007   CLUSTER FORGET d80a9c494633a6d84697ac5330dfb024e4a0866d

    #(2)发现错误
      (error)ERR Can't forget my master!
      (error)ERR I tried hard but I can't forget myself...
      #意思就是,从节点不能移除 master 节点,且如果登录的是主节点要移除的是自己也不行

    #(3)解决办法
      切换到另外一个主节点即可。
      例如,删除 7007和7008
      cluster forget d80a9c494633a6d84697ac5330dfb024e4a0866d
      cluster forget c70173985021665bacd74231f03c2a001468e703

    #(4)核验
      cluster nodes
    #(5)保存当前配置
      cluster saveconfig

    【5.2】redis-trib.rb 增删节点

    参考:redis使用总结(二)

    【5.2.1】redis-trib.rb 增加扩张节点

    #(1)新增主节点,7001是原本存在的主节点(这里可以是集群中的任意节点),7007是新主节点
      redis-trib.rb add-node 192.168.135.174:7007 192.168.135.173:7001
      #命令的意思是,添加主节点 192.168.135.174:7001 到 192.168.135.17:7001所在集群

      #报错,因为我们之前使用过它加入进群
        [ERR] Node 192.168.135.174:7007 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

      #解决
      在192.168.135.174机器上
        redis-cli -p 7007 -h 192.168.135.174 shutdown
        rm -rf /data/redis/7007conf/{appendonly.aof,redis.rdb,redis.pid,nodes-7007.conf}
        redis-server /data/redis/7007conf/7007redis.conf
      再次执行命令,执行成功,如下图:
          
    #(2)登录集群任意节点,获取 id标识
      redis-cli -h 192.168.135.173 -c -p 7001 cluster nodes

    #(3)添加从节点,7001是原本存在的主节点(这里可以写集群中的任意节点信息),7008是新增为7007从库的新节点
      redis-trib.rb add-node --slave --master-id c70173985021665bacd74231f03c2a001468e703 192.168.135.175:7008 192.168.135.173:7001
      #命令的意思,添加从节点,然后其主节点ID为...(通过cluster nodes获取 7007的id),从节点IP:端口, 加入 192.168.135.173:7001 所在的集群

    #(4)为主节点重新分配solt
      redis-trib.rb reshard 192.168.135.174:7007
        #重新分配,会弹出如下对话框,输入4000,即设置该节点slot数为4000
      How many slots do you wan to move(from 1 to 16384)? 4000
    What is the receiving node ID? #输入7007的 id
      Source node #1:all #从哪里分配?all则标识全部节点重新洗牌分配(新环境可以,但旧环境会导致停机的),也可以写具体的node_id

      #自动平衡槽数量
        redis-trib.rb rebalance 192.168.135.174:7007

    【5.2.2】redis-trib.rb 缩减节点

    #(1)流程说明
    
      A:确定要下线移除的节点是否存在slot,如果有,需要先把slot迁移到其他节点,保证整个集群槽节点映射的完整性;
      
      B:当下线的节点没有槽或本身是从节点时,就可以通知集群内其他节点(或者叫忘记节点),当下线的节点被集群忘记后正常关闭。
    #(2)登录任意集群节点查看 node_id
      redis-cli -c -h 192.168.135.173 -p 7001 cluster nodes
    #(3
    )删除节点   #分为两种,一种是删除主节点 192.168.135.174:7007,另一种是删除从节点 192.168.135.175:7008   
      #删除从节点7008(因为没有分配哈希槽,可以直接删除)
        redis-trib.rb del-node 192.168.135.175:7008
    c70173985021665bacd74231f03c2a001468e703
        #redis-trib.rb del-node ip:port node_id
      
      #删除主节点7007(分配了hash槽,需要把hash槽转移到别的节点去,才能够删除)
      直接删除肯定会报错的:
         
    #(4)缩减槽位
    redis-trib.rb reshard 192.168.135.174:7007 #后面这个IP及端口,其实是集群内任意节点都可以,主要是为了让命令识别是哪个集群,任意节点都可以让其识别出整个集群信息
    #redis-trib.rb reshard --from e37957bd67cc4932183c6549ee7368cbc93b7499 --to ba694e2969adb6c06a1f7dc596168ccc57ee9e1d --slots 1500 --yes 192.168.135.173:7001


        

      看上图中,下班部分的框线,意思是

      (1)想要移走多少个slot?

      (2)谁接受这些slot,这里我写的node_id 是7001的

      (3)这些移动的槽来源在哪里,写我们的7007对应的node_id即可

      #移走之后,可以删掉7007节点了

        redis-trib.rb del-node 192.168.135.174:7007 99a603ef36215bfadf382dadb62f9bfe59711b41


    #知道了上面reshard意思,我们可以直接用命令写完这些,不需要交互方式写。
      redis-trib.rb reshard --from e37957bd67cc4932183c6549ee7368cbc93b7499 --to ba694e2969adb6c06a1f7dc596168ccc57ee9e1d --slots 1500 --yes 192.168.135.173:7001
    #把7001对应的node_id 移动1500个槽给 7004

         

          

           

    【6】redis cluster的故障转移

         redis集群实现了,高可用,当集群内少量节点出现故障时,通过故障转移可以保证集群正常对外服务。

      当集群里某个节点出现了问题,redis集群内的节点通过Ping Pong消息发现节点是否健康,是否有故障。

      故障恢复:

        如果下线节点是主节点,则需要在它的从节点中选一个替换它,保证集群的高可用,转移过程如下:

          (1)资格检查(必须要主节点才有资格投票)

          (2)准备选举时间

          (3)发起投票

          (4)选举投票,从库>50%

     【6.1】查看当前集群状况,构造测试数据

    redis-cli -c -p 7001 -h 192.168.135.173

      

     好,如上图,现在三个主库上都有了。

    模拟:现在重启 192.168.135.175 机器,包含7003和7006 2个节点

      

       如上图,之前t5是在7006的,现在get t5切换到了7002 证明已经自动故障转移了

      重启 192.168.135.175 7003和7006 节点之后,我们可以看到主从又自动分配了,但原本的主从关系已经随着故障转移彻底改变了。

        

    【7】集群性能测试方法

    这个命令在/data/redis/bin/redis-benchmark  ,是redis自带的。

    用法及参数如下:

    redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests>] [-k <boolean>]
    
     -h <hostname>      Server hostname (default 127.0.0.1)
     -p <port>          Server port (default 6379)
     -s <socket>        Server socket (overrides host and port)
     -a <password>      Password for Redis Auth
     -c <clients>       Number of parallel connections (default 50)
     -n <requests>      Total number of requests (default 100000)
     -d <size>          Data size of SET/GET value in bytes (default 3)
     --dbnum <db>       SELECT the specified db number (default 0)
     -k <boolean>       1=keep alive 0=reconnect (default 1)
     -r <keyspacelen>   Use random keys for SET/GET/INCR, random values for SADD
      Using this option the benchmark will expand the string __rand_int__
      inside an argument with a 12 digits number in the specified range
      from 0 to keyspacelen-1. The substitution changes every time a command
      is executed. Default tests use this to hit random keys in the
      specified range.
     -P <numreq>        Pipeline <numreq> requests. Default 1 (no pipeline).
     -e                 If server replies with errors, show them on stdout.
                        (no more than 1 error per second is displayed)
     -q                 Quiet. Just show query/sec values
     --csv              Output in CSV format
     -l                 Loop. Run the tests forever
     -t <tests>         Only run the comma separated list of tests. The test
                        names are the same as the ones produced as output.
     -I                 Idle mode. Just open N idle connections and wait.
    
    Examples:
    
     Run the benchmark with the default configuration against 127.0.0.1:6379:
       $ redis-benchmark
    
     Use 20 parallel clients, for a total of 100k requests, against 192.168.1.1:
       $ redis-benchmark -h 192.168.1.1 -p 6379 -n 100000 -c 20
    
     Fill 127.0.0.1:6379 with about 1 million keys only using the SET test:
       $ redis-benchmark -t set -n 1000000 -r 100000000
    
     Benchmark 127.0.0.1:6379 for a few commands producing CSV output:
       $ redis-benchmark -t ping,set,get -n 100000 --csv
    
     Benchmark a specific command line:
       $ redis-benchmark -r 10000 -n 10000 eval 'return redis.call("ping")' 0
    
     Fill a list with 10000 random elements:
       $ redis-benchmark -r 10000 -n 10000 lpush mylist __rand_int__
    
     On user specified command lines __rand_int__ is replaced with a random integer
     with a range of values selected by the -r option.

    案例语句:

    #(1)常规通用
    -c 客户端,-r 请求多少个随机key ,-n 总请求量 ,-t 操作 ,-P 通道、线程 time /data/redis/bin/redis-benchmark -h 192.168.135.173 -p 7001 -c 200 -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q

    #(2)100个并发连接,100000个请求,检测host为192.168.135.173,port为6379的redis服务器性能
    redis-benchmark -h 192.168.135.173 -p 7001 -c 100 -n 100000

    #(3)测试存取大小为100字节的数据包的性能
    redis-benchmark -h 192.168.135.173 -p 7001 -q -d 100

    #(4)测试某些redis操作的性能
    redis-benchmark -t set,lpush -n 100000 -q

    #(5)只测试某些值存取的性能
    redis-benchmark -n 100000 -q script load "redis.call('set','key1','value1')"
    
    

    【8】redis5.0.x版本集群安装

    所有的步骤思路,和4.0.11并无不同,只是命令语法改了一点而已

    8.1】创建集群并自动分配槽
    
    redis
    -cli --cluster create 192.168.80.131:7001 192.168.80.131:7002 192.168.80.131:7003 192.168.80.131:7004 192.168.80.131:7005 192.168.80.131:7006 --cluster-replicas 1

    8.2】对集群槽位重新分片
    redis-cli --cluster reshard 192.168.135.173:7001
      
      How many slots do you want to move(from 1 to 16384)? 需要移动分配的槽位数量
      
    What is the receiving node ID  指定接收这些槽位数的 节点ID
      Source node #1:  all/ID 重新分片的源节点(source node)
      Do you want to proceed with the proposed reshard plan (yes/no)? yes 确认

    【8.3】检查集群是否正常

    redis-cli --cluster check 192.168.135.173:7001

    【8.4】添加节点

    redis-cli --cluster add-node 192.168.135.174:7007 192.168.135.173:7001

    #命令中的 add-node 表示我们要 将一个节点添加到集群里面, add-node 之后跟着的是新节点的 IP 地址和端口号, 再之后跟着的是集群中任意一个已存在节点的 IP 地址和端口号
    和其他主节点相比, 新节点还有两点区别:
      新节点没有包含任何数据, 因为它没有包含任何哈希桶。
      尽管新节点没有包含任何哈希嘈, 但它仍然是一个主节点, 所以在集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中。

    (1)添加节点后,让节点成为主节点

      #可以使用如下命令来分配槽位使其成为真正的主节点。

        redis-cli --cluster reshard 192.168.135.174:7007 (这个IP+端口,可以是集群内任意节点信息)
    (2)添加节点后,让节点变成从节点
      
      #实现使用 cluster nodes 查看好对应的主节点 node_id =》登录上从节点:redis-cli -h 192.168.135.174 -p 7007 =》 设置该节点为指定主节点node_id的从库:命令如下

        redis 192.168.135.174:7007> cluster replicate 主节点ID
    【8.5】删除节点

    #删除从节点
      redis-cli --cluster del-node 192.168.135.174:7007 10363eb...

     #删除主节点
        #如果主节点有从节点,将从节点转移到其他主节点
        #如果主节点有slot,去掉分配的slot,然后在删除主节点

        redis-cli --cluster del-node 192.168.135.174:7007 108929...

        [ERR] Node 127.0.0.1:7003 is not empty! Reshard data away and try again.

        [ERR] 哈希槽非空

      #重新分片去掉所有哈希槽

        redis-cli --cluster reshard 192.168.135.174:7007

      #重新分片后从节点也自动转移到其他主节点了

        redis-cli --cluster del-node 192.168.135.174:7007 10363eb...

    参考文献:

    https://www.cnblogs.com/PatrickLiu/p/8458788.html

    https://www.cnblogs.com/wslook/p/9152596.html

    Redis(1.12)Redis cluster搭建常见错误

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/gered/p/11771601.html
Copyright © 2020-2023  润新知