博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用java代码连接RedisCluster集群实现
阅读量:2057 次
发布时间:2019-04-29

本文共 5503 字,大约阅读时间需要 18 分钟。

Redis5.x集群学习须知

学前须知

当前redis的最新版本是5.0以上,其搭建cluster的方法与早期的redis4.0以前的不太一样,不再使用ruby相关的组件。

  • 1.redis集群的常见搭建方式:划分大概是5种方式

  • 2.Redis集群的原理和机制

  • 3.学会搭建一个Redis集群

  • 4.测试搭建好的集群:连接测试,高可用性测试


已经建设好的集群类似如下方式:采用对key做hash后,分到不同区段的slot的方式,同时master节点宕机,slave节点切换顶替。实现redis高负载高可用

在这里插入图片描述

3.1 使用java代码连接RedisCluster集群实现

package redistest;import org.apache.commons.pool2.impl.GenericObjectPoolConfig;import redis.clients.jedis.HostAndPort;import redis.clients.jedis.JedisCluster;import java.io.IOException;import java.util.HashSet;import java.util.Set;/** 使用JedisCluster类中各种构造函数,可以连接Jedis Cluster(Client Sharding)集群 * @author fangchangtan * @date 2019-10-15 19:55 */public class RedisClusterTest {
public static void main(String[] args) throws IOException {
GenericObjectPoolConfig config = new GenericObjectPoolConfig(); // 最大连接数 config.setMaxTotal(30); // 最大空闲数 config.setMaxIdle(10); // 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常: // Could not get a resource from the pool config.setMaxWaitMillis(2000); Set
jedisClusterNode = new HashSet
(); jedisClusterNode.add(new HostAndPort("172.19.32.xxx", 7001)); jedisClusterNode.add(new HostAndPort("172.19.32.xxx", 7002)); jedisClusterNode.add(new HostAndPort("172.19.32.xxx", 7003)); jedisClusterNode.add(new HostAndPort("172.19.32.yyy", 7004)); jedisClusterNode.add(new HostAndPort("172.19.32.yyy", 7005)); jedisClusterNode.add(new HostAndPort("172.19.32.yyy", 7006)); //1.如果集群没有密码// JedisCluster jc = new JedisCluster(jedisClusterNode,config); //2.如果使用到密码,请使用如下构造函数 JedisCluster jc = new JedisCluster(jedisClusterNode, 1000,30,3,"root",config); jc.set("foo", "bar"); jc.set("test", "value"); jc.set("52", "poolTestValue288"); jc.set("44", "444"); jc.set("name", "poolTestValue2"); System.out.println("=================="); System.out.println( jc.decr("44")); System.out.println(jc.get("name")); System.out.println(jc.get("52")); System.out.println(jc.get("test")); jc.close(); }}

运行结果:

在这里插入图片描述

3.2 常见问题总结:

问题1 java连接Redis异常:JedisMovedDataException

redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 1539 127.0.0.1:6379

解决方案: 将连接对象从 Jedis 换成 JedisCluster。就可以了。

问题原因 : MOVED表示使用的是Redis群集。而 Jedis 不是集群模式。

//import redis.clients.jedis.HostAndPort;//import redis.clients.jedis.JedisCluster;HostAndPort hostAndPort = new HostAndPort(host, port);Set
hostAndPortSet = new HashSet<>();hostAndPortSet.add(hostAndPort);JedisCluster jedis = new JedisCluster(hostAndPortSet);jedis.setnx(key, value);

问题2:NOAUTH Authentication required.

Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.

解决方案: 可以选择相应的JedisCluster类的构造函数

其中password字段即为要填写的集群登录密码

public JedisCluster(Set
jedisClusterNode,int connectionTimeout, int soTimeout,int maxAttempts, String password, final GenericObjectPoolConfig poolConfig) {
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, poolConfig);}

问题原因 : 如果Redis配置了密码,则java连接redisCluster时候需要添加密码配置连接。

问题3 :JedisClusterMaxAttemptsException: No more cluster attempts left.

测试redis cluster集群高可用性的时候,当杀死master节点之后,java连接rediscluster的代码出现如下错误!

redis.clients.jedis.exceptions.JedisClusterMaxAttemptsException: No more cluster attempts left.	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:86)	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:124)	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:124)	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:124)	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:124)	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:124)	at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:25)	at redis.clients.jedis.JedisCluster.set(JedisCluster.java:143)	at redistest.RedisClusterTest.main(RedisClusterTest.java:48)

这个问题碰到了很长是哪没有解决,没办法,只能采用折中的方法。

解决方案: 在java代码中捕捉slave切换到master过程中异常错误

JedisCluster jc = new JedisCluster(nodes, 15000,3, config);for (int i = 0; i < 1000; i++) {
try {
Thread.sleep(1000); } catch (InterruptedException e) {
e.printStackTrace(); } try {
System.out.println(jc.toString()); jc.set("foo", "bar"); jc.set("test", "value"); jc.set("52", "poolTestValue288"); jc.set("44", "444"); jc.set("name", "poolTestValue2"); jc.set(""+i,""+i); System.out.println("==================");// System.out.println( jc.decr("44")); System.out.println(jc.get("name")); System.out.println(jc.get("52")); System.out.println(jc.get("test")); System.out.println(jc.get(""+i)); } catch (JedisClusterMaxAttemptsException e) {
jc.close(); //当slave切换到master过程中,cluster捕捉到该异常时候 jc = new JedisCluster(nodes, 15000,5, config); e.printStackTrace(); } } }jc.close();

这种只能暂时的解决一部分问题,但是会有数据相应的丢失!小伙伴们有什么好的办法,欢迎提出来,多谢啦!

问题原因:master挂了之后,slave升级为master节点之后,对于java客户端来说无感(没有感觉到元信息的变化),还是在尝试连接原来master的slot,导致失。

在这里插入图片描述

转载地址:http://lmvlf.baihongyu.com/

你可能感兴趣的文章
【UML】《Theach yourself uml in 24hours》——hour4
查看>>
Set、WeakSet、Map以及WeakMap结构基本知识点
查看>>
【NLP学习笔记】(一)Gensim基本使用方法
查看>>
【NLP学习笔记】(二)gensim使用之Topics and Transformations
查看>>
【深度学习】LSTM的架构及公式
查看>>
【深度学习】GRU的结构图及公式
查看>>
【python】re模块常用方法
查看>>
剑指offer 19.二叉树的镜像
查看>>
剑指offer 20.顺时针打印矩阵
查看>>
剑指offer 21.包含min函数的栈
查看>>
剑指offer 23.从上往下打印二叉树
查看>>
剑指offer 25.二叉树中和为某一值的路径
查看>>
剑指offer 26. 数组中出现次数超过一半的数字
查看>>
剑指offer 27.二叉树的深度
查看>>
剑指offer 29.字符串的排列
查看>>
剑指offer 31.最小的k个树
查看>>
剑指offer 32.整数中1出现的次数
查看>>
剑指offer 33.第一个只出现一次的字符
查看>>
剑指offer 34.把数组排成最小的数
查看>>
剑指offer 35.数组中只出现一次的数字
查看>>