
Dragonfly是一種針對(duì)現(xiàn)代應(yīng)用程序負(fù)荷需求而構(gòu)建的內(nèi)存數(shù)據(jù)庫,在多線程、Shared-nothing 架構(gòu)之上實(shí)現(xiàn)了全新的算法和數(shù)據(jù)結(jié)構(gòu),單實(shí)例支持百萬 QPS。完全兼容Redis和Memcached的 API,遷移時(shí)無需修改任何代碼。相比于這些傳統(tǒng)的內(nèi)存數(shù)據(jù)庫,Dragonfly提供了其25倍的吞吐量,高緩存命中率和低尾延遲,同時(shí)Dragonfly還能輕松進(jìn)行垂直擴(kuò)展。
近日正式發(fā)布了 1.0 版本,開發(fā)團(tuán)隊(duì)稱已支持在生產(chǎn)環(huán)境使用,他們針對(duì)四個(gè)關(guān)鍵領(lǐng)域 —— 性能、擴(kuò)展性、效率和可靠性投入了大量的開發(fā)資源。
基準(zhǔn)測試

Dragonfly在c6gn.16xlarge上達(dá)到了每秒380萬個(gè)查詢(QPS),相比于Redis,吞吐量提高了25倍。
在Dragonfly的峰值吞吐量下,P99延遲如下:
| op | r6g | c6gn | c7g |
|---|---|---|---|
| set | 0.8ms | 1ms | 1ms |
| get | 0.9ms | 0.9ms | 0.8ms |
| setex | 0.9ms | 1.1ms | 1.3ms |
所有基準(zhǔn)測試均使用memtier_benchmark(見下文),根據(jù)服務(wù)器類型和實(shí)例類型調(diào)整線程數(shù)。memtier運(yùn)行在獨(dú)立的c6gn.16xlarge機(jī)器上。對(duì)于setex基準(zhǔn)測試,我們使用了500的到期范圍,以便其能夠存活直到測試結(jié)束。
memtier_benchmark --ratio ... -t <threads> -c 30 -n 200000 --distinct-client-seed -d 256 \
--expiry-range=...
當(dāng)以管道模式運(yùn)行,并設(shè)置參數(shù)--pipeline=30時(shí),Dragonfly可以實(shí)現(xiàn)10M qps的SET操作和 15M qps的GET操作。
Memcached / Dragonfly
我們?cè)?AWS 的 c6gn.16xlarge 實(shí)例上比較了 memcached 和 Dragonfly。如下圖所示,與 memcached 相比,Dragonfly 的吞吐量在讀寫兩方面上都占據(jù)了優(yōu)勢,并且在延遲方面也還不錯(cuò)。對(duì)于寫入工作,Dragonfly 的延遲更低,這是由于在 memcached 的寫入路徑上存在競爭(請(qǐng)參見此處)。
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 |
對(duì)于讀取基準(zhǔn)測試,Memcached 表現(xiàn)出了更低的延遲,但在吞吐量方面比不上Dragonfly。
內(nèi)存效率
在接下來的測試中,我們使用 debug populate 5000000 key 1024 命令向 Dragonfly 和 Redis 分別寫入了約 5GB 的數(shù)據(jù)。然后我們使用 memtier 發(fā)送更新流量并使用 "bgsave" 命令啟動(dòng)快照。下圖清楚地展示了這兩個(gè)服務(wù)器在內(nèi)存效率方面的表現(xiàn)。

在空閑狀態(tài)下,Dragonfly 比 Redis 節(jié)省約 30% 的內(nèi)存。 在快照階段,Dragonfly 也沒有顯示出任何明顯的內(nèi)存增加。 但同時(shí),Redis 在峰值時(shí)的內(nèi)存幾乎達(dá)到了 Dragonfly 的 3 倍。 Dragonfly 完成快照也很快,僅在啟動(dòng)后幾秒鐘內(nèi)就完成了。 有關(guān) Dragonfly 內(nèi)存效率的更多信息參見 dashtable 文檔。
安裝使用
使用起來很簡單,先下載軟件包,目前最新的版本是 v1.1.2
https://github.com/dragonflydb/dragonfly/releases
解壓后,linux 環(huán)境下直接執(zhí)行就行,如果報(bào)錯(cuò)缺少依賴包,根據(jù)提示安裝即可。
./dragonfly-x86_64 --logtostderr \
--requirepass=youshallnotpass --cache_mode=true \
-dbnum 1 --bind localhost --port 6379 \
--save_schedule "*:30" --maxmemory=12gb \
--keys_output_limit=12288 --dbfilename dump.rdb
目前,Dragonfly 支持以下 Redis 特定參數(shù):
-
port:Redis 連接端口,默認(rèn)為 6379。 -
bind:使用本地主機(jī)名僅允許本地連接,使用公共 IP 地址允許外部連接到該 IP 地址。 -
requirepass:AUTH 認(rèn)證密碼,默認(rèn)為空""。 -
maxmemory:限制數(shù)據(jù)庫使用的最大內(nèi)存(以字節(jié)為單位)。0 表示程序?qū)⒆詣?dòng)確定其最大內(nèi)存使用量。默認(rèn)為 0。 -
dir:默認(rèn)情況下,dragonfly docker 使用/data文件夾進(jìn)行快照。CLI 使用的是 ""。你可以使用-vdocker 選項(xiàng)將其映射到主機(jī)文件夾。 -
dbfilename:保存/加載數(shù)據(jù)庫的文件名。默認(rèn)為 "dump";
此外,還有 Dragonfly 特定的參數(shù)選項(xiàng):
memcache_port:在此端口上啟用 memcached 兼容的 API。默認(rèn)禁用。-
keys_output_limit:在keys命令中返回的最大鍵數(shù)。默認(rèn)為 8192。keys命令是危險(xiǎn)命令。我們會(huì)截?cái)嘟Y(jié)果以避免在獲取太多key時(shí)內(nèi)存溢出。 dbnum:select支持的最大數(shù)據(jù)庫數(shù)。cache_mode:請(qǐng)參見下面的 緩存 部分。hz:鍵到期評(píng)估頻率。默認(rèn)為 100??臻e時(shí),使用較低的頻率可以占用較少的 CPU資源,但這會(huì)導(dǎo)致清理過期鍵的速度下降。save_schedule:以UTC 時(shí)間規(guī)范保存快照,格式: HH:MM(24 小時(shí)制時(shí)間)。默認(rèn)為空""。primary_port_http_enabled:如果為 true,則允許在主 TCP 端口上訪問 http 控制臺(tái)。默認(rèn)為 true。admin_port:如果設(shè)置,將在指定的端口上啟用對(duì)控制臺(tái)的管理訪問。支持 HTTP 和 RESP 協(xié)議。默認(rèn)禁用。admin_bind:如果設(shè)置,將管理控制臺(tái) TCP 連接綁定到給定地址。支持 HTTP 和 RESP 協(xié)議。默認(rèn)為any。cluster_mode:支持集群模式。目前僅支持emulated。默認(rèn)為空""。cluster_announce_ip:集群模式下向客戶端公開的 IP。
添加 systemctl 管理
[Unit]
Description=dragonfly
[Service]
Type = simple
User = root
Group = root
ExecStart=/usr/local/dragonfly/dragonfly-x86_64 --logtostderr --requirepass=youshallnotpass --cache_mode=true -dbnum 1 --bind "*" --port 6379 --save_schedule "*:30" --maxmemory=12gb --keys_output_limit=12288 --dbfilename dump.rdb
ExecStop=/bin/kill $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
docker 下只需要
docker run --network=host --ulimit memlock=-1 docker.dragonflydb.io/dragonflydb/dragonfly
docker容器啟動(dòng)后,默認(rèn)端口6379
Dragonfly實(shí)現(xiàn)緩存與 Redis 的 LRU 不同,它可以抵抗近期流量的波動(dòng)。
不需要像 Redis 中那樣的隨機(jī)抽樣或其他近似值, 每個(gè)項(xiàng)目的內(nèi)存開銷為零, 具有非常小 O(1)的運(yùn)行時(shí)開銷,這是一種新穎的緩存設(shè)計(jì)方法。