一、简介

 其实哨兵模式和cluster模式都可以叫做redis集群,哨兵模式已经能满足一定的业务需要。cluster模式是后来redis官方出的一套集群方案。其核心原理类似于hashMap,主要为了解决哨兵模式单点读压力的

二、部署

  • 这里使用ruby部署redis cluster,首先下载安装,只需要在一台服务器上安装即可
    yum install ruby
    yum install rubygems
  • 下载ruby运行需要的包,这里是redis-3.3.5.gem,安装
    gem install redis-3.3.5.gem
  • 拷贝redis/src/redis-trib.rb 到redis安装目的,我这里是/data/service/bin/
  • 这里需要6台服务器,为了方便,每一台服务器上起2个服务,端口分别是6379,6380
  • 修改每一个redis.conf(6台都需要),注释掉cluster-enabled yes
  • 请启动每一个redis服务
  • 创建启动集群的启动脚本,内容如下:
    /redis-trib.rb create --replicas 1 192.168.25.128:7001 192.168.25.128:7002 192.168.25.128:7003 192.168.25.128:7004 192.168.25.128:7005 192.168.25.128:7006
  • 执行此脚本
Creating cluster
 Connecting to node 192.168.25.128:7001: OK
 Connecting to node 192.168.25.128:7002: OK
 Connecting to node 192.168.25.128:7003: OK
 Connecting to node 192.168.25.128:7004: OK
 Connecting to node 192.168.25.128:7005: OK
 Connecting to node 192.168.25.128:7006: OKPerforming hash slots allocation on 6 nodes…
 Using 3 masters:
 192.168.25.128:7001
 192.168.25.128:7002
 192.168.25.128:7003
 Adding replica 192.168.25.128:7004 to 192.168.25.128:7001
 Adding replica 192.168.25.128:7005 to 192.168.25.128:7002
 Adding replica 192.168.25.128:7006 to 192.168.25.128:7003
 M: 2e48ae301e9c32b04a7d4d92e15e98e78de8c1f3 192.168.25.128:7001
 slots:0-5460 (5461 slots) master
 M: 8cd93a9a943b4ef851af6a03edd699a6061ace01 192.168.25.128:7002
 slots:5461-10922 (5462 slots) master
 M: 2935007902d83f20b1253d7f43dae32aab9744e6 192.168.25.128:7003
 slots:10923-16383 (5461 slots) master
 S: 74f9d9706f848471583929fc8bbde3c8e99e211b 192.168.25.128:7004
 replicates 2e48ae301e9c32b04a7d4d92e15e98e78de8c1f3
 S: 42cc9e25ebb19dda92591364c1df4b3a518b795b 192.168.25.128:7005
 replicates 8cd93a9a943b4ef851af6a03edd699a6061ace01
 S: 8b1b11d509d29659c2831e7a9f6469c060dfcd39 192.168.25.128:7006
 replicates 2935007902d83f20b1253d7f43dae32aab9744e6
 Can I set the above configuration? (type ‘yes’ to accept): yesNodes configuration updated
 。。。。。。。。。。省略。。。。。。
  • test it!
    注意:
    可能遇到到问题
    1、xxx is not Empty,请停着个xxx的节点,删除bin目录下的dump.rdb,notes.conf,note6380.conf,必要时删除/var/run/redis.pid
    2、cannot connect to xxxx,你着redis配置密码了,在ruby的client里面写上你配置的密码,具体怎么找这个文件,find命令
    3、执行集群启动基本一直卡在:Waiting for the cluster to join …,请在你服务器上开启16379和16380端口,反正就是10000+你redis的端口

三、原理

原理图如下

cluster redis 限制 redis cluster enable_服务器


reids cluster模式最小得6个服务,每个服务之间通过ping-pong机制实现相互感知(注意:此模式没有单独的哨兵监控,集群内部完全自制)。redis集群数据存储类似于hashmap,其将数据划成16484个片区(又叫插槽,每个槽可以放n多个数据),通过对key进行一定的算法与16384取模,得到其在16384中间的一个片区中。如上图姑且认为1-4;2-5;3-6,两两结对,前者为master负责写(其实也具备读能力),后者slave负责读,而且是只读,防止数据出现不一致,同时slave从master同步数据。按照上述配对,1-4主从将只负责0-5500片区的读写;2~5主从只负责5501-11000片区的读写;3-6主从负责11001-16383片区的读写,从而实现了分摊了读写的压力。

三、容灾恢复

  • 主节点(如1)宕机,从节点(如4)将上位成master
  • 主节点又活了,角色反转为slave
  • 主从成对的宕机,redis cluster将重新在剩下的节点上分配16384个片区(通过配置:cluster-require-full-coverage)

四、java如何使用

public void jedisCluster() throws Exception {
	// 这里建议能把所有节点都写上就写上,防止单点连接失败
	Set<HostAndPort> nodes = new HashSet<>();
	nodes.add(new HostAndPort(yourIp, 7001));
	nodes.add(new HostAndPort(yourIp, 7002));
	nodes.add(new HostAndPort(yourIp, 7003));
	nodes.add(new HostAndPort(yourIp, 7004));
	nodes.add(new HostAndPort(yourIp, 7005));
	nodes.add(new HostAndPort(yourIp, 7006));
	JedisCluster jedisCluster = new JedisCluster(nodes);
	jedisCluster.set("k1", "100");
	String result = jedisCluster.get("k1");
	System.out.println(result);
	jedisCluster.close();
}

五、探讨cluster模式存在的问题

  • 多键操作不支持(如mset k1 v1 k2 v2;k1,k2可能不在一个服务器上)
  • 由于多键操作不支持直接导致redis事物不支持
  • 由于多键操作不支持直接导致redis可能不支持luna脚本(未测试),那些希望通过redis搭配luna脚本实现抢购秒杀方案的可能需要在测试一下,有空本人在测试一下。