# 028. 在项目中重新搭建一套读写分离+高可用+多 master 的 redis cluster 集群
上一章节对 redis cluster 最最基础的一些知识进行了了解。
redis cluster: master+slave 复制和读写分离/高可用和主备切换 都是自动支持的,支持多个 master 的 hash slot 支持数据分布式存储
所以停止之前所有的实例,包括 redis 主从和哨兵集群
# redis cluster 的重要配置
cluster-enabled <yes/no>
cluster-config-file <filename>
这是指定一个文件,供 cluster 模式下的 redis 实例将集群状态保存在那里,包括集群中其他机器的信息,比如节点的上线和下限,故障转移,不是我们去维护的,给它指定一个文件,让 redis 自己去维护的
cluster-node-timeout <milliseconds>
节点存活超时时长,超过一定时长,认为节点宕机,master 宕机的话就会触发主备切换,slave 宕机就不会提供服务
# 在三台机器上启动 6 个 redis 实例
redis cluster 集群要求至少 3 个 master,去组成一个高可用,健壮的分布式的集群,每个 master 都建议至少给一个 slave,3 个 master,3 个 slave,最少的要求
正式环境下,建议都是说在 6 台机器上去搭建,至少 3 台机器,保证每个 master 都跟自己的 slave 不在同一台机器上,如果是 6 台自然更好
3 台机器去搭建 6 个 redis 实例的 redis cluster
hostname | 配置文件 |
---|---|
eshop-cache01 | 7001.conf、 7002.conf |
eshop-cache02 | 7003.conf、 7004.conf |
eshop-cache03 | 7005.conf、 7006.conf |
TIP
redis 还是一样的,只是配置文件中的属性不同了,建议使用默认的配置文件重新配置
配置目录整体概览
|- /etc
|- /redis # 存放配置文件,按端口名命名
|- 7001.conf
|- /redis-cluster # 存放 redis 集群维护的配置文件目录
|- /init.d
|-/redis_7001 # 启动脚本
|- /var
|-/log/redis # 存放日志文件
|-/7001.log # 日志文件
|-/redis/7001 # 存放数据文件
2
3
4
5
6
7
8
9
10
配置文件和启动脚本
对于配置文件 主要要修改的在下面了
port 7001
cluster-enabled yes
cluster-config-file /etc/redis-cluster/node-7001.conf
cluster-node-timeout 15000
daemonize yes
pidfile /var/run/redis_7001.pid
dir /var/redis/7001
logfile /var/log/redis/7001.log
# 如果后续不能正常创建集群,请把这里修改成 ip 的形式
bind eshop-cache01
appendonly yes
2
3
4
5
6
7
8
9
10
11
为了方便快捷的把配置文件搞好。先执行以下命令
mkdir -p /etc/redis-cluster
mkdir -p /var/log/redis
mkdir -p /var/redis/7001
# 复制默认配置文件,并修改
cp /usr/local/redis-3.2.8/redis.conf /etc/redis/7001.conf
# 复制启动脚本,需要 6 个启动脚本 ,里面的 REDISPORT=7001 需要修改成和文件名对应的端口
cp /usr/local/redis-3.2.8/utils/redis_init_script /etc/init.d/redis_7001
2
3
4
5
6
7
8
然后下载 7001.conf 到 windows 中,按以上配置文件修改完成后, 复制其余 5 份出来,只要全局把 7001 替换成 其余 5 分节点的端口和 bind 修改好就可以了
启动 6 个 redis 实例
# 通过之前一样的命令启动 6 个实例
./redis_7001 start
# 查看日志是否启动正常,现在配置了日志文件的
cat /var/log/redis/7001.log
2
3
4
# 创建集群
之前启动的 6 个redis 实例只是单机的,需要使用工具创建集群
通过官网提供的工具 redis-trib.rb 工具创建,该工具依赖了 ruby,先装依赖
# 不要直接使用此命令安装,因为安装的是低版本的。参考本文后面的 Ruby 的安装
yum install -y ruby
# 不要使用 yum 安装,在 centos 6 中只会安装 1.8 版本的,并且连 ruby 也一起安装的
yum install -y rubygems
# 前面的安装请参考 本文后面的 Ruby 安装
gem install redis
## 让 redis-trib.rb 工具不在具体目录下也可以使用,和 windows path 效果类似
cp /usr/local/redis-3.2.8/src/redis-trib.rb /usr/local/bin
# 创建集群,注意这里需要使用 ip 地址,否则不成功
# --replicas: 每个 master 有几个 slave
# 6 台机器,3 个 master,3 个 slave,尽量自己让 master 和 slave 不在一台机器上
redis-trib.rb create --replicas 1 192.168.99.170:7001 192.168.99.170:7002 192.168.99.171:7003 192.168.99.171:7004 192.168.99.172:7005 192.168.99.172:7006
2
3
4
5
6
7
8
9
10
11
12
13
14
15
安装的话,不需要每台机器都安装,在 01 上安装和创建集群即可
# 在输入 yes 后,会如果报错。
Can I set the above configuration? (type 'yes' to accept): yes
/opt/rubies/ruby-2.3.8/lib/ruby/gems/2.3.0/gems/redis-4.1.0/lib/redis/client.rb:124:in `call': ERR Slot 0 is already busy (Redis::CommandError)
原因是 slot 被占用,解决方案如下,登录各个节点执行 cluster reset
[root@eshop-cache02 redis]# redis-cli -h 192.168.99.171 -p 7003
192.168.99.171:7003> cluster reset
OK
192.168.99.171:7003> exit
[root@eshop-cache02 redis]# redis-cli -h 192.168.99.171 -p 7004
192.168.99.171:7004> cluster reset
OK
192.168.99.171:7004> exit
[root@eshop-cache02 redis]# redis-cli -h 192.168.99.170 -p 7001
192.168.99.170:7001> cluster reset
OK
192.168.99.170:7001> exit
[root@eshop-cache02 redis]# redis-cli -h 192.168.99.170 -p 7002
192.168.99.170:7002> cluster reset
OK
192.168.99.170:7002> exit
[root@eshop-cache02 redis]# redis-cli -h 192.168.99.172 -p 7005
192.168.99.172:7005> cluster reset
OK
192.168.99.172:7005> exit
[root@eshop-cache02 redis]# redis-cli -h 192.168.99.172 -p 7006
192.168.99.172:7006> cluster reset
OK
192.168.99.172:7006> exit
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
再次创建集群后,终于成功了。从安装 ruby 开始到现在已经过去了 4 个小时, 真是太坎坷了
可以看到如下的日志,它选择了 3 个master,3 个 slave 并且都不在一台机器上
[root@eshop-cache01 redis]# redis-trib.rb create --replicas 1 192.168.99.170:7001 192.168.99.170:7002 192.168.99.171:7003 192.168.99.171:7004 192.168.99.172:7005 192.168.99.172:7006
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.99.170:7001
192.168.99.171:7003
192.168.99.172:7005
Adding replica 192.168.99.171:7004 to 192.168.99.170:7001
Adding replica 192.168.99.170:7002 to 192.168.99.171:7003
Adding replica 192.168.99.172:7006 to 192.168.99.172:7005
M: 3807711e01cd28509d7ba9839e601058bf2a30cf 192.168.99.170:7001
slots:0-5460 (5461 slots) master
S: b0d66be3b15e117696c50a781ff24a842456733d 192.168.99.170:7002
replicates 0ff0e8ab05a8b032aeacf24e0c7fea77be3f5c55
M: 0ff0e8ab05a8b032aeacf24e0c7fea77be3f5c55 192.168.99.171:7003
slots:5461-10922 (5462 slots) master
S: a174fe6613862db8985f82caac58bde91dfbd664 192.168.99.171:7004
replicates 3807711e01cd28509d7ba9839e601058bf2a30cf
M: cb2256b653cf5b7b3f9d1478cfa2953cc334c5bf 192.168.99.172:7005
slots:10923-16383 (5461 slots) master
S: 9247dfb394441619da9da5b75b62b034c3f420e5 192.168.99.172:7006
replicates cb2256b653cf5b7b3f9d1478cfa2953cc334c5bf
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 192.168.99.170:7001)
M: 3807711e01cd28509d7ba9839e601058bf2a30cf 192.168.99.170:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 9247dfb394441619da9da5b75b62b034c3f420e5 192.168.99.172:7006
slots: (0 slots) slave
replicates cb2256b653cf5b7b3f9d1478cfa2953cc334c5bf
M: cb2256b653cf5b7b3f9d1478cfa2953cc334c5bf 192.168.99.172:7005
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: a174fe6613862db8985f82caac58bde91dfbd664 192.168.99.171:7004
slots: (0 slots) slave
replicates 3807711e01cd28509d7ba9839e601058bf2a30cf
M: 0ff0e8ab05a8b032aeacf24e0c7fea77be3f5c55 192.168.99.171:7003
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: b0d66be3b15e117696c50a781ff24a842456733d 192.168.99.170:7002
slots: (0 slots) slave
replicates 0ff0e8ab05a8b032aeacf24e0c7fea77be3f5c55
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
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
39
40
41
42
43
44
45
46
47
48
49
50
可以通过 check 命令检查
[root@eshop-cache01 redis]# redis-trib.rb check eshop-cache01:7001
>>> Performing Cluster Check (using node eshop-cache01:7001)
M: 3807711e01cd28509d7ba9839e601058bf2a30cf eshop-cache01:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 9247dfb394441619da9da5b75b62b034c3f420e5 192.168.99.172:7006
slots: (0 slots) slave
replicates cb2256b653cf5b7b3f9d1478cfa2953cc334c5bf
M: cb2256b653cf5b7b3f9d1478cfa2953cc334c5bf 192.168.99.172:7005
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: a174fe6613862db8985f82caac58bde91dfbd664 192.168.99.171:7004
slots: (0 slots) slave
replicates 3807711e01cd28509d7ba9839e601058bf2a30cf
M: 0ff0e8ab05a8b032aeacf24e0c7fea77be3f5c55 192.168.99.171:7003
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: b0d66be3b15e117696c50a781ff24a842456733d 192.168.99.170:7002
slots: (0 slots) slave
replicates 0ff0e8ab05a8b032aeacf24e0c7fea77be3f5c55
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 读写分离+高可用+多 master
集群安装成功之后,就具有了如下功能:
- 读写分离:每个 master 都有一个 slave
- 高可用:master 宕机,slave 自动被切换过去
- 多 master:横向扩容支持更大数据量
# Ruby 的安装
# Ruby 安装
在 ruby 官网找到一个安装任意版本的工具 ruby-install (opens new window)
cd /ust/local
# 安装 ruby-install
wget -O ruby-install-0.7.0.tar.gz https://github.com/postmodern/ruby-install/archive/v0.7.0.tar.gz
tar -xzvf ruby-install-0.7.0.tar.gz
cd ruby-install-0.7.0/
sudo make install
# 安装 2.3 版本 ruby,执行后会看到 update runby.. 应该是吧之前 1.8 版本的更新了
# 要等待好长时间,在安装过程中的时候 32% [305/947] io.c ,947 的进度条。。
ruby-install ruby 2.3
# 如果你之前通过 yum 安装过 低版本的 ruby,那么需要移除掉
yum remove ruby
# 移除之后,发现提示有误
[root@eshop-cache01 ruby-2.3.8]# ruby -v
-bash: /usr/bin/ruby: No such file or directory
# 其实在 ruby-install ruby 2.3 安装完成过程中是有显示安装位置的
# 通过 ls 命令 连接到安装目录的 ruby 文件即可
ln -s /usr/local/src/ruby-2.3.8/ruby /usr/bin/ruby
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
以下尝试过好长时间都不能安装上,主要是 rvm 安装不了
解决 gem install redis redis requires Ruby version >= 2.2.2.报错问题 (opens new window)
# 安装 curl
sudo yum install curl
# 安装 RVM
# curl -L get.rvm.io | bash -s stable
# curl -L https://get.rvm.io | bash -s stable
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
# 我再执行这步骤的时候老是报错 curl returned status '35'. ,下载不下来
# 按照官网的 https://rvm.io/ 方式也是报错
curl -sSL https://get.rvm.io | bash -s stable
source /usr/local/rvm/scripts/rvm
# 查看 rvm 库中已知的 ruby 版本
rvm list known
# 安装一个 ruby 版本
rvm install 2.3.3
# 使用一个 ruby 版本
rvm use 2.3.3
# 卸载一个已知版本
rvm remove 2.0.0
ruby --version
# 再安装redis就可以了
gem install redis
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# rubygems 安装
安装方式请参考官网:https://rubygems.org/pages/download
cd /usr/local
wget https://rubygems.org/rubygems/rubygems-3.0.3.zip
# 如果没有安装 zip,请执行 yum install unzip
unzip rubygems-3.0.3.zip
cd rubygems-3.0.3
ruby setup.rb
ln -s /usr/local/rubygems-3.0.3/bin/gem /usr/bin/gem
2
3
4
5
6
7