深入解读 Dragonfly:Redis 与 Memcached 的现代内存数据存储替代方案 📅 发布时间:2026/9/11 18:43:38 👁 浏览次数: 深入解读 DragonflyRedis 与 Memcached 的现代内存数据存储替代方案【免费下载链接】dragonflyA modern replacement for Redis and Memcached项目地址: https://gitcode.com/GitHub_Trending/dr/dragonflyDragonfly 是一款为现代应用负载而设计的内存数据存储in-memory data store它完全兼容 Redis 与 Memcached 的 API迁移时无需修改任何业务代码。本文基于当前仓库的 README.md 主文档结合 docs/quick-start/README.md、docs/differences.md、docs/dashtable.md 与src/server下的源码实现系统讲解 Dragonfly 的快速上手、配置参数、设计决策与底层架构读完即可理解它的运行方式并掌握完整的启动与调优方案。一、Dragonfly 是什么Dragonfly 是一个专为现代应用负载构建的内存数据存储。它的核心定位是API 级兼容完全兼容 Redis 与 Memcached 的 API采用时无需改动代码即可平滑替换垂直扩展能力强相比传统单线程内存存储其吞吐量随实例规格增长而持续提升同时在同等负载下占用更少的计算与内存资源低尾延迟在保持亚毫秒级延迟的同时支撑极高的吞吐。从当前仓库源码看Dragonfly 已实现约 185 条 Redis 命令大致对应 Redis 5.0 的 API 面与 13 条 Memcached 命令命令族实现分布在 src/server 下如 string_family.cc、generic_family.cc、list_family.cc 等。也就是说绝大多数基于 Redis/Memcached 的现有客户端与业务代码可以直接切换过来。二、三分钟快速开始Docker 是体验 Dragonfly 最快捷的方式。以下是不同平台下的启动命令详见 docs/quick-start/README.md。Linux 环境使用 host 网络直通性能表现最佳docker run --networkhost --ulimit memlock-1 docker.dragonflydb.io/dragonflydb/dragonflymacOS 环境networkhost在 macOS 上存在兼容问题改用端口映射docker run -p 6379:6379 --ulimit memlock-1 docker.dragonflydb.io/dragonflydb/dragonflyWindows 环境通过 WSL 容器运行wslc run -p 6379:6379 --ulimit memlock-1 docker.dragonflydb.io/dragonflydb/dragonfly启动后Dragonfly 会同时响应http与redis两种协议请求。你可以用redis-cli连接localhost:6379也可以直接在浏览器中访问http://localhost:6379。部分机器上如果出现初始化错误可以尝试追加--privileged标志运行。用 redis 客户端验证读写redis-cli 127.0.0.1:6379 set hello world OK 127.0.0.1:6379 keys * 1) hello 127.0.0.1:6379 get hello world除了 Docker仓库还提供了多种部署方式Docker Compose 配置见 contrib/dockerKubernetes Helm Chart 见 contrib/charts/dragonfly。三、基准测试表现3.1 与 Redis 对比官方基准使用memtier_benchmark在 AWS 上执行压测程序运行在同一可用区AZ的另一台负载测试实例c5n上命令为memtier_benchmark -c 20 --test-time 100 -t 4 -d 256 --distinct-client-seed在常见的单线程 Redis 运行实例m5.large上Dragonfly 表现与 Redis 相当场景RedisDragonflySET--ratio 1:0QPS 159KP99.9 1.16msP99 0.82msQPS 173KP99.9 1.26msP99 0.9msGET--ratio 0:1QPS 194KP99.9 0.8msP99 0.65msQPS 191KP99.9 0.95msP99 0.8ms这说明 Dragonfly 内部为垂直扩展而设计的算法层在单线程运行时并不会带来明显开销。换用更强的实例m5.xlargememtier_benchmark -c 20 --test-time 100 -t 6 -d 256 --distinct-client-seed后两者差距开始拉大场景RedisDragonflySET--ratio 1:0QPS 190KP99.9 2.45msP99 0.97msQPS 279KP99.9 1.95msP99 1.48msGET--ratio 0:1QPS 220KP99.9 0.98msP99 0.8msQPS 305KP99.9 1.03msP99 0.87ms核心结论是Dragonfly 的吞吐能力随实例规格持续增长而单线程的 Redis 受 CPU 瓶颈限制会达到性能上限。在 AWS 网络能力最强的实例c6gn.16xlarge上官方基准测得 Dragonfly 相比单进程 Redis 吞吐量提升约 25 倍QPS 突破 380 万。在峰值吞吐下Dragonfly 的 99 分位延迟如下操作r6gc6gnc7gset0.8ms1ms1msget0.9ms0.9ms0.8mssetex0.9ms1.1ms1.3ms注所有基准均使用memtier_benchmark执行线程数按服务器与实例类型调优memtier运行在独立的 c6gn.16xlarge 机器上SETEX 基准将过期时间设为 500 秒以确保在测试结束前不失效。基准命令模板memtier_benchmark --ratio ... -t threads -c 30 -n 200000 --distinct-client-seed -d 256 \ --expiry-range...在 pipeline 模式--pipeline30下Dragonfly 的 SET 可达到1000 万 QPS、GET 可达到1500 万 QPS。3.2 与 Memcached 对比在 AWS c6gn.16xlarge 实例上官方对比了 Dragonfly 与 MemcachedSET 基准服务器QPS千/秒延迟 99%99.9%Dragonfly38440.9ms2.4msMemcached8061.6ms3.2msGET 基准服务器QPS千/秒延迟 99%99.9%Dragonfly37171ms2.4msMemcached21000.34ms0.6ms结论在相当延迟水平下Dragonfly 的读写吞吐均超过 Memcached写路径上延迟优势更明显这与 Memcached 写路径的锁竞争有关详细分析见 docs/memcached_benchmark.md。读基准中 Memcached 延迟更低但吞吐也更低。3.3 内存效率官方测试流程先用debug populate 5000000 key 1024向两个服务器填充约 5GB 数据再用memtier发送更新流量最后执行bgsave触发快照并观测内存。测试结果表明空闲状态下 Dragonfly 比 Redis 内存效率高约 30%且快照阶段内存几乎无可见增长Redis 在峰值时内存使用量约为 Dragonfly 的 3 倍。Dragonfly 的 snapshot 在数秒内即可完成。更深入的内存效率原理可参考 docs/dashtable.md。四、配置参数详解Dragonfly 支持通用的 Redis 参数例如可以直接运行dragonfly --requirepassfoo --bind localhost4.1 Redis 兼容参数参数说明默认值portRedis 连接端口6379bindlocalhost仅允许本机连接公网 IP 允许来自外部的连接0.0.0.0允许所有 IPv4—requirepassAUTH 认证密码maxmemory数据库最大内存上限人类可读字节数0自动决定dir快照保存目录Docker 默认/dataCLI 默认可用 Docker-v映射到宿主机目录dbfilename数据库保存/加载文件名dump其中maxmemory与dir/dbfilename有更细的源码行为从 src/server/dfly_main.cc 可以看到当maxmemory未显式指定时Dragonfly 会自行探测可用内存并按约 80% 的比例自动设置上限并输出日志说明从 src/server/server_family.cc 的定义看dbfilename默认值为dump-{timestamp}且除{timestamp}外还支持{Y}、{m}、{d}等宏做文件名时间展开实际运行时快照文件名会包含时间戳从 src/server/dfly_main.cc 可以确认当显式指定的maxmemory过小小于线程数 × 256MB时会有相关校验逻辑。4.2 Dragonfly 特有参数参数说明默认值memcached_port启用 Memcached 兼容 API 的端口禁用keys_output_limitkeys命令最多返回的 key 数量8192dbnumselect支持的最大数据库数量16cache_mode启用缓存模式见下文新型缓存设计falsehzkey 过期评估频率100snapshot_cron自动备份快照的 cron 调度表达式分钟粒度标准 cron 语法primary_port_http_enabled是否允许在主 TCP 端口上访问 HTTP 控制台trueadmin_port管理控制台端口同时支持 HTTP 与 RESP 协议禁用admin_bind管理控制台 TCP 绑定地址同时支持 HTTP 与 RESP 协议anyadmin_nopass管理端口免认证开放访问falsecluster_mode集群模式目前仅支持emulatedcluster_announce_ip集群命令向客户端通告的 IP—announce_port集群命令向客户端及复制主节点通告的端口—snapshot_cron支持的标准 cron 表达式示例Cron 表达式含义* * * * *每分钟执行*/5 * * * *每 5 分钟执行5 */2 * * *每 2 小时的第 5 分钟执行0 0 * * *每天 00:00午夜执行0 6 * * 1-5周一至周五 06:00 执行keys是危险命令keys_output_limit的作用是截断结果以避免一次拉取过多 key 导致内存暴涨定义见 src/server/generic_family.cc。hz值越低空闲时 CPU 占用越低但淘汰/过期速度越慢定义见 src/server/engine_shard.cc。cluster_mode、cluster_announce_ip等集群参数的源码定义分别位于 src/server/cluster_support.cc 与 src/server/cluster/cluster_family.cc。4.3 常用参数启动示例./dragonfly-x86_64 --logtostderr --requirepassyoushallnotpass --cache_modetrue -dbnum 1 --bind localhost --port 6379 --maxmemory12gb --keys_output_limit12288 --dbfilename dump.rdb4.4 参数的三种提供方式除了命令行 flag参数还可以通过以下两种方式传入--flagfile filename文件中每行列一个 flag键值对 flag 用等号而非空格分隔flag 值无需引号环境变量设置DFLY_x其中x为 flag 的准确名称区分大小写。更完整的选项如日志管理、TLS 支持等可运行dragonfly --help查看。五、设计决策5.1 新型缓存设计Novel cache designDragonfly 内置一套统一的自适应缓存算法简单且内存高效。通过--cache_modetrue启用后只有当内存接近maxmemory上限时Dragonfly 才会淘汰未来最不可能被访问的条目。其 flag 定义见 src/server/engine_shard_set.ccABSL_FLAG(bool, cache_mode, false, If true, the backend behaves like a cache, by evicting entries when getting close to maxmemory limit);从 src/server/db_slice.cc 的构造函数可以看到cache_mode会作为参数传入DbSlice直接影响数据库切片层的驱逐行为。配合 Dash 表结构该淘汰算法实现了零内存开销的缓存策略详见下文 Dashtable 章节。5.2 过期时间与精度权衡过期时间范围被限制在约8 年以内对于毫秒精度的过期命令PEXPIRE、PSETEX等当期限大于2^28ms时会被就近取整到秒误差小于0.001%对于大范围过期场景可以接受。若该精度取舍不适合你的场景可以通过 issue 反馈。Dragonfly 与 Redis 过期语义的详细差异见 docs/differences.md。5.3 原生 HTTP 控制台与 Prometheus 指标默认情况下Dragonfly 在主 TCP 端口6379上同时提供 HTTP 访问能力——服务器会在连接建立阶段自动识别 Redis 协议或 HTTP 协议。也就是说用浏览器访问http://localhost:6379即可打开控制台。访问:6379/metrics可查看 Prometheus 兼容指标导出的指标与 Grafana 仪表盘兼容预置配置见 tools/local/monitoring重要安全提醒HTTP 控制台仅应在可信网络内访问。如果 Dragonfly 的 TCP 端口对外暴露建议用--http_admin_consolefalse或--nohttp_admin_console禁用它。六、架构背景与底层原理Dragonfly 的诞生源于一个 2022 年的实验如果从零设计一个内存数据存储会是什么样基于作者们作为云厂商工程师使用内存存储的经验他们为 Dragonfly 确立了两个关键特性所有操作的原子性保证以及在高吞吐下依然保持亚毫秒级低延迟。6.1 共享无状态架构Shared-Nothing第一个挑战是如何充分利用现代公有云服务器的 CPU、内存与 I/O 资源。Dragonfly 采用shared-nothing 架构将键空间keyspace在线程之间分区每个线程管理自己独立的字典数据切片这些切片被称为shard。支撑该架构的线程与 I/O 管理库 Helio 位于本仓库的 helio 目录。6.2 基于 VLL 的事务框架为了给多 key 操作提供原子性保证Dragonfly 借鉴了学术界的最新成果——论文VLL: a lock manager redesign for main memory database systems并以此构建事务框架。shared-nothing 架构与 VLL 的结合使得 Dragonfly 可以在不使用 mutex 或 spinlock的情况下组合出原子的多 key 操作这是其 PoC 阶段的关键里程碑。6.3 Dashtable核心哈希表结构Dragonfly 的核心哈希表基于论文Dash: Scalable Hashing on Persistent MemoryarXiv:2003.07302设计。虽然该论文聚焦持久内存领域但其设计思想恰好适配内存存储的需求。Dash 设计让 Dragonfly 保留了 Redis 字典的两大特性数据增长期间的增量哈希能力在变更下使用无状态 scan 操作遍历字典的能力。与此同时Dash 在 CPU 与内存使用上更高效。基于 DashDragonfly 进一步实现了三个独特能力详细原理见 docs/dashtable.mdTTL 记录的高效过期利用 Dashtable 的segment 分段结构在 segment 因插入满而需要分裂时顺带扫描并清理过期条目扫描成本为 O(1)甚至可能因此避免扩容零内存开销的新型缓存淘汰算法在字典元数据上直接承载驱逐所需信息无需额外 LRU/LFU 结构无 fork 的快照算法完全异步、无需 fork 子进程即可维持 point-in-time 快照保证。从内存账本来看经典 Redis 字典每个条目平均需要 16-32 字节开销而 Dashtable 每个条目仅需 6-16 字节开销。由于每个 segment 独立增长表的内存使用平滑消除了扩容时的内存尖峰与延迟尖峰。6.4 与 Redis 的若干差异迁移时还需注意以下细节详见 docs/differences.md字符串长度与索引字符串大小限制为 256MBGETRANGE、SETRANGE等命令的索引应为 [-2147483647, 2147483648] 范围内的有符号 32 位整数SORT不区分 locale过期 flag 组合EXPIRE、PEXPIRE、EXPIREAT、PEXPIREAT允许NX与GT/LT组合键不存在时按 NX 处理否则按 GT/LT 单独判定Redis 会拒绝这些组合Lua 版本使用 2022 年发布的 Lua 5.4.4因此也支持 Lua 整数。七、总结Dragonfly 以共享无状态 VLL 事务 Dash 哈希表三块基石构建了现代内存数据存储的骨架垂直扩展的吞吐能力、亚毫秒级低延迟、更优的内存效率以及无需 fork 的快照与零开销缓存淘汰等创新特性。API 层面完全兼容 Redis 与 Memcached配合 docs/quick-start、docs/differences.md、docs/dashtable.md 等文档开发者可以快速评估并迁移现有业务。源码层面的命令族实现src/server、Helio 线程库helio与测试用例tests/dragonfly为深入理解其实现提供了完整素材。【免费下载链接】dragonflyA modern replacement for Redis and Memcached项目地址: https://gitcode.com/GitHub_Trending/dr/dragonfly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考