Storaged 是 NebulaGraph 的核心服务架构,负责保障数据的持久性、可用性与可扩展性,读写效率直接影响整个系统的性能表现。
NebulaGraph 研发@文豪将从 NebulaGraph 底层存储引擎 RocksDB [1] 的角度出发,剖析 Storaged 的架构设计,并结合实际生产案例,分享诊断与解决性能瓶颈的经验。
NebulaGraph 数据读写机制
在 NebulaGraph 中,点 (Vertex) 和边 (Edge) 都以键值对形式存储,底层采用 RocksDB 作为存储引擎(3.x 版本使用 RocksDB 3.7.3)。数据通过分片与副本进行存储,每个分片副本对应一个独立的 RocksDB 实例。

数据在多个存储节点间的分布基于哈希函数实现:
点根据其 ID 进行分片。
边则根据源顶点 ID 进行分片。
这一设计确保了点及其边位于同一分片,有利于提升查询性能。但对于超级节点(与大量其他节点存在连接的关键节点),可能会带来负载不均的问题,而哈希算法有助于将这些节点更均衡地分散到不同 Storaged 实例上。
基于 Raft 的多副本一致性
为保证副本一致性,NebulaGraph 采用 Raft 共识算法 [2],在副本中选举出 Leader, Leader 负责处理绝大多数读写请求,Followers 则作为备份。当 Leader 因网络问题或维护下线时,系统会重新选举新 Leader.
数据写入与复制的流程如下:
Leader 将数据写入预写日志(WAL)。
写入操作被复制到所有 Followers,Followers 同样将其写入各自 WAL.
Followers 异步将数据持久化至 RocksDB,并向 Leader 发送确认。
Leader 收到所有 Followers 的确认后,将写入提交至 RocksDB.

区域的高可用部署
在对高可用性要求较高的环境中,建议将分片副本分布在不同区域(Zone)中。
区域指基础设施中逻辑或物理上独立的单元。在云环境中,区域通常对应可用区(AZ)[3]——同一地域内相互隔离的数据中心。
它们之间的距离足够近,可保证低延迟通信,同时又足够远,能降低因局部故障导致同时中断的风险。在此架构下:
写入始终由 Leader 处理,无论其位于哪个区域。
读取可通过区域感知 (Zone Affinity) 进行优化:查询会优先选择与处理该查询的 Graphd 同区域的 Storaged 实例。
启用区域感知后,Leader 和 Follower 均可服务读请求,从而提升效率并降低跨区域数据传输成本(例如在 AWS 中,同区域内数据传输免费)。
Storaged 高延迟
常见问题及解决方案
在生产环境中,P90 查询延迟升高、查询失败增多往往是性能问题的信号。虽然问题可能源于 Graphd 或 Metad,但当根本原因在 Storaged 时,一定会表现为存储延迟升高。本节将介绍导致存储延迟高的常见原因及其应对方法。
1. 资源利用不足
如果 Storaged 延迟很高,但 CPU 使用率、磁盘 I/O 和吞吐量却很低,可能是软件未能充分利用硬件资源。此时应重点检查 Thrift 服务与 RocksDB 的线程分配情况。
Storaged 主要依赖三个线程池:
Thrift IO 线程池:以事件循环模式处理接入连接。
Thrift 工作线程池:处理服务请求,包括写入。
读取处理线程池:通过 RocksDB 管理磁盘读取。
Thrift IO 线程处理连接的速度很快,很少成为延迟瓶颈。若延迟持续存在,应重点关注工作线程池和读取处理线程池。在生产环境中,通常建议将这些线程池的大小设置为与运行 Storaged 的机器或 Pod 的 CPU 核数相匹配,以达到最佳性能。
2. CPU 使用率过高
如果所有 Storaged 实例均出现 CPU 使用率过高的情况,根本原因通常属于以下几类。
(1) 数据导入期间的 CPU 峰值
如果 CPU 使用率主要在数据导入时升高,很可能是因为 RocksDB Compaction [4]。Compaction 是 RocksDB 日志结构合并树(LSM tree)中合并与重组数据的关键过程,旨在优化读取性能,但也会消耗大量计算资源。
为缓解 Compaction 期间的 CPU 压力,可考虑以下优化:
降低 Compaction 并发度:
调低max_subcompactions和max_background_jobs,减缓速度,更均匀地分配 CPU 负载。优化自定义压实过滤器:
在 NebulaGraph 中,当启用 TTL [6] 时,过期数据会通过自定义压实过滤器 [5] 进行垃圾回收。该过滤器在压实过程中扫描受影响的顶点和边,并检查其 TTL 是否到期。这一额外检查会带来 CPU 开销。配置项
min_level_for_custom_filter决定了自定义压实过滤器从 LSM 树的哪一层开始处理数据。较低的值会使过滤器扫描更多层数据,从而增加 CPU 负载。
较高的值会推迟 TTL 过滤的时机,降低 CPU 使用率,但会导致过期数据暂时留存更久。
由于min_level_for_custom_filter 设置过高可能导致存储膨胀甚至可用性问题,因此需要谨慎调优,以在 CPU 效率与过期数据留存之间找到平衡。下文将进一步探讨累积过期数据的影响。
(2) 无写入时 CPU 使用率仍持续偏高
即使没有活跃写入,CPU 使用率仍居高不下,原因可能关联到 RocksDB 读取操作或 Storaged 内部的线程争用。为了更精确地诊断,建议在高 CPU 的 Storaged 实例上运行perf top进行分析。
在物理机或虚拟机上,直接运行
perf top即可。在 Kubernetes 部署中,需要额外的权限配置。我们的 Nebula Operator [7] 已包含必要配置,只需一个设置即可启用
perf top。
如果perf top显示 Thrift 内部队列中出现大量线程上下文切换和抢占,则表明线程过多——过多活跃线程在竞争 CPU 资源。此时,减少工作线程和读取处理线程的数量有助于提升 CPU 效率。
3. 磁盘 I/O 使用率过高
如果 IOPS 或 I/O 吞吐量达到磁盘上限,会显著影响查询延迟。
(1) 数据导入期间 I/O 过高
如果磁盘 I/O 过高仅出现在数据导入时,可能的原因包括:
数据导入速度过快
Compaction 并发度过高
解决措施包括:
降低导入速度或调整批次大小
调低
max_subcompactions和max_background_jobs以限制 Compaction 并发度
(2) I/O 持续偏高并伴随存储错误
如果磁盘 I/O 持续处于高位并接近磁盘极限,同时 Graphd 日志中出现类似RPC failure in StorageClient with timeout或loadshedding 等错误,这很可能表明过期数据量过多。
此时,Storaged 正在频繁扫描磁盘以过滤数据,导致 I/O 负载显著增加。可通过以下命令验证数据状态:
SUBMIT JOB STATS;SHOW STATS;
如果过期数据量达到正常水平的两倍或更高,可触发全量 Compaction 来清理过期数据:
SUBMIT JOB COMPACT;
总结
本文深入介绍了 Storaged 中数据的存储、分区、复制与访问机制,并提供了诊断和解决高存储延迟的最佳实践。
如果你想看更多官方技术干货,欢迎来论坛给 NebulaGraph 研发们提需求,留言你的命题,我们来实现~
https://discuss.nebula-graph.com.cn/t/topic/17355
Reference
[1] RocksDB. https://github.com/facebook/rocksdb
[2] Raft. Ongaro, Diego, and John Ousterhout. "In search of an understandable consensus algorithm." 2014 USENIX annual technical conference (USENIX ATC 14). 2014.
[3] 可用区概念. https://learn.microsoft.com/zh-cn/azure/reliability/availability-zones-overview?tabs=azure-cli
[4] RocksDB Compaction. https://github.com/facebook/rocksdb/wiki/Compaction
[5] Compaction Filter. https://github.com/facebook/rocksdb/wiki/Compaction-Filter
[6] NebulaGraph 中的 TTL. https://docs.nebula-graph.io/3.8.0/3.ngql-guide/8.clauses-and-options/ttl-options/
[7] Nebula Operator. https://github.com/vesoft-inc/nebula-operator
🔥日本 nMeetUp 火热报名中
✦
如果你觉得 NebulaGraph 能帮到你,或者你只是单纯支持开源精神,可以在 GitHub 上为 NebulaGraph 点个 Star!
每一个 Star 都是对我们的支持和鼓励✨
GitHub:https://github.com/vesoft-inc/nebula
官网:https://www.nebula-graph.com.cn/
论坛:https://discuss.nebula-graph.com.cn/
✦
✦
扫码添加
可爱星云
技术交流
资料分享
NebulaGraph 用户案例
✦
Why Graph Database?⬇️
风控场景:普适智能|中证数智|BlockSec|携程|Airwallex|众安保险|中国移动|Akulaku|邦盛科技|360数科|BOSS直聘|金蝶征信|快手|青藤云安全
平台建设:博睿数据|携程|众安科技|微信|OPPO|vivo|美团|百度爱番番|携程金融|普适智能|BIGO
知识图谱:普适智能|中证数智|中医药大学|企查查|腾讯音乐|中科大脑|泰康在线|苏宁|微澜|同花顺|携程酒店
营销推荐:阿里妈妈
GraphRAG:中科数睿
✦
✦

