@[toc]
基本实现对比
Jedis | Lettuce | |
---|---|---|
支持JDK版本 | JDK6+ | JDK8+ |
IO模型 | BIO | NIO(Netty) |
连接复用 | 连接池 | 单一长连接 |
线程安全 | Jedis线程不安全 | StatefulRedisConnection线程安全 |
性能对比
Redis-Server测试环境:
- 服务器配置:四核16G
- Redis版本:5.0.5
- Redis配置文件:默认配置
Redis-Client测试环境:
- 服务器配置:四核16G
- JDK版本:JDK8、基于Springboot 2.1.6.RELEASE版本的RedisTemplate测试
- Jedis连接池配置:max:50,min:10
- 测试工具:JMH(Java基准性能测试--JMH使用介绍)
如下图所示,对于各种大小value的get、set测试,二者无论是响应时间还是吞吐量,都相差不大,没有数量级的差异。(影响测试结果的因素有很多,存在一些偶然因素,所以这个结果不能说明Lettuce的响应性能就比Jedis好)
同时也能看出来随着value大小的增加,无论是吞吐量还是响应性能都急剧的下降,所以我们在开发过程中存入Redis中的数据要尽可能的小。
Jedis的基本用法
pom添加依赖
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
使用Jedis的示例代码
public class JedisSimpleUse {
private String host = "localhost";
private int port = 6379;
private String password = "password";
/**
* 直接构建Jedis实例的方式使用Jedis
*/
public void useJedis() {
//指定Redis服务Host和port, Jedis是非线程安全的,只能单个线程访问,每个线程都要单独构建Jedis对象
Jedis jedis = new Jedis(host, port);
try {
//如果Redis服务连接需要密码,指定密码
jedis.auth(password);
//访问Redis服务
String value = jedis.get("key");
} finally {
//使用完关闭连接
jedis.close();
}
}
private JedisPool jedisPool;
/**
* 初始化JedisPool
*/
public void initJedisPool() {
GenericObjectPoolConfig genericObjectPool = new GenericObjectPoolConfig();
jedisPool = new JedisPool(genericObjectPool, host, port, Protocol.DEFAULT_TIMEOUT, password);
}
/**
* 基于连接池的方式使用Jedis
*/
public void useJedisPool() {
Jedis jedis = jedisPool.getResource();
try {
//访问Redis服务
String value = jedis.get("key");
} finally {
//使用完关闭连接
jedis.close();
}
}
public static void main(String[] args) {
JedisSimpleUse jedisSimpleUse = new JedisSimpleUse();
//调用Jedis实例方法
jedisSimpleUse.useJedis();
// 初始化JedisPool,只需要初始化一次
jedisSimpleUse.initJedisPool();
// 多次基于JedisPool调用Redis
jedisSimpleUse.useJedisPool();
jedisSimpleUse.useJedisPool();
}
}
Jedis配合Springboot RedisTemplate使用
pom添加依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.6.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!--因为spring-boot-starter-data-redis默认引用了lettuce,所以需要排除lettuce-->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
application.properties配置文件
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=password
测试代码
@Component
@SpringBootApplication
public class JedisWithRedisTemplate {
/**
* SpringBoot autoconfigure在classpath中发现Jedis class会自动注入StringRedisTemplate
*/
@Autowired
StringRedisTemplate redisTemplate;
public void testRedisTemplate() {
//redisTemplate封装了对Jedis的获取和释放、并使用JedisPool连接池
redisTemplate.opsForValue().set("key", "val123");
String value = redisTemplate.opsForValue().get("key");
System.out.println("get redis value with RedisTemplate, value is :" + value);
redisTemplate.delete("key");
}
public static void main(String[] args) {
// 创建SpringApplicationContext容器
ConfigurableApplicationContext applicationContext = SpringApplication.run(JedisWithRedisTemplate.class, args);
//从容器中获取测试Bean
JedisWithRedisTemplate jedisWithRedisTemplate = applicationContext.getBean(JedisWithRedisTemplate.class);
jedisWithRedisTemplate.testRedisTemplate();
}
}
Lettuce的基本用法
pom添加依赖
<dependencies>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>
测试代码
public class LettuceSimpleUse {
private void testLettuce() throws ExecutionException, InterruptedException {
//构建RedisClient对象,RedisClient包含了Redis的基本配置信息,可以基于RedisClient创建RedisConnection
RedisClient client = RedisClient.create("redis://localhost");
//创建一个线程安全的StatefulRedisConnection,可以多线程并发对该connection操作,底层只有一个物理连接.
StatefulRedisConnection<String, String> connection = client.connect();
//获取SyncCommand。Lettuce支持SyncCommand、AsyncCommands、ActiveCommand三种command
RedisStringCommands<String, String> sync = connection.sync();
String value = sync.get("key");
System.out.println("get redis value with lettuce sync command, value is :" + value);
//获取SyncCommand。Lettuce支持SyncCommand、AsyncCommands、ActiveCommand三种command
RedisAsyncCommands<String, String> async = connection.async();
RedisFuture<String> getFuture = async.get("key");
value = getFuture.get();
System.out.println("get redis value with lettuce sync command, value is :" + value);
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
new LettuceSimpleUse().testLettuce();
}
}
Lettuce配合Springboot RedisTemplate使用
pom配置文件
<dependencies>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.6.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
application.properties
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=passwords
测试代码
@SpringBootApplication
public class LettuceWithRedisTemplate {
/**
* SpringBoot autoconfigure在classpath中发现Lettuce class会自动注入StringRedisTemplate
*/
@Autowired
StringRedisTemplate redisTemplate;
public void testRedisTemplate() {
//redisTemplate封装了对Lettuce StatefulRedisConnection的调用
redisTemplate.opsForValue().set("key", "val123");
String value = redisTemplate.opsForValue().get("key");
System.out.println("get redis value with RedisTemplate, value is :" + value);
redisTemplate.delete("key");
}
public static void main(String[] args) {
// 创建SpringApplicationContext容器
ConfigurableApplicationContext applicationContext = SpringApplication.run(LettuceWithRedisTemplate.class, args);
//从容器中获取测试Bean
LettuceWithRedisTemplate lettuceWithRedisTemplate = applicationContext.getBean(LettuceWithRedisTemplate.class);
lettuceWithRedisTemplate.testRedisTemplate();
}
}