应用缓存与同机部署的Redis缓存性能对比

背景

有相当一部分开发同学认为,有了Redis就没必要使用应用缓存。这其实是相当错误的观念。
为了验证,我通过基于JMH基准测试工具,对应用内存操作及同一台机器上的Redis进行操作进行性能对比。通过实际结果来展示两者的性能差距。

测试平台

软件

java version "11.0.16" 2022-07-19 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.16+11-LTS-199)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.16+11-LTS-199, mixed mode)
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jmh.version>1.36</jmh.version>
    </properties>
    
 <dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson</artifactId>
      <version>3.20.0</version>
  </dependency>
   <dependency>
       <groupId>org.openjdk.jmh</groupId>
       <artifactId>jmh-core</artifactId>
       <version>${jmh.version}</version>
   </dependency>
   <dependency>
       <groupId>org.openjdk.jmh</groupId>
       <artifactId>jmh-generator-annprocess</artifactId>
       <version>${jmh.version}</version>
   </dependency>

硬件

在这里插入图片描述

# sysctl machdep.cpu
machdep.cpu.cores_per_package: 10
machdep.cpu.core_count: 10
machdep.cpu.logical_per_package: 10
machdep.cpu.thread_count: 10
machdep.cpu.brand_string: Apple M1 Pro

测试结果

应用缓存的测试结果

Benchmark                                                Mode     Cnt       Score   Error   Units
MemoryBenchmark.testAtomicLong                          thrpt               0.061          ops/ns
MemoryBenchmark.testAtomicLong                           avgt              68.881           ns/op
MemoryBenchmark.testAtomicLong                         sample  168554     227.721 ± 7.093   ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.00    sample                 ≈ 0           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.50    sample             167.000           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.90    sample             375.000           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.95    sample             458.000           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.99    sample             500.000           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.999   sample            1374.000           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p0.9999  sample           30643.232           ns/op
MemoryBenchmark.testAtomicLong:testAtomicLong·p1.00    sample          279040.000           ns/op
MemoryBenchmark.testAtomicLong                             ss            1646.000           ns/op

同机Redis的测试结果

Benchmark                                               Mode    Cnt        Score      Error   Units
RedisBenchmark.testAtomicLong                          thrpt              ≈ 10⁻⁵             ops/ns
RedisBenchmark.testAtomicLong                           avgt          682971.881              ns/op
RedisBenchmark.testAtomicLong                         sample  12349   647815.826 ± 5691.209   ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.00    sample          264192.000              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.50    sample          623616.000              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.90    sample          831488.000              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.95    sample          909312.000              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.99    sample         1180672.000              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.999   sample         2361344.000              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p0.9999  sample         5163376.640              ns/op
RedisBenchmark.testAtomicLong:testAtomicLong·p1.00    sample         5169152.000              ns/op
RedisBenchmark.testAtomicLong                             ss         1994145.750              ns/op

结论

可以看到,应用内存操作AtomicLong自增,平均一次操作为68.881纳秒,而通过Redis进行一次操作为682971.881纳秒。耗时为10000倍,而这样的开销主要体现在网络传输上,而非Redis自身。
为此我还写了段lua脚本,测试直接以Redis Cli的方式执行100w次自增所花费的之间。

测试代码

内存代码

/**
 * @Author ZhouLiangCheng
 * @Date 2023/4/27
 * @Version 1.0
 */
@BenchmarkMode({Mode.All})
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(1)
@Warmup(iterations = 1, time = 2)
@Threads(4)
@Measurement(iterations = 1, time = 2)
@Timeout(time = 5)
public class MemoryBenchmark {

    Logger logger = LoggerFactory.getLogger(MemoryBenchmark.class);

    AtomicLong atomicLong;

    @Setup(Level.Trial)
    public void init() {
        atomicLong = new AtomicLong();
    }

    @TearDown(Level.Trial)
    public void end() {
        logger.info(atomicLong.get() + "");
    }

    @Benchmark
    public void testAtomicLong() {
        atomicLong.incrementAndGet();
    }
}

Redis测试代码

/**
 * @Author ZhouLiangCheng
 * @Date 2023/4/27
 * @Version 1.0
 */
@BenchmarkMode({Mode.All})
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(1)
@Warmup(iterations = 1, time = 2)
@Threads(4)
@Measurement(iterations = 1, time = 2)
@Timeout(time = 5)
public class RedisBenchmark {

    Logger logger = LoggerFactory.getLogger(MemoryBenchmark.class);

	RedissonClient client;

    @Setup
    public void init() {
        Config config = new Config();
        config.useSingleServer()
                .setTimeout(10000)
                .setAddress("redis://10.1.1.66:6379")
                .setDatabase(0)
                .setPassword("12345678")
                .setConnectionPoolSize(16)
                .setConnectionMinimumIdleSize(16)
        ;
        client = Redisson.create(config);
    }

    @TearDown
    public void end() {
        client.shutdown();
        RAtomicLong abc = client.getAtomicLong("a");
        logger.info(abc.get() + "");
    }

    @Benchmark
    public void testAtomicLong() {
        RAtomicLong abc = client.getAtomicLong("a");
        long l = abc.addAndGet(1);
    }
}

Lua脚本代码


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕咕咕zhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值