12. SDR 管道API-pipleline

1. Redis 的pipeline

1.1 什么是pipeline

Redis 中的pipeline 管道命令类似于批处理执行命令。 普通执行一次Redis 命令会进行一次TCP连接的创建与销毁, 执行多条Redis 命令就会进行多次TCP连接的创建与销毁, 而TCP 连接的创建与销毁时比较耗时。 采用pipeline技术, 是先将多条命令添加到队列中,然后创建一次TCP连接,将每次命令的执行结果(返回值为非void的命令)依次添加到list中,然后一次性返回,最后关闭TCP连接。

1.2 pipeline 特点

  • 一次pipeline 操作只创建和销毁一次TCP连接
  • pipeline 中的多条命令存储在一个队列中,所以命令执行是有顺序的
  • pipeline 中每条返回值不是void的命令都会返回一个结果,然后存储在List中. 纵使返回值为null
  • pipeline 中返回值为void的命令, 不会返回结果, 也就是说list中不会有此对象的返回值.
  • pipeline 中允许执行不同的命令

1.3 SDR API

SDR 提供了两中API来执行pipeline命令,区别在于对命令返回的结果进行反向序列化时,使用redisTemplate自身的valueSerializer,还是使用自定义的valueSerializer. 通常使用第一种方式即可.

API 签名方法描述
public List executePipelined(RedisCallback<?> action)执行pipeline命令,使用redisTemplate的valueSerializer对结果进行解析
public List executePipelined(RedisCallback<?> action, @Nullable RedisSerializer<?> resultSerializer)执行pipleLine命令, 使用自定义的serializer 对结果集进行解析

2. API 测试

笔者构造四条命令来测试pipeline 的执行机制:

  • 命令一返回为A, 所以list中添加第一个元素
  • 命令二返回为void,所以list中不添加
  • 命令三返回为null, 所以list中添加第二个元素,只不过值为null
  • 命令四返回为B,所以list中添加第三个元素

2.1 默认序列化方式执行pipeline

  • 笔者使用stringRedisTemplate 开启pipeline , 所以pipeline 中value序列化为stringRedisTemplate的序列化方式, 即StringRedisSerializer.
  • 每个命令返回值都会使用StringRedisSerializer进行反向序列化。
@Test
public void test() {

    // 初始化数据10条数据
    ListOperations<String, String> ops = stringRedisTemplate.opsForList();
    ops.leftPush("queue", "{\"@class\":\"org.zongf.learn.sdr.l01.UserPO\",\"username\":\"zhangsan\",\"password\":\"123456\",\"age\":20}");
    ops.leftPush("queue", "{\"@class\":\"org.zongf.learn.sdr.l01.UserPO\",\"username\":\"zhangsan\",\"password\":\"123456\",\"age\":20}\n");

    // 管道符获取命令
    List<Object> list = stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
        @Override
        public Object doInRedis(RedisConnection connection) throws DataAccessException {
            // 使用StringRedisTemplate, 可以将RedisConnection 转换为StringRedisConnection
            StringRedisConnection stringRedisConnection = (StringRedisConnection) connection;

            // 返回值为string
            stringRedisConnection.rPop("queue");

            // 返回值为void
            stringRedisConnection.slaveOfNoOne();

            // 返回值为null
            stringRedisConnection.rPop("no-exsists-queue");

            // 返回值为string
            stringRedisConnection.rPop("queue");

            return null;
        }
    });

    for (Object object : list) {
        String clz = object != null ? object.getClass().toString() : null;
        System.out.println(clz + "--> " + object);

    }
}

输出结果:

class java.lang.String--> {"@class":"org.zongf.learn.sdr.l01.UserPO","username":"zhangsan","password":"123456","age":20}
null--> null
class java.lang.String--> {"@class":"org.zongf.learn.sdr.l01.UserPO","username":"zhangsan","password":"123456","age":20}

2.2 自定义序列化方式

  • 笔者使用json 序列化工具反向解析每个命令的执行结果, 所以返回结果可以直接是List
  • 使用指定Serializer 方式API时, RedisConnection 不能再转换为StringRedisConnection
@Test
public void test2() {

    // 初始化数据10条数据
    ListOperations<String, String> ops = stringRedisTemplate.opsForList();
    ops.leftPush("queue", "{\"@class\":\"org.zongf.learn.sdr.l01.UserPO\",\"username\":\"zhangsan\",\"password\":\"123456\",\"age\":20}");
    ops.leftPush("queue", "{\"@class\":\"org.zongf.learn.sdr.l01.UserPO\",\"username\":\"zhangsan\",\"password\":\"123456\",\"age\":20}\n");

    // 管道符获取命令
    List<UserPO> list = redisTemplate.executePipelined(new RedisCallback<Object>() {
        @Override
        public Object doInRedis(RedisConnection connection) throws DataAccessException {

            // 返回值为string
            connection.rPop("queue".getBytes());

            // 返回值为void
            connection.slaveOfNoOne();

            // 返回值为null
            connection.rPop("no-exsists-queue".getBytes());

            // 返回值为string
            connection.rPop("queue".getBytes());

            return null;
        }
    }, new GenericJackson2JsonRedisSerializer());

    System.out.println("result:" + list);
}

输出结果:

class org.zongf.learn.sdr.l01.UserPO--> UserPO{username='zhangsan', password='123456', age=20}
null--> null
class org.zongf.learn.sdr.l01.UserPO--> UserPO{username='zhangsan', password='123456', age=20}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值