• 三台机器搭建redis集群过程及问题记录


    1. 前言

    Redis版本 5.0.4
    服务器版本 Linux CentOS 6;CentOS 7;CentOS 9;
    redis集群需要至少要三个master节点,我们这里搭建三个master节点,并且给每个master再搭建一个slave节点,总共6个redis节点,三主三从。

    2. 搭建集群

    • 给三台机器都装上redis
      Linux安装部署Redis
      https://blog.csdn.net/craftsman2020/article/details/122851974

    • 创建redis-cluster目录
      分别在各个服务器下的redis安装目录下(/usr/local/redis/)创建redis-cluster目录

    cd  /usr/local/redis/
    mkdir  redis-cluster
    
    • 1
    • 2

    在redis-cluster下分别创建8001,8002

    cd /usr/local/redis/redis-cluster
    mkdir 8001 8002
    
    • 1
    • 2

    其他两台机器一样的操作,端口分别为8003 8004、 8005 8006

    • 2.3 拷贝配置文件
      将之前的redis.conf拷贝至8001目录
    cp /usr/local/redis/redis.conf  /usr/local/redis/redis-cluster/8001/
    
    • 1

    其他5个目录一样操作

    • 修改redis.conf
    1)daemonize yes
    2)port 8001(分别对每个机器的端口号进行设置)
    3)dir /usr/local/redis/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)
    4)cluster-enabled yes(启动集群模式)
    5)cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对应上)
    6)cluster-node-timeout 5000
    7) bind 127.0.0.1(去掉bind绑定访问ip信息, 注释掉,或改为0.0.0.0也可)
    8) protected-mode no (关闭保护模式)
    9)appendonly yes
    如果要设置密码需要增加如下配置:
    10)requirepass xxx (设置redis访问密码)
    11)masterauth xxx (设置集群节点间访问密码,跟上面一致)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    将修改好的8001的redis.conf配置文件分别拷贝至8002-8006,修改响应的端口,文件名

    cp /usr/local/redis/redis-cluster/8001/redis.conf /usr/local/redis/redis-cluster/8002/
    scp /usr/local/redis/redis-cluster/8001/redis.conf root@192.168.2.59:/usr/local/redis/redis-cluster/8003/
    scp /usr/local/redis/redis-cluster/8001/redis.conf root@192.168.2.59:/usr/local/redis/redis-cluster/8004/
    scp  /usr/local/redis/redis-cluster/8001/redis.conf root@192.168.1.60:/usr/local/redis/redis-cluster/8005/
    scp  /usr/local/redis/redis-cluster/8001/redis.conf root@192.168.1.60:/usr/local/redis/redis-cluster/8006/
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    新拷贝的五个文件仅修改配置项:port、dir、cluster-config-file 即可

    • 分别启动6个redis实例
    redis-server /usr/local/redis/redis-cluster/8001/redis.conf
    redis-server /usr/local/redis/redis-cluster/8002/redis.conf
    redis-server /usr/local/redis/redis-cluster/8003/redis.conf
    redis-server /usr/local/redis/redis-cluster/8004/redis.conf
    redis-server /usr/local/redis/redis-cluster/8005/redis.conf
    redis-server /usr/local/redis/redis-cluster/8006/redis.conf
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 创建集群
    redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.2.58:8001 192.168.2.58:8002 192.168.2.59:8003 192.168.2.59:8004 192.168.1.60:8005 192.168.1.60:8006
    
    
    • 1
    • 2
    • 验证集群
      连接A机器任意一个节点
    redis-cli -a 123456 -c -h 192.168.2.58 -p 8001  -a 123456
    
    • 1

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    • 查看集群信息
      在这里插入图片描述
    • 查看集群节点
      在这里插入图片描述
    • 关闭集群
    redis-cli -a 123456 -c -h 192.168.2.58 -p 8001 shutdown
    redis-cli -a 123456 -c -h 192.168.2.58-p 8002 shutdown
    redis-cli -a 123456 -c -h 192.168.2.59 -p 8003 shutdown
    redis-cli -a 123456 -c -h 192.168.2.59 -p 8004 shutdown
    redis-cli -a 123456 -c -h 192.168.1.60 -p 8005 shutdown
    redis-cli -a 123456 -c -h 192.168.1.60 -p 8006 shutdown
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 用脚本关闭和启动集群
    • 用脚本关闭集群
    #!/bin/bash
    #所有服务器节点的hostname
    allnodes=('10.12.2.59' '10.12.2.58' '192.168.1.60')
    local_ip=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"​`
    echo "### " date
    echo "### local_ip: ${local_ip}"
    PORT=8001
    ENDPORT=8007
    PASSWROD=123456
    while [ $((PORT < ENDPORT)) != "0" ]; do
        for ip in ${allnodes[@]};
        do
            if [ "$ip" = "$local_ip" ];
            then 
                local_count=`ps -ef|grep redis |grep $PORT | wc -l`
                if [ $local_count -gt 0 ];
                then
                    echo "### Stoping Local Redis $ip:$PORT"
                    redis-cli -p $PORT -a $PASSWROD shutdown
                else 
                    echo "no Local redis $ip:$PORT"
                fi
            else
                #判断某个端口是否已被占用,如果是,则执行关闭命令
                count=`ssh root@$ip lsof -i:$PORT | wc -l`
                if [ $count -gt 0 ];
                then
                    echo "### Stopping Redis $ip:$PORT"
                    ssh root@$ip redis-cli -p $PORT -a $PASSWROD shutdown 2>/dev/null
                else
                    echo "no redis $ip:$PORT"
                fi
            fi
        done
        PORT=$((PORT+1))
    done
    exit 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 用脚本启动集群
    #!/bin/bash
    #所有服务器节点的hostname
    declare -A dic
    dic=([8001]="10.12.2.58" [8002]="10.12.2.58" [8003]="10.12.2.59" [8004]="10.12.2.59" [8005]="192.168.1.60" [8006]="192.168.1.60")
    
    local_ip=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"​`
    echo "### " date
    echo "### local_ip: ${local_ip}"
    
    for port in ${!dic[*]}
    do 
        ip=${dic[${port}]}
        #echo ip: ${ip} ${port}
        if [ "$ip" = "$local_ip" ];
        then 
            local_count=`ps -ef|grep redis |grep $port | wc -l`
            if [ $local_count -eq 0 ];
            then
                echo "Start Local Redis Server $ip $port"
                redis-server /usr/local/redis/redis-cluster/$port/redis.conf
            else
                echo "Local Redis Server $ip $port already exists!"
            fi
        else
            count=`ssh root@$ip ps -ef|grep redis-server|grep -v grep|grep $port| wc -l`
            if [ $count -eq 0 ];
            then
                echo "Start Redis Server $ip $port"
                ssh root@$ip redis-server /usr/local/redis/redis-cluster/$port/redis.conf
            else
                echo "Redis Server $ip $port already exists!"
            fi
        fi    
    done
    exit 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    注意:

    • 各集群都设置开开机启动,设置方法请参考https://blog.csdn.net/craftsman2020/article/details/128130348?spm=1001.2014.3001.5502
    • 为了方便启动和终止程序,用shell脚本操作。
    • 集群各机器操作系统版本尽量协调,避免出现Centos6和Centos9无法ssh访问的问题。

    3. 遇到的问题

    • 三台机器设置免密互访
      但由于这三台机器centos版本差异大,导致Centos9和Centos6无法设置免密互访。
      设置免密报错,直接用ssh指令连接也会报错:
      在这里插入图片描述
      尝试在生成公钥的文件夹里(一般在当前用户目录下的.ssh文件中)创建一个config文件(没有后缀),用文本文档格式打开,添加下方内容
    Host *
    HostkeyAlgorithms +ssh-rsa
    PubkeyAcceptedKeyTypes +ssh-rsa
    
    • 1
    • 2
    • 3

    参考:
    https://blog.csdn.net/weixin_51443484/article/details/125944815
    https://weibo.com/ttarticle/p/show?id=2309404806141325738316
    但是并没有解决。

    之后在centos6上对centos9设置免密:

    ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.60
    
    • 1

    报错如下:

    no hostkey alg
    
    • 1

    在centos9上对centos6设置免密报错如下:

    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    
    /usr/bin/ssh-copy-id: ERROR: Unable to negotiate with 192.168.1.30 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
    
    • 1
    • 2
    • 3
    • 4

    之后采取了折中的办法,因为Centos7可以对另外两台脚本互设免密,所以就把启动和终止redis集群的脚本放在了Centos7上。

    • 连接redis集群报错:(error) MOVED的解决方法
    ./redis-cli -h 192.168.2.58 -p 8001-a 123456
    
    192.168.2.58 :8001 > get name
    
    (error) MOVED 5798 192.168.2.58 :8001
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这种情况一般是因为启动 redis-cli 时没有设置集群模式所导致。

    启动时使用 -c 参数来启动集群模式,命令如下:

    ./redis-cli -h 192.168.2.58 -p 8001 -a 123456 -c
    
    192.168.2.58:8001 > get name
    
    -> Redirected to slot [5798] located at 192.168.2.58 :8001
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • (error) READONLY You can‘t write against a read only replica.
      出现以上错误,表示当前redis服务是只读的,没有写权限,估计该服务是被当作从数据库使用了。
      当在redis集群的从节点上做写操作时会遇到以上报错。

    • Redis (error) CROSSSLOT Keys in request don’t hash to the same slot
      参考 https://blog.csdn.net/TreeShu321/article/details/102766814

    4. cluster指令

    192.168.1.150:8007> cluster help
     1) CLUSTER <subcommand> arg arg ... arg. Subcommands are:
     2) ADDSLOTS <slot> [slot ...] -- Assign slots to current node.
     3) BUMPEPOCH -- Advance the cluster config epoch.
     4) COUNT-failure-reports <node-id> -- Return number of failure reports for <node-id>.
     5) COUNTKEYSINSLOT <slot> - Return the number of keys in <slot>.
     6) DELSLOTS <slot> [slot ...] -- Delete slots information from current node.
     7) FAILOVER [force|takeover] -- Promote current replica node to being a master.
     8) FORGET <node-id> -- Remove a node from the cluster.
     9) GETKEYSINSLOT <slot> <count> -- Return key names stored by current node in a slot.
    10) FLUSHSLOTS -- Delete current node own slots information.
    11) INFO - Return onformation about the cluster.
    12) KEYSLOT <key> -- Return the hash slot for <key>.
    13) MEET <ip> <port> [bus-port] -- Connect nodes into a working cluster.
    14) MYID -- Return the node id.
    15) NODES -- Return cluster configuration seen by node. Output format:
    16)     <id> <ip:port> <flags> <master> <pings> <pongs> <epoch> <link> <slot> ... <slot>
    17) REPLICATE <node-id> -- Configure current node as replica to <node-id>.
    18) RESET [hard|soft] -- Reset current node (default: soft).
    19) SET-config-epoch <epoch> - Set config epoch of current node.
    20) SETSLOT <slot> (importing|migrating|stable|node <node-id>) -- Set slot state.
    21) REPLICAS <node-id> -- Return <node-id> replicas.
    22) SLOTS -- Return information about slots range mappings. Each range is made of:
    23)     start, end, master and replicas IP addresses, ports and ids
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5. 相关文章

    (1) redis集群搭建

    redis集群搭建

    (2) 华为云两台机器内网互联

    华为云两台机器内网互联

    (3) /etc/rc.d/init.d 详解|程序开机自启

    /etc/rc.d/init.d 详解|程序开机自启

    (4) Redis5.0+ Redis集群水平扩容|节点删除

    Redis5.0+ Redis集群水平扩容|节点删除

    (5) 三台机器搭建redis集群过程及问题记录

    三台机器搭建redis集群过程及问题记录

    (6) redis5.0集群搭建(两台服务器)

    redis5.0集群搭建(两台服务器)

    (7) Linux安装部署Redis

    Linux安装部署Redis

    (8) 【redis】 windows环境下安装、配置、使用、卸载

    【redis】 windows环境下安装、配置、使用、卸载

    (9) CentOS chkconfig的安装及使用

    CentOS chkconfig的安装及使用

    (10) 解决Linux局域网不能相互访问

    解决Linux局域网不能相互访问

    (11) redis集群中节点fail,noaddr

    redis集群中节点fail,noaddr

    (12) shell脚本使用字典

    shell脚本使用字典

  • 相关阅读:
    LeetCode //C - 108. Convert Sorted Array to Binary Search Tree
    (附源码)ssm教材管理系统 毕业设计 011229
    基于骑手优化优化的BP神经网络(分类应用) - 附代码
    ES6------04let经典案例实现
    Python生成器
    ARM Cortex-A9:裸机开发,点亮LED3
    从Spring源码探究IOC初始化流程
    网络安全事件应急演练方案
    BBR 公平收敛
    &lt;&lt;Java语言程序设计&gt;&gt;进阶篇 Exercise22_3
  • 原文地址:https://blog.csdn.net/craftsman2020/article/details/128175886