-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
(I am creating a new issue about this, as suggested.)
Dependencies
- spring-data-redis: 2.7.2
- jedis: 3.9.0 (but this also happens with 3.8.0)
- commons-pool2: 2.11.1
Configuration settings
spring.redis.jedis.pool.max-active=60spring.redis.jedis.pool.max-idle=60spring.redis.jedis.pool.min-idle=10
What my code does
public void scan(RedisClusterNode redisClusterNode, RedisClusterConnection redisClusterConnection, int scanLimit) { // scanLimit = 50
ScanOptions scanOptions = ScanOptions.scanOptions().count(scanLimit).build();
try (Cursor<byte[]> cursor = redisClusterConnection.scan(redisClusterNode, scanOptions)) {
do {
cursor.next();
} while (cursor.hasNext());
}
}This is how I set the redisClusterNode and redisClousterConnection fields before I pass them to the function:
RedisConnection redisConnection = Objects.requireNonNull(stringRedisTemplate.getConnectionFactory()).getConnection();
if (redisConnection instanceof RedisClusterConnection) {
RedisClusterConnection redisClusterConnection = Objects.requireNonNull(stringRedisTemplate.getConnectionFactory()).getClusterConnection();
Iterable<RedisClusterNode> redisClusterNodes = redisClusterConnection.clusterGetNodes();
StreamSupport.stream(redisClusterNodes.spliterator(), false).forEach(
(redisClusterNode) -> { scan(redisClusterNode, redisClusterConnection, scanLimit);}
);
} else {
// ...
}How things fail
Shortly after I invoke this method, I will get the following:
[redis.clients.jedis.JedisFactory] [commons-pool-evictor] ERROR - <<JedisFactory>> Error while validating pooled Jedis object.
java.lang.ClassCastException: java.util.ArrayList cannot be cast to [B
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:270) ~[jedis-3.8.0.jar:?]
at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:384) ~[jedis-3.8.0.jar:?]
at redis.clients.jedis.JedisFactory.validateObject(JedisFactory.java:214) ~[jedis-3.8.0.jar:?]
at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:745) ~[commons-pool2-2.11.1.jar:2.11.1]
at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:160) ~[commons-pool2-2.11.1.jar:2.11.1]
at org.apache.commons.pool2.impl.EvictionTimer$WeakRunner.run(EvictionTimer.java:113) ~[commons-pool2-2.11.1.jar:2.11.1]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_362]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[?:1.8.0_362]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_362]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[?:1.8.0_362]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_362]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_362]
at java.lang.Thread.run(Thread.java:750) ~[?:1.8.0_362]
The timing of this exception differs. Sometimes it shows up right away, sometimes it takes a few seconds (and iterations of the cursor).
Note that the size of the shard is big: ~90M keys.
Things I've tried successfully
- Running against a much smaller cluster (each shard with hundreds of keys)
Things I've tried without success
- Running with only one thread active in the pool.
- Running with an unlimited number of idle threads in the pool.
- Setting
scanLimitto1.
@mp911de suggested the following:
It sounds as if a cluster node connection was in use by two processes. I suggest monitoring JedisCluster's node connection pool (JedisClusterInfoCache.nodes) while your SCAN is in progress. The node in the ConnectionPool should remain acquired while your scan cursor remains open.
I've enabled breakpoints across the JedisClusterInfoCache class, and only see this method accessed by the thread that performs the scan. Then the commons-pool-evictor thread will kick in, and the exception above will surface.
So I'm afraid I'm still stuck here. Thanks in advance for any pointer you may have for me.