spring-data-redis-客户端,配置,序列化,Pipeline管道

客户端

1. jedis

  1. Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等
  2. 在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推荐使用Jedis和Redisson
  3. Jedis同样也是托管在github上,地址:GitHub - redis/jedis: Redis Java client
  4. Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个 Jedis实例增加物理连接,官方推荐

2. Lettuce

  • Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisCon最ection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
  • 在SpringBoot Data Redis1.X之前默认使用的是Jedis,但目前最新版的修改成了Lettuce。

Jedis

Spring Data Redis 版本 Jedis 版本

1.7.x 2.9.0

2.0.x 2.9.0

2.1.x 2.9.0

2.2.x 3.2.0

2.3.x 3.2.0

2.4.x 3.6.0

Spring Data Redis

#最大活动对象数     
redis.pool.maxTotal=1000    
#最大能够保持idel状态的对象数      
redis.pool.maxIdle=100  
#最小能够保持idel状态的对象数   
redis.pool.minIdle=50    
#当池内没有返回对象时,最大等待时间    
redis.pool.maxWaitMillis=10000    
#当调用borrow Object方法时,是否进行有效性检查    
redis.pool.testOnBorrow=true    
#当调用return Object方法时,是否进行有效性检查    
redis.pool.testOnReturn=true  
#“空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1.  
redis.pool.timeBetweenEvictionRunsMillis=30000  
#向调用者输出“链接”对象时,是否检测它的空闲超时;  
redis.pool.testWhileIdle=true  
# 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3.  
redis.pool.numTestsPerEvictionRun=50  
#redis服务器的IP    
redis.ip=xxxxxx  
#redis服务器的Port    
redis1.port=6379   

引入配置

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-pool2</artifactId>
</dependency>
spring:
  data:
    redis:
      host: 82.157.62.33
      password: du123
      port: 6899
      database: 8
      lettuce:
        pool:
          max-active: 30
          max-idle: 10
          max-wait: 12
          min-idle: 3
  # 释放连接的扫描间隔(毫秒)
          time-between-eviction-runs: 3000
          enabled: true

序列化

默认使用 jdk 序列化 二进制

1. 对象必须实现序列化接口

2. 默认使用的JDK的序列化

RedisDemoBean redisDemoBean = new RedisDemoBean();
redisDemoBean.setAa("ss");
redisDemoBean.setTrh("dd");
redisTemplate.opsForValue().set("dd",redisDemoBean);

配置序列化

@Configuration
public class RedisTemplateConfiguration {

    @Bean("redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(objectMapper, Object.class);

        // 设置key和value的序列化规则
        redisTemplate.setValueSerializer(objectJackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(objectJackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

@SpringBootTest
public class JsonTest {

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Test
    public void redisTempTestMy(){
        UserBean build = UserBean.builder().age(11).password("oo").name("ddd").build();
        redisTemplate.opsForValue().set("user007", build);

        System.out.println();
    }
}

Pipeline管道 

Rdis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。当请求进来以后,都是经过服务器进行返回,那如果服务器没有响应时,那么其他请求进入等待。这时服务器也无法处理新请求,那有没有办法解决呢?使用管道就能解决,即:将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。这种技术应用非常广泛比如MySQL的批量插入就如此

@SpringBootTest
@Slf4j
public class RestaurantTest {

  @Resource
  private RedisTemplate redisTemplate;

  @Resource
  TRestaurantsMapper tRestaurantsMapper;

  // 逐行插入
  @Test
  void testSyncForHash() {
    List<TRestaurants> restaurants = tRestaurantsMapper.selectList(null);

    TimeInterval timer = DateUtil.timer();
    restaurants.forEach(restaurant -> {
      Map<String, Object> restaurantMap = BeanUtil.beanToMap(restaurant);
      String key = "res" + restaurant.getId();
      redisTemplate.opsForHash().putAll(key, restaurantMap);
    });

    log.info("执行时间:{}", timer.intervalSecond()); // 执行时间:118957
  }

  /**
     * Pipeline 管道插入
     */
  @Test
  void testSyncForHashPipeline() {
    List<TRestaurants> restaurants = tRestaurantsMapper.selectList(null);

    TimeInterval timer = DateUtil.timer();
    List<Long> list = redisTemplate.executePipelined((RedisCallback<Long>) connection -> {
      for (TRestaurants restaurant : restaurants) {
        try {
          String key = "res" + restaurant.getId();
          Map<String, Object> restaurantMap = BeanUtil.beanToMap(restaurant);
          StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
          Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
          Map<byte[], byte[]> restaurantStringMap = Maps.newHashMap();
          restaurantMap.forEach((k, v) -> {
            restaurantStringMap.put(stringRedisSerializer.serialize(k), jackson2JsonRedisSerializer.serialize(v));
          });
          connection.hashCommands().hMSet(stringRedisSerializer.serialize(key), restaurantStringMap);
        } catch (Exception e) {
          log.info(restaurant.toString());
          continue;
        }
      }
      return null;
    });

    log.info("执行时间:{}", timer.intervalSecond());
  }

}
  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值