我正在尝试在我的redis数据存储上进行多次获取,该存储分布在多个分片上。但是,我想要执行此操作的键不属于同一个分片,因此我无法使用redis'内置的multi-get。
相反,我试图用期货来实现这一目标。但是在检查查找时间之后,几乎看起来这些缓存调用都是串行进行的。
服务器上的请求/秒约为1.5k,响应时间平均为10 ms。我读过的文献告诉我,我的线程池大小应该是request / sec *响应时间。由于我正在产生3个线程,因此它变为1500 * 0.010 * 3 = 45.我尝试使用50,100,300的线程池大小。但这也没有帮助。
我正在使用Jedis作为客户端。我认为这可能是超出Jedis的最大总/空闲连接限制的问题。但即使将此值从8增加到24,我发现查找时间没有差异。
我知道会有一些开销,因为会有上下文切换和产生新线程的开销。
任何人都可以帮我弄清楚我错过的地方。如果您需要更多信息,请告诉我。
for(String recordKey : pidArr) {
//Adding futures. Max 3
if(count >= 3) {
break;
}
count++;
Callable<String> a = new FeedCacheCaller(recordKey);
Future<String> future = feedThreadPool.submit(a);
futureList.add(future);
}
//Getting the data from the futures
for(Future<String> foo : futureList) {
try {
String data = foo.get();
logger.debug(data);
feedDataList.add(parseInfo(data));
} catch (Exception e) {
logger.error("somethings going wrong in retrieval",e);
}
}
这是Callable类
公共类FeedCacheCaller实现Callable {
String pid = null;
FeedCache feedCache;
public FeedCacheCaller(String pid) {
this.pid = pid;
this.feedCache = new FeedCache();
}
@Override
public String call() throws Exception {
return feedCache.get(pid);
}
}
编辑1:
这是Jedis的侧面代码。
public class FeedCache {
private ShardedJedisPool feedClient = RedisPool.getPool("feed");
public String get(String key) {
ShardedJedis client = null;
String value = null;
try {
client = feedClient.getResource();
byte[] valueByteArray = client.get(key.getBytes(Constants.CHARSET));
if (valueByteArray != null) {
value = new String(CacheUtils.decompress(valueByteArray),
Constants.CHARSET);
}
} catch (JedisConnectionException e) {
if (client != null) {
feedClient.returnBrokenResource(client);
client = null;
}
logger.error(e.getMessage());
} finally {
if (client != null) {
feedClient.returnResource(client);
}
}
return value;
}
}
以下是初始化ShardedJedisPool
的代码public class RedisPool {
private static final Logger logger = LoggerFactory.getLogger(
RedisPool.class);
private static ConcurrentHashMap<String, ShardedJedisPool> redisPools = new ConcurrentHashMap<String, ShardedJedisPool>();
public static void initializePool(String poolName) {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
ArrayList<String> servers = new ArrayList<String>(Arrays.asList(
Constants.config.getStringArray(
poolName + "_redis_servers")));
for (int i = 0; i < servers.size(); i++) {
JedisShardInfo shardInfo = new JedisShardInfo(servers.get(i).split(":")[0], Integer.parseInt(servers.get(i).split(":")[1]));
shards.add(shardInfo);
}
redisPools.putIfAbsent(poolName,
new ShardedJedisPool(new GenericObjectPoolConfig(), shards));
}
public static ShardedJedisPool getPool(String poolName) {
if (!redisPools.containsKey(poolName)) {
synchronized (RedisPool.class) {
if (!redisPools.containsKey(poolName)) {
initializePool(poolName);
}
}
}
return redisPools.get(poolName);
}
public static void shutdown(String poolName) {
ShardedJedisPool pool = getPool(poolName);
pool.destroy();
redisPools.remove(poolName);
}
public static void main(String args[]) {
initializePool("vizidtoud");
}
}