Skip to main content

One post tagged with "中间件"

View All Tags

· 4 min read
天山飞猫

前一阵发现了一个号称比Redis性能高25倍的新内存数据库出现了,叫 Dragonfly

而且他还全面支持redis的api,今天终于有空了,把这个新玩具跑起来看看,是不是真的和他说的一样。

0. 部署

直接Docker部署还是很方便的。我本机为了测试和开发方便,都是用docker-compose管理的。大概这样: docker-compose.yml

version: '3'
services:
mysql:
image: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456
volumes:
- d:\\Dockers\\Mysql8:/var/lib/mysql
- d:\\Dockers\\Mysql-files:/var/lib/mysql-files
ports:
- 3306:3306
redis:
restart: always
image: redis
ports:
- 6379:6379
dragonfly:
restart: always
image: docker.dragonflydb.io/dragonflydb/dragonfly
ports:
- 6378:6379
rabbitmq:
image: mayan31370/docker-image-rabbitmq:delayed-exchange_stomp
restart: always
ports:
- 5672:5672
- 15672:15672
- 61613:61613
mongo:
restart: always
image: mongo

1. 用JMH测试一波试试

建了一个简单的JMH项目,写了一下测试


import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;

@State(Scope.Benchmark)
public class MyBenchmark {

private StatefulRedisConnection<String, String> redisConnection;
private StatefulRedisConnection<String, String> dragonflyConnection;

@Setup(Level.Trial)
public void init() {
redisConnection = RedisClient.create(
RedisURI.builder().withHost("localhost").withPort(6379).build()).connect();
dragonflyConnection = RedisClient.create(
RedisURI.builder().withHost("localhost").withPort(6378).build()).connect();
}

@Benchmark
@BenchmarkMode(Mode.Throughput)
public void testRedisOpsForValue() {
redisConnection.sync().set("a","1");
redisConnection.sync().get("a");
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void testDragonflyOpsForValue() {
dragonflyConnection.sync().set("a","1");
dragonflyConnection.sync().get("a");
}

@Benchmark
@BenchmarkMode(Mode.Throughput)
public void testRedisOpsForHash() {
redisConnection.sync().hset("b","b","1");
redisConnection.sync().hget("b","b");
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void testDragonflyOpsForHash() {
dragonflyConnection.sync().hset("b","b","1");
dragonflyConnection.sync().hget("b","b");
}
@TearDown(Level.Trial)
public void finish() {
redisConnection.close();
dragonflyConnection.close();
}
}

2. 结果分析

BenchmarkModeCntScoreErrorUnits
MyBenchmark.testDragonflyOpsForHashthrpt153966.922±866.481ops/s
MyBenchmark.testDragonflyOpsForValuethrpt153904.415±955.113ops/s
MyBenchmark.testRedisOpsForHashthrpt156836.774±615.484ops/s
MyBenchmark.testRedisOpsForValuethrpt156940.175±602.979ops/s

这里用了同步操作,只能看出两个速度差不多,甚至redis在单线程上的性能更加的优秀

通过redis-cli查看内存使用情况,也是redis更胜一筹。 Dragonfly会比Redis多占用30%的内存。

3. 使用 memtier_benchmark 来进行并发测试

memtier_benchmark 是一个由Redis Labs开发的命令行工具,专门用来测试非关系型键值对的数据库的性能。 转送门:https://github.com/RedisLabs/memtier_benchmark 按照README指引,一路操作即可,我是用的win10的WSL2中的ubuntu22.04,你呢?

1          Threads
30 Connections per thread
20000 Requests per client

Set key value

Redis

CMDOps/secAvg. Latencyp99 Latencyp99.99 LatencyKB/sec
Set19591.091.548033.0230010.87900707.88
HSet19206.981.560392.799006.015001198.26
SAdd19053.651.572932.975008.383001002.62
LUA18514.211.618502.911007.135001120.98

Dragonfly

CMDOps/secAvg. Latencyp99 Latencyp99.99 LatencyKB/sec
Set16645.991.762233.215009.47100601.47
HSet16178.981.847373.7590012.607001009.35
SAdd16709.351.818623.3910012.15900879.26
LUA569.6053.0916861.1830070.6550034.49

不知道是我配置的原因,还是Dragonfly只在高配服务器上有更加优秀的表现,这个有待进一步的测试,就我的开发环境,还是老实用Redis吧。 尤其lua脚本的执行效率,实在有点令人发指。