From 421eb12228eeeafeb6ae72f677350a511ddde723 Mon Sep 17 00:00:00 2001 From: Conrad Date: Mon, 27 Jul 2015 08:47:40 -0400 Subject: [PATCH] Add jedis pool caching. This commit seeks to reduce the number of idle connections to redis that our code uses by making clients share thread-safe connection pools (which is the point of a connection pool). This only changes utility methods to generate and access jedis pools, and does not seek to address any issues relating to the use of the connections that may or may not be causing problems. The changes are as follows: 1. Add a static cache of all connection pools - Each connection pool is distinguished by its ip and port. Two requested connections to the same ip:port combinations will use the same connection pool. 2. Increase the max size of each pool to 20 - Overall, by having fewer idle connections, this commit should still end up with fewer connections going at any given time. 3. Make explicit setting to block while waiting for a connection - This should already be the default, but it is made explicit just in case. --- .../src/mineplex/serverdata/Utility.java | 67 +++++++++++++------ 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java index 790a2efa3..b71a39583 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java @@ -1,5 +1,7 @@ package mineplex.serverdata; +import java.util.concurrent.ConcurrentHashMap; + import mineplex.serverdata.servers.ConnectionData; import mineplex.serverdata.servers.ServerManager; import redis.clients.jedis.Jedis; @@ -15,17 +17,20 @@ import com.google.gson.GsonBuilder; * @author Ty * */ -public class Utility +public class Utility { // The Gson instance used to serialize/deserialize objects in JSON form. private static Gson _gson = new GsonBuilder().create(); public static Gson getGson() { return _gson; } - + + // map of all instantiated connection pools, distinguished by their ip:port combination + private static final ConcurrentHashMap _pools = new ConcurrentHashMap(); + // Public static jedis pool for interacting with central default jedis repo. private static JedisPool _masterPool; private static JedisPool _slavePool; - + /** * @param object - the (non-null) object to serialize * @return the serialized form of {@code object}. @@ -34,7 +39,7 @@ public class Utility { return _gson.toJson(object); } - + /** * @param serializedData - the serialized data to be deserialized * @param type - the resulting class type of the object to be deserialized @@ -44,7 +49,7 @@ public class Utility { return _gson.fromJson(serializedData, type); } - + /** * @param delimiter - the delimiter character used to separate the concatenated elements * @param elements - the set of string elements to be concatenated and returned. @@ -54,15 +59,15 @@ public class Utility { int length = elements.length; String result = length > 0 ? elements[0] : new String(); - + for (int i = 1; i < length; i++) { result += delimiter + elements[i]; } - + return result; } - + /** * @return the current timestamp (in seconds) fetched from the central jedis repository * for synced timestamps. @@ -72,7 +77,7 @@ public class Utility long currentTime = 0; JedisPool pool = getPool(false); Jedis jedis = pool.getResource(); - + try { currentTime = Long.parseLong(jedis.time().get(0)); @@ -90,10 +95,10 @@ public class Utility pool.returnResource(jedis); } } - + return currentTime; } - + /** * @return the current timestamp (in milliseconds) fetched from the central jedis repository * for synced timestamps. @@ -121,23 +126,35 @@ public class Utility pool.returnResource(jedis); } } - + return currentTime * 1000; } - + /** * @param connData - the connection data specifying the database to be connected to. * @return a newly instantiated {@link JedisPool} connected to the provided {@link ConnectionData} repository. */ public static JedisPool generatePool(ConnectionData connData) { - JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); - jedisPoolConfig.setMaxWaitMillis(1000); - jedisPoolConfig.setMinIdle(5); - jedisPoolConfig.setTestOnBorrow(true); - return new JedisPool(jedisPoolConfig, connData.getHost(), connData.getPort()); + String key = getConnKey(connData); + JedisPool pool = _pools.get(key); + if (pool == null) + { + JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); + jedisPoolConfig.setMaxWaitMillis(1000); + jedisPoolConfig.setMinIdle(5); + jedisPoolConfig.setTestOnBorrow(true); + + jedisPoolConfig.setMaxTotal(20); + jedisPoolConfig.setBlockWhenExhausted(true); + + pool = new JedisPool(jedisPoolConfig, connData.getHost(), connData.getPort()); + _pools.put(key, pool); + } + + return pool; } - + /** * @param writeable - whether or not the Jedis connections returned should be writeable to. * @return a globally available {@link JedisPool} @@ -150,7 +167,7 @@ public class Utility { _masterPool = generatePool(ServerManager.getMasterConnection()); } - + return _masterPool; } else @@ -158,11 +175,17 @@ public class Utility if (_slavePool == null) { ConnectionData slave = ServerManager.getSlaveConnection(); - + _slavePool = generatePool(slave); } - + return _slavePool; } } + + private static String getConnKey(ConnectionData connData) + { + return connData.getHost() + ":" + connData.getPort(); + } + }