20181029redis分片+主从集群学习搭建
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot(插槽)上,cluster 负责维护node<->slot<->value
首先先将刚才的几个redis服务关闭。然后清空RDB文件。保证数据库为空
进入3个redis目录,分别修改redis.conf配置:
- 设置不同的端口,6379、6380、6381
- 开启集群,cluster-enabled yes
- 指定集群的配置文件,cluster-config-file "nodes-xxxx.conf"
4.启动每个redis
&& 是接下来需要做的事情,进去xxx 启动redis ,返回上一级目录
安装ruby环境
因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。
yum -y install zlib ruby rubygems
gem install redis
手动安装:
yum -y install zlib ruby rubygems
rz上传redis-3.2.1.gem
gem install -l redis-3.2.1.gem
创建集群
1.进入安装目录下的src文件下
2.运行此脚本文件
执行脚本
./redis-trib.rb create --replicas 0 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381
--replicas 0:指定了从数据的数量为0
注意:这里不能使用127.0.0.1,否则在Jedis客户端使用时无法连接到!
确认“yes”
集群搭建成功
测试
客户端重新定向
redis-cli -c
set 一个值
退出重定向,进入192.168.206.66:6379 ,获取123 得到abc,并且跳转到6380端口
插槽分配,查看插槽,使用cluster nodes 命令
该信息反映出了集群中的每个节点的id、身份、连接数、插槽数等。
当我们执行set abc 123命令时,redis是如何将数据保存到集群中的呢?执行步骤:
- 接收命令set 123 abc
- 通过key(abc)计算出插槽值,然后根据插槽值找到对应的节点。(123的插槽值为:7638)
- 重定向到该节点执行命令
整个Redis提供了16384个插槽,也就是说集群中的每个节点分得的插槽数总和为16384。
./redis-trib.rb 脚本实现了是将16384个插槽平均分配给了N个节点。
注意:如果插槽数有部分是没有指定到节点的,那么这部分插槽所对应的key将不能使用。
计算key的插槽值:
key的有效部分使用CRC16算法计算出哈希值,再将哈希值对16384取余,得到插槽值。
什么是有效部分?
- 如果key中包含了’{‘符号,且在’{‘符号后存在’}’符号,并且’{‘和’}’之间至少有一个字符,则有效部分是指’{‘和’}’之间的部分;
- key={hello}_java的有效部分是hello
- 如果不满足上一条情况,整个key都是有效部分;
- key=hello_java的有效部分是全部
新增节点
新增端口号为6382 的节点,
首先复制一份配置文件6382 执行: cp 6381 6382 -r
删除多余的文件,并更改配置文件 port端口号,集群文件,cluster-config 三个地方
进入src目录下执行 redis-trib.rb
执行脚本:
./redis-trib.rb add-node 192.168.206.66:6382 192.168.206.66:6379
加入成功
但是新的节点并没有插槽,所以数据也存不进去
需要其他的节点分一些插槽给新的节点
使用命令 ./redis-trib.rb reshard 192.168.206.66:6379
查看节点信息 redis-cli cluster nodes
6382 有了1000个插槽了
删除节点
- 假设我们想要删除6382这个节点
- 执行脚本:./redis-trib.rb reshard 192.168.206.66:6382
选择需要转移的插槽的数量,因为6382有5128个,所以转移1000个
查看节点信息 redis-cli cluster nodes
6382 已经没有插槽了 这个时候可以移除6382 节点
./redis-trib.rb del-node 192.168.206.66:6382 66ede2b286aa162fcbba4a5fca92862417fe5b19
查看节点信息
6382节点已经被删除了
分片集群已经搭建好了 但是存在不足就是如果一台宕机,信息将会不可用,这里再采用主从复制来增加redis集群的高可用
- 集群中的每个节点都会定期的向其它节点发送PING命令,并且通过有没有收到回复判断目标节点是否下线;
- 集群中每一秒就会随机选择5个节点,然后选择其中最久没有响应的节点放PING命令;
- 如果一定时间内目标节点都没有响应,那么该节点就认为目标节点疑似下线;
- 当集群中的节点超过半数认为该目标节点疑似下线,那么该节点就会被标记为下线(fail);
- 当集群中的任何一个节点下线,就会导致插槽区有空档,不完整,那么该集群将不可用;
- 如何解决上述问题?
- 在Redis集群中可以使用主从模式实现某一个节点的高可用
- 当该节点(master)宕机后,集群会将该节点的从数据库(slave)转变为(master)继续完成集群服务;
再复制三台redis,并且分别更改配置文件
复制之前,killall redis-server 并且删除redis里面所有数据
完成后,启动六台redis
创建集群,指定了从库数量为1,创建顺序为主库(3个)、从库(3个):
./redis-trib.rb create --replicas 1 192.168.206.66:6379 192.168.206.66:6380 192.168.206.66:6381 192.168.206.66:6479 192.168.206.66:6480 192.168.206.66:6481
查看节点信息
redis-cli cluster nodes
可以测试
redis-cli -c
停掉6380 6480 变为master
再次获取123
依旧可以获得!
注意
- 集群中的节点只能使用0号数据库,如果执行SELECT切换数据库会提示错误。