JedisCluster没有Pipeline?
2020年4月30日,Redis 6.0.0正式发布,标志着redis从此告别单线程。在此之前,在大数据生产环境中使用的是一个30个节点的Codis集群,SparkStreaming以此作为缓存,QPS高峰大概在2000w/s。
因为Codis不再更新迭代,于是在Redis 6.0.6版本发布的时候搭建了Redis Cluster,新的应用将不再使用Codis。之前连接Codis使用的Java客户端是Jedis,通过Pipeline方式批次执行命令,以此来提高效率。而Redis Cluster的客户端JedisCluster没有提供Pipeline方式,只能单条执行命令,于是开始考虑其他的Java客户端。
这里备选了两个客户端:「lettuce」和「Redisson」
pipeline原理
这里先说一下Jedis的pipeline的原理。通过pipeline对redis的所有操作命令,都会先放到一个List中,当pipeline直接执行或者通过jedis.close()调用sync()的时候,所有的命令都会一次性地发送到客户端,并且每个操作命令返回一个response,通过get来获取操作结果。
lettuce
lettuce提供了async异步方式来实现pipeline的功能,来测试一下是否可按批次处理命令。
测试代码:
public static void main(String[] args) throws Exception {
RedisURI uri = RedisURI.builder()
.withHost(“47.102.xxx.xxx”)
.withPassword(“Redis6.0.6”.toCharArray())
.withPort(10001)
.build();
RedisClusterClient client = RedisClusterClient.create(uri);
StatefulRedisClusterConnection<String, String> connect = client.connect();
RedisAdvancedClusterAsyncCommands<String, String> async = connect.async();
// 断点1
async.set(“key1”, “v1”);
Thread.sleep(1000 * 3);
// 断点2
async.set(“key2”, “v2”);
// 断点3
async.flushCommands();
Thread.sleep(1000 * 3);
connect.close();
client.shutdown();
}
在程序中设置三个断点。如果是pipeline的话,只有执行完断点3,两条set命令才会执行。运行结果:JedisCluster没有Pipeline?那就写一篇详细使用教程吧结果表明还未到flushCommands(),第一个set命令已经执行。到这你可能就会以为lettuce其实还是逐条命令执行,只是开启了异步请求模式。其实不然,在lettuce异步操作中,默认开启了「命令自动刷新」功能,所以给你的假象还是逐条执行,在此需要「禁用自动刷新」来开启pipeline功能。
在set()之前加上一行代码:
async.setAutoFlushCommands(false);
运行结果:
Redisson
redisson提供了batch来实现pipeline的功能。
测试代码:
Config config = new Config();
config.useClusterServers()
.addNodeAddress(“redis://47.102.219.86:10001”)
.setPassword(“Redis@6.0.6”);
RedissonClient redisson = Redisson.create(config);
RBatch batch = redisson.createBatch();
String key = “test”;
for (int i = 1; i < 3; i+