nGQL 性能调优

  • nebula 版本:v3.1.0
  • 部署方式:分布式
  • 安装方式: RPM
  • 是否为线上版本:Y
  • 硬件信息
    CPU: 72 Core Intel(R) Xeon(R) Gold 6240 CPU @ 2.60GHz
    Memory: 192 G DDR4
    SSD: NVME 16 T

Below are the details:

Nebula Version: v3.1.0

Deployment:

三台机器每台一个 nebula-metad, 一个 nebula-graphd, 一个 nebula-storaged.

Machine Info:

CPU: 72 Core Intel(R) Xeon(R) Gold 6240 CPU @ 2.60GHz
Memory:   192 G DDR4
SSD: NVME 16 T

Space Statistics:

Partition Number:240 Replica Factor : 3

  • vertices: 800 million
    • member Tag : 250 million
  • edges: 9.5 billion
    • follow: 2.6 billion
show hosts
+----------------+------+-----------+----------+--------------+---------------------------+----------------------------+---------+
| Host           | Port | HTTP port | Status   | Leader count | Leader distribution       | Partition distribution     | Version |
+----------------+------+-----------+----------+--------------+---------------------------+----------------------------+---------+
| "10.0.0.1"  | 9779 | 19669     | "ONLINE" | 80           | "base_space:80" | "base_space:240" | "3.1.0" |
| "10.0.0.2" | 9779 | 19669     | "ONLINE" | 80           | "base_space:80" | "base_space:240" | "3.1.0" |
| "10.0.0.3" | 9779 | 19669     | "ONLINE" | 80           | "base_space:80" | "base_space:240" | "3.1.0" |
+----------------+------+-----------+----------+--------------+---------------------------+----------------------------+---------+

---------+------------+------------+
| Type    | Name       | Count      |
+---------+------------+------------+
| "Tag"   | "content"  | 532806319  |
| "Tag"   | "member"   | 261499703  |
| "Edge"  | "follow"   | 2611243656 |
| "Edge"  | "upvote"   | 6837411544 |
| "Space" | "vertices" | 794306022  |
| "Space" | "edges"    | 9448655200 |
+---------+------------+------------+

问题场景:
A 关注了 B, B 关注了 C, 想找出所有的B

A 可能关注了 10 到 1000 人
C 可能有 10 到 10000000 的关注者

使用 FIND ALL PATH 、GO 语句查询比较慢,是否有更优的查询方式或者调优方案?

nGQL and profile result

Case detail: 用户 m_1 关注了 277 用户, m_2 有大约100万关注者

MATCH:

尝试使用 MATCH 语句花费大概 17 秒.

MATCH (m)-[e:follow]->(n:member) WHERE id(m)=="m_1" MATCH (n)-[f:follow]->(l) WHERE id(l)=="m_2" RETURN id(n);

Explain result :

match_explain

Profile result:

match_profile

在本例中,我们不需要任何属性,所以我们尝试了 GO and FIND PATH 语句:

GO:

GO FROM "m_1" OVER follow YIELD dst(edge) AS member_id INTERSECT GO FROM "m_2" OVER follow REVERSELY YIELD src(edge) AS member_id

Explain result :

go_explain

Profile result:

go_profile

FIND PATH

FIND ALL PATH FROM "m_1" TO "m_2" OVER follow,follow UPTO 2 STEPS YIELD path AS p | YIELD nodes($-.p) AS nodes | YIELD $-.nodes AS nodes, size($-.nodes) AS len | YIELD id($-.nodes[1]) as id WHERE $-.len == 3 

Explain result:

find_all_path_explain

Profile result:

find_all_path_profile

GO语句花费3秒,FIND PATH语句花费6秒。以上所有的方法我们都不能满足我们的要求。在阅读了关于处理超级顶点的文档后,我们尝试了一些解决方案。

  • Compact: 没有效果
  • Truncation: 不能满足需求,因为我们想要所有的数据

客户端处理方案也不适合我们:

  • 删除多条边,合并为一条: 两个成员之间只有一个关注类型的边
  • 拆分相同类型的边,变为多种不同类型的边: 同上
  • 切分顶点本身:一个用户没办法切分
1 个赞

profile 看不清,好像拉数据就画了1s多

图片都是传的原图,可以右键在新窗口打开图片,可以放大的喔

原来可以这样啊。

GO FROM “m_1” OVER follow YIELD dst(edge) AS member_id INTERSECT GO FROM “m_2” OVER follow REVERSELY YIELD src(edge) AS member_id
这个语句已经挺优了,你看下运行时的CPU使用呢

不要用src(edge) 直接用 edge._dst 这样呢
src() dst() 这两个函数花了点时间

2 个赞
GO FROM "m_1" OVER follow YIELD follow._dst AS member_id INTERSECT GO FROM "m_2" OVER follow REVERSELY YIELD follow._dst AS member_id

使用这个方法后,确实又优化了很多!大概提升了50%左右。从3.5s降到1.6s


从查询语句的角度上来看,目前是不是没有优化的空间了?

从其他方面还有没有优化方案?


另外我们现在的3台机器的配置,去压测,这个场景可以压到 1.1W QPS,P95在65ms左右。此时 CPU 已经被打满了。

横向扩容增加 graphd 和 storage 是否能够提升集群吞吐性能?
这里理解增加 graphd 可以增加计算资源,可以一定程度分担计算压力,增加 storage 后,会不会因为数据分片变多后,跨机器数据读取概率变大,进而增加响应时间



第3步拉数据大概789ms,这个通过加storage机器能少量优化时延。因为万兆网其实挺快的,你每次拉的数据量也挺大,在不在一台机器影响不大。

增加整体QPS的话,加机器肯定可以的。你现在CPU不够了

blockcache放大一点,也许有点用。(取决于数据有多久了)
或者说仔细看下每个进程都在忙啥

如果你试试 go a yield b |go b where dst == c 这样呢
c是稠密点,b找c也许会快点

2 个赞

是指 storaged 的 rocksdb_block_cache 吧?
目前机器内存为 192G, 现在设置的 rocksdb_block_cache=65536(MB)(64G)

看配置里推荐是设置为 1/3 of all memory, 那我这里还可以继续调高吗?


这里的「每个进程都在忙啥」怎么去分析呢?

GO FROM "m_1" OVER follow YIELD follow._dst AS m_vid | GO FROM $-.m_vid OVER follow WHERE follow._dst == "m_2" YIELD follow._src AS member_id

这个查询非常快! :scream: 大多数情况下,a、b关注的人是少于 c 被关注的人数的。

稍后我再压一下。

1 个赞
  • 可以看看 3.3.0 有没有进一步提升哈,今天刚发布
  • 另外 graphd.conf 里可以再看看 --query_concurrently=true 打开了查询会不会有提升

简单就打几个pstack 看看
不怕麻烦就perf下

CPU bound 需要知道忙在哪里

对,可以打开这个并发试试。
(不过这里面实现我也还没看过。。。。

对了,如果这个调优过程是有效的,是否可以联系一下@思维
整理个guide

楼主,请问下这个调优是有效的嘛?