Redis集群介绍
redis集群是在redis 3.0版本推出的一个功能,其有效的解决了redis在分布式方面的需求。当遇到单机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的。并且从另一方面讲,redis中sentinel有效的解决了故障转移的问题,也解决了主节点下线客户端无法识别新的可用节点的问题,但是如果是从节点下线了,sentinel是不会对其进行故障转移的,并且连接从节点的客户端也无法获取到新的可用从节点,而这些问题在Cluster中都得到了有效的解决。
redis集群中数据是和槽(slot)挂钩的,其总共定义了16384个槽,所有的数据根据一致哈希算法会被映射到这16384个槽中的某个槽中;另一方面,这16384个槽是按照设置被分配到不同的redis节点上的,比如启动了三个redis实例:cluster-A,cluster-B和cluster-C,这里将0-5460号槽分配给cluster-A,将5461-10922号槽分配给cluster-B,将10923-16383号槽分配给cluster-C(总共有16384个槽,但是其标号类似数组下标,是从0到16383)。也就是说数据的存储只和槽有关,并且槽的数量是一定的,由于一致hash算法是一定的,因而将这16384个槽分配给无论多少个redis实例,对于确认的数据其都将被分配到确定的槽位上。redis集群通过这种方式来达到redis的高效和高可用性目的。
这里需要进行说明的一点是,一致哈希算法根据数据的key值计算映射位置时和所使用的节点数量有非常大的关系。一致哈希分区的实现思路是为系统中每个节点分配一个token,范围一般在0~2^32,这些token构成一个哈希环,数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该hash值的token节点,需要操作的数据就保存在该节点上。通过分析可以发现,一致哈希分区存在如下问题:
1,加减节点会造成哈希环中部分数据无法命中,需要手动处理或忽略这部分数据;
2,当使用少量节点时,节点变化将大范围影响环中数据映射,因此这种方式不适合少量节点的分布式方案;
3,普通的一致性哈希分区在增减节点时需要增加一倍或减去一半节点才能保证数据和负载的平衡。
正是由于一致哈希分区的这些问题,redis使用了虚拟槽来处理分区时节点变化的问题,也即将所有的数据映射到16384个虚拟槽位上,当redis节点变化时数据映射的槽位将不会变化,并且这也是redis进行节点扩张的基础。
Redis集群的搭建
server1:192.168.6.130
server2:192.168.6.129
1,解压安装
tar xf redis-3.2.13.tar.gz
cd redis-3.2.13/
make && make install
2.创建 Redis 节点
首先在 server1机器上 /opt/目录下创建 redis-cluster 目录;
mkdir -p /opt/redis-cluster
在 /opt/redis-cluster 目录下,创建名为7001、7002、7003的目录,并将 redis.conf 拷贝到这三个目录中
mkdir 7001 7002 7003
cp redis.conf /opt/redis-cluster/7001
cp redis.conf /opt/redis-cluster/7002
cp redis.conf /opt/redis-cluster/7003
分别修改这三个配置文件,修改如下内容
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /opt/redis-cluster/7001/redis.pid
logfile “/opt/redis-cluster/7001/redis.log”
dir /opt/redis-cluster/7001/
appendfilename “7001.aof"
protected-mode no
接着在另外一台机器上操作重复以上三步,只是把目录改为7004、7005、7006,对应的配置文件也按照这个规则修改即可
3,启动redis服务
server1 :
./src/redis-server /opt/redis-cluster/7001/redis.conf
./src/redis-server /opt/redis-cluster/7002/redis.conf
./src/redis-server /opt/redis-cluster/7003/redis.conf
server2:
./src/redis-server /opt/redis-cluster/7004/redis.conf
./src/redis-server /opt/redis-cluster/7005/redis.conf
./src/redis-server /opt/redis-cluster/7006/redis.conf
查看服务启动状况
4, 创建集群
cd /root/redis-3.2.13/src/
./redis-trib.rb create --replicas 1 server1:7001 server1:7002 server:7003
server2:7004 server2:7005 server3:7006
报错:
安装ruby
yum install ruby
yum install rubygems
gem install redis
再次创建集群
./redis-trib.rb create --replicas 1 server1:7001 server1:7002 server:7003
server2:7004 server2:7005 server3:7006
集群创建成功
5,测试连接
/root/redis-3.2.13/src/redis-cli -c -p 7001
6,增加节点
server1先增加一个7007节点
cd /root/redis-3.2.13/src
./redis-server /opt/redis-cluster/7007/redis.conf
把7007节点加入集群
./redis-trib add-node127.0.0.1:7007 127.0.0.1:7001
7 ,分配hash
./redis-trib.rb reshard 127.0.0.1:7001
8,给新节点增加备机
server2先启动节点7008 (略)
server1增加从节点
cd /root/redis-3.2.13/src
./redis-trib.rb add-node server2:7008 server1:7007
进入7008节点
redis-cli -c -p 7008 -h 192.168.6.129
redis replicate 7007ID
9 ,删除节点
删除从节点
./redis-trib.rb del-node 192.168.6.129:7008 从ID
删除主节点
先把数据移走
./redis-trib.rb reshard 127.0.0.1:7007
然后在删除节点,方式和删除从节点一样
测试
集群初始key值查看
集群初始node情况查看
集群获取key值测试
模拟一台Master宕机
从自动升级为master,数据没有丢失
将从的slots移走,这里移到了7001 和7002两台master上
移走之后slots为0
移走一个master节点,数据分布在7001 和7002节点上,数据没有丢失,可以正常获取
将7003 节点彻底从集群里面移除
删除宕机不能连接的从节点
新增一个节点7007,查看集群node状态
给新增节点分配slots,让他可以存储数据
新节点分配slots完成,数据也跟着一起分配到了新节点
新节点获取数据测试,一切正常
集群新增一个节点7009,让这个节点作为7007的从
查看主从数据是否一致
测试完成,一切正常