Redis客户端Lettuce和Jedis对比
bigegpt 2024-11-21 10:40 36 浏览
随着SpringBoot版本迭代更新,关联的redis客户端也发生相应的变化。SpringBoot 1.5.x版本默认的Redis客户端为Jedis。SpringBoot 2.x版本默认的Redis客户端为Lettuce。
Redis两大客户端的区别
Lettuce | Jedis | |
作用 | 连接 Redis Server的客户端 | 连接 Redis Server的客户端 |
连接方式 | (1)基于Netty框架实现NIO和线程安全的客户端。(2)多个线程共享一个RedisConnection连接, 它基于Netty NIO 框架来高效地管理多个连接,从而提供了异步和同步数据访问方式,用于构建非阻塞的反应性应用程序 | Jedis 在实现上是直连 redis server,多线程环境下非线程安全,除非使用连接池,为每个 redis实例增加物理连接 |
版本 | SpringBoot 2.x版本默认使用 | SpringBoot 1.5.x版本默认使用 |
客户端直连和连接池连接的区别
直连:客户端连接redis使用的是TCP协议,每次直连都会建立TCP连接。
连接池:连接池的方式是可以预先初始化好客户端连接,所以每次只需要从连接池借用即可,而借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。
优点 | 缺点 | |
直连方式 | 简单方便,适用于少量长期连接的场景 | (1)物理连接,每次直连都会建立TCP连接,而TCP连接的新建和关闭开销较大 (2)Jedis对象线程不安全 |
连接池方式 | (1)无需每次连接生成Jedis对象,降低开销 (2) 使用连接池的形式保护和控制资源的使用 (3)线程安全 | 使用比起直连较麻烦 |
使用方式区别
1.通过Jedis客户端来连接redis服务器
引入jar包
注意:由于SpringBoot2.x版本 spring-boot-starter-data-redis默认集成Lettcue作为redis客户端,如果需要使用jedis作为客户端,需要排除lettuce。
<!--redis starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!--排除lettuce客户端-->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--jedis客户端-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
application.yml配置文件配置服务器信息以及连接池。
redis: # redis
host: localhost
port: 6379
password:
jedis: # jedis客户端连接池
pool:
max-idle: 8
max-active: 8
min-idle: 1
max-wait: 1000
jedis直连方式(没有配置连接池):
@Configuration
public class JedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.password}")
private String password;
@Bean
public JedisConnectionFactory jedisConnectionFactory(){
// 使用Standalone模式配置环境,SpringBoot2.0版本之后推荐使用Standalone(单机版)、Sentinel、RedisCluster(集群)模式之一配置环境类
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(password);
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
@Bean
public StringRedisTemplate redisTemplate(){
return new StringRedisTemplate(jedisConnectionFactory());
}
}
Jedis配置连接池JedisPoolConfig
@Configuration
public class JedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.jedis.pool.max-idle}")
private Integer maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private Integer minIdle;
@Value("${spring.redis.jedis.pool.max-active}")
private Integer maxActive;
@Value("${spring.redis.jedis.pool.max-wait}")
private Integer maxWait;
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
// 使用Standalone模式配置环境,SpringBoot2.0版本之后推荐使用Standalone、Sentinel、RedisCluster模式之一配置环境类
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(password);
// 由于JedisConnectionFactory没有提供redisStandaloneConfiguration和jedisConfig的构造方法,需要自己构造
// 获得默认的连接池构造器
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
// 指定jedisPoolConfig来修改默认的连接池构造器
jpcb.poolConfig(jedisPoolConfig);
// 通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
// 单机配置 + 客户端配置 = jedis连接工厂
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
@Bean
public StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
return new StringRedisTemplate(redisConnectionFactory);
}
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMaxWaitMillis(maxWait);
return jedisPoolConfig;
}
}
使用方式:直接注入StringRedisTemplate到容器中即可。
2.通过Lettuce客户端连接redis服务器
引入jar包
<!--spring boot 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>
yml配置
redis: # redis
host: localhost
port: 6379
password:
lettuce:
pool:
min-idle: 2
max-idle: 8
max-active: 8
max-wait: 1000
由于SpringBoot2.0版本之后默认集成Lettuce为redis的客户端,其配置信息会自动加载到连接工厂LettuceConnectionFactory,它是RedisConnectionFactory的实现类。
@Configuration
public class RedisLettuceConfig {
/**
* 默认情况下的模板只能支持 RedisTemplate<String,String>,只能存入字符串
* 因此,我们需要自定义RedisTemplate,设置序列化器,这样我们可以很方便的操作实例对象
* @param connectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory connectionFactory){
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
// 设置key序列化为string
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置value序列化为json
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 设置hash key序列化为string
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 设置hash value序列化为json
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
// 设置redis连接工厂,在配置文件里面已配置好,SpringBoot2.x版本会自动读取对应的参数
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
调用的时候直接注入RedisTemplate到容器中即可,注意:如果value是实体类,需要实现序列化Serializable
问题总结
问题1:Lettuce连接池数量为什么为1?
lettuce默认关闭了多个连接池,默认只有一个,在多线程下共用一个连接,线程安全。
问题2:如何让连接池中minIdle生效?
需要设置timeBetweenEvictionRunsMillis属性为正数。lettuce连接池属性timeBetweenEvictionRunsMillis如果不设置 默认是 -1,当该属性值为负值时,lettuce连接池要维护的最小空闲连接数的目标minIdle就不会生效
问题3:shareNativeConnection属性作用是什么?
factory.setShareNativeConnection(true),shareNativeConnection 这个属性默认是true,允许多个连接公用一个物理连接。如果设置false ,每一个连接的操作都会开启和关闭socket连接。如果设置为false,会导致性能下降
问题4:validateConnection属性作用是什么?
validateConnection这个属性是每次获取连接时,校验连接是否可用。默认false,不去校验。默认情况下,lettuce开启一个共享的物理连接,是一个长连接,所以默认情况下是不会校验连接是否可用的。如果设置true,会导致性能下降。
问题5:选择客户端的注意事项?
- 如果使用Jedis客户端,需要排除Lettuce客户端,并导入jedis依赖,最重要的是需要配置连接池,需要在配置类里进行配置并注入到Spring容器中。
- 如果使用Lettuce客户端,需要导入Lettuce依赖的连接池commons-pool,连接池的数量默认为1。
相关推荐
- 悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)
-
新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...
- 高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源
-
凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...
- 微服务架构实战:商家管理后台与sso设计,SSO客户端设计
-
SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...
- 还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑
-
在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...
- Seata源码—6.Seata AT模式的数据源代理二
-
大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...
- 30分钟了解K8S(30分钟了解微积分)
-
微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...
- SpringBoot条件化配置(@Conditional)全面解析与实战指南
-
一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...
- 一招解决所有依赖冲突(克服依赖)
-
背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...
- 你读过Mybatis的源码?说说它用到了几种设计模式
-
学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...
- golang对接阿里云私有Bucket上传图片、授权访问图片
-
1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...
- spring中的资源的加载(spring加载原理)
-
最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...
- Android资源使用(android资源文件)
-
Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...
- 如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)
-
深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...
- @Autowired与@Resource原理知识点详解
-
springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...
- java的redis连接工具篇(java redis client)
-
在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)