JedisMovedDataException(将 sadd 与管道一起使用时)
JedisMovedDataException (When using sadd with pipeline)
我有一个 3 节点 EC2 redis 集群设置,我正在尝试使用管道模式将记录添加到 redis(使用 sadd)。
在 3 个节点中添加大约 70/82 和 81 个键后出现以下错误:
Exception in thread "main" redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 1539 172.31.59.103:6379
at redis.clients.jedis.Protocol.processError(Protocol.java:93)
at redis.clients.jedis.Protocol.process(Protocol.java:122)
at redis.clients.jedis.Protocol.read(Protocol.java:191)
at redis.clients.jedis.Connection.getOne(Connection.java:258)
at redis.clients.jedis.ShardedJedisPipeline.sync(ShardedJedisPipeline.java:44)
at org.hu.e63.MovieLens21MPipeline.push(MovieLens21MPipeline.java:47)
at org.hu.e63.MovieLens21MPipeline.main(MovieLens21MPipeline.java:53
我查看了 this 线程,我的代码很像这样:
输入文件来自这里(ratings.csv): http://files.grouplens.org/datasets/movielens/ml-latest-small.zip
代码如下:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;
public class MovieLens21MPipeline {
ShardedJedis jedis;
public MovieLens21MPipeline() {
JedisShardInfo si = new JedisShardInfo("172.31.59.103", 6379, 5000);
List<JedisShardInfo> list = new ArrayList<JedisShardInfo>();
list.add(si);
list.add(new JedisShardInfo("172.31.59.104", 6379, 5000));
list.add(new JedisShardInfo("172.31.59.105", 6379, 5000));
jedis = new ShardedJedis(list);
}
public void push() {
ShardedJedisPipeline pipeline = jedis.pipelined();
Scanner s;
try {
s = new Scanner(new File("input/ratings.csv"));
StringBuilder key = new StringBuilder();
String s1 = s.nextLine(); // Skip first line
while (s.hasNextLine()) {
s1 = s.nextLine();
String[] spl = s1.split(",");
// key="u:"+spl[0]+":m";
key.append("u:").append(spl[0]).append(":m");
pipeline.sadd(key.toString(), spl[1]);
key.setLength(0);
}
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("bye" + e.getMessage());
}
pipeline.sync();
}
public static void main(String[] args) {
MovieLens21MPipeline obj = new MovieLens21MPipeline();
long startTime = System.currentTimeMillis();
obj.push();
long endTime = System.currentTimeMillis();
double d = 0.0;
d = (double) (endTime - startTime);
System.out.println("Throughput: " + d);
}
}
感谢任何帮助。
MOVED 表示您正在使用 Redis 集群。 ShardedJedis 不适用于 Redis 集群,因此您应该改用 JedisCluster。
请注意,JedisCluster 没有管道模式,因此您可能需要一个一个地发送您的操作。
希望对您有所帮助。
就像Lim说的,你是在集群模式下使用Redis。使用 JedisCluster 可以解决这个问题。另外,作为补充,JedisCluster为什么有效?
从JedisCluster的源码可以知道
private T runWithRetries(byte[] key, int attempts, boolean tryRandomNode, boolean asking) {
if (attempts <= 0) {
throw new JedisClusterMaxRedirectionsException("Too many Cluster redirections?");
}
Jedis connection = null;
try {
// omit ... get connection
return execute(connection);
} catch (JedisNoReachableClusterNodeException jnrcne) {
throw jnrcne;
} catch (JedisConnectionException jce) {
// release current connection before recursion
// omit
return runWithRetries(key, attempts - 1, tryRandomNode, asking);
} catch (JedisRedirectionException jre) {
// if MOVED redirection occurred,
if (jre instanceof JedisMovedDataException) {
// here is the key point
// it rebuilds cluster's slot cache
// recommended by Redis cluster specification
// Jedis or ShardedJedis won't run this code
this.connectionHandler.renewSlotCache(connection);
}
// omit ...
return runWithRetries(key, attempts - 1, false, asking);
} finally {
releaseConnection(connection);
}
}
我有一个 3 节点 EC2 redis 集群设置,我正在尝试使用管道模式将记录添加到 redis(使用 sadd)。
在 3 个节点中添加大约 70/82 和 81 个键后出现以下错误:
Exception in thread "main" redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 1539 172.31.59.103:6379
at redis.clients.jedis.Protocol.processError(Protocol.java:93)
at redis.clients.jedis.Protocol.process(Protocol.java:122)
at redis.clients.jedis.Protocol.read(Protocol.java:191)
at redis.clients.jedis.Connection.getOne(Connection.java:258)
at redis.clients.jedis.ShardedJedisPipeline.sync(ShardedJedisPipeline.java:44)
at org.hu.e63.MovieLens21MPipeline.push(MovieLens21MPipeline.java:47)
at org.hu.e63.MovieLens21MPipeline.main(MovieLens21MPipeline.java:53
我查看了 this 线程,我的代码很像这样:
输入文件来自这里(ratings.csv): http://files.grouplens.org/datasets/movielens/ml-latest-small.zip
代码如下:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;
public class MovieLens21MPipeline {
ShardedJedis jedis;
public MovieLens21MPipeline() {
JedisShardInfo si = new JedisShardInfo("172.31.59.103", 6379, 5000);
List<JedisShardInfo> list = new ArrayList<JedisShardInfo>();
list.add(si);
list.add(new JedisShardInfo("172.31.59.104", 6379, 5000));
list.add(new JedisShardInfo("172.31.59.105", 6379, 5000));
jedis = new ShardedJedis(list);
}
public void push() {
ShardedJedisPipeline pipeline = jedis.pipelined();
Scanner s;
try {
s = new Scanner(new File("input/ratings.csv"));
StringBuilder key = new StringBuilder();
String s1 = s.nextLine(); // Skip first line
while (s.hasNextLine()) {
s1 = s.nextLine();
String[] spl = s1.split(",");
// key="u:"+spl[0]+":m";
key.append("u:").append(spl[0]).append(":m");
pipeline.sadd(key.toString(), spl[1]);
key.setLength(0);
}
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("bye" + e.getMessage());
}
pipeline.sync();
}
public static void main(String[] args) {
MovieLens21MPipeline obj = new MovieLens21MPipeline();
long startTime = System.currentTimeMillis();
obj.push();
long endTime = System.currentTimeMillis();
double d = 0.0;
d = (double) (endTime - startTime);
System.out.println("Throughput: " + d);
}
}
感谢任何帮助。
MOVED 表示您正在使用 Redis 集群。 ShardedJedis 不适用于 Redis 集群,因此您应该改用 JedisCluster。 请注意,JedisCluster 没有管道模式,因此您可能需要一个一个地发送您的操作。
希望对您有所帮助。
就像Lim说的,你是在集群模式下使用Redis。使用 JedisCluster 可以解决这个问题。另外,作为补充,JedisCluster为什么有效?
从JedisCluster的源码可以知道
private T runWithRetries(byte[] key, int attempts, boolean tryRandomNode, boolean asking) {
if (attempts <= 0) {
throw new JedisClusterMaxRedirectionsException("Too many Cluster redirections?");
}
Jedis connection = null;
try {
// omit ... get connection
return execute(connection);
} catch (JedisNoReachableClusterNodeException jnrcne) {
throw jnrcne;
} catch (JedisConnectionException jce) {
// release current connection before recursion
// omit
return runWithRetries(key, attempts - 1, tryRandomNode, asking);
} catch (JedisRedirectionException jre) {
// if MOVED redirection occurred,
if (jre instanceof JedisMovedDataException) {
// here is the key point
// it rebuilds cluster's slot cache
// recommended by Redis cluster specification
// Jedis or ShardedJedis won't run this code
this.connectionHandler.renewSlotCache(connection);
}
// omit ...
return runWithRetries(key, attempts - 1, false, asking);
} finally {
releaseConnection(connection);
}
}