zoukankan      html  css  js  c++  java
  • 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搭建常见错误

  • 相关阅读:
    Windows10 ntoskrnl.exe占用大量的磁盘空间(100%)
    Windows10 正式企业版激活
    edit-distance
    climbing-stairs
    minimum-path-sum
    unique-paths-II
    unique-paths
    剑指 Offer 42. 连续子数组的最大和
    剑指 Offer 54. 二叉搜索树的第k大节点
    矩阵中的路径
  • 原文地址:https://www.cnblogs.com/gered/p/11771601.html
Copyright © 2011-2022 走看看