前一阵发现了一个号称比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. 结果分析
Benchmark | Mode | Cnt | Score | Error | Units |
---|---|---|---|---|---|
MyBenchmark.testDragonflyOpsForHash | thrpt | 15 | 3966.922 | ±866.481 | ops/s |
MyBenchmark.testDragonflyOpsForValue | thrpt | 15 | 3904.415 | ±955.113 | ops/s |
MyBenchmark.testRedisOpsForHash | thrpt | 15 | 6836.774 | ±615.484 | ops/s |
MyBenchmark.testRedisOpsForValue | thrpt | 15 | 6940.175 | ±602.979 | ops/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
CMD | Ops/sec | Avg. Latency | p99 Latency | p99.99 Latency | KB/sec |
---|---|---|---|---|---|
Set | 19591.09 | 1.54803 | 3.02300 | 10.87900 | 707.88 |
HSet | 19206.98 | 1.56039 | 2.79900 | 6.01500 | 1198.26 |
SAdd | 19053.65 | 1.57293 | 2.97500 | 8.38300 | 1002.62 |
LUA | 18514.21 | 1.61850 | 2.91100 | 7.13500 | 1120.98 |
Dragonfly
CMD | Ops/sec | Avg. Latency | p99 Latency | p99.99 Latency | KB/sec |
---|---|---|---|---|---|
Set | 16645.99 | 1.76223 | 3.21500 | 9.47100 | 601.47 |
HSet | 16178.98 | 1.84737 | 3.75900 | 12.60700 | 1009.35 |
SAdd | 16709.35 | 1.81862 | 3.39100 | 12.15900 | 879.26 |
LUA | 569.60 | 53.09168 | 61.18300 | 70.65500 | 34.49 |
不知道是我配置的原因,还是Dragonfly只在高配服务器上有更加优秀的表现,这个有待进一步的测试,就我的开发环境,还是老实用Redis吧。 尤其lua脚本的执行效率,实在有点令人发指。