【笔记】百万并发-RedisTemplate压测

服务端准备

虚拟机规格

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次/秒

猜你喜欢

转载自blog.csdn.net/shumeizwb/article/details/140895008