大数跨境
0
0

超干货!Storaged 性能诊断与调优攻略

超干货!Storaged 性能诊断与调优攻略 NebulaGraph
2025-12-10
2
导读:从架构原理到参数调优,一文搞定 Storaged

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.

数据写入与复制的流程如下:

  1. Leader 将数据写入预写日志(WAL)。

  2. 写入操作被复制到所有 Followers,Followers 同样将其写入各自 WAL.

  3. Followers 异步将数据持久化至 RocksDB,并向 Leader 发送确认。

  4. 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 timeoutloadshedding 等错误,这很可能表明过期数据量过多。

此时,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直聘金蝶征信快手青藤云安全

平台建设:博睿数据携程众安科技微信OPPOvivo美团百度爱番番携程金融普适智能BIGO

知识图谱:普适智能|中证数智中医药大学企查查腾讯音乐中科大脑泰康在线苏宁微澜同花顺携程酒店

数据血缘:波克城市微众银行携程金融

智能运维BOSS直聘|58同城中亦安图

供应链:京东物流震坤行

营销推荐:阿里妈妈

GraphRAG:中科数睿

✨ NebulaGraph 推荐阅读

【声明】内容源于网络
0
0
NebulaGraph
一个开源的分布式图数据库
内容 731
粉丝 0
NebulaGraph 一个开源的分布式图数据库
总阅读463
粉丝0
内容731