在一次请求中如果需要请求五次以上的redis,即便说redis的效率很高,但是网络开销也会极大的浪费效率,不满足高并发的需求。在我老大的指点下,我现在知道两种可以极大的提高redis请求效率的方式:
1. pipeline。redis支持管道操作,可以开启管道多次请求合并为一次性请求,个人理解适合一次性插入不同的数据到redis中时使用。示例代码如下:
public static void addOrgId(final String key, final Set<String> orgSet) {
if (null != orgSet && orgSet.size() > 0) {
redisConnection.execute(new RedisCallback<Void>() {
@Override
public Void doInRedis(RedisConnection connection) throws DataAccessException {
String[] orgIdArr = new String[orgSet.size()];
orgSet.toArray(orgIdArr);
byte[][] rawMember = new byte[orgIdArr.length][];
for (int i = 0; i < orgIdArr.length; i++) {
rawMember[i] = orgIdArr[i].getBytes();
}
connection.openPipeline();
connection.sAdd(keySerializer.serialize(key), rawMember);
connection.expire(keySerializer.serialize(key), 30 * 60);
connection.closePipeline();
return null;
}
});
} else {
logger.warn("{}: orgSet is empty", key);
}
}
2. lua脚本。如下图是redisTemplate的一个方法,它可以执行script的lua脚本,后面的参数是传入lua脚本中使用的,脚本是在redis端操作的可以多次查询修改比较,在我们的服务中都是一次操作。
private void initLua(DefaultRedisScript<Long> script, String luaName) {
script.setResultType(Long.class);
script.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/"+luaName+".lua")));
}
public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) {
return scriptExecutor.execute(script, keys, args);
}
这两种方法我建议第二种,lua脚本是一种高效的语言,基础的语法齐全,可以做多种操作,然后将最终结果返回。
抛砖引玉,更多的还是要靠大家去探索。