服务端准备
虚拟机规格
redis服务启动
客户端准备
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>RedisTemplateTest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>3.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j2-impl -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.23.1</version>
<!-- <scope>test</scope>-->
</dependency>
<!-- https://mvnrepository.com/artifact/io.lettuce/lettuce-core -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.4.0.RELEASE</version>
</dependency>
</dependencies>
</project>
底层Jedis
org.example.Main
package org.example;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;
import java.util.concurrent.*;
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
public class Main {
private static final ExecutorService workder = Executors.newFixedThreadPool(1000,
(r)->{
Thread thread = new Thread(r);
thread.setName("Thread-workder-" + thread.getId());
return thread;
});
private static final ExecutorService printer = Executors.newFixedThreadPool(1,
(r)->{
Thread thread = new Thread(r);
thread.setName("Thread-printer-" + thread.getId());
return thread;
});
public static void main(String[] args) throws InterruptedException {
int requests = args.length > 0 ? Integer.parseInt(args[0]) : 1000;
// 配置Jedis连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(1000);
poolConfig.setMaxIdle(1000);
poolConfig.setMinIdle(1000);
// 创建JedisConnectionFactory
JedisConnectionFactory factory = new JedisConnectionFactory(poolConfig);
factory.setHostName("192.168.253.176");
factory.setPort(6379);
// 启动JedisConnectionFactory
factory.start();
RedisTemplate<String, Long> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
// 设置键值序列化器为字符串类型
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericToStringSerializer<>(Long.class));
redisTemplate.afterPropertiesSet();
// 存储一个字符串值
redisTemplate.opsForValue().set("count", 0L);
// 获取存储的值
Long value = redisTemplate.opsForValue().get("count");
System.out.println("获取的值: " + value);
// 设置带有过期时间的值
// redisTemplate.opsForValue().set("key2", "value2", 10, TimeUnit.SECONDS);
CountDownLatch latch = new CountDownLatch(requests);
long begin = System.currentTimeMillis();
for (int i = 0; i < requests; i++)
{
workder.execute(()->{
Long count = redisTemplate.opsForValue().increment("count", 1L);
latch.countDown();
printer.execute(()->{
if(count % 100000 == 0) {
System.out.println("count: " + count);
}
});
});
}
latch.await();
long end = System.currentTimeMillis();
long delta = end - begin;
System.out.println("总计" + requests+"次请求");
System.out.println("总计耗时" + delta + "ms");
System.out.println("平均耗时" + delta / requests + "ms");
System.out.println("QPS:" + requests * 1000L / delta);
// 检查键是否存在
// boolean exists = redisTemplate.hasKey("key1");
// System.out.println("key1 是否存在: " + exists);
System.exit(0);
}
}
底层lettuce
org.example.LettuceTest
package org.example;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class LettuceTest {
private static final ExecutorService workder = Executors.newFixedThreadPool(1000,
(r)->{
Thread thread = new Thread(r);
thread.setName("Thread-workder-" + thread.getId());
return thread;
});
private static final ExecutorService printer = Executors.newFixedThreadPool(1,
(r)->{
Thread thread = new Thread(r);
thread.setName("Thread-printer-" + thread.getId());
return thread;
});
public static void main(String[] args) throws InterruptedException {
int requests = args.length > 0 ? Integer.parseInt(args[0]) : 1000;
LettuceConnectionFactory factory = new LettuceConnectionFactory("192.168.253.176", 6379);
factory.setAutoStartup(true);
factory.setEagerInitialization(true);
factory.setShareNativeConnection(true);
factory.start();
// 创建 RedisTemplate
RedisTemplate<String, Long> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
// 配置StringRedisSerializer
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(new GenericToStringSerializer<>(Long.class));
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
redisTemplate.afterPropertiesSet(); // 重要:调用afterPropertiesSet方法以确保配置生效
// 存储一个字符串值
redisTemplate.opsForValue().set("count", 0L);
// 获取存储的值
Long value = redisTemplate.opsForValue().get("count");
System.out.println("获取的值: " + value);
// 设置带有过期时间的值
// redisTemplate.opsForValue().set("key2", "value2", 10, TimeUnit.SECONDS);
CountDownLatch latch = new CountDownLatch(requests);
long begin = System.currentTimeMillis();
for (int i = 0; i < requests; i++)
{
workder.execute(()->{
Long count = redisTemplate.opsForValue().increment("count", 1L);
latch.countDown();
printer.execute(()->{
if(count % 100000 == 0) {
System.out.println("count: " + count);
}
});
});
}
latch.await();
long end = System.currentTimeMillis();
long delta = end - begin;
System.out.println("总计" + requests+"次请求");
System.out.println("总计耗时" + delta + "ms");
System.out.println("平均耗时" + delta / requests + "ms");
System.out.println("QPS:" + requests * 1000L / delta);
// 检查键是否存在
// boolean exists = redisTemplate.hasKey("key1");
// System.out.println("key1 是否存在: " + exists);
System.exit(0);
}
}
压测结果
底层Jedis
运行参数
执行结果
QPS 11650次/秒
底层lettuce
执行参数
执行结果
QPS 110582次/秒