CentOS7 配置redis3.0集群开机启动
阅读原文时间:2021年04月20日阅读:1

1. Redis Cluster的架构图。

1.1redis-cluster架构图

架构细节

(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.

(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

1.2 redis--cluster

(1)领着选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-node-timeout),认为当前master节点挂掉.

(2):什么时候整个集群不可用(cluster_state:fail),当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误

    a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成进群的slot映射[0-16383]不完成时进入fail状态.

    b:如果进群超过半数以上master挂掉,无论是否有slave集群进入fail状态.

ps:当集群不可用时,所有对集群的操作做都不可用,收到((error)CLUSTERDOWN Thecluster is down)错误。

2.redis集群安装

线上的统一聊天和推送项目使用的是Redis主从,redis版本3.0

redis主从和MySQL主从目的差不多,但redis主从配置很简单,主要在从节点配置文件指定主节点ip和端口:slaveof  120.77.213.193  6379,然后启动主从,主从就搭建好了redis主从中如果主节点发生故障,不会自动切换,需要借助redis的Sentinel或者keepalive来实现主的故障转移

redis集群是一个无中心的分布式redis存储架构,可以在多个节点之间进行数据共享,解决了redis高可用、可扩展等问题,redis集群提供了以下两个好处
(1)、将数据自动切分(split)到多个节点
(2)、当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。
一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
集群中的主从复制
集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作

下面开始搭建redis集群

因为redis-cluster要求最少6个节点(maseter*3 + slave*3)主  附

1.安装ruby与相关组件:

查看服务器是否安装ruby:
yum list | grep ruby
rpm -qa | grep ruby

若没有安装,则安装组件:

yum install ruby
然后输入y则安装成功

安装gem相关:

yum install rubygems

gem install redis

这里可能无法安装,因为无法连接gem服务器:
[@zw_22_90 src]# gem install redis --version 3.0.0
ERROR: Could not find a valid gem 'redis' (= 3.0.0) in any repository
ERROR: While executing gem … (Gem::RemoteFetcher::FetchError)

需要手工下载并安装:
wget https://rubygems.global.ssl.fastly.net/gems/redis-3.2.1.gem
gem install -l ./redis-3.2.1.gem

2. 安装redis

redis 6个节点的ip和端口对应关系

120.77.213.193:7001

120.77.213.193:7002

120.77.213.193:7003

120.77.213.193:7004

120.77.213.193:7005

120.77.213.193:7006

[root@iZwz91nfqrmmcjz3ax4vqvZ ~]# cd  /usr/java
[root@iZwz91nfqrmmcjz3ax4vqvZ java]# mkdir redis-cluster
[root@iZwz91nfqrmmcjz3ax4vqvZ java]# cd redis-cluster
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# wget http://download.redis.io/releases/redis-3.0.6.tar.gz  
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# tar -zxvf  redis-3.0.6.tar.gz
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# mkdir redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# mkdir redis7002
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# mkdir redis7003
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# mkdir redis7004
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# mkdir redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# mkdir redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cd  redis-3.0.6
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-3.0.6]#make                 编译

3、修改配置文件redis.conf

拷贝/redis-3.0.6/src目录下的3个文件:

redis-server    redis-cli     redis-benchmark到redis-3.0.6目录

复制redis-3.0.6的文件到7001个redis文件夹下,执行命令:

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cp -Rf redis-3.0.6/*   redis7001

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cd redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]#  vi redis.conf
修改配置文件
daemonize &nbsp; &nbsp;yes &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//redis后台运行
port &nbsp;7001 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //端口10000
cluster-enabled &nbsp;yes &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//开启集群 &nbsp;把注释#去掉
cluster-config-file &nbsp;nodes_10000.conf &nbsp;       //集群的配置 &nbsp;配置文件首次启动自动生成
cluster-node-timeout &nbsp;5000 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;    //请求超时 &nbsp;设置5秒够了
appendonly &nbsp;yes &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  //aof日志开启 &nbsp;有需要就开启,它会每次写操作都记录一条日志[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cp -Rf redis7001/*   redis7002


[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cp -Rf redis7001/*   redis7003
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cp -Rf redis7001/*   redis7004
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cp -Rf redis7001/*   redis7005
[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cp -Rf redis7001/*   redis7006

拷贝完成之后要分别修改7002/7003/7004/7005/7006目录下面redis.conf文件中的port参数

4 分别进入6个文件,启动6个redis实例

redis-server redis.conf 

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cd redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# ./redis-server ./redis.conf 
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# cd ../redis7002
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7002]# ./redis-server ./redis.conf 
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7002]# cd ../redis7003
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7003]# ./redis-server ./redis.conf 
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7003]# cd ../redis7004
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7004]# ./redis-server ./redis.conf 
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7004]# cd ../redis7005
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7005]# ./redis-server ./redis.conf 
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7005]# cd ../redis7006
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7006]# ./redis-server ./redis.conf 

启动完成后:

执行ps -ef|grep redis可看到如下:

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# ps -ef|grep redis
root      5478     1  0 14:24 ?        00:00:00 ./redis-server *:7001 [cluster]
root      5485     1  0 14:24 ?        00:00:00 ./redis-server *:7002 [cluster]
root      5489     1  0 14:24 ?        00:00:00 ./redis-server *:7003 [cluster]
root      5493     1  0 14:24 ?        00:00:00 ./redis-server *:7004 [cluster]
root      5497     1  0 14:24 ?        00:00:00 ./redis-server *:7005 [cluster]
root      5502     1  0 14:24 ?        00:00:00 ./redis-server *:7006 [cluster]
root      5512  4934  0 14:26 pts/1    00:00:00 grep --color=auto redis

5.执行redis的创建集群命令创建集群(注意ip地址和端口号)

将src文件夹下的redis-trib.rb文件拷贝到redis-cluster目录下,执行命令:

./redis-trib.rb  create --replicas 1 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

提示是否允许修改配置文件,输入yes----即可启动redis集群  

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# ./redis-trib.rb  create --replicas 1 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
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
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
Adding replica 127.0.0.1:7006 to 127.0.0.1:7003
M: c60d1642a36bb253364daa244b1e1e868606c4a6 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 63eedc9839436f369be521e724d59822a7291841 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: 312cbfb3f8f7613587b923eb091b43510942898e 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
S: f7fde42093d0cd2797a55d4712667f19811c5237 127.0.0.1:7004
   replicates c60d1642a36bb253364daa244b1e1e868606c4a6
S: 2e7ba20edd2012eb861ad9c6cc4402ffb1bbc68a 127.0.0.1:7005
   replicates 63eedc9839436f369be521e724d59822a7291841
S: d3173bad6d9564470ea98f69d7552cd666c44d60 127.0.0.1:7006
   replicates 312cbfb3f8f7613587b923eb091b43510942898e
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:7001)
M: c60d1642a36bb253364daa244b1e1e868606c4a6 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 63eedc9839436f369be521e724d59822a7291841 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: 312cbfb3f8f7613587b923eb091b43510942898e 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
M: f7fde42093d0cd2797a55d4712667f19811c5237 127.0.0.1:7004
   slots: (0 slots) master
   replicates c60d1642a36bb253364daa244b1e1e868606c4a6
M: 2e7ba20edd2012eb861ad9c6cc4402ffb1bbc68a 127.0.0.1:7005
   slots: (0 slots) master
   replicates 63eedc9839436f369be521e724d59822a7291841
M: d3173bad6d9564470ea98f69d7552cd666c44d60 127.0.0.1:7006
   slots: (0 slots) master
   replicates 312cbfb3f8f7613587b923eb091b43510942898e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

这样就可以登录客户端查看集群状况:

进入redis7001

执行:

./redis-cli -c -p 7001则进入客户端.

测试

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cd redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# ./redis-cli -c -p 7001
127.0.0.1:7001> get key
-> Redirected to slot [12539] located at 127.0.0.1:7003
(nil)
127.0.0.1:7003> set name test
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set adress lye
-> Redirected to slot [1562] located at 127.0.0.1:7001
OK
127.0.0.1:7001> get key
-> Redirected to slot [12539] located at 127.0.0.1:7003
(nil)
127.0.0.1:7003> set key val
OK
127.0.0.1:7003> get key
"val"
127.0.0.1:7003> set key2 val2
-> Redirected to slot [4998] located at 127.0.0.1:7001
OK
127.0.0.1:7001> get key2
"val2"

查询所有的key   

keys *

集群状态查看:

cluster nodes
cluster info 

6.设置密码

注意事项:

1.如果是使用redis-trib.rb工具构建集群,集群构建完成前不要配置密码,集群构建完毕再通过config set + config rewrite命令逐个机器设置密码

2.如果对集群设置密码,那么requirepass和masterauth都需要设置,否则发生主从切换时,就会遇到授权问题,可以模拟并观察日志

3.各个节点的密码都必须一致,否则Redirected就会失败

方法一:

[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# vi redis.conf 

masterauth  

requirepass  abc

默认前面存在#号的,修改密码需要把#删除

修改完重启

[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# ./redis-server ./redis.conf&

方法二:

[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# ./redis-cli -c -p 7001
127.0.0.1:7001> config set masterauth abc
OK
127.0.0.1:7001> config set requirepass abc
OK
127.0.0.1:7001> config rewrite

测试:

[root@iZwz91nfqrmmcjz3ax4vqvZ redis-cluster]# cd redis7001
[root@iZwz91nfqrmmcjz3ax4vqvZ redis7001]# ./redis-cli -c -p 7001 
127.0.0.1:7001> cluster nodes
NOAUTH Authentication required.   #因为设置了密码,所以如何操作需要输入密码验证
127.0.0.1:7001> auth "abc"        #这里输入设置密码
OK
127.0.0.1:7001> cluster nodes
d3173bad6d9564470ea98f69d7552cd666c44d60 127.0.0.1:7006 slave 312cbfb3f8f7613587b923eb091b43510942898e 0 1483519617809 6 connected
2e7ba20edd2012eb861ad9c6cc4402ffb1bbc68a 127.0.0.1:7005 slave 63eedc9839436f369be521e724d59822a7291841 0 1483519618809 5 connected
63eedc9839436f369be521e724d59822a7291841 127.0.0.1:7002 master - 0 1483519621815 2 connected 5461-10922
c60d1642a36bb253364daa244b1e1e868606c4a6 127.0.0.1:7001 myself,master - 0 0 1 connected 0-5460
312cbfb3f8f7613587b923eb091b43510942898e 127.0.0.1:7003 master - 0 1483519619811 3 connected 10923-16383
f7fde42093d0cd2797a55d4712667f19811c5237 127.0.0.1:7004 slave c60d1642a36bb253364daa244b1e1e868606c4a6 0 1483519620814 4 connected
127.0.0.1:7001> 

Redis Cluster 再次安装出现的异常

今天补充一下一个异常,当你Redis Cluster 集群在集群一次,比如IP地址要变化或者什么的,你再次集群的时候你会发现一个异常:

  1. Node 127.0.0.1:10001 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

这个时候你需要把开始生成的nodes_*.conf 、appendonly.aof 、dump.rdb  文件删除,再次集群就可以了。

这里是设置的是某一个redis开机启动,没有使用集群,这里设置的是7001

1. 根据启动脚本要求,将修改好的配置文件以端口为名复制一份到指定目录。需使用root用户

mkdir /etc/redis
cp redis.conf /etc/redis/7001.conf

修改7001.conf文件

daemonize no 改为 daemonize  yes

pidfile  /var/run/redis.pid  改为  pidfile  /var/run/redis_7001.pid

 2. 将启动脚本复制到/etc/init.d目录下,本例将启动脚本命名为redis。

cp  utils/redis_init_script   /etc/init.d/redis

编辑redis,插入下面2行注释

#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 2345 80 90
# description: Redis is a persistent key-value database

完整配置为

#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 2345 80 90
# description: Redis is a persistent key-value database

REDISPORT=7001
EXEC=/usr/java/redis-cluster/redis7001/redis-server
CLIEXEC=/usr/java/redis-cluster/redis7001/redis-cli

PIDFILE=/var/run/redis_${REDISPORT}.pid
CONF="/etc/redis/${REDISPORT}.conf"

case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF &
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $CLIEXEC -p $REDISPORT shutdown
                while [ -x /proc/${PID} ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
    *)
        echo "Please use start or stop as first argument"
        ;;
esac

#注册为服务
chkconfig --add redis
#设置为开机自启动服务器
chkconfig redis on
#打开服务
service redis start
#关闭服务
service redis stop