在繼續之前,請考慮給我們一個 GitHub star️。謝謝你!
其他語言: 簡體中文 日本文 한국어
網站 • 文件 • 快速入門 • 社區不和諧 • Dragonfly 論壇 • 加入 Dragonfly 社區
GitHub 討論 • GitHub 問題 • 貢獻 • Dragonfly Cloud
Dragonfly 是專為現代應用程式工作負載所建置的記憶體資料儲存體。
Dragonfly 與 Redis 和 Memcached API 完全相容,無需更改程式碼即可採用。與傳統的記憶體資料儲存相比,Dragonfly 的吞吐量提高了 25 倍,快取命中率更高,尾部延遲更低,並且對於相同大小的工作負載,運行資源最多可減少 80%。
我們首先在m5.large實例上將 Dragonfly 與 Redis 進行比較,m5.large 執行個體由於其單執行緒架構而通常用於執行 Redis。基準測試程式使用memtier_benchmark -c 20 --test-time 100 -t 4 -d 256 --distinct-client-seed從同一可用區中的另一個負載測試實例 (c5n) 執行
Dragonfly 顯示了類似的性能:
--ratio 1:0 ):| 雷迪斯 | DF |
|---|---|
| QPS:159K,P99.9:1.16ms,P99:0.82ms | QPS:173K,P99.9:1.26ms,P99:0.9ms |
--ratio 0:1 ):| 雷迪斯 | DF |
|---|---|
| QPS:194K,P99.9:0.8ms,P99:0.65ms | QPS:191K,P99.9:0.95ms,P99:0.8ms |
上面的基準測試表明,DF 內部允許垂直擴展的演算法層在單執行緒運行時不會造成太大損失。
然而,如果我們採用更強一點的實例(m5.xlarge),DF 和 Redis 之間的差距就會開始擴大。 ( memtier_benchmark -c 20 --test-time 100 -t 6 -d 256 --distinct-client-seed ):
--ratio 1:0 ):| 雷迪斯 | DF |
|---|---|
| QPS:190K,P99.9:2.45ms,P99:0.97ms | QPS:279K,P99.9:1.95ms,P99:1.48ms |
--ratio 0:1 ):| 雷迪斯 | DF |
|---|---|
| QPS:220K,P99.9:0.98ms,P99:0.8ms | QPS:305K,P99.9:1.03ms,P99:0.87ms |
Dragonfly 吞吐能力隨著實例規模不斷增長,而單線程 Redis 在 CPU 上遇到瓶頸,在效能方面達到局部最大值。
如果我們在網路能力最強的實例 c6gn.16xlarge 上比較 Dragonfly 和 Redis,則與 Redis 單一進程相比,Dragonfly 的吞吐量提高了 25 倍,超過 3.8M QPS。
Dragonfly 在尖峰吞吐量下的第 99 百分位數延遲指標:
| 操作 | 6g | 6gn | 7g |
|---|---|---|---|
| 放 | 0.8毫秒 | 1毫秒 | 1毫秒 |
| 得到 | 0.9毫秒 | 0.9毫秒 | 0.8毫秒 |
| 塞泰克斯 | 0.9毫秒 | 1.1毫秒 | 1.3毫秒 |
所有基準測試均使用memtier_benchmark (見下文)執行,並根據伺服器和實例類型調整了執行緒數。 memtier在單獨的 c6gn.16xlarge 機器上運行。我們將 SETEX 基準的到期時間設定為 500,以確保它能夠在測試結束後繼續存在。
memtier_benchmark --ratio ... -t < threads > -c 30 -n 200000 --distinct-client-seed -d 256
--expiry-range=...在管道模式--pipeline=30下,Dragonfly 對於 SET 操作達到10M QPS ,對於 GET 操作達到15M QPS 。
我們在 AWS 上的 c6gn.16xlarge 實例上將 Dragonfly 與 Memcached 進行了比較。
在延遲相當的情況下,Dragonfly 吞吐量在寫入和讀取工作負載方面均優於 Memcached 吞吐量。由於 Memcached 中寫入路徑上的爭用,Dragonfly 在寫入工作負載中表現出更好的延遲。
| 伺服器 | QPS(千qps) | 延遲99% | 99.9% |
|---|---|---|---|
| 蜻蜓 | ? 3844 | ? 0.9毫秒 | ? 2.4毫秒 |
| 記憶體快取 | 806 | 1.6毫秒 | 3.2毫秒 |
| 伺服器 | QPS(千qps) | 延遲99% | 99.9% |
|---|---|---|---|
| 蜻蜓 | ? 3717 | 1毫秒 | 2.4毫秒 |
| 記憶體快取 | 2100 | ? 0.34毫秒 | ? 0.6毫秒 |
Memcached 在讀取基準測試中表現出較低的延遲,但吞吐量也較低。
為了測試記憶體效率,我們使用debug populate 5000000 key 1024命令向 Dragonfly 和 Redis 填充了約 5GB 的數據,使用memtier發送更新流量,並使用bgsave命令啟動快照。
該圖展示了每台伺服器在記憶體效率方面的表現。
Dragonfly 在空閒狀態下的記憶體效率比 Redis 高 30%,在快照階段沒有出現任何明顯的記憶體使用增加。在高峰期,Redis 記憶體使用量增加到 Dragonfly 的近 3 倍。
蜻蜓更快完成了快照,幾秒鐘之內。
有關 Dragonfly 記憶體效率的更多信息,請參閱我們的 Dashtable 文件。
Dragonfly 在適用的情況下支援常見的 Redis 參數。例如,您可以執行: dragonfly --requirepass=foo --bind localhost 。
Dragonfly 目前支援以下 Redis 特定參數:
port :Redis 連接埠( default: 6379 )。bind :使用localhost僅允許本機主機連線或公用 IP 位址以允許連線至該 IP位址(即也可從外部)。使用0.0.0.0允許所有 IPv4。requirepass :AUTH 驗證的密碼( default: "" )。maxmemory :資料庫使用的最大記憶體(以人類可讀位元組為單位)的限制( default: 0 )。 maxmemory值為0意味著程式將自動決定其最大記憶體使用量。dir :Dragonfly Docker 預設使用/data資料夾進行快照,CLI 使用"" 。您可以使用-v Docker 選項將其對應到主機資料夾。dbfilename :儲存和載入資料庫的檔案名稱( default: dump )。還有一些特定於 Dragonfly 的參數:
memcached_port :啟用 Memcached 相容 API 的連接埠( default: disabled )。
keys_output_limit : keys指令中傳回的鍵的最大數量( default: 8192 )。請注意, keys是一個危險的命令。我們截斷其結果以避免在獲取太多鍵時內存使用激增。
dbnum : select支援的最大資料庫數。
cache_mode :請參閱下面新穎的快取設計部分。
hz :密鑰過期評估頻率( default: 100 )。較低的頻率在空閒時使用較少的 CPU,但代價是驅逐速度較慢。
snapshot_cron :自動備份快照的 Cron 計畫表達式,使用標準 cron 語法,粒度為分鐘( default: "" )。以下是一些 cron 計劃表達式範例,請隨時在我們的文件中閱讀有關此參數的更多資訊。
| Cron 計劃表達式 | 描述 |
|---|---|
* * * * * | 每分鐘 |
*/5 * * * * | 每五分鐘一次 |
5 */2 * * * | 每 2 小時 5 分 |
0 0 * * * | 每天 00:00(午夜) |
0 6 * * 1-5 | 週一至週五 06:00(黎明) |
primary_port_http_enabled :如果為true ( default: true ),則允許存取主 TCP 連接埠上的 HTTP 控制台。
admin_port :在指派的連接埠上啟用對控制台的管理員存取( default: disabled )。同時支援 HTTP 和 RESP 協定。
admin_bind :將管理控制台 TCP 連線綁定到給定位址( default: any )。同時支援 HTTP 和 RESP 協定。
admin_nopass :啟用對分配連接埠上控制台的開放管理訪問,無需身份驗證令牌( default: false )。同時支援 HTTP 和 RESP 協定。
cluster_mode :支援叢集模式( default: "" )。目前僅支援emulated .
cluster_announce_ip :叢集指令向客戶端宣告的 IP。
announce_port :叢集指令向客戶端和複製主機宣布的連接埠。
./dragonfly-x86_64 --logtostderr --requirepass=youshallnotpass --cache_mode=true -dbnum 1 --bind localhost --port 6379 --maxmemory=12gb --keys_output_limit=12288 --dbfilename dump.rdb也可以透過以下方式提供參數:
--flagfile <filename> :檔案應每行列出一個標誌,並用等號取代鍵值標誌的空格。標誌值不需要引號。DFLY_x ,其中x是標誌的確切名稱,區分大小寫。如需日誌管理或 TLS 支援等更多選項,請執行dragonfly --help 。
Dragonfly 目前支援約 185 個 Redis 指令以及除cas之外的所有 Memcached 指令。幾乎與 Redis 5 API 一樣,Dragonfly 的下一個里程碑將是穩定基本功能並實現複製 API。如果您需要的命令尚未實現,請提出問題。
對於 Dragonfly 原生複製,我們正在設計分散式記錄格式,它將支援更高數量級的速度。
在複製功能之後,我們將繼續為 Redis 版本 3-6 API 新增缺少的命令。
請參閱我們的命令參考以了解 Dragonfly 目前支援的命令。
Dragonfly 具有單一、統一、自適應的快取演算法,該演算法簡單且記憶體高效。
您可以透過傳遞--cache_mode=true標誌來啟用快取模式。一旦啟用此模式,蜻蜓將逐出將來最不可能偶然發現的項目,但僅限於接近maxmemory限制時。
有效期限範圍限制為 ~8 年。
對於大於 2^28ms 的截止日期,具有毫秒精度的過期截止日期(PEXPIRE、PSETEX 等)四捨五入到最接近的秒,其誤差小於 0.001%,對於大範圍應該是可以接受的。如果這不適合您的用例,請聯絡或提出一個問題來解釋您的案例。
有關 Dragonfly 到期期限和 Redis 實作之間的更多詳細差異,請參閱此處。
預設情況下,Dragonfly 允許透過其主 TCP 連接埠 (6379) 進行 HTTP 存取。沒錯,您可以透過 Redis 協定和 HTTP 協定連線到 Dragonfly — 伺服器在連線啟動期間會自動辨識該協定。繼續使用您的瀏覽器嘗試。 HTTP 存取目前沒有太多信息,但將來會包含有用的調試和管理信息。
造訪 URL :6379/metrics查看 Prometheus 相容的指標。
Prometheus 導出的指標與 Grafana 儀表板相容,請參閱此處。
重要的! HTTP 控制台應可在安全網路內存取。如果您將 Dragonfly 的 TCP 連接埠暴露在外部,我們建議您使用--http_admin_console=false或--nohttp_admin_console停用控制台。
Dragonfly 最初是一個實驗,旨在了解記憶體資料儲存在 2022 年設計時會是什麼樣子。操作的原子性,以及在非常高的吞吐量下實現低亞毫秒延遲。
我們的第一個挑戰是如何使用當今公有雲中可用的伺服器來充分利用 CPU、記憶體和 I/O 資源。為了解決這個問題,我們使用無共享架構,它允許我們在執行緒之間劃分記憶體儲存的鍵空間,以便每個執行緒都可以管理自己的字典資料片。我們將這些切片稱為「碎片」。為無共享架構提供執行緒和 I/O 管理的函式庫在這裡是開源的。
為了為多鍵操作提供原子性保證,我們利用了最新學術研究的進展。我們選擇了論文「VLL:主記憶體資料庫系統的鎖定管理器重新設計」來開發Dragonfly 的事務框架。多鍵操作。
我們的第二個挑戰是為新商店設計更有效率的資料結構。為了實現這一目標,我們的核心哈希表結構是基於論文「Dash:持久記憶體上的可擴展哈希」。這篇論文本身以持久記憶體領域為中心,與主記憶體儲存沒有直接關係,但它仍然最適用於我們的問題。論文中提出的雜湊表設計使我們能夠維護 Redis 字典中存在的兩個特殊屬性:資料儲存成長期間的增量雜湊能力以及使用無狀態掃描操作在更改時遍歷字典的能力。除了這兩個屬性之外,Dash 在 CPU 和記憶體使用方面也更有效率。透過利用 Dash 的設計,我們能夠透過以下功能進一步創新:
一旦我們為 Dragonfly 奠定了基礎並且對其性能感到滿意,我們就繼續實現 Redis 和 Memcached 功能。到目前為止,我們已經實作了約 185 個 Redis 指令(大致相當於 Redis 5.0 API)和 13 個 Memcached 指令。
最後,
我們的使命是為雲端工作負載建立一個設計精良、超快速、經濟高效的記憶體資料存儲,利用最新的硬體進步。我們打算解決目前解決方案的痛點,同時保留其產品 API 和主張。