1.1
1.1.1 添加主节点
集群创建成功后可以向集群中添加节点,下面是添加一个master主节点
Ø 添加7007结点作为新节点
执行命令:./redis-trib.rb add-node 127.0.0.1:7007 127.0.0.1:7001
Ø 查看集群结点发现7007已添加到集群中
1.1.2 hash槽重新分配
添加完主节点需要对主节点进行hash槽分配,这样该主节才可以存储数据。
Ø 查看集群中槽占用情况
redis集群有16384个槽,集群中的每个结点分配自已槽,通过查看集群结点可以看到槽占用情况。
Ø 给刚添加的7007结点分配槽
第一步:连接上集群(连接集群中任意一个可用结点都行)
[root@redis01 redis0707]# ./redis-trib.rb reshard 192.168.101.3:7001 |
第二步:输入要分配的槽数量
输入:500,表示要分配500个槽
第三步:输入接收槽的结点id
输入:15b809eadae88955e36bcdbb8144f61bbbaf38fb
PS:这里准备给7007分配槽,通过cluster nodes查看7007结点id为:
15b809eadae88955e36bcdbb8144f61bbbaf38fb
第四步:输入源结点id
输入:all
第五步:输入yes开始移动槽到目标结点id
输入:yes
1.1.3 添加从节点
集群创建成功后也可以向集群中添加从节点。
Ø 添加7008从结点,将7008作为7007的从结点
命令:./redis-trib.rb add-node --slave --master-id 主节点id 新节点的ip和端口 旧节点ip和端口
执行如下命令:
./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7008 192.168.101.3:7001 |
cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 是7007结点的id,可通过cluster nodes查看。
注意:如果原来该结点在集群中的配置信息已经生成到cluster-config-file指定的配置文件中(如果cluster-config-file没有指定则默认为nodes.conf),这时可能会报错:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0 |
解决方法是删除生成的配置文件nodes.conf,删除后再执行./redis-trib.rb add-node指令
Ø 查看集群中的结点,刚添加的7008为7007的从节点:
1.1.4 删除结点
命令:./redis-trib.rb del-node 127.0.0.1:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017
删除已经占有hash槽的结点会失败,报错如下:
[ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again.
需要将该结点占用的hash槽分配出去(参考hash槽重新分配章节)。
2 Jedis连接集群
需要开启防火墙,或者直接关闭防火墙。
[root@localhost-0723 bin]# service iptables stop -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 6380 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 7001 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 7002 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 7003 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 7004 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 7005 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 7006 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ~ "/etc/sysconfig/iptables" 22L, 1079C 已写入 [root@localhost-0723 bin]# service iptables restart iptables:应用防火墙规则: [确定] [root@localhost-0723 bin]# |
2.1 代码实现
创建JedisCluster类连接redis集群。
@Test public void testJedisCluster() throws Exception { //创建一连接,JedisCluster对象,在系统中是单例存在 Set<HostAndPort> nodes = new HashSet<>(); nodes.add(new HostAndPort("127.0.0.1", 7001)); nodes.add(new HostAndPort("127.0.0.1", 7002)); nodes.add(new HostAndPort("127.0.0.1", 7003)); nodes.add(new HostAndPort("127.0.0.1", 7004)); nodes.add(new HostAndPort("127.0.0.1", 7005)); nodes.add(new HostAndPort("127.0.0.1", 7006)); JedisCluster cluster = new JedisCluster(nodes); //执行JedisCluster对象中的方法,方法和redis一一对应。 cluster.set("cluster-test", "my jedis cluster test"); String result = cluster.get("cluster-test"); System.out.println(result); //程序结束时需要关闭JedisCluster对象 cluster.close(); } |
2.2 使用spring
Ø 配置applicationContext.xml
<!-- 连接池配置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大连接数 --> <property name="maxTotal" value="30" /> <!-- 最大空闲连接数 --> <property name="maxIdle" value="10" /> <!-- 每次释放连接的最大数目 --> <property name="numTestsPerEvictionRun" value="1024" /> <!-- 释放连接的扫描间隔(毫秒) --> <property name="timeBetweenEvictionRunsMillis" value="30000" /> <!-- 连接最小空闲时间 --> <property name="minEvictableIdleTimeMillis" value="1800000" /> <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 --> <property name="softMinEvictableIdleTimeMillis" value="10000" /> <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 --> <property name="maxWaitMillis" value="1500" /> <!-- 在获取连接的时候检查有效性, 默认false --> <property name="testOnBorrow" value="true" /> <!-- 在空闲时检查有效性, 默认false --> <property name="testWhileIdle" value="true" /> <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true --> <property name="blockWhenExhausted" value="false" /> </bean> <!-- redis集群 --> <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster"> <constructor-arg index="0"> <set> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.101.3"></constructor-arg> <constructor-arg index="1" value="7001"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.101.3"></constructor-arg> <constructor-arg index="1" value="7002"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.101.3"></constructor-arg> <constructor-arg index="1" value="7003"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.101.3"></constructor-arg> <constructor-arg index="1" value="7004"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.101.3"></constructor-arg> <constructor-arg index="1" value="7005"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.101.3"></constructor-arg> <constructor-arg index="1" value="7006"></constructor-arg> </bean> </set> </constructor-arg> <constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg> </bean> |
Ø 测试代码
private ApplicationContext applicationContext; @Before public void init() { applicationContext = new ClassPathXmlApplicationContext( "classpath:applicationContext.xml"); }
// redis集群 @Test public void testJedisCluster() { JedisCluster jedisCluster = (JedisCluster) applicationContext .getBean("jedisCluster");
jedisCluster.set("name", "zhangsan"); String value = jedisCluster.get("name"); System.out.println(value); } |