Lettuce和Jedis的基准测试

作者: 我是杨正 | 来源:发表于2018-10-14 11:11 被阅读1次

    原文链接: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;
        @Setup
        public void setup() {
            jedis = new Jedis("127.0.0.1", 6379);
        }
        @Benchmark
        public 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;
        @Setup
        public void setup() {
            RedisClient client = RedisClient.create("redis://localhost");
            connection = client.connect();
        }
        @Benchmark
        public 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的基准测试

        本文链接:https://www.haomeiwen.com/subject/irszaftx.html