I have had write a test program which using Jedis to read/write Redis Cluster. It create 32 threads and every thread init a instance of JedisCLuster(). But it will cost more than half minute to create total 32 JedisCluster Instances.
By tracking the problem, I found out that the bottleneck is in setNodeIfNotExist():
1 2 3 4 5 6 |
JedisCluster() --> BinaryJedisCluster() --> JedisSlotBasedConnectionHandler() --> JedisClusterInfoCache() --> discoverClusterNodesAndSlots() --> setNodeIfNotExist() |
In the method setNodeIfNotExist() of class JedisClusterInfoCache, “new JedisPool()” will cost a lot of time because it will use apache commons pool and apache-commons-pool will register MBean Server with JMX. The register operation of JMX is the bottelneck.
The first solution for this problem is to disable JMX when calling JedisCluster():
1 2 3 |
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setJmxEnabled(false); client = JedisCluster(nodesSet, poolConfig); |
The second solution is “create one JedisCluster() instance for all threads”. After I commited patch for Jedis to set JMX disable as default, Marcos Nils remind me that JedisCluster() is thread-safe, for it has using commons-pool to manage the connection resource.