springboot项目中redis客户端(Jedis、Lettuce、Redisson)

一、redis客户端的对比

1)、Jedis

Jedis作为Redis官方推荐的一款客户端,也算是简单好用,基础功能齐全,在中小型项目中还是很好用的,但是Jedis是直连模式,在多个线程间共享一个Jedis实例时是线程不安全的。
– 为啥不安全呢?不是说Redis是单线程,是世界上最安全的吗?
看官不要激动,这里说的不安全不是说Redis处理数据不安全,而是Jedis向Redis服务器提交数据和从Redis上拿数据不安全,简单阅读Jedis的源码就不难发现,在单个Jedis实例中,向Redis推数据的写流(RedisOutputStream)和从Redis获取数据的读流(RedisInputStream)都是全局属性,当多个线程同时使用这个Jedis实例,也就是说同时操作Redis的写流和读流,结果显而易见,数据会发生不可描述的奇妙融合。

– 那Jedis是不是就不能用了呢?
不是的,多个线程用一个实例会产生问题,那我们就避免这个情况呀,我们为每一个线程分配一个Jedis实例,让他们单独去操作自己的数据。一般使用JedisPoll线程池来实现。

2)、Lettuce

Lettuce也是Redis官方推荐的客户端,是一个基于netty和Reactor的可伸缩线程安全Redis客户端。Lettuce提供了同步、异步、反应式API来与Redis进行交互。和Jedis不同的是Lettuce实例是线程安全的,那就是说,多个线程可以共用一个Lettuce实例来与Redis服务端交互,当然Lettuce也支持通过增加Lettuce实例来满足项目需求。

– 是否优先使用Lettuce?
是的,一般通过springboot引入的Redis支持里面依赖的就是Lettuce。

3)、Redisson

Redisson也是Redis官方推荐的客户端。相比与前面的两种客户端,最后一种客户端想必有一部分人会很陌生。

– 引用官网来简单介绍Redisson
Redisson采用了基于NIO的Netty框架,不仅能作为Redis底层驱动客户端,具备提供对Redis各种组态形式的连接功能,对Redis命令能以同步发送、异步形式发送、异步流形式发送或管道形式发送的功能,LUA脚本执行处理,以及处理返回结果的功能,还在此基础上融入了更高级的应用方案,不但将原生的Redis Hash,List,Set,String,Geo,HyperLogLog等数据结构封装为Java里大家最熟悉的映射(Map),列表(List),集(Set),通用对象桶(Object Bucket),地理空间对象桶(Geospatial Bucket),基数估计算法(HyperLogLog)等结构,在这基础上还提供了分布式的多值映射(Multimap),本地缓存映射(LocalCachedMap),有序集(SortedSet),计分排序集(ScoredSortedSet),字典排序集(LexSortedSet),列队(Queue),阻塞队列(Blocking Queue),有界阻塞列队(Bounded Blocking Queue),双端队列(Deque),阻塞双端列队(Blocking Deque),阻塞公平列队(Blocking Fair Queue),延迟列队(Delayed Queue),布隆过滤器(Bloom Filter),原子整长形(AtomicLong),原子双精度浮点数(AtomicDouble),BitSet等Redis原本没有的分布式数据结构。不仅如此,Redisson还实现了Redis文档中提到像分布式锁Lock这样的更高阶应用场景。事实上Redisson并没有不止步于此,在分布式锁的基础上还提供了联锁(MultiLock),读写锁(ReadWriteLock),公平锁(Fair Lock),红锁(RedLock),信号量(Semaphore),可过期性信号量(PermitExpirableSemaphore)和闭锁(CountDownLatch)这些实际当中对多线程高并发应用至关重要的基本部件。正是通过实现基于Redis的高阶应用方案,使Redisson成为构建分布式系统的重要工具。
在提供这些工具的过程当中,Redisson广泛的使用了承载于Redis订阅发布功能之上的分布式话题(Topic)功能。使得即便是在复杂的分布式环境下,Redisson的各个实例仍然具有能够保持相互沟通的能力。在以这为前提下,结合了自身独有的功能完善的分布式工具,Redisson进而提供了像分布式远程服务(Remote Service),分布式执行服务(Executor Service)和分布式调度任务服务(Scheduler Service)这样适用于不同场景的分布式服务。使得Redisson成为了一个基于Redis的Java中间件(Middleware)。

总结

Jedis 和 Lettuce 是比较纯粹的 Redis 客户端,几乎没提供什么高级功能。Jedis 的性能比较差,所以如果你不需要使用 Redis 的高级功能的话,优先推荐使用 Lettuce 。

Redisson 的优势是提供了很多开箱即用的 Redis 高级功能,如果你的应用中需要使用到 Redis 的高级功能,建议使用 Redisson。在这种情况下,一般是Lettuce +Redisson一起使用。

二、springboot简单集成

1)、springboot集成Lettuce

引入依赖:

<!--redis(spring-boot-starter-data-redis中包含的Lettuce)-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--Lettuce使用线程池必要包-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

配置文件:

####################redis连接配置############
redis:
  host: 127.0.0.1
  port: 6379
  password: 123456
  database: 0
  timeout: 2000ms
  lettuce:
    pool:
      # 连接池最大连接数
      max-active: 20
      # 连接池中的最小空闲连接
      max-idle: 10
      # 连接池最大阻塞等待时间(使用负数表示没有限制,单位ms)
      max-wait: 3000

配置RedisTemplate<String, Object>:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置数据源的连接工厂(默认会传入框架中自带的(也就是读取完配置文件装配的)LettuceConnectionFactory )
        // 也可以自己定义,注入容器,再通过@Qualifier("")传进来 
        template.setConnectionFactory(factory);
        //设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
        return template;
    }
}

2)、Redisson

引入依赖:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.11.1</version>
</dependency>

配置文件:

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private String port;
    @Value("${spring.redis.password}")
    private String password;
   
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        // redis为单机模式
        config.useSingleServer()
                .setAddress("redis://" + host + ":" + port)
                .setPassword(password);
        return Redisson.create(config);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //关联
        template.setConnectionFactory(factory);
        //设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
        return template;
    }
}

完毕!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值