目录
一、概述
1.Redis集群种类
Redis集群模式主要有2种:
主从集群、分布式集群。
前者主要是为了高可用或是读写分离,后者为了更好的存储数据,负载均衡。
2.为什么使用Redis集群
1、处理高并发:安装分片规则,将数据自动切分(split)到多个节点
2、高可用:当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。
3.Redis哈希槽
一个 redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
slot返回有关哪个集群插槽映射到哪个redis实例的详细信息。该命令适用于redis集群客户端库实现,以便检索(或在收到重定向时更新)将集群散列槽与实际节点网络坐标(由ip地址和tcp端口组成)关联的映射,以便在接收到命令时,可以将其发送到命令中指定的键的正确实例。
也就是说哈希槽是用来决定这个key存在哪个节点,通过哈希计算,得到槽值为1,那么这个数据将存到节点1的Redis上,但是对于并发性的问题,大家可能会有一个误解,如同时有大于16384个请求,我们是否等待16383个槽处理完之后再处理16384之后的请求呢?答案是不需要,槽值一旦被计算出来,就只作为一个值来用,这个值决定了访问哪个节点的Redis,而计算这个值的速度,或者并发量(同一时刻允许多少次计算),并不取决与槽有多少,而是取决与这台服务器的计算能力
如图,该Redis集群拥有三个节点,哈希槽平均分配
4.集群中的主从复制
集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作
注意:
1、如果某一个主节点和他所有的从节点都下线的话,redis集群就会停止工作了。redis集群不保证数据的强一致性,在特定的情况下,redis集群会丢失已经被执行过的写命令
2、使用异步复制(asynchronous replication)是redis 集群可能会丢失写命令的其中一个原因,有时候由于网络原因,如果网络断开时间太长,redis集群就会启用新的主节点,之前发给主节点的数据就会丢失。
5.主从切换原理
Redis的主从原理与MySQL相似,都是设置两台机器,一主一从。也就是常说的热备与冷备。设置主从的同时,设置两个哨兵进程,用来检测主节点是否宕机。若发现主节点宕机,立马从从节点内选取出合适的节点 作为新的主节点。这点与VIP(虚拟IP技术有点相似)。
6.Redis群集TCP端口
每个Redis群集的节点都需要打开两个TCP连接,由于这两个连接就需要两个端口,分别是用于为客户端提供服务的常规Redis TCP命令端口(例如6379)以及通过将10000和命令端口相加(10000+6379)而获得的端口,就是集群端口(例如16379)。
第二个大号端口用于群集总线,即使用二进制协议的节点到节点通信通道。 节点使用群集总线进行故障检测,配置更新,故障转移授权等。 客户端不应尝试与群集总线端口通信,为了保证Redis命令端口的正常使用,请确保在防火墙中打开这两个端口,否则Redis群集节点将无法通信。
命令端口和集群总线端口偏移量是固定的,始终为10000。
请注意,为了让Redis群集正常工作,您需要为每个节点:
1、用于与客户端进行通信的普通客户端通信端口(通常为6379)对所有需要到达群集的客户端以及所有其他群集节点(使用客户端端口进行密钥迁移)都是开放的。
2、集群总线端口(客户端端口+ 10000)必须可从所有其他集群节点访问。
如果不打开这两个TCP端口,则redis集群将无法正常工作。
集群总线使用不同的二进制协议进行节点到节点的数据交换,这更适合于使用很少的带宽和处理时间在节点之间交换信息。
7.Redis集群数据共享
Redis集群没有使用一致的散列,而是一种不同的分片形式,其中每个 key 在概念上都是我们称之为散列槽的部分。
Redis集群中有16384个散列槽,为了计算给定 key 的散列槽,我们简单地取16384模的CRC16。
Redis集群中的每个节点负责哈希槽的一个子集,例如,您可能有一个具有3个节点的集群,其中:
- 1、节点A包含从0到5500的散列槽。
- 2、节点B包含从5501到11000的散列槽。
- 3、节点C包含从11001到16383的散列槽。
这允许轻松地添加和删除集群中的节点。例如,如果我想添加一个新节点D,我需要将节点A,B,C中的一些散列槽移动到D。同样,如果我想从集群中删除节点A,我可以只移动由A使用的散列槽到B和C,当节点A将为空时,我可以将它从群集中彻底删除。
因为将散列槽从一个节点移动到另一个节点不需要停机操作,添加和移除节点或更改节点占用的散列槽的百分比也不需要任何停机时间。
只要涉及单个命令执行(或整个事务或Lua脚本执行)的所有 key 都属于同一散列插槽,Redis群集就支持多个 key 操作。用户可以使用称为散列标签的概念强制多个 key 成为同一个散列槽的一部分。
Hash标记记录在Redis集群规范文档中,但要点是如果在关键字{}括号内有一个子字符串,那么只有该花括号“{}”内部的内容被散列,例如 this{foo}key 和 another{foo}key 保证在同一散列槽中,并且可以在具有多个 key 作为参数的命令中一起使用。
8.Redis集群之主从模型
为了在主服务器节点的子集失败或不能与大多数节点通信时保持可用,Redis集群使用主从模型,其中每个散列槽从1(主服务器本身)到N个副本(N -1个附加从节点).
在一个不具备主从模型的集群中,如果节点B失效,则群集无法继续,因为我们没有办法再在5501-11000范围内提供散列槽。然而,当创建集群时(或稍后),我们为每个主服务器节点添加一个从服务器节点,以便最终集群由作为主服务器节点的A,B,C以及作为从服务器节点的A1,B1,C1组成,如果节点B发生故障,系统能够继续运行,因为节点B的从服务器B1拥有相同的数据,则集群将促使节点B1作为新的主服务器节点并且将继续正确地操作。
但请注意,如果节点B和B1在同一时间发生故障,则Redis群集无法继续运行。
9.Redis集群数据一致性保证
Redis 集群无法保证很强的一致性。 实际上,这意味着在某些情况下,Redis 集群可能会丢失系统向客户确认的写入。
Redis集群可能会丢失写入的第一个原因是因为它使用异步复制。这意味着在写入期间会发生以下事情:
- 1、你的客户端写给主服务器节点 B
- 2、主服务器节点B向您的客户端回复确认。
- 3、主服务器节点B将写入传播到它的从服务器B1,B2和B3。
正如你可以看到主服务器节点 B 在回复客户端之前不等待B1,B2,B3的确认,因为这会对Redis造成严重的延迟损失,所以如果你的客户端写入了某些东西,主服务器节点 B 确认写入,就在将写入发送给它的从服务器节点存储之前系统崩溃了,其中一个从站(没有收到写入)可以提升为主站,永远丢失写入。
这与大多数配置为每秒将数据刷新到磁盘的数据库所发生的情况非常相似,因为过去的经验与传统数据库系统有关,不会涉及分布式系统,因此您已经能够推断这种情况。同样,通过强制数据库在回复客户端之前刷新磁盘上的数据,这样可以提高一致性,但这通常会导致性能极低。这与Redis Cluster中的同步复制相当。
基本上,性能和一致性之间需要权衡。
Redis集群在绝对需要时也支持同步写入,通过WAIT命令实现,这使得丢失写入的可能性大大降低,但请注意,即使使用同步复制,Redis集群也不可能实现完全的一致性:总是有可能会发生故常,在无法接受写入的从设备被选为主设备的时候 。
还有另一个值得注意的情况,Redis集群也将丢失数据的写入,这种情况发生在网络分区的时候,客户端与包含至少一个主服务器的少数实例隔离。
以A,B,C,A1,B1,C1三个主站和三个从站组成的6个节点集群为例。还有一个客户,我们称为Z1。
分区发生后,可能在分区的一侧有A,C,A1,B1,C1,另一侧有B和Z1。
Z1仍然能够写入B,它也会接受Z1的写入。如果分区在很短的时间内恢复,则群集将正常继续。但是,如果分区使用比较长的时间将B1提升为多数侧分区的主设备,则Z1发送给B的写入操作将丢失。
请注意,Z1能够发送给B的写入量有一个最大窗口(maximum window):如果分区多数侧有足够的时间选择一个从设备作为主设备,那么少数侧的每个主节点将停止接受写操作。
这个时间值是Redis集群非常重要的配置指令,称为 node timeout (节点超时)。
在节点超时过后,主节点被认为是失效的,并且可以被其副本之一替换。类似地,节点超时过后,主节点无法感知大多数其他主节点,它进入错误状态并停止接受写入。
10.redis容错机制
每个redis提供了节点之间相互发送ping命令,用于测试每个节点的健康状态,集群中连接正常的节点收到其他接节点发送的ping命令时,会返回一个pong字符串
Redis投票机制:如果一个节点A给B发送ping没有得到pong返回,那么A就会通知其他节点再次给B发送ping,如果集群中超过一半的节点给B发送ping都没有得到返回,那么B就被坐实game over了,所以为了避免单点故障,一般都会为redis的每个节点提供了备份节点,B节点挂掉之后立马启动B的节点服务器。
二、部署Redis集群
下面讲解如何部署Redis集群,分为以下几步
1)部署管理服务器
2)部署Redis节点服务器
3)访问测试Redis集群
1.部署Redis集群的条件(各语言支持redis的情况)
原文摘自Redis官网,
At this stage one of the problems with Redis Cluster is the lack of client libraries implementations.
I'm aware of the following implementations:
- redis-rb-cluster is a Ruby implementation written by me (@antirez) as a reference for other languages. It is a simple wrapper around the original redis-rb, implementing the minimal semantics to talk with the cluster efficiently.
- redis-py-cluster A port of redis-rb-cluster to Python. Supports majority of redis-py functionality. Is in active development.
- The popular Predis has support for Redis Cluster, the support was recently updated and is in active development.
- The most used Java client, Jedis recently added support for Redis Cluster, see the Jedis Cluster section in the project README.
- StackExchange.Redis offers support for C# (and should work fine with most .NET languages; VB, F#, etc)
- thunk-redis offers support for Node.js and io.js, it is a thunk/promise-based redis client with pipelining and cluster.
- redis-go-cluster is an implementation of Redis Cluster for the Go language using the Redigo library client as the base client. Implements MGET/MSET via result aggregation.
- The
redis-cli
utility in the unstable branch of the Redis repository at GitHub implements a very basic cluster support when started with the-c
switch.
以下是翻译结果:
在当前的开发阶段,redis缺乏客户端库实现(也就是说需要三方库来实现)
- Ruby实现:在Linux上部署Redis集群需要得到Ruby的支持
- python:pythoy拥有大量的库文件来操作redis集群。目前也在积极研发中
- PHP:PHP的支持由Predis来支持
- java:java由Jedis提供对redis与redis集群的操作
- C#:redis提供对C#的支持
- Node.js:thunk-redis提供对Node.js的支持
- Go:redis-go-cluster接口提供对Go的支持。Go语言可通过MGET/MSET来获取redis结果集。
2.拓扑结构与ip规划
在这个实验中,我们需要8台服务器,6台作为Redis服务器(3主3从),1台作为管理主机,1台作为客户端用于测试,ip地址请按照ip规划图中所示配置.
管理主机参考命令
选项 | 作用 |
create | 创建集群 |
check | 检查集群 |
reshard | 重新分片 |
del-node | 删除主机 |
add-node --slave | 添加slave主机 |
add-node | 添加master主机 |
3.部署管理服务器
下列操作需要在管理服务器上进行
[redis.gem下载地址]https://rubygems.org/gems/redis/versions/4.1.3
1)部署ruby脚本运行环境
- [root@mgm57 ~]#yum -y install rubygems
- [root@mgm57 ~]# which gem
- /usr/bin/gem
- [root@mgm57 ~]# ls *.gem
- redis-3.2.1.gem
- [root@mgm57 ~]# gem install redis-3.2.1.gem
- Successfully installed redis-3.2.1
- Parsing documentation for redis-3.2.1
- Installing ri documentation for redis-3.2.1
- 1 gem installed
2)创建管理集群脚本
这个脚本用来管理Redis集群
- [root@mgm57 ~]#mkdir /root/bin //创建命令检索目录
- [root@mgm57 ~]#tar -zxvf redis-4.0.8.tar.gz
- [root@mgm57 ~]#cd redis-4.0.8/src/
- [root@mgm57 ~]#cp redis-trib.rb /root/bin/ //创建管理集群脚本
- [root@mgm57 ~]#chmod +x /root/bin/redis-trib.rb
- [root@mgm57 ~]#redis-trib.rb help //查看命令帮助
4.部署Redis节点服务器
1)安装Redis
需要在6台服务器中都安装
[root@redis1 redis]# yum -y install gcc
[root@redis1 redis]# wget http://download.redis.io/releases/redis-4.0.14.tar.gz
[root@redis1 redis]# tar -zxf redis-4.0.8.tar.gz
[root@redis1 redis]# cd redis-4.0.8/
[root@redis1 redis-4.0.8]# make
[root@redis1 redis-4.0.8]# make install
[root@redis1 redis-4.0.8]# cd utils/
[root@redis1 utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
//以下全敲回车键,使用默认配置
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379 //端口号
Config file : /etc/redis/6379.conf //配置文件目录
Log file : /var/log/redis_6379.log //日志目录
Data dir : /var/lib/redis/6379 //数据库目录
Executable : /usr/local/bin/redis-server //启动程序的目录
Cli Executable : /usr/local/bin/redis-cli //命令行的连接工具
Is this ok? Then press ENTER to go on or Ctrl-C to abort. //回车完成配置
Copied /tmp/6379.conf => /etc/init.d/redis_6379 //服务启动脚本
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server... //提示服务已经启动
Installation successful! //提示安装成功
2)修改配置文件并启动服务
6台服务器都需要修改配置文件,修改内容:ip,端口号(以本机为主),开启集群功能,存储集群信息的配置文件,集群通信超时时间
- [root@redisA ~]# vim /etc/redis/6379.conf //修改配置文件
- bind 192.168.4.51 //修改ip
- port 6351 //修改端口(可选配置)
- cluster-enabled yes //启用集群功能
- cluster-config-file nodes-6379.conf //存储集群信息的配置文件
- cluster-node-timeout 5000 //集群节点通信超时时间
- :wq
- [root@redisA ~]# rm -rf /var/lib/redis/6379/* //清空数据
- [root@redisA ~]# vim +43 /etc/init.d/redis_6379 //修改关闭项
- $CLIEXEC -h 192.168.4.51 -p 6351 shutdown
- :wq
- [root@redisA ~]# killall redis-server #在安装redis使默认启动,由于修改了配置文件无法正常关闭,用进程管理工具强制杀死
- [root@redisA ~]# /etc/init.d/redis_6379 start //启动服务
- Starting Redis server...
- [root@redisA ~]# netstat -utnlp | grep redis-server //查看服务开启信息
- tcp 0 0 192.168.4.51:6351 0.0.0.0:* LISTEN 21201/redis-server
- tcp 0 0 192.168.4.51:16351 0.0.0.0:* LISTEN 21201/redis-server
5.在管理服务器上创建集群
创建集群,通过redis-trib.rb脚本,输入6台服务器的ip与端口,中间需要输入yes同意创建,最后提示[OK] All 16384 slots covered 代表创建成功
- [root@mgm57 ~]# redis-trib.rb create --replicas 1 \
- > 192.168.4.51:6351 192.168.4.52:6352 192.168.4.53:6353 \
- > 192.168.4.54:6354 192.168.4.55:6355 192.168.4.56:6356
- >>> Performing hash slots allocation on 6 nodes...
- Using 3 masters:
- 192.168.4.51:6351
- 192.168.4.52:6352
- 192.168.4.53:6353
- Adding replica 192.168.4.55:6355 to 192.168.4.51:6351
- Adding replica 192.168.4.56:6356 to 192.168.4.52:6352
- Adding replica 192.168.4.54:6354 to 192.168.4.53:6353
- M: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots:0-5460 (5461 slots) master
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:5461-10922 (5462 slots) master
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:10923-16383 (5461 slots) master
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- S: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- replicates d9f8fe6d6d9dd391be8e7904501db1535e4d17cb
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- 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.4.51:6351)
- M: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- slots: (0 slots) slave
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- slots: (0 slots) slave
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- S: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- slots: (0 slots) slave
- replicates d9f8fe6d6d9dd391be8e7904501db1535e4d17cb
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered. //提示16384个槽分配完毕
- [root@mgm57 ~]#
6.查看集群信息
上面我们创建了Redis集群,创建成功后,在管理服务器上查看集群状态,可以看到哈希槽数量平均分配(每个节点5461),主从服务器默认为一主一从(主从结构自动配置,所以服务器数量最好是偶数),执行redis-trib.rb 脚本,参数为info,输入任意一个集群中的ip:端口即可查看信息
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.51:6351 //查看集群信息
- 192.168.4.51:6351 (d9f8fe6d...) -> 0 keys | 5461 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 0 keys | 5462 slots | 1 slaves.
- 192.168.4.53:6353 (9e44139c...) -> 0 keys | 5461 slots | 1 slaves.
- [OK] 0 keys in 3 masters.
- 0.00 keys per slot on average
以上是简单的输出信息,如果想查看更加详细的集群信息,如下操作.我们可以查到每台服务器的唯一地址,如192.168.4.51服务器的唯一地址为d9f8fe6d6d9dd391be8e7904501db1535e4d17cb,哈希槽数5461.唯一地址前为M代表为主服务器,S代表从服务器,从服务器上没有哈希槽
- [root@mgm57 ~]# redis-trib.rb check 192.168.4.51:6351 //检测集群
- >>> Performing Cluster Check (using node 192.168.4.51:6351)
- M: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- slots: (0 slots) slave
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- slots: (0 slots) slave
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- S: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- slots: (0 slots) slave
- replicates d9f8fe6d6d9dd391be8e7904501db1535e4d17cb
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
我们也可以在任意一台服务器上查看集群信息
cluster info :查看集群信息
cluster nodes : 查看集群节点信息
- [root@redisA ~]# redis-cli -h 192.168.4.51 -p 6351
- 192.168.4.51:6351> cluster info //查看集群信息
- cluster_state:ok
- ……
- ……
- cluster_known_nodes:6
- cluster_size:3
- 192.168.4.51:6351> cluster nodes //查看集群节点信息
- d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354@16354 slave 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 0 1561357552212 4 connected
- 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356@16356 slave 324e05df3f143ef97e50d09be0328a695e655986 0 1561357554216 6 connected
- d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351@16351 myself,master - 0 1561357545000 1 connected 0-5460
- 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352@16352 master - 0 1561357553214 2 connected 5461-10922
- 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353@16353 master - 0 1561357554216 3 connected 10923-16383
- 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355@16355 slave d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 0 1561357553716 5 connected
7.访问集群
访问集群前我们有几个测试目的需要先了解一下
1)不同节点间是否可以数据共享 : 不可以
2)一个节点中的主从服务器是否数据共享:可以
3)在任意一台Redis服务器上存储数据是否会调用分片规则进行存储:会调用
- [root@client50 ~]# redis-cli -c -h 192.168.4.51 -p 6351 //连接服务器51
- 192.168.4.51:6351> set x 100 //存储
- -> Redirected to slot [16287] located at 192.168.4.53:6353 //提示存储在53主机
- OK
- 192.168.4.53:6351> set y 200
- -> Redirected to slot [16287] located at 192.168.4.53:6353 //提示存储在53主机
- OK
- 192.168.4.53:6351> set z 300 //存储
- -> Redirected to slot [8157] located at 192.168.4.52:6352 //提示存储在52主机
- OK
- [root@client50 ~]# redis-cli -c -h 192.168.4.52 -p 6352 //连接服务器52
- 192.168.4.52:6352> keys * //在52主机查看数据 只有变量z
- 1) "z"
- [root@client50 ~]# redis-cli -c -h 192.168.4.53 -p 6353 //连接服务器53
- 192.168.4.53:6353> keys *
- 1) "y"
- 2) "x"
- [root@client50 ~]# redis-cli -c -h 192.168.4.54 -p 6354 //查看集群信息知道53的从服务器为54
- 192.168.4.53:6354> keys *
- 1) "y"
- 2) "x"
三、添加新服务器
在一个创建好的服务器中,如果需要新填服务器,可以安装一以下骤来操作
步骤:
- 部署新redis服务器
- 添加master角色主机到集群里
- 添加slave角色主机到集群里
1.部署新redis服务器 ip为192.168.4.58
装包,初始化,启用集群功能,重启服务
- ]#yum -y install gcc
- ]#tar -zxvf redis-4.0.8.tar.gz
- ]#cd redis-4.0.8/
- ]#make
- ]#make install
- ]#./utils/install_server.sh
- ]# /etc/init.d/redis_6379 stop
- vim /etc/redis/6379.conf
- bind 192.168.4.58
- port 6358
- cluster-enabled yes //启用集群
- cluster-config-file nodes-6379.conf //存储集群信息文件
- cluster-node-timeout 5000
- :wq
- ]# vim +43 /etc/init.d/redis_6379
- $CLIEXEC -h 192.168.4.58 -p 6358 shutdown
- :wq
- ]# /etc/init.d/redis_6379 start
- ]# netstat -utnlp | grep redis-server
- tcp 0 0 192.168.4.58:6358 0.0.0.0:* LISTEN 21201/redis-server
- tcp 0 0 192.168.4.58:16358 0.0.0.0:* LISTEN 21201/redis-server
2.添加master角色主机到集群里
1)在管理主机,添加master角色主机
格式为redis-trib.rb add-node 新服务器ip:端口 集群服务器ip:端口
注意:集群服务器ip可以是集群中的任意一台主服务器的ip地址
- [root@mgm57 ~]# redis-trib.rb add-node 192.168.4.58:6358 192.168.4.53:6353 //执行添加命令
- >>> Adding node 192.168.4.58:6358 to cluster 192.168.4.53:6353
- >>> Performing Cluster Check (using node 192.168.4.53:6353)
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- slots: (0 slots) slave
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- slots: (0 slots) slave
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- S: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots: (0 slots) slave
- replicates 2d343a9df48f6f6e207949e980ef498466a44dad
- M: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- >>> Send CLUSTER MEET to node 192.168.4.58:6358 to make it join the cluster.
- [OK] New node added correctly. //提示添加完成
2) 在管理主机,查看集群新消息
我们可以看到新添进来的服务器,但是它还没有哈希槽,我们下面需要为它分配哈希槽
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.53:6353 //查看集群信息
- 192.168.4.53:6353 (9e44139c...) -> 3 keys | 5461 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 2 keys | 5462 slots | 1 slaves.
- 192.168.4.58:6358 (4fe1fa46...) -> 0 keys | 0 slots | 0 slaves. //主服务器58
- 192.168.4.55:6355 (2d343a9d...) -> 3 keys | 5461 slots | 1 slaves.
- [OK] 8 keys in 4 masters.
- 0.00 keys per slot on average.
- [root@mgm57 ~]#
3)在管理主机,检测集群
- [root@mgm57 ~]# redis-trib.rb check 192.168.4.53:6353 //检测集群
- >>> Performing Cluster Check (using node 192.168.4.53:6353)
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- slots: (0 slots) slave
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- slots: (0 slots) slave
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- M: 4fe1fa467ad237802021f5aac5f1d5b3e0db47ef 192.168.4.58:6358
- slots: (0 slots) master //master服务器58 ,没有hash槽
- 0 additional replica(s)
- S: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots: (0 slots) slave
- replicates 2d343a9df48f6f6e207949e980ef498466a44dad
- M: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- [root@mgm57 ~]#
4)在管理主机,重新分配hash槽
注意一下分配hash槽的规则,我们可以指定当前拥有槽的主服务器,重新分配hash槽数量
命令:redis-trib.rb reshard 集群中任意一台主服务器ip:端口
下面标红的代表需要输入参数的提示
先看第一条,How many slots do you want to move (from 1 to 16384)? 此处需要你手动输入槽数(需要自己计算),现在有4个节点,所以我们可以输入4096(16384/4),
再看第二条What is the receiving node ID?这里询问你需要移动到哪一台主机上,我们移动到新服务器192.168.4.58上,注意,这里需要输入它的集群唯一地址,通过命令check可以查看.
再看第三条,Source node #1,此处是问你要从哪个节点上获取hash槽,我们输入all,全部,从当前有槽的节点上平均获取(提示,你也可以手动输入主机地址来获取hash槽数,需要你输入唯一地址,且输入done结束分配,但是你需要确定这个节点上有足够hash槽数量)
- [root@mgm57 ~]# redis-trib.rb reshard 192.168.4.53:6353
- How many slots do you want to move (from 1 to 16384)?4096 //拿出4096个hash 槽给主机192.168.4.58
- What is the receiving node ID? c5e0da48f335c46a2ec199faa99b830f537dd8a0 //主机192.168.4.58的id值
- Source node #1:all //从当前所有master服务器获取hash槽
- Do you want to proceed with the proposed reshard plan (yes/no)?yes //同意以上配置
- ...
- Moving slot 12283 from 192.168.4.53:6353 to 192.168.4.58:6358:
- Moving slot 12284 from 192.168.4.53:6353 to 192.168.4.58:6358:
- Moving slot 12285 from 192.168.4.53:6353 to 192.168.4.58:6358:
- Moving slot 12286 from 192.168.4.53:6353 to 192.168.4.58:6358:
- Moving slot 12287 from 192.168.4.53:6353 to 192.168.4.58:6358:
5)在管理主机,查看集群信息
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.53:6353
- 192.168.4.53:6353 (9e44139c...) -> 2 keys | 4096 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 1 keys | 4096 slots | 1 slaves.
- 192.168.4.58:6358 (4fe1fa46...) -> 4 keys | 4096 slots | 0 slaves. //hash槽4096个
- 192.168.4.55:6355 (2d343a9d...) -> 1 keys | 4096 slots | 1 slaves.
- [OK] 8 keys in 4 masters.
- 0.00 keys per slot on average.
- [root@mgm57 ~]#
3.添加slave角色主机到集群里
光有主服务器还不行,你需要为这个节点添加从服务器
1)部署新的redis服务器 192.168.4.59
上面有详细操作,这里不重复演示
2)在管理主机,添加slave角色主机
命令格式:redis-trib.rb add-node --slave 从服务器ip:端口 集群中任意一台ip:端口
- [root@mgm57 ~]# redis-trib.rb add-node --slave 192.168.4.59:6359 192.168.4.51:6351 //执行添加命令
- >>> Adding node 192.168.4.59:6359 to cluster 192.168.4.51:6351
- >>> Performing Cluster Check (using node 192.168.4.51:6351)
- S: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots: (0 slots) slave
- replicates 2d343a9df48f6f6e207949e980ef498466a44dad
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- slots: (0 slots) slave
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- M: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- slots:1365-5460 (4096 slots) master
- 1 additional replica(s)
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:12288-16383 (4096 slots) master
- 1 additional replica(s)
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- slots: (0 slots) slave
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:6827-10922 (4096 slots) master
- 1 additional replica(s)
- M: 4fe1fa467ad237802021f5aac5f1d5b3e0db47ef 192.168.4.58:6358
- slots:0-1364,5461-6826,10923-12287 (4096 slots) master
- 0 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- Automatically selected master 192.168.4.58:6358
- >>> Send CLUSTER MEET to node 192.168.4.59:6359 to make it join the cluster.
- Waiting for the cluster to join.
- >>> Configure node as replica of 192.168.4.58:6358. //提示添加完成
- [OK] New node added correctly.
3) 在管理主机,查看集群新消息
我们可以看到,管理主机会为没有从服务器的节点优先分配从服务器,不需要你手动操作
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.51:6351 //查看信息
- 192.168.4.55:6355 (2d343a9d...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.53:6353 (9e44139c...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 2 keys | 4096 slots | 1 slaves.
- 192.168.4.58:6358 (4fe1fa46...) -> 5 keys | 4096 slots | 1 slaves. //有1个从服务器
- [OK] 13 keys in 4 masters.
- 0.00 keys per slot on average.
- [root@mgm57 ~]#
4)在管理主机,检测集群
- [root@mgm57 ~]# redis-trib.rb check 192.168.4.53:6353 //检测集群
- >>> Performing Cluster Check (using node 192.168.4.51:6351)
- S: d9f8fe6d6d9dd391be8e7904501db1535e4d17cb 192.168.4.51:6351
- slots: (0 slots) slave
- replicates 2d343a9df48f6f6e207949e980ef498466a44dad
- S: 7f3fa4f20c8c516d5b412ecc22550ed8e7bb8d7a 192.168.4.59:6359 //从服务器
- slots: (0 slots) slave
- replicates 4fe1fa467ad237802021f5aac5f1d5b3e0db47ef //58主机的id值
- S: 894dd0008053f6fb65e9e4a36b755d9351607500 192.168.4.56:6356
- slots: (0 slots) slave
- replicates 324e05df3f143ef97e50d09be0328a695e655986
- M: 2d343a9df48f6f6e207949e980ef498466a44dad 192.168.4.55:6355
- slots:1365-5460 (4096 slots) master
- 1 additional replica(s)
- M: 9e44139cffb8ebd7ed746aabbf4bcea9bf207645 192.168.4.53:6353
- slots:12288-16383 (4096 slots) master
- 1 additional replica(s)
- S: d9634ba0aa5c1a07193da4a013da6051c1515922 192.168.4.54:6354
- slots: (0 slots) slave
- replicates 9e44139cffb8ebd7ed746aabbf4bcea9bf207645
- M: 324e05df3f143ef97e50d09be0328a695e655986 192.168.4.52:6352
- slots:6827-10922 (4096 slots) master
- 1 additional replica(s)
- M: 4fe1fa467ad237802021f5aac5f1d5b3e0db47ef 192.168.4.58:6358 //主服务器
- slots:0-1364,5461-6826,10923-12287 (4096 slots) master
- 1 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
5)在客户端,访问从服务器59,查看数据
你也许会有这样的疑问,我们没有在58这台主机上插入数据,为什么会有五条,回忆一下,我们之前在新添主机的时候做了什么操作,没错我们移动了hash槽,将之前三台节点上的部分hash槽移动到新的节点上,这就使得数据(key)也跟着移动到了新的节点上,这就解释了为什么新节点上有这些数据,但是哪些hash槽上有这些key,需要我们自己查看,查看key对应的slot
:redis-cli -c -h 192.168.4.59 -p 6359 ,输入 cluster keyslot key
- [root@host50 ~]# redis-cli -c -h 192.168.4.59 -p 6359
- 192.168.4.59:6359> keys * //自动同步主服务器58的数据
- 1) "name"
- 2) "name2"
- 3) "age"
- 4) "y"
- 5) "shcool5"
- 192.168.4.59:6359>
四、移除服务器
光知道添加服务器还不行,我们还需要学会如何移除服务器,这里演示移除一个数据库节点,必须遵循先移除从服务器,再移除主服务器的顺序
- 把slave服务器移除集群
- 把master服务器移除集群
1.把slave服务器移除集群
在管理主机,移除slave服务器,从服务器没有槽,直接移除即可。
执行命令:redis-trib.rb del-node 集群中的任意ip:端口 被移除服务器的唯一地址
- [root@mgm57 ~]# redis-trib.rb del-node 192.168.4.51:6351 f6649ea99b2f01faca26217691222c17a3854381 //执行移除命令
- >>> Removing node f6649ea99b2f01faca26217691222c17a3854381
- from cluster 192.168.4.57:6351
- >>> Sending CLUSTER FORGET messages to the cluster...
- >>> SHUTDOWN the node. //停止移除服务的Redis服务
2)在管理主机,查看集群信息
此时已经显示没有从服务器了
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.51:6351
- 192.168.4.55:6355 (2d343a9d...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.53:6353 (9e44139c...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 2 keys | 4096 slots | 1 slaves.
- 192.168.4.58:6358 (4fe1fa46...) -> 5 keys | 4096 slots | 0 slaves. //58主机,没有从服务器
- [OK] 13 keys in 4 masters.
- 0.00 keys per slot on average.
2.把master服务器移除集群
在管理主机,我们需要将被移除服务器的slot槽移除到其他节点上,否则无法删除服务器
下面标红的代表需要输入参数的提示
先看第一条,How many slots do you want to move (from 1 to 16384)? 此处需要你手动输入槽数(需要自己计算),这里需要写被移除节点主机的所有槽数
再看第二条What is the receiving node ID? 这里询问你需要移动到哪一台主机上,我们移动到除被移除节点的任意一个节点都可
再看第三条,Source node #1,此处是问你要从哪个节点上获取hash槽,填写被移除主机的唯一地址
- [root@mgm57 ~]# redis-trib.rb reshard 192.168.4.53:6353 //调整一个除被移除节点的主服务器都可
- How many slots do you want to move (from 1 to 16384)?4096 //移除4096个数槽
- What is the receiving node ID? d9f8fe6d6d9dd391be8e7904501db1535e4d17cb //移动到哪台,填51的唯一地址
- Source node #1: c5e0da48f335c46a2ec199faa99b830f537dd8a0 //要移动给谁的id即目标主机
- Source node #2:done //设置完毕
- ...
- Moving slot 12282 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
- Moving slot 12283 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
- Moving slot 12284 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
- Moving slot 12285 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
- Moving slot 12286 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
- Moving slot 12287 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
- Do you want to proceed with the proposed reshard plan (yes/no)?yes //提交
- ...
- Moving slot 12282 from 192.168.4.58:6358 to 192.168.4.53:6353:
- Moving slot 12283 from 192.168.4.58:6358 to 192.168.4.53:6353:
- Moving slot 12284 from 192.168.4.58:6358 to 192.168.4.53:6353:
- Moving slot 12285 from 192.168.4.58:6358 to 192.168.4.53:6353:
- Moving slot 12286 from 192.168.4.58:6358 to 192.168.4.53:6353:
- Moving slot 12287 from 192.168.4.58:6358 to 192.168.4.53:6353:
2)在管理主机,查看集群信息
此时已经没有槽了
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.51:6351
- 192.168.4.55:6355 (2d343a9d...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.53:6353 (9e44139c...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 2 keys | 4096 slots | 1 slaves.
- 192.168.4.58:6358 (4fe1fa46...) -> 0 keys | 0 slots | 0 slaves. //零个槽
- [OK] 13 keys in 4 masters.
- 0.00 keys per slot on average.
- [root@mgm57 ~]#
3)在管理主机,移除master主机
输入命令:redis-trib.rb del-node 集群中任意一台节点的ip:端口 被移除主机的唯一地址
- [root@mgm57 ~]# redis-trib.rb del-node 192.168.4.53:6353 c5e0da48f335c46a2ec199faa99b830f537dd8a0
- >>> Removing node e081313ec843655d9bc5a17f3bed3de1dccb1d2b from cluster 192.168.4.51:6351
- >>> Sending CLUSTER FORGET messages to the cluster...
- >>> SHUTDOWN the node.
- [root@mgm57 ~]#
4)在管理主机,查看集群信息
此时已经看不到节点了,代表移除成功
- [root@mgm57 ~]# redis-trib.rb info 192.168.4.51:6351
- 192.168.4.55:6355 (2d343a9d...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.53:6353 (9e44139c...) -> 3 keys | 4096 slots | 1 slaves.
- 192.168.4.52:6352 (324e05df...) -> 2 keys | 4096 slots | 1 slaves.
- [OK] 13 keys in 3 masters. //主服务器个数3台,没有58
- 0.00 keys per slot on average.
- [root@mgm57 ~]#