RedisTemplate使用PipeLine的总结

最近做一个统计项目,数据量非常大,之前使用scan命令对redis中指定key进行扫描,效率较低可以忽略,但是tcp连接的time-wait不一会就超过了几万,对性能造成了极大的浪费同时执行时间也很慢,而且当数据量进一步增大可能会影响其他服务。为了减少tcp连接数量,将redis的scan修改为pipeLine操作。

本文使用的是RedisTemplate调用execute,connection使用的redis原生的操作,这里简单使用了zCount来计算keys中集合数据的长度。获取结果为result,这里要使用pipeline需要调用Connection.openPipeline()。Connection.closePipeline()返回值为List<Object>是执行后的结果。

 redisTemplate.execute(new RedisCallback<Long>() {
            @Nullable
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();
                for (int i = 0; i < 1000000; i++) {
                    String key = "123" + i;
                    connection.zCount(key.getBytes(), 0,Integer.MAX_VALUE);
                }
                List<Object> result=connection.closePipeline();
                return null;
            }
        });

如果要获取返回值,我们可以调用如下代码executePipelined,这样就可以返回我们需要的结果,下面我们可以对list进行操作。

 List<Long> List = redisTemplate.executePipelined(new RedisCallback<Long>() {
            @Nullable
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();
               for (int i = 0; i < 1000000; i++) {
                    String key = "123" + i;
                    connection.zCount(key.getBytes(), 0,Integer.MAX_VALUE);
                }
                return null;
            }
        });

在这里需要注意4点内容:

1.connection的返回结果是基本上是byte数组,如果需要存储的数据,需要对byte[]数组反序列化。

2.在doInRedis中返回值必须返回为null,为什么返回为空可以定位到内部代码去查看,这里不再赘述。

3. connection.openPipeline()可以调用,也可以不调用,但是connection.closePipeline()最好不调用,调用了拿不到返回值,因为调用的时候会直接将结果返回,同时还不会对代码进行反序列化。

4.反序列化需要传入反序列化对象,如下图所示,这些对象都可以进行相应的实例化。

猜你喜欢

转载自blog.csdn.net/xiaoliu598906167/article/details/82218525