一、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;
}
}
完毕!
————————————————
版权声明:本文为CSDN博主「java学僧」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ye_GuoLin/article/details/115208061