@[toc]
基本實(shí)現(xiàn)對(duì)比
Jedis | Lettuce | |
---|---|---|
支持JDK版本 | JDK6+ | JDK8+ |
IO模型 | BIO | NIO(Netty) |
連接復(fù)用 | 連接池 | 單一長(zhǎng)連接 |
線(xiàn)程安全 | Jedis線(xiàn)程不安全 | StatefulRedisConnection線(xiàn)程安全 |
性能對(duì)比
Redis-Server測(cè)試環(huán)境:
- 服務(wù)器配置:四核16G
- Redis版本:5.0.5
- Redis配置文件:默認(rèn)配置
Redis-Client測(cè)試環(huán)境:
- 服務(wù)器配置:四核16G
- JDK版本:JDK8牺氨、基于Springboot 2.1.6.RELEASE版本的RedisTemplate測(cè)試
- Jedis連接池配置:max:50,min:10
- 測(cè)試工具:JMH(Java基準(zhǔn)性能測(cè)試--JMH使用介紹)
如下圖所示,對(duì)于各種大小value的get温算、set測(cè)試岗钩,二者無(wú)論是響應(yīng)時(shí)間還是吞吐量申眼,都相差不大谬晕,沒(méi)有數(shù)量級(jí)的差異宿亡。(影響測(cè)試結(jié)果的因素有很多,存在一些偶然因素彪腔,所以這個(gè)結(jié)果不能說(shuō)明Lettuce的響應(yīng)性能就比Jedis好)
同時(shí)也能看出來(lái)隨著value大小的增加侥锦,無(wú)論是吞吐量還是響應(yīng)性能都急劇的下降,所以我們?cè)陂_(kāi)發(fā)過(guò)程中存入Redis中的數(shù)據(jù)要盡可能的小德挣。
Jedis的基本用法
pom添加依賴(lài)
<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";
/**
* 直接構(gòu)建Jedis實(shí)例的方式使用Jedis
*/
public void useJedis() {
//指定Redis服務(wù)Host和port恭垦, Jedis是非線(xiàn)程安全的,只能單個(gè)線(xiàn)程訪(fǎng)問(wèn)格嗅,每個(gè)線(xiàn)程都要單獨(dú)構(gòu)建Jedis對(duì)象
Jedis jedis = new Jedis(host, port);
try {
//如果Redis服務(wù)連接需要密碼番挺,指定密碼
jedis.auth(password);
//訪(fǎng)問(wèn)Redis服務(wù)
String value = jedis.get("key");
} finally {
//使用完關(guān)閉連接
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 {
//訪(fǎng)問(wèn)Redis服務(wù)
String value = jedis.get("key");
} finally {
//使用完關(guān)閉連接
jedis.close();
}
}
public static void main(String[] args) {
JedisSimpleUse jedisSimpleUse = new JedisSimpleUse();
//調(diào)用Jedis實(shí)例方法
jedisSimpleUse.useJedis();
// 初始化JedisPool,只需要初始化一次
jedisSimpleUse.initJedisPool();
// 多次基于JedisPool調(diào)用Redis
jedisSimpleUse.useJedisPool();
jedisSimpleUse.useJedisPool();
}
}
Jedis配合Springboot RedisTemplate使用
pom添加依賴(lài)
<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>
<!--因?yàn)閟pring-boot-starter-data-redis默認(rèn)引用了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
測(cè)試代碼
@Component
@SpringBootApplication
public class JedisWithRedisTemplate {
/**
* SpringBoot autoconfigure在classpath中發(fā)現(xiàn)Jedis class會(huì)自動(dòng)注入StringRedisTemplate
*/
@Autowired
StringRedisTemplate redisTemplate;
public void testRedisTemplate() {
//redisTemplate封裝了對(duì)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) {
// 創(chuàng)建SpringApplicationContext容器
ConfigurableApplicationContext applicationContext = SpringApplication.run(JedisWithRedisTemplate.class, args);
//從容器中獲取測(cè)試Bean
JedisWithRedisTemplate jedisWithRedisTemplate = applicationContext.getBean(JedisWithRedisTemplate.class);
jedisWithRedisTemplate.testRedisTemplate();
}
}
Lettuce的基本用法
pom添加依賴(lài)
<dependencies>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>
測(cè)試代碼
public class LettuceSimpleUse {
private void testLettuce() throws ExecutionException, InterruptedException {
//構(gòu)建RedisClient對(duì)象,RedisClient包含了Redis的基本配置信息懂扼,可以基于RedisClient創(chuàng)建RedisConnection
RedisClient client = RedisClient.create("redis://localhost");
//創(chuàng)建一個(gè)線(xiàn)程安全的StatefulRedisConnection禁荸,可以多線(xiàn)程并發(fā)對(duì)該connection操作,底層只有一個(gè)物理連接.
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
測(cè)試代碼
@SpringBootApplication
public class LettuceWithRedisTemplate {
/**
* SpringBoot autoconfigure在classpath中發(fā)現(xiàn)Lettuce class會(huì)自動(dòng)注入StringRedisTemplate
*/
@Autowired
StringRedisTemplate redisTemplate;
public void testRedisTemplate() {
//redisTemplate封裝了對(duì)Lettuce StatefulRedisConnection的調(diào)用
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) {
// 創(chuàng)建SpringApplicationContext容器
ConfigurableApplicationContext applicationContext = SpringApplication.run(LettuceWithRedisTemplate.class, args);
//從容器中獲取測(cè)試Bean
LettuceWithRedisTemplate lettuceWithRedisTemplate = applicationContext.getBean(LettuceWithRedisTemplate.class);
lettuceWithRedisTemplate.testRedisTemplate();
}
}