Redis集群的搭建
当一台redis里的存储空间不够用了,就需要搭建集群了。
redis-cluster架构图
cluster是集群的意思
- 所有redis节点彼此互联(PING-PONG机制)内部使用二进制协议优化传输速度和带宽
- 节点的fail是通过集群中超过半数的节点检测失效时才生效
- 客户端与redis节点直连,不需要中间proxy(代理)层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
以前搭建tomcat集群的时候就有代理,那就是nginx。
节点之间保存的数据都是不一样的,集群保存的数据都是不一样的,一样的那叫主备。
如果有一个节点挂了,这个集群就挂了。为了保证高可用,应该为每个节点弄一个备份机。这个节点挂了,备份节点顶上来,保证集群的正常使用。
投票容错机制
redis有一个投票容错机制。
一般的集群都有一个管理工具,但在redis里边没有。
某个节点挂了,我们是怎么知道的呢?
这需要有一个投票机制,选举的时候都是少数服从多数。判断一个节点是否挂了,需要有超过半数的节点投票来确定这个节点挂了。如果没有超过半数,就不认为这个节点挂了。
现在图中有五个节点,其中红色的节点挂了。黄色的节点发现他挂了,然后广播一下让其他节点确定一下这个节点是否挂了。现在有三个节点确定他挂了,一共有5个节点,超过了半数,所以确定他挂了。这时候就会看看有没有备份节点,如果没有的话,就都歇了,集群就挂了。
考虑一个问题,集群中应该有几个节点?
一个节点的那叫单机版。如果有两个节点的话,其中一个节点挂了,另一个是需要投票的,那这就很尴尬了,无论怎么投票都是超不过半数的。所以至少应该有三个节点,有一个挂了,另外两个一投票就确认他挂了,然后集群就挂了。
还有一个问题,如果有三个节点,其中两个同时挂了,那咋办?
不知道,但这种情况比较少
数据的存储分配
我现在有好几个节点,当我存数据的时候应该存储到哪个节点中,如何均匀的将数据分到各个节点中?
- redis集群中内置了[0-16383],也就是16384个哈希槽,当需要在集群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点。
比如第一个节点对应的哈希槽为0-5000,我存一个键为Hello的,计算完后他的编号为500,500在0-5000之间,于是我就把他存到了第一个节点中。
也就是说搭建集群的话,最多有16384个节点。
redis集群的搭建
redis集群中至少应该有三个节点。要保证集群的高可用,需要每个节点有一个备份机。redis集群至少需要6台服务器。
那我自己玩儿的话,需要弄6个虚拟机。太麻烦。
搭建伪分布式。可以使用一台虚拟机运行6个redis实例。需要修改redis的端口号为7001-7006
集群环境搭建准备
在/usr/local里新建一个文件夹
mkdir redis-cluster
之前装过一个单机版的redis。现在把/usr/local/redis/bin里边的东西复制一份到redis-cluster/redis01
cp redis/bin redis-cluster/redis01 -r
因为之前放过数据,redis01里边有dump.rdb,把他删除掉,搭建集群的节点应该是没有数据的,如果玩儿过持久化的东西,里边还能有appendonly.aof,有的话也删除掉。
rm -f dump.rdb
然后修改其配置文件redis.conf
port 7001
cluster-enabled yes 把这个的注释打开
然后把redis01复制五份
cp -r redis01/ redis02
cp -r redis01/ redis03
cp -r redis01/ redis04
cp -r redis01/ redis05
cp -r redis01/ redis06
然后分别修改其端口号
创建一个批处理文件来启动这6个redis
vim start-all.sh
在里边填写
cd redis01
./redis-server redis.conf
cd ..
cd redis02
./redis-server redis.conf
cd ..
cd redis03
./redis-server redis.conf
cd ..
cd redis04
./redis-server redis.conf
cd ..
cd redis05
./redis-server redis.conf
cd ..
cd redis06
./redis-server redis.conf
然后执行sh start-all.sh
然后执行ps aux|grep redis,可以看到这六个redis都启动了。
然后把源码中,也就是redis-3.0.0/src中的redis-trib.rb复制到redis-cluster中
cp redis-trib.rb /usr/local/redis-cluster/
ruby是一种脚本语言,其文件后缀为.rb
需要ruby的运行环境
yum install ruby
安装redis接口,因为网慢,先修改镜像,删除原来的镜像,添加开源中国的镜像
gem sources --remove https://rubygems.org/
gem sources -a https://gems.ruby-china.org/
gem install redis --version 3.0.0
如果下载麻烦,可以自己去网上下载一个redis-3.0.0.gem,然后执行
gem install redis-3.0.0.gem
然后执行
./redis-trib.rb create --replicas 1 192.168.25.130:7001 192.168.25.130:7002 192.168.25.130:7003 192.168.25.130:7004 192.168.25.130:7005 192.168.25.130:7006
create就是创建,replicas的意思是副本的意思,1代表的是每个节点有一个备份机,
我执行完后,报了一堆警告
/usr/local/share/gems/gems/redis-3.0.0/lib/redis.rb:182: warning: wrong element type nil at 90 (expected array)
/usr/local/share/gems/gems/redis-3.0.0/lib/redis.rb:182: warning: ignoring wrong elements is deprecated, remove them explicitly
/usr/local/share/gems/gems/redis-3.0.0/lib/redis.rb:182: warning: this causes ArgumentError in the next release
也不知道为啥,但也没影响。。。
还会告诉哪些是主节点,哪些是备份节点,和槽的分配
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.25.130:7001
192.168.25.130:7002
192.168.25.130:7003
Adding replica 192.168.25.130:7004 to 192.168.25.130:7001
Adding replica 192.168.25.130:7005 to 192.168.25.130:7002
Adding replica 192.168.25.130:7006 to 192.168.25.130:7003
M: 2fdebb6f9facb38636f710f0a96982b4c2d1f28a 192.168.25.130:7001
slots:0-5460 (5461 slots) master
M: 3d504ac503009ce0883f20e00550812f73157aae 192.168.25.130:7002
slots:5461-10922 (5462 slots) master
M: 0e1c1be6fb2dae524d11bbd2422c468f4348cfdd 192.168.25.130:7003
slots:10923-16383 (5461 slots) master
S: 9665bdb6d66fd8bf0777f8a752a1eefac0d33af8 192.168.25.130:7004
replicates 2fdebb6f9facb38636f710f0a96982b4c2d1f28a
S: 915777c6aa21b70fc29051d6ac2c9891249476ea 192.168.25.130:7005
replicates 3d504ac503009ce0883f20e00550812f73157aae
S: 032026abf866ac0a52189908d29ab5e743326f05 192.168.25.130:7006
replicates 0e1c1be6fb2dae524d11bbd2422c468f4348cfdd
会询问是否接受以上配置,输入yes
slot是槽的意思
之后会告诉你咋分配的,然后告诉你16384个槽都分配好了
>>> Performing Cluster Check (using node 192.168.25.130:7001)
M: 2fdebb6f9facb38636f710f0a96982b4c2d1f28a 192.168.25.130:7001
slots:0-5460 (5461 slots) master
M: 3d504ac503009ce0883f20e00550812f73157aae 192.168.25.130:7002
slots:5461-10922 (5462 slots) master
M: 0e1c1be6fb2dae524d11bbd2422c468f4348cfdd 192.168.25.130:7003
slots:10923-16383 (5461 slots) master
M: 9665bdb6d66fd8bf0777f8a752a1eefac0d33af8 192.168.25.130:7004
slots: (0 slots) master
replicates 2fdebb6f9facb38636f710f0a96982b4c2d1f28a
M: 915777c6aa21b70fc29051d6ac2c9891249476ea 192.168.25.130:7005
slots: (0 slots) master
replicates 3d504ac503009ce0883f20e00550812f73157aae
M: 032026abf866ac0a52189908d29ab5e743326f05 192.168.25.130:7006
slots: (0 slots) master
replicates 0e1c1be6fb2dae524d11bbd2422c468f4348cfdd
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
连接redis集群,连接其中任意一个就行,需要加上-c参数
[root@localhost redis-cluster]# redis01/redis-cli -p 7004 -c
127.0.0.1:7004> set name eaglezsx
-> Redirected to slot [5798] located at 192.168.25.130:7002
OK
会告诉你生成的那个编号是5798,存储到了192.168.25.130:7002上边了。
关闭集群的脚本
[root@localhost redis-cluster]# vim shutdown-all.sh
redis01/redis-cli -p 7001 shutdown
redis01/redis-cli -p 7002 shutdown
redis01/redis-cli -p 7003 shutdown
redis01/redis-cli -p 7004 shutdown
redis01/redis-cli -p 7005 shutdown
redis01/redis-cli -p 7006 shutdown