redis使用pipeline查询大量key

概述

redis是一个高性能的单线程的key-value数据库。它的执行过程为:

发送命令 -> 待执行队列 -> 命令执行 -> 返回结果

如果我们使用redis进行批量插入数据,正常情况下相当于将以上四个步骤批量执行N次。发送命令返回结果称为Round Trip Time(RTT,往返时间)。那要是有些场景需要批量执行一些命令,那不是GG。

所以Redis提供了pipeline管道机制,它能将一组Redis命令进行组装,通过一次RTT传输给Redis,并将这组Redis命令的执行结果按顺序返回给客户端。

但是如果一次性查询大量key,也是会堵塞在redis的,所以拆分成几个小的pipline比较合适。或者使用游标去查询数据。

注意点

  1. Pipeline是非原子的,在上面原理解析那里已经说了就是 Redis
    实际上还是一条一条的执行的,而执行命令是需要排队执行的,所以就会出现原子性问题。
  2. Pipeline中包含的命令不要包含过多。
  3. Pipeline每次只能作用在一个 Redis 节点上。
  4. Pipeline 不支持事务,因为命令是一条一条执行的。

使用demo

序列化和反序列化方式设置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public RedisTemplate<String, String> redisTemplate() {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

批量get使用demo


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class RedisClusterPipelineDemo {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public Map<String, String> executePipeline() {
        Map<String, String> resultMap = redisTemplate.executePipelined((RedisCallback<Map<String, String>>) connection -> {
            ScanOptions scanOptions = ScanOptions.scanOptions().match("key*").build();
            Cursor<byte[]> cursor = connection.scan(scanOptions);

            Map<String, String> map = new HashMap<>();
            while (cursor.hasNext()) {
                byte[] keyBytes = cursor.next();
                String key = redisTemplate.getStringSerializer().deserialize(keyBytes);
                byte[] valueBytes = connection.get(keyBytes);
                String value = redisTemplate.getStringSerializer().deserialize(valueBytes);
                map.put(key, value);
            }
            return map;
        });

        return resultMap;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值