本文主要是介绍Lettuce和Jedis的基准测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原文链接:https://www.dubby.cn/detail.html?id=9108
1.准备工作
本地需要安装Redis,使用JMH做基准测试的框架:
<dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-core</artifactId><version>1.21</version>
</dependency>
<dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-generator-annprocess</artifactId><version>1.21</version><scope>provided</scope>
</dependency>
项目添加Jedis和Lettuce的依赖:
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version>
</dependency>
<dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>5.0.3.RELEASE</version>
</dependency>
如果你对JMH不是很熟悉,建议你去看看Code Tools: jmh,和samples 。
2.编写测试代码
2.1 Jedis
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 1)
@Threads(100)
@State(Scope.Thread)
@Measurement(iterations = 2, time = 600, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class JedisStudy {private static final int LOOP = 1;private Jedis jedis;@Setuppublic void setup() {jedis = new Jedis("127.0.0.1", 6379);}@Benchmarkpublic void get() {for (int i = 0; i < LOOP; ++i) {jedis.get("a");}}
}
public static void main(String[] args) throws RunnerException {Options options = new OptionsBuilder().include(JedisStudy.class.getSimpleName()).output("benchmark/jedis-Throughput.log").forks(1).build();new Runner(options).run();
}
这里用到的注解,其中@OutputTimeUnit(TimeUnit.MILLISECONDS)
很容易理解,就是测试结果的单位,@Threads(100)
是开启多少个线程测试;@Warmup(iterations = 1)
是预热的循环次数;@BenchmarkMode(Mode.Throughput)
是测试的模式,可以测试吞吐,延时等;@Measurement(iterations = 2, time = 600, timeUnit = TimeUnit.MILLISECONDS)
是测试的循环次数,以及时长;其中比较难以理解的就是@State(Scope.Thread)
,这里我简单描述下吧,@State(Scope.Thread)
和下面的@Setup
配合使用,意思是每个测试线程,都会使用独立的一个变量,这个变量就是Jedis jedis
,使用@Setup
所修饰的方法来做初始化。
参考JMHSample_03_States 和JMHSample_04_DefaultState 。
其中因为Jedis是线程不安全的,所以每个线程使用的都是一个单独的Jedis对象,这里可以使用Pool来优化,读者如果感兴趣,可以尝试。
2.2 Lettuce
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 1)
@Threads(100)
@State(Scope.Benchmark)
@Measurement(iterations = 2, time = 600, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class LettuceAsyncStudy {private static final int LOOP = 1;private StatefulRedisConnection<String, String> connection;@Setuppublic void setup() {RedisClient client = RedisClient.create("redis://localhost");connection = client.connect();}@Benchmarkpublic void get() throws ExecutionException, InterruptedException {RedisAsyncCommands<String, String> commands = connection.async();List<RedisFuture<String>> redisFutureList = new ArrayList<>();for (int i = 0; i < LOOP; ++i) {RedisFuture<String> future = commands.get("a");redisFutureList.add(future);future.get();}redisFutureList.forEach(f -> {try {f.get();} catch (Exception e) {e.printStackTrace();}});}
}
public static void main(String[] args) throws RunnerException {Options options = new OptionsBuilder().include(LettuceAsyncStudy.class.getSimpleName()).output("benchmark/lettuceAsync-Throughput.log").forks(1).build();new Runner(options).run();
}
这里和上面Jedis的区别就是@State(Scope.Benchmark)
,其实就是StatefulRedisConnection<String, String> connection
这个对象是所有测试线程共享的,因为Lettuce的StatefulRedisConnection是线程的安全的,所以可以这么用。
3.测试结果
Client | 线程数(并发数) | 每次测试方法里循环执行get的次数 | Throughput(ops/ms) |
---|---|---|---|
Jedis | 100 | 1 | 46.628 |
Lettuce | 100 | 1 | 106.589 |
– | – | – | – |
Jedis | 100 | 10 | 5.307 |
Lettuce | 100 | 10 | 14.802 |
– | – | – | – |
Jedis | 100 | 100 | 0.483 |
Lettuce | 100 | 100 | 1.599 |
这篇关于Lettuce和Jedis的基准测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!