一、集群常识
1.redis在3.0定制软件开发之前是集群,定制软件开发仅支持单实例的,3.0定制软件开发以后开始支持集群。
2.3.0定制软件开发的集群命令也不是那么亲和,需要用ruby定制软件开发编写的脚本(定制软件开发而且需要登录redis定制软件开发客户端操作),启动、增删节点、定制软件开发移动槽位等。以后,定制软件开发可以使用比较亲和的redis-cli --cluster 定制软件开发不需要登录客户端,定制软件开发直接可以进行各种操作(前提:定制软件开发集群模式已开启)。
3.redis定制软件开发集群是没有统一的入口的,定制软件开发不存在中心节点或者代理节点,通过#redis-cli -c - h -p 定制软件开发登录任一客户端后,定制软件开发集群客户端各节点数据可以互通,(定制软件开发默认会开启梦游模式,定制软件开发你要的数据,我没有,定制软件开发但是我可以告诉你哪台机器有定制软件开发并且给你跳转到那台机器,定制软件开发并返回你要的数据)。
4.定制软件开发对于事务的支持,仅支持被Hashtag统一前缀{}后的key(定制软件开发这些统一前缀的key定制软件开发会落到同一组主从机器)上的数据,定制软件开发才可以支持事务,定制软件开发如果是普通key定制软件开发散列到不同的主从上是定制软件开发不支持事务的。
5.redis定制软件开发集群为了达到高可用,定制软件开发会考虑到宕机,定制软件开发那么里面有个投票机制,定制软件开发需要一半以上的投票认为某台master宕机了(哨兵也是这个机制),然后推举新的slave为master。2台机器,投票方式只有1:1和0:2(对于过半这条要求,2台有些牵强),所以,集群的搭建至少是3台master。又因为集群要求1个master至少有一个小弟slave,那么一个集群至少需要6台redis实例。
6.Redis 集群引入了槽位的概念,整个集群共有哈希槽位16384个。假如集群中有三对主从,也就是三个节点,称作A节点、B节点、C节点,那么默认槽位是平均分配的。
节点 A 包含 0 到 5500号哈希槽.
节点 B 包含5501 到 11000 号哈希槽.
节点 C 包含11001 到 16384号哈希槽.
槽位的移动,不会造成数据丢失,但是,如果某个节点的主从全部宕机,那么整个节点所对应槽位中的数据将会暂时全部丢失(不可访问),直到节点被恢复正常。
好了,了解了这些知识点后,做到心中不慌,下面跟随我一起愉快的玩耍吧,开启梦游之旅………
意犹未尽,如需了解更多,点击、,进入后点击文档进行查看。
二、准备工作
1.redis的安装部署
点击、协助部署,这两个版本均可,不影响步骤。
2.从熟悉redis解压目录结构到README
#cd /usr/src/redis-5.0.4/ && ls 进入redis解压目录,并查看目录列表
#cd utils && ls 查看utils下的目录结构
#cd create-cluster && ls 查看集群命令所在目录的结构
#vim README 学会看这个文件,你就基本学会了走路,它很重要!
创建步骤:
1.编辑绿色的create-cluster可执行文件,修改里的端口,默认是30000,本案例暂不修改。
2.使用./create-cluster start命令,自动依次启动30001-30006,六个redis实例(默认就好)
3.使用./create-cluster create命令,自动依次创建一个redis集群(把6个实例组合一起)
4.此刻集群已经创建并准备完毕,可以发现rdb和aof文件已经在当前命令执行目录自动创建
关闭步骤:
1. 使用./create-cluster stop命令后,所有实例会自动关闭,如需重启集群,使用./create-cluster start即可 (英文帮助信息也挺苦口婆心的,如果你改变主意的话,O(∩_∩)O哈哈~)
2./create-cluster clean 会自动移除所有的aof日志,返还你一个纯净的运行环境
英文的一看就懵,给你大白话翻译一下,是不是很prefect,还是看不懂,表要紧,go on !
最后意犹未尽,可以返还此处,回味一下哦……
3.跟随README的旨意,看一下create-cluster脚本
#vim create-cluster 查看这个绿色的可执行文件(它也是操作集群的一个命令)
PORT=30000 集群的默认端口,这里可以不用修改
TIMEOUT=2000 超时时间,超时后集群要搞些事情,比如选举新的master
NODES=6 集群最少要求,要配置6个节点(默认即可)
REPLICAS=1 为集群中的每个主节点创建1个从节点。在NODES节点是6的前提下:
如果REPLICAS=1 配置为1,意味着一个主只跟1个从(一套主从两台机器),这个集群中会有3套主从。
如果REPLICAS=2 配置为2,意味着一个主只跟2个从(一套主从三台机器),这个集群中会有2套主从。明显,集群不建议这么做,一个集群被要求最少要有3个master。
以上配置文件看一下就可以,学习节点,可以不用修改
好了,跟随README的旨意,我们继续吧!没想象的那么难 ^_^
三、方法一:用集群命令create-cluster create 开启集群(系统自动指定redis实例)
1.启动集群create-cluster start
#pwd 查看当前目录的位置
/usr/src/redis-5.0.4/utils/create-cluster
#ls
create-cluster README
#./create-cluster start 使用当前目录的命令,创建并启动集群, 看到6个redis实例跑起来了。
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
注:start命令的作用是,自动创建30001-30006六个redis实例,并自动启动。
2.创建集群,并自动分配主从create-cluster create
#./create-cluster create 正式创建集群,中间过程会询问是否同意分配方案,选Y即可。
注:create 命令作用,首先把6台redis实例,这帮散兵游勇集合到一起,形成一个集群团伙,内部自动分配master、是slave,以及槽位
特别提示:README里4.指明,create命令被运行后会在当前目录自动生成持久化数据文件,这些文件在实验结束后,可以删除。
3.集群客户端的三种使用方式(错误的、梦游模式、非梦游模式)
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
上面中是系统自动启动的6个redis server服务,他们的主从关系,前面是从,后面是主。
1.错误方式启动集群客户端redis-cli -p (不会梦游,也不能使用)
#redis-cli -p 30001 尝试以常规方式启动集群中的第一分组的redis30001 客户端
127.0.0.1:30001> set k1 aaa
(error) MOVED 12706 127.0.0.1:30003 被提示k1b被转移到30003 了
127.0.0.1:30001> get k1 取不到k1,被提示k1被转移到30003
(error) MOVED 12706 127.0.0.1:30003
注:之所以不会自动返回k1,是启动集群的方式不对,需要带-c参数。
其中的原理具体见:开篇“一、集群常识”的“第3条”,已说明。
2.正确方式启动集群客户端redis-cli -c -p (会梦游,难以支持事务)
#redis-cli -p 30001 错误启动集群客户端的方式
127.0.0.1:30001> set k1 aaa
(error) MOVED 12706 127.0.0.1:30003
127.0.0.1:30001> get k1
(error) MOVED 12706 127.0.0.1:30003
127.0.0.1:30001> exit 退出错误的启动方式
# redis-cli -c -p 30001 正确启动集群的方式(带-c,c就是cluster)
127.0.0.1:30001> get k1
-> Redirected to slot [12706] located at 127.0.0.1:30003
(nil)
127.0.0.1:30003> set k2 bbb
-> Redirected to slot [449] located at 127.0.0.1:30001
OK
127.0.0.1:30001> get k2
"bbb"
127.0.0.1:30001> set k3 ccc
OK
127.0.0.1:30001> get k3
"ccc"
127.0.0.1:30001> set k4 ddd
-> Redirected to slot [8455] located at 127.0.0.1:30002
OK
127.0.0.1:30002> get k4
"ddd"
反复设key,为目睹梦游模式芳容,发现集群中的客户端来回跳跃,感觉像是开启了梦游模式。
3.尝试使用事务watch multi
127.0.0.1:30002> watch k1
-> Redirected to slot [12706] located at 127.0.0.1:30003
OK
127.0.0.1:30003> multi 开启事务
OK
127.0.0.1:30003> get k4
-> Redirected to slot [8455] located at 127.0.0.1:30002
"ddd"
127.0.0.1:30002> set k5 66
-> Redirected to slot [12582] located at 127.0.0.1:30003
OK
127.0.0.1:30003> exec 提交事务
(error) ERR EXEC without MULTI 事务报错了
127.0.0.1:30003>
事务在梦游中如愿以偿的失败了,究其原因:
向集群保存数据时,因为hash算法的原因,后台会把数据保存在不同的主从上,被操作的数据不在同一套主从上,(事务开启在30003上,中间操作的数据在30002或者30001上),就无法保证数据的一致性,所以报错。
4.用Hashtag{}标签设置key(开启非梦游模式,用来支持事务)
127.0.0.1:30003> set {oo}k1 222
-> Redirected to slot [1629] located at 127.0.0.1:30001
OK
127.0.0.1:30001> set {oo}k2 333 用Hashtag标签,设置一批数据,发现都会落在30001上
OK
127.0.0.1:30001> set {oo}k3 444
OK
127.0.0.1:30001> set {oo}k5 555
OK
127.0.0.1:30001> watch {oo}k1
OK
127.0.0.1:30001> multi 开启事务
OK
127.0.0.1:30001> get {oo}k1
QUEUED
127.0.0.1:30001> set {oo}k1 xxx
QUEUED
127.0.0.1:30001> set {oo}k6 666
QUEUED
127.0.0.1:30001> mget {oo}k1 {oo}k6
QUEUED
127.0.0.1:30001> exec 提交事务
1) "222"
2) OK
3) OK
4) 1) "xxx"
2) "666"
127.0.0.1:30001> 这次没有报错,原因是数据都在同一套主从上,没有发生梦游模式
说明:Hash tag标签{},在一栏有明确说明;另外在predix代理源码目录的/conf/sentinel.conf中也有明确定义(同时也定义了hash算法),如下代码片段所示。
SentinelServerPool {
Databases 16
Hash crc16
HashTag "{}"
小结:
使用Hashtag标签模式时,无论你怎么设值,相同前缀的数据都通过hash算法,命中在一台机器上,便于事务的正常运行。
只要是key 使用标签的前缀是一致的{} 大括号中的内容一致,就不会出现梦游(来回切换不同端口的redis实例)。结论:集群在Hashtag标签模式的加持下,是支持事务的!
4.收尾工作,清除实验数据
# pwd
/usr/src/redis-5.0.4/utils/create-cluster 操作前,确保目录位置,还在集群目录下,便于清场
#./create-cluster stop 先关闭前面启动的集群
#./create-cluster clean 清理持久化测试文件
四、方法二:用客户端命令redis-cli --cluster create 开启集群(手动指定redis实例)
1.redis-cli --cluster help查看集群手动创建命令的语法格式
#redis-cli --cluster help 查看帮助命令
Cluster Manager Commands:
create host1:port1 ... hostN:portN 手动指定N个IP+端口
--cluster-replicas <arg> 后缀参数replicas ,指明一个主跟几个从
……
据此帮助得知,如果用这个命令,那么就要准备Host1~HostN,也就是要准备N台redis-server服务,这里我们依然准备6台,端口从7000~7005,同时给各redis-server服务配套自己的redis.conf文件。
2.手动准备6个redis实例的持久化目录和配置文件,并逐一启动
本步骤的操作目的:
创建6个目录用来分别存放6台redis-server启动时用到的conf文件,同时它们也分别作为各redis-server服务的持久化目录。好处:
1.把测试数据集中存放,便于清理
2.稍后这六台redis-server手动启动后,需要用redis-cli --cluster 命令把6兄弟组成一个集群
1.创建持久化目录
#cd && make -p test/cluster-test 创建持久化目录所在的根目录
#cd && cd test/cluster-test && mkdir 7000 7001 7002 7003 7004 7005 && ls 创建持久化目录
2.创建redis-server所需要的配置文件
#cd 7000
#vim 7000.conf 注:这个文件,是redis源码目录下redis.conf的精简版。
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
然后:wq保存并退出即可。
注:nodes.conf,你也可以根据自己的口味命名为nodes_7000.conf,本案例为了方便起见,就不这么配置了。
配置解析:
port 7000 指明,用该配置文件启动的redis-server时,该服务的端口就是配置的7000
cluster-enabled yes 开启集群模式,允许用集群命令(redis-cli --cluster create )拉这台redis-server入伙,默认是no,关闭的
cluster-config-file nodes.conf 集群和该服务之间的配置信息存放位置,不用理会,这个文件集群内部自己管理,自己创建、修改、更新
cluster-node-timeout 5000 该服务和集群失去联系的超时时间,一旦超时5秒,集群将会对该服务采取一些措施
appendonly yes 是否开启AOF,数据操作日志追加,默认是no(仅开启rdb)
附注: (版本有点儿老,是3.0的,需要安装ruby,如果按官网配,后面还会安装一些tar包,中间会多次报错,感兴趣的,可以挑战一下官网步骤)
3.分别给其它5个redis-server的conf文件进行修改(仅修改端口就可以)
#cd && test/cluster-test && ls 切回持久化根目录,确保目录位置没弄错,开启一波骚操作
#cp ./7000.conf ./7001/7001.conf 以一步配置的7000.conf为模板,逐个复制配置文件到其它持久化目录
#cp ./7000.conf ./7002/7002.conf
#cp ./7000.conf ./7003/7003.conf
#cp ./7000.conf ./7004/7004.conf
#cp ./7000.conf ./7005/7005.conf#vim ./7001/7001.conf 把第一行的端口修改为7001后,保存并退出
#vim ./7002/7002.conf 把第一行的端口修改为7002后,保存并退出
#vim ./7003/7003.conf 把第一行的端口修改为7003后,保存并退出
#vim ./7004/7004.conf 把第一行的端口修改为7004后,保存并退出
#vim ./7005/7005.conf 把第一行的端口修改为7005后,保存并退出最后以7005为例展示一下,每个文件只需要修改端口即可,其它不在一一累述。
port 7005
cluster-enabled yes
cluster-config-file nodes.conf
cluster--timeout 5000
appendonly yes
以上步骤简单而繁琐,但是便于理解,如果你比较好学,sed -i 也比较适合你的口味。
#cp 7000.conf ./7001/7001.conf && sed -i "s/7000/7001/g" ./7001/7001.conf 复制配置文件7000.confg,并修改新文件70001.conf里的端口7000为70001,最后回写到7001.conf
注:-i 表示我要修改文件内容(没有-i修改不会生效);s/替换以某字符开头的文件内容,后面是正则;/g 全部替换(此处写不写都可以)
4.分别开启新窗口,逐个启动redis-server服务
由于操作步骤简单,图片不再一一截取,要注意的是:每个服务都要开启新窗口操作。
新窗口一
#cd && clear && cd test/cluster-test/7000 切换到redis-server 7000的持久化目录
#redis-server 7000.conf 启动7000端口的redis服务(该命令在哪个窗口启动,哪个目录就会被默认认定为其持久化目录,所以上面要切换到7000目录下)
新窗口二
#cd && clear && cd test/cluster-test/7001 切换到redis-server 7001的持久化目录
#redis-server 7001.conf 启动7001端口的redis服务
新窗口二
#cd && clear && cd test/cluster-test/7002 切换到redis-server 7002的持久化目录
#redis-server 7002.conf 启动7002端口的redis服务
新窗口四
#cd && clear && cd test/cluster-test/7002 切换到redis-server 7002的持久化目录
#redis-server 7002.conf 启动7002端口的redis服务
新窗口五
#cd && clear && cd test/cluster-test/7004 切换到redis-server 7004的持久化目录
#redis-server 7004.conf 启动7004端口的redis服务
新窗口六
#cd && clear && cd test/cluster-test/7005 切换到redis-server 7005的持久化目录
#redis-server 7005.conf 启动7005端口的redis服务
注:
1.这些命令可以写在一个shell中,一次性批量启动,在此不做过多展开。启动图片信息如下,不再一一截取。
2.如果在后续步骤中有误操作,导致实验中断,需回头进入test/cluster-test下的各个目录,把自动生成的文件逐个删除,删除命令如下:
#rm -rf /root/test/cluster-test/700*/appendonly.aof
#rm -rf /root/test/cluster-test/700*/dump.rdb
#rm -rf /root/test/cluster-test/700*/nodes.conf
3.根据上述帮助逐个指定服务器的ip、端口,以replicas 数,手动开启集群
redis-cli --cluster create 127.0.0.1:7000 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 --cluster-replicas 1 指定每个master副本数量为1
中间会暂停一下,询问是否同意上述分配方案,输入:yes即可。
4.手动启动redis客户端(该模式,也会上演梦游,同理使用Hashtag可以避免梦游)
#redis-cli -c -p 7000
127.0.0.1:7000> set k1 111
-> Redirected to slot [12706] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set k2 222
-> Redirected to slot [449] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get k1
-> Redirected to slot [12706] located at 127.0.0.1:7002
"111"
127.0.0.1:7002>
此处不重复演示Hashtag的非梦游模式(如有需要查看,请参考上面方法一的最后一步),至此,第二种方法演示完毕,这种更为灵活和常用。
五、槽位转移命令的使用:数据分配不均时,槽位移动
#redis-cli --cluster help 查看reshard槽位操作帮助
Cluster Manager Commands:
……
reshard host:port 语法格式,后面的是各个需要经过交互的确认步骤
--cluster-from <arg>
--cluster-to <arg>
--cluster-slots <arg>
--cluster-yes
--cluster-timeout <arg>
--cluster-pipeline <arg>
--cluster-replace
小提示:下面的步骤非常简单,基本是傻瓜式操作,由于需要展示效果,显得篇幅略长。
1.指定需要操作转移的主机
#redis-cli --cluster reshard 127.0.0.1:7000 开始运行槽位分配命令
2.指定要把多少槽位转移走
槽位转移的个数,最好是整十数的倍数,这里定义为2000(可以根据实际情况调整)
3.指定接收槽位的主机的node ID
从上面复制7000端口主机的node ID,把槽位转移给7000
4.需要被转移的2000槽位,由哪些主机提供
Source node #1 提供槽位的node id,这里可以是一台或多台
Source node #2
Source node #3 doneg如果果没有其他主机来贡献槽位了,最后一行就写Done
特别提示一下:这里提供槽位方,必须是master的node id才可以,否则会报如下错误:
5.回车键,确定命令的执行,开始槽位转移
输入:yes 开始执行槽位转移。(一旦输入yes后,开工没有回头箭了,直到执行完毕,并且上面命令,会被大串的日志信息覆盖!!)
注:被移动的2000个槽位,具体是从槽位提供者的哪些槽位,是系统自己决断的,不受人为控制。
6.info命令查看,各节点槽位移动后的变化
#redis-cli --cluster info 127.0.0.1:7000
注:#redis-cli --cluster check 127.0.0.1:7000 这个命令,也可以查看槽位消息,且更为详细一些
六、新增、移除节点
#redis-cli --cluster help 查看语法帮助,后面不再过多开展
……
add-node new_host:new_port existing_host:existing_port #新主机添加到集群中
--cluster-slave
--cluster-master-id <arg>
del-node host:port node_id #从集群中移除某台主机……
先写到这儿吧,后期如有需要再做更新,总之能看到这里,基本也对整个集群搭建有了一定了解了,边角料慢慢研究。
尾言
全文纯手工打造,难免有纰漏之处,欢迎批评指导,不过中间遇到的坑,大都已注明。
创作不易,本文如能解决您遇到的疑惑,动动您发财的小手,予以点赞,谢谢!
附注:predixy、twemproxy搭理的搭建
1、
2、