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.
This commit is contained in:
Conrad 2015-07-27 08:47:40 -04:00
parent 727427165f
commit 421eb12228
1 changed files with 45 additions and 22 deletions

View File

@ -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<String, JedisPool> _pools = new ConcurrentHashMap<String, JedisPool>();
// 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();
}
}