dragonfly README

The project's README from github.com/dragonflydb/dragonfly. As one markdown file: README.md.

Dragonfly

ci-tests Total pulls Monthly pulls Twitter URL

Before moving on, please consider giving us a GitHub star ⭐️. Thank you!

Other languages: 简体中文 日本語 한국어 Português ภาษาไทย

Website • Docs • Quick Start • Community Discord • Dragonfly User Conference • Join the Dragonfly Community

GitHub Discussions • GitHub Issues • Contributing • AI Agents Guide • Dragonfly Cloud

The world's most efficient in-memory data store

Dragonfly is an in-memory data store built for modern application workloads.

Fully compatible with Redis and Memcached APIs, Dragonfly requires no code changes to adopt. Compared to legacy in-memory datastores, Dragonfly delivers 25X more throughput, higher cache hit rates with lower tail latency, and can run on up to 80% less resources for the same sized workload.

Contents

Benchmarks

We first compare Dragonfly with Redis on m5.large instance which is commonly used to run Redis due to its single-threaded architecture. The benchmark program runs from another load-test instance (c5n) in the same AZ using memtier_benchmark -c 20 --test-time 100 -t 4 -d 256 --distinct-client-seed

Dragonfly shows a comparable performance:

  1. SETs (--ratio 1:0):
Redis DF
QPS: 159K, P99.9: 1.16ms, P99: 0.82ms QPS:173K, P99.9: 1.26ms, P99: 0.9ms
  1. GETs (--ratio 0:1):
Redis DF
QPS: 194K, P99.9: 0.8ms, P99: 0.65ms QPS: 191K, P99.9: 0.95ms, P99: 0.8ms

The benchmark above shows that the algorithmic layer inside DF that allows it to scale vertically does not take a large toll when running single-threaded.

However, if we take a bit stronger instance (m5.xlarge), the gap between DF and Redis starts growing. (memtier_benchmark -c 20 --test-time 100 -t 6 -d 256 --distinct-client-seed):

  1. SETs (--ratio 1:0):
Redis DF
QPS: 190K, P99.9: 2.45ms, P99: 0.97ms QPS: 279K , P99.9: 1.95ms, P99: 1.48ms
  1. GETs (--ratio 0:1):
Redis DF
QPS: 220K, P99.9: 0.98ms , P99: 0.8ms QPS: 305K, P99.9: 1.03ms, P99: 0.87ms

Dragonfly throughput capacity continues to grow with instance size, while single-threaded Redis is bottlenecked on CPU and reaches local maxima in terms of performance.

If we compare Dragonfly and Redis on the most network-capable instance c6gn.16xlarge, Dragonfly showed a 25X increase in throughput compared to Redis single process, crossing 3.8M QPS.

Dragonfly's 99th percentile latency metrics at its peak throughput:

op r6g c6gn c7g
set 0.8ms 1ms 1ms
get 0.9ms 0.9ms 0.8ms
setex 0.9ms 1.1ms 1.3ms

All benchmarks were performed using memtier_benchmark (see below) with number of threads tuned per server and instance type. memtier was run on a separate c6gn.16xlarge machine. We set the expiry time to 500 for the SETEX benchmark to ensure it would survive the end of the test.

  memtier_benchmark --ratio ... -t <threads> -c 30 -n 200000 --distinct-client-seed -d 256 \
     --expiry-range=...

In pipeline mode --pipeline=30, Dragonfly reaches 10M QPS for SET and 15M QPS for GET operations.

Dragonfly vs. Memcached

We compared Dragonfly with Memcached on a c6gn.16xlarge instance on AWS.

With a comparable latency, Dragonfly throughput outperformed Memcached throughput in both write and read workloads. Dragonfly demonstrated better latency in write workloads due to contention on the write path in Memcached.

SET benchmark

Server QPS(thousands qps) latency 99% 99.9%
Dragonfly 🟩 3844 🟩 0.9ms 🟩 2.4ms
Memcached 806 1.6ms 3.2ms

GET benchmark

Server QPS(thousands qps) latency 99% 99.9%
Dragonfly 🟩 3717 1ms 2.4ms
Memcached 2100 🟩 0.34ms 🟩 0.6ms

Memcached exhibited lower latency for the read benchmark, but also lower throughput.

Memory efficiency

To test memory efficiency, we filled Dragonfly and Redis with ~5GB of data using the debug populate 5000000 key 1024 command, sent update traffic with memtier, and kicked off the snapshotting with the bgsave command.

This figure demonstrates how each server behaved in terms of memory efficiency.

Dragonfly was 30% more memory efficient than Redis in the idle state and did not show any visible increase in memory use during the snapshot phase. At peak, Redis memory use increased to almost 3X that of Dragonfly.

Dragonfly finished the snapshot faster, within a few seconds.

For more info about memory efficiency in Dragonfly, see our Dashtable doc.

Configuration

Dragonfly supports common Redis arguments where applicable. For example, you can run: dragonfly --requirepass=foo --bind localhost.

Dragonfly currently supports the following Redis-specific arguments:

There are also some Dragonfly-specific arguments:

./dragonfly-x86_64 --logtostderr --requirepass=youshallnotpass --cache_mode=true -dbnum 1 --bind localhost --port 6379 --maxmemory=12gb --keys_output_limit=12288 --dbfilename dump.rdb

Arguments can be also provided via:

For more options like logs management or TLS support, run dragonfly --help.

Design decisions

Novel cache design

Dragonfly has a single, unified, adaptive caching algorithm that is simple and memory efficient.

You can enable caching mode by passing the --cache_mode=true flag. Once this mode is on, Dragonfly will evict items least likely to be stumbled upon in the future but only when it is near the maxmemory limit.

Expiration deadlines with relative accuracy

Expiration ranges are limited to ~8 years.

Expiration deadlines with millisecond precision (PEXPIRE, PSETEX, etc.) are rounded to the closest second for deadlines greater than 2^28ms, which has less than 0.001% error and should be acceptable for large ranges. If this is not suitable for your use case, get in touch or open an issue explaining your case.

For more detailed differences between Dragonfly expiration deadlines and Redis implementations, see here.

Native HTTP console and Prometheus-compatible metrics

By default, Dragonfly allows HTTP access via its main TCP port (6379). That's right, you can connect to Dragonfly via Redis protocol and via HTTP protocol — the server recognizes the protocol automatically during the connection initiation. Go ahead and try it with your browser. HTTP access currently does not have much info but will include useful debugging and management info in the future.

Go to the URL :6379/metrics to view Prometheus-compatible metrics.

The Prometheus exported metrics are compatible with the Grafana dashboard, see here.

Important! The HTTP console is meant to be accessed within a safe network. If you expose Dragonfly's TCP port externally, we advise you to disable the console with --http_admin_console=false or --nohttp_admin_console.

Background

Dragonfly started as an experiment to see how an in-memory datastore could look if it was designed in 2022. Based on lessons learned from our experience as users of memory stores and engineers who worked for cloud companies, we knew that we need to preserve two key properties for Dragonfly: Atomicity guarantees for all operations and low, sub-millisecond latency over very high throughput.

Our first challenge was how to fully utilize CPU, memory, and I/O resources using servers that are available today in public clouds. To solve this, we use shared-nothing architecture, which allows us to partition the keyspace of the memory store between threads so that each thread can manage its own slice of dictionary data. We call these slices "shards". The library that powers thread and I/O management for shared-nothing architecture is open-sourced here.

To provide atomicity guarantees for multi-key operations, we use the advancements from recent academic research. We chose the paper "VLL: a lock manager redesign for main memory database systems” to develop the transactional framework for Dragonfly. The choice of shared-nothing architecture and VLL allowed us to compose atomic multi-key operations without using mutexes or spinlocks. This was a major milestone for our PoC and its performance stood out from other commercial and open-source solutions.

Our second challenge was to engineer more efficient data structures for the new store. To achieve this goal, we based our core hashtable structure on the paper "Dash: Scalable Hashing on Persistent Memory". The paper itself is centered around the persistent memory domain and is not directly related to main-memory stores, but it's still most applicable to our problem. The hashtable design suggested in the paper allowed us to maintain two special properties that are present in the Redis dictionary: The incremental hashing ability during datastore growth the ability to traverse the dictionary under changes using a stateless scan operation. In addition to these two properties, Dash is more efficient in CPU and memory use. By leveraging Dash's design, we were able to innovate further with the following features:

Once we had built the foundation for Dragonfly and we were happy with its performance, we went on to implement the Redis and Memcached functionality. We have to date implemented ~185 Redis commands (roughly equivalent to Redis 5.0 API) and 13 Memcached commands.

And finally,
Our mission is to build a well-designed, ultra-fast, cost-efficient in-memory datastore for cloud workloads that takes advantage of the latest hardware advancements. We intend to address the pain points of current solutions while preserving their product APIs and propositions.

Contributors

Thanks to all the contributors to Dragonfly project!

dragonfly (dragonflydb/dragonfly)

Searching Database…

31.8K ·GitHub
这是什么?一个内存数据存储,定位为 Redis 和 Memcached 的现代替代品——与两者的 API 完全兼容,所以不需要改代码;官方宣称吞吐量最高提升 25 倍,资源消耗最多减少 80%。
它是像 Redis 那样独立运行的服务器,还是我嵌入到自己应用里的库?它是一个独立的服务器:应用通过标准的 Redis 协议连接 6379 端口,另外还可以通过 --memcachedport 参数额外提供一个兼容 Memcached 的 API。
我怎么把它跑起来?用快速入门里的 Docker 镜像,或者从源码构建。它的启动方式跟 Redis 一样——例如 dragonfly --requirepass=foo --bind localhost——默认监听 6379 端口。
它的行为和 Redis 完全一样吗,有没有一些特殊的坑?有几个注意点:TTL 上限约 8 年,超过 2^28 毫秒时毫秒精度会被取整;keys 命令默认最多只返回 8192 个结果;集群模式目前只是模拟实现的。
什么情况下它真的比原版 Redis 强?当单个 Redis 进程碰到 CPU 瓶颈的时候:Dragonfly 能随实例规格继续扩展——在测试过的最大实例上达到 Redis 吞吐量的 25 倍(380 万 QPS)——而且空闲时的内存占用要省大约 30%。
作者为什么要新造一个数据存储,而不是直接用 Redis?Dragonfly 最初是一个实验:如果放在 2022 年从头设计,一个内存数据存储会是什么样子?目标是既保留原子性保证和亚毫秒级延迟,又能充分利用现代多核服务器——它采用 shared-nothing 架构,每个线程独占键空间的一个分片,多键事务基于 VLL 论文实现为无锁设计,哈希表则基于 Dash 论文。
把它直接暴露到公网上安全吗?要小心:主 TCP 端口(6379)上默认开启了一个 HTTP 控制台。如果要把 Dragonfly 暴露到外部,请用 --httpadminconsole=false 把它关掉,并通过 --requirepass 设置密码。
我能用现有的工具监控它吗?可以——把 Prometheus 或浏览器指向 :6379/metrics:Dragonfly 在主端口上直接提供兼容 Prometheus 的指标,这些指标也能配合 Grafana 面板使用。
它支持像 Memcached 那样的缓存淘汰吗?支持,用的是一套自适应的缓存算法:以 --cachemode=true 启动,Dragonfly 会优先淘汰最不可能再被用到的数据,但只在接近 maxmemory 上限时才会开始淘汰。
备份和快照是怎么工作的?用 bgsave 手动触发快照,或者把 snapshotcron 设成标准的 cron 表达式来做定时备份。快照过程很省内存:测试中 Dragonfly 在快照期间内存几乎没有明显增长,而 Redis 会飙升到接近 3 倍。
What are similar projects?redis, phpredis, kividb, valkey, dicedb, KeyDB, garnet, rocksdb
Size
31.9 MB
Stars
31.8K
Age
4y
Commits · 90 Days