开启运维之路之第 9 篇——Redis单机多点集群

Redis集群

redis cluster是去中心化,去中间件的,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

Redis 集群采用一种叫做哈希槽 (hash slot)的方式来分配。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。

注意的是:必须要3个以后的主节点,否则在创建集群时会失败。

假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:
节点A覆盖0-5460;
节点B覆盖5461-10922;
节点C覆盖10923-16383。

如果想新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上:

节点A覆盖1365-5460
节点B覆盖6827-10922
节点C覆盖12288-16383
节点D覆盖0-1364,5461-6826,10923-12287
同样删除一个节点也是类似,移动完成后就可以删除这个节点了。

redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。

所以我们在集群建立的时候,一定要为每个主节点都添加了从节点, 比如像这样, 集群包含主节点A、B、C, 以及从节点A1、B1、C1, 那么即使B挂掉系统也可以继续正确工作。B1节点替代了B节点,所以Redis集群将会选择B1节点作为新的主节点,集群将会继续正确地提供服务。 当B重新开启后,它就会变成B1的从节点。

不过需要注意,如果节点B和B1同时挂了,Redis集群就无法继续正确地提供服务了。

Redis单机多节点集群:

1、将 集群工具 redis-trib.rb 复制到 usr/local/bin 目录下:注意要根据 redis 安装的路径进行选择,如果根据本人的这套教程,就没问题。

[root@localhost ~]# cd /root/redis-4.0.10/src/
[root@localhost src]# ls -a


可以看到集群工具 redis-trib.rb。要加 -a 才能显示。

复制到 usr/local/bin 目录下:

[root@localhost src]# cp redis-trib.rb /usr/local/bin/

现在弄 3主3从,一共 6 个节点,就要涉及 6 个端口:7001,7002,7003,7004,7005,7006。前面 3 个我们用作主节点,后面 3 个从节点。

我们先在root目录下新建一个redis_cluster目录,然后该目录下再创建6个目录,目录名分别是7001,7002,7003,7004,7005,7006,用来存在redis配置文件。

[root@localhost src]# cd
[root@localhost ~]# mkdir redis_cluster
[root@localhost ~]# cd redis_cluster/
[root@localhost redis_cluster]# mkdir 7001 7002 7003 7004 7005 7006
[root@localhost redis_cluster]# ls
7001  7002  7003  7004  7005  7006

先复制一份 Redis 的配置文件到 7001 目录下:(输入绝对路径,就不用担心当前处于什么目录下操作)

[root@localhost redis_cluster]# cp /root/redis-4.0.10/redis.conf /root/redis_cluster/7001/

修改 7001 目录下的配置文件:

[root@localhost redis_cluster]# cd 7001/
[root@localhost 7001]# vi redis.conf 

修改下面几个配置:特别注意,请别使用小键盘按数字,会产生冲突键,导致很多错乱问题!请使用字母上方的数字键!

修改配置,要合理运用 i 输入模式 和 Esc 模式,即修改一个,就Esc,这样就方便进行下一个查询和修改。

①端口号 port:7001,可以搜索 /port 快速定位,n 是下一个,N是上一个匹配项

②后台启动:daemonize yes  可以搜索:/daemonize

③pidfile文件:可以搜索 /pidfile  修改成:pidfile /var/run/redis_7001.pid

④开启集群:cluster-enabled yes 可以搜索:/cluster-enabled 去掉前面的注释 #

⑤保存节点配置,自动创建:cluster-config-file nodes_7001.conf

⑥集群超时时间,节点超过这个时间没反应就断定是宕机:cluster-node-timeout 5000

⑦存储方式,将写操作记录保存到日志中:appendonly yes

OK,修改完,保存,退出。:wq

把7001下的配置分别复制到7002-7006 然后对应的再修改下配置:

[root@localhost 7001]# cp /root/redis_cluster/7001/redis.conf /root/redis_cluster/7002/
[root@localhost 7001]# cp /root/redis_cluster/7001/redis.conf /root/redis_cluster/7003/
[root@localhost 7001]# cp /root/redis_cluster/7001/redis.conf /root/redis_cluster/7004/
[root@localhost 7001]# cp /root/redis_cluster/7001/redis.conf /root/redis_cluster/7005/
[root@localhost 7001]# cp /root/redis_cluster/7001/redis.conf /root/redis_cluster/7006/

这里使用绝对路径。有个技巧,键盘的方向键 上↑ 、下↓ 可以查看之前敲过的命令。

然后,7002-7006这5个配置文件都需要修改下面的信息:(把所有 7001 的改成相对应的数字即可)

①端口号 port:从 7002 - 7006,   搜索 /port
③pidfile文件:从 7002 - 7006,   搜索 /pidfile
⑤保存节点配置,自动创建:从 7002 - 7006   搜索 /cluster-config-file

小技巧:退回到上一个目录。

[root@localhost 7001]# cd ..
[root@localhost redis_cluster]# 

然后修改文件:

[root@localhost redis_cluster]# vi 7002/redis.conf 
[root@localhost redis_cluster]# vi 7003/redis.conf 
[root@localhost redis_cluster]# vi 7004/redis.conf 
[root@localhost redis_cluster]# vi 7005/redis.conf 
[root@localhost redis_cluster]# vi 7006/redis.conf 

然后小心修改。。。

修改完毕,启动 6 个节点:

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7001/redis.conf 
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7002/redis.conf 
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7003/redis.conf 
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7004/redis.conf 
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7005/redis.conf 
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7006/redis.conf

可以查看 Redis 进程:[root@localhost ~]# ps -ef | grep redis

看到,端口号 6379 是默认的也启动了,还有 7001 - 7006 端口号都启动了 Redis。

接下来,创建集群。

刚才我们已经把 集群工具 redis-trib.rb 放到 usr/local/bin 目录下了。

在使用前,需要安装ruby,让它们能连接:

[root@localhost ~]# yum -y install ruby ruby-devel rubygems rpm-build
作为依赖被升级:
  elfutils-libelf.x86_64 0:0.170-4.el7  elfutils-libs.x86_64 0:0.170-4.el7    
  openssl.x86_64 1:1.0.2k-12.el7        openssl-libs.x86_64 1:1.0.2k-12.el7   
  rpm.x86_64 0:4.11.3-32.el7            rpm-build-libs.x86_64 0:4.11.3-32.el7 
  rpm-libs.x86_64 0:4.11.3-32.el7       rpm-python.x86_64 0:4.11.3-32.el7     

完毕!
[root@localhost ~]# gem install redis

发现报错:

[root@localhost ~]# gem install redis
Fetching: redis-4.0.1.gem (100%)
ERROR:  Error installing redis:
	redis requires Ruby version >= 2.2.2.
[root@localhost ~]# 

要求 Ruby 的版本 在2.2.2以上,点击查看解决方案

解决步骤:

①安装RVM:

[root@localhost ~]# gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
稍等片刻。。。
[root@localhost ~]# curl -L get.rvm.io | bash -s stable
稍等片刻。。。。。。
[root@localhost ~]# find / -name rvm -print
/usr/local/rvm
/usr/local/rvm/src/rvm
/usr/local/rvm/src/rvm/bin/rvm
/usr/local/rvm/src/rvm/lib/rvm
/usr/local/rvm/src/rvm/scripts/rvm
/usr/local/rvm/bin/rvm
/usr/local/rvm/lib/rvm
/usr/local/rvm/scripts/rvm
[root@localhost ~]# 

②查看rvm库中已知的ruby版本:

[root@localhost ~]# source /usr/local/rvm/scripts/rvm
[root@localhost ~]# rvm list known
稍等片刻。。。

③安装一个ruby版本:

[root@localhost ~]# rvm install 2.3.3

稍等片刻。。

④使用一个ruby版本:

[root@localhost ~]# rvm use 2.3.3
Using /usr/local/rvm/gems/ruby-2.3.3
[root@localhost ~]# 

⑤设置默认版本:

[root@localhost ~]# rvm use 2.3.3 --default
Using /usr/local/rvm/gems/ruby-2.3.3
[root@localhost ~]# 

⑥卸载一个已知版本

[root@localhost ~]# rvm remove 2.0.0
ruby-2.0.0-p648 - #already gone
Using /usr/local/rvm/gems/ruby-2.3.3

⑦安装redis:

[root@localhost ~]# gem install redis
Fetching: redis-4.0.1.gem (100%)
Successfully installed redis-4.0.1
Parsing documentation for redis-4.0.1
Installing ri documentation for redis-4.0.1
Done installing documentation for redis after 1 seconds
1 gem installed

搞定 Ruby 工具!

创建集群:

[root@localhost ~]# 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

16384 个哈希槽都被使用,说明集群创建成功了。

有些时候,奇葩的问题如截图:

那是因为创建集群的时候,产生一些额外数据文件,没有清理掉。7001上不是空的,有数据,创建集群会失败。因为之前测试的数据存在这里。因此要把它们都删掉。步骤如下:

①查看 redis 进程,杀掉:[root@localhost ~]# ps -ef|grep redis

说明:你们的进程跟我的不一样,而且每次启动之后的进程也会不一样,以实际为准。

杀掉进程:kill -9 进程ID

[root@localhost ~]# kill -9 2385
[root@localhost ~]# kill -9 2390
[root@localhost ~]# kill -9 2395
[root@localhost ~]# kill -9 2400
[root@localhost ~]# kill -9 2407
[root@localhost ~]# kill -9 2414
[root@localhost ~]# ps -ef | grep redis
root       2446   2293  0 10:26 pts/0    00:00:00 grep --color=auto redis
[root@localhost ~]# 

②进入 redis 的根目录,把两个文件 anaconda-ks.cfg(未必有这个文件,有则删,无则不管)、appendonly.aof (aof是隐藏文件,需要加 -a) 删除:

[root@localhost ~]# cd /usr/local/redis/
[root@localhost redis]# ls -a
.  ..  appendonly.aof  auth  bin  dump.rdb  redis.conf
[root@localhost redis]# rm -rf appendonly.aof 
[root@localhost redis]# 

然后返回根目录,把anaconda-ks.cfg、appendonly.aof也删掉,以绝后患

[root@localhost redis]# cd
[root@localhost ~]# ls
anaconda-ks.cfg                              nodes-7006.conf
appendonly.aof                               redis-4.0.10

这样会不行,还会报错。原因是因为:之前我们测试的时候,有错误的信息,也保存到了nodes-7001.conf文件了。所以,我们需要把这些文件都删掉,还有aof等文件。刚才说的那些文件都删掉。所以,正确的做法是:删掉 aof ,6个.conf 文件

[root@localhost ~]# rm -rf appendonly.aof 
[root@localhost ~]# rm -rf anaconda-ks.cfg
[root@localhost ~]# rm -rf nodes-7001.conf 
[root@localhost ~]# rm -rf nodes-7002.conf 
[root@localhost ~]# rm -rf nodes-7003.conf 
[root@localhost ~]# rm -rf nodes-7004.conf 
[root@localhost ~]# rm -rf nodes-7005.conf 
[root@localhost ~]# rm -rf nodes-7006.conf

OK,重新启动 6 个节点,再开启集群即可。请先 cd 回到根目录,再敲下面的命令:

 

[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7001/redis.conf
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7002/redis.conf
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7003/redis.conf
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7004/redis.conf
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7005/redis.conf
[root@localhost ~]# /usr/local/redis/bin/redis-server redis_cluster/7006/redis.conf
创建集群:
[root@localhost ~]# 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

OK,绕了一圈,很多问题会遇到,各种删掉文件啊、启动啊,搞个 shell 脚本,一键搞定,如何?好の!

创建 shell 命令:[root@localhost ~]# vi startRedisCluster.sh

rm -rf appendonly.aof
rm -rf anaconda-ks.cfg
rm -rf nodes-7001.conf
rm -rf nodes-7002.conf
rm -rf nodes-7003.conf
rm -rf nodes-7004.conf
rm -rf nodes-7005.conf
rm -rf nodes-7006.conf

/usr/local/redis/bin/redis-server redis_cluster/7001/redis.conf
/usr/local/redis/bin/redis-server redis_cluster/7002/redis.conf
/usr/local/redis/bin/redis-server redis_cluster/7003/redis.conf
/usr/local/redis/bin/redis-server redis_cluster/7004/redis.conf
/usr/local/redis/bin/redis-server redis_cluster/7005/redis.conf
/usr/local/redis/bin/redis-server redis_cluster/7006/redis.conf

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

复制粘贴上面的命令,输入 i 进入编辑模式,shift + Insert 粘贴。然后保存退出。:wq

然后给 shell 脚本授权:[root@localhost ~]# chmod u+x *.sh

OK,我们测试一下这个 shell 脚本是否合格。先查看 redis 进程,杀掉进程。说明,shell 脚本没有杀掉 redis进程,因为进程ID每次都是变动的,需要手动杀掉。还有一点,不能误杀 Redis 进程,会导致连接中断:

启动我们写的 shell 脚本:[root@localhost ~]# ./startRedisCluster.sh 

OK,没毛病!老铁!

 

集群数据测试:

redis-cli是redis默认的客户端工具,启动时加上`-c`参数,`-p`指定端口,就可以连接到集群。

[root@localhost ~]# /usr/local/redis/bin/redis-cli -c -p 7003
127.0.0.1:7003> set username biandan
OK

OK,用其它节点查看这条数据。

127.0.0.1:7003> exit
[root@localhost ~]# /usr/local/redis/bin/redis-cli -c -p 7006
127.0.0.1:7006> get username
-> Redirected to slot [14315] located at 127.0.0.1:7003
"biandan"

看到一行:-> Redirected to slot [14315] located at 127.0.0.1:7003

直接去到 7003 的 14315 哈希槽访问 username 了。

说明集群没毛病。

接下来,测试集群宕机!

①干掉一个节点,比如干掉 7004:

先查看进程:

127.0.0.1:7003> exit
[root@localhost ~]# ps -ef | grep redis
root       2297      1  0 10:58 ?        00:00:06 ./bin/redis-server *:6379
root       2527      1  0 12:12 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]
root       2532      1  0 12:12 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7002 [cluster]
root       2537      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]
root       2542      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7004 [cluster]
root       2547      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7005 [cluster]
root       2552      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]
root       7463   2214  0 12:41 pts/0    00:00:00 grep --color=auto redis
[root@localhost ~]# 

看到 7004 的启动占用 ID 为2542,干掉它:

[root@localhost ~]# kill -9 2542

再查看进程,确认被干掉了:

[root@localhost ~]# ps -ef | grep redis
root       2297      1  0 10:58 ?        00:00:06 ./bin/redis-server *:6379
root       2527      1  0 12:12 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]
root       2532      1  0 12:12 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7002 [cluster]
root       2537      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]
root       2547      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7005 [cluster]
root       2552      1  0 12:13 ?        00:00:01 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]
root       7467   2214  0 12:42 pts/0    00:00:00 grep --color=auto redis
[root@localhost ~]# 

查看集群情况:

[root@localhost ~]# redis-trib.rb check 127.0.0.1:7001

看到,7001,7002,7003还在主节点,7005,7006是从节点。集群还正常。

再干掉 7002。因为 7001 VS 7004,7002 VS 7005,7003 VS 7006,它们是主从关系。

[root@localhost ~]# kill -9 2532

查看进程:

[root@localhost ~]# ps -ef | grep redis
root       2297      1  0 10:58 ?        00:00:07 ./bin/redis-server *:6379
root       2527      1  0 12:12 ?        00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7001 [cluster]
root       2537      1  0 12:13 ?        00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7003 [cluster]
root       2547      1  0 12:13 ?        00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7005 [cluster]
root       2552      1  0 12:13 ?        00:00:02 /usr/local/redis/bin/redis-server 127.0.0.1:7006 [cluster]
root       7495   2214  0 12:48 pts/0    00:00:00 grep --color=auto redis
[root@localhost ~]# 

再查看集群情况:[root@localhost ~]# redis-trib.rb check 127.0.0.1:7001

集群就使用不了了。16384个哈希槽没能正常分配。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值