图系统-HugeGraph整体性能测试(三)
上一篇和第一篇已经大致把整个HG的核心结构, 基本特性和特点结合实际”存储+代码”做了基本介绍, 这篇就是
HG初识系列
的结束篇, 结合实际的生产数据, 给Hugegraph大部分后端做了一个基本的性能测试, 希望可以给想使用HG的同学一个实际参考.PS: 因为实际数据和机器的不同, 测试结果可能出现很大差异, 有任何问题欢迎留言或邮件联系.
0x00.概述
大体结论:
- 在单机10亿数量级的情况, RocksDB可以较好胜任, 性能大幅超出预期. 写入最快可达6亿/h, 读取速度也接近8万/s遍历, 但是单磁盘会频繁掉速, 建议磁盘换为SSD或组RAID. (详见后文官方解释)
- Mysql在百万级别查询速度情况良好, 可以有6万/s的遍历速度,单写入对错误数据的容忍性最低. (存疑)
- Hbase 在3DataNode测试环境下写入速度良好, 有3亿点/h , 近6亿边/h. 读取速度在一度的时候表现也挺好, 但深度提高读取速度会显著下降.
- Cassandra在10亿数量级情况, 写入稳定在1亿/h, 较慢. 奇怪的是读测试目前是相对最慢的.
- (对比)JanusGraph使用的Cassandra作为后端, 同样机器下写入速度点1亿/h, 边2亿/h (不写ES)
后面是详细的测试说明..
0x01. 基本环境
A. 硬件环境
Loader和Server都是服务端物理机(1或3台),Loader和Server端分离, 核心配置如下:
- CPU : 同20物理核 (Xeon E5-2630 )
- 内存 : 128G内存 (可用30G+) / 314G内存 (可用177G+)
- 磁盘 : 8T HDD / 2T HDD (系统盘SSD?)
- 网卡 : 同万兆网卡
- OS : 同CentOS 7.x
2.21更新: 最近补充测试了一下云虚拟机主机小水管的部署, 双核CPU + 2G内存…. 应该算很低的配置了, 此时要注意直接使用默认的导入参数Server端是会瞬间OOM的. (单台机器Loader和Server和Studio都在一起.)
在配置很低的时候, 我是手动调低了batchSize (默认是500条每次) ,改为200条很顺畅 (极限在哪没测…), 然后建议手动调低导入线程数 (默认是CPU*2 + 1
,但是不知道是算的物理核还是逻辑核, 反正手动调为CPU物理核个数比较稳.)
B. 系统环境
- Hugegraph-Server : 0.8.0
- Hugegraph-Loader : 1.2.0
- gcc : 4.85+
- 后端存储:
- rocksDB (使用单HDD磁盘)
- Mysql 5.6 (使用单HDD磁盘)
- Cassandra 3.11 (三节点)
- HBase 2.0 (三节点, region server: 3)
C. 测试数据
测试数据包括route
和dns
两个数据源, 其详细结构暂略,总共 6.4亿点 + 7.4亿边, 大致如下:
route: 27G数据 (点:1.2亿点 / 边:0.8亿边)
dns: 82G数据 (点:5.2亿 / 边:6.6亿)
注意: Mysql因为单表单磁盘的承载能力, 所以需要单独的百万级别的测试数据, Rocksdb
/ Cassandra
/Hbase都是全量的数据导入.
0x02. 写入测试
0. 写入参数
现在采用的是除了Hbase外, 其他默认都开启了二级索引, 注意大量的解析和写入错误可能会很大的影响导入速度, 变为单条写入模式.. 所以之后可能测试结果还会更新一次.
1 | bin/hugegraph-loader -g hugegraph -s /path/to/schema.groovy -f /path/to/struct.json --max-parse-errors 200000 --max-insert-errors 200000 -h 10.203.xx.xx --retry-interval 5 --retry-times 1 --timeout 5 |
补: 参数默认值参考官方说明. (batchSize和线程数建议不要随便改, 可能卡死)
RocksDB
1.写入结果
这是官方测试rocksDB参考 :
- 关闭label index,22.8w 边/s
- 开启label index,15.3w 边/s
目前实测 :
单HDD盘, 综合完整导入时间来看, 顶点4.6万/s, 边4.5万/s, 折合1.6亿/h 顶点或边, 中间会有很明显的卡顿, 或速度急剧偏低 . 问题参考文末 (导入前82G –导入后—> 87G )
注: 因为rocksDB前期或稳定的时候点有 12万/s, 边有20万/s (折合2.5亿/h的点, 7亿/h的边)
1 | ---------------------route------------------------ |
2. 资源消耗
因为Loader程序资源占用较少, 数据应该也读到了内存中, 所以主要关注Server端 :
CPU: 最高2000% , 最低300% , 平均800% 左右 (低负载的时候一般是写入卡住了…)
内存: 30G (需要手动修改server启动配置)
网卡:?MB/s (这个值…待定)
Hbase
采用HBase存储引擎时平均插入点9万/秒,插入边16万/秒 , 速度稳定, 没有明显卡顿 ,还算挺不错.
1 | ---------------------route------------------------ |
Server端资源消耗
- CPU: 967% (us: 22.6%)
- 内存:4.7%
- 网卡:123M/s
Cassandra
Cassandra 目前测试来看, 顶点和边写入正常状态大概3万/s ,折合1亿/h , 导入很稳定 ,容错性最好
1 | ---------------------route------------------------ |
负载好像忘记记了… 不过没什么特别的地方
Mysql
Mysql因为自身存储结构和单表支持数据量原因, 不能支持上亿数据写入单表. 写入就会反复卡死, 测试数据量需要重新生成一批百万级别的点+边…
所以写入速度还不好写一个具体值, 会经常性的出现Broken pipe
提示. 详见文尾问题区.
JanusGraph
JanusGraph导入数据源与HG一致, 无ES索引 —> 平均写入点或边4万条/秒 (导入方式使用MR/Spark)
1 | ---------------------route------------------------ |
因为Janus这里直接走内嵌的core-jar包, 没有走server
端, 所以资源消耗就不好对比了, 包括分布式的任worker.
0x03. 读取测试
根据实际的业务需求, 和对读取性能的绝对值评估, 核心采用K步邻居判断, 以及余下补充:
- 路径查询
- K步邻居
- 批量点边
注意: 需要调整HG自带的缓存设置, 以及调整
gremlin-server.yaml
里的缓存设置, 不然对查询速度的结果影响很大.附 : HG自带的扩展查询详细参考官方 , Gremlin查询参考自Tinkerpop文档以及HG官方issue
1.路径查询
1 | # 最短路径 (ShortestPath-自带) |
查询类型 / 对应后端 | RocksDB | Hbase | Mysql^(*)^ | Cassandra | JanusGraph | |
---|---|---|---|---|---|---|
5度最短路 (IP之间) | 0.55s | 0.65s | 0.3s | 1.5s | / | |
5度最短路 (域名之间) | 2.5s | 12s | / | 11s | / | |
5度全路径查询(域名) | 2.7s | 13s | 0.4s | 11s | / | |
5度最短路-Gremlin(IP之间) | 0.28s | 0.34s | / | 4s | 4s |
() : *补充**
- Mysql数据量是百万级别, 有些数据缺失导致无结果, 其他后端数据源一致.
- RocksDB同样也存在缓存的问题… 可能是加载到了内存, 目前无法控制…第一次查询和之后的查询时延相差10倍以上..
- gremlin的测试, 是否gremlin-server自己设置了缓存 ,目前测试看也是有的, 这都会很影响测试多次结果
2. K步邻居
测试的几个case:
1 | # k-neighbor: |
查询类型 / 对应后端 | RocksDB (时间/数目) | Hbase | Mysql | Cassandra | JanusGraph | |
---|---|---|---|---|---|---|
1层K步邻居 | 1.3s / 75567个 | 0.7s / 75567个 | / | 2.5s/76335个 | 18s/11526个 | |
2层K步邻居 | 5.4s / 77834个 | 42s / 77834个 | / | 65s/81770个 | 48s/8486个 | |
3层K步邻居 | 5.9s / 77834个 | 43s / 77834个 | / | 超时 | 超时 | |
4层K步邻居 | / | / | / | / | ||
gremlin | - | - | - | - |
备注:
- gremlin超时 ,
/
代表暂时无意义 (也不确定是否是超时还是Hugeserver无响应了..) K-OUT
因为是K步邻居的一部分实现, 所以就不单独列出了.- JanusGraph的查询语句与HG的类似,但二度邻居好像是按照K-out返回的,这里可能需要再调整gremlin写法…
3. 批量点查
1 | #这个封装实际只是根据顶点ID查询,应该是与hugeGraph的ID构成策略有关,如果利用gremlin直接查,耗时相差不大 |
查询类型 / 对应后端 | RocksDB (时间/数目) | Hbase | Mysql | Cassandra | JanusGraph(*) | |
---|---|---|---|---|---|---|
批量点查 | 0.03s / 4个 | 0.11s | 0.02s | 0.06s / 4个 | / | |
批量边查 | 0.05s / 3个 | 0.8s | 0.05s / 3个 | / | ||
批量属性差 | 1.5s/10个 | |||||
gremlin |
(*):JanusGraph因为ID的构成方式,无法根据顶点ID直接查点/边,只能查属性
补充 :
- 同样Rocksdb第一次查平均
0.1s
. 后续平均30ms, 各后端差别不大, 稍快于gremlin查询. - 测试个位数的点查意义很小, 几乎体现不出区别, 后续应该补上批量查万级别的点, 通过
Shard
获取一批点/边ID - 主要用途应该也是为了便于最短路/K步邻居的顶点ID批量传入查询具体数据… (推测..)
0x04.存在的问题
Rocksdb , Mysql ,
Cassandra导入的时候都可能出现很严重的问题, 导致写入中断, 或者速度大幅降低, 或完全卡死,这里列一下, 仅供参考
1.RocksDB写入相关问题
这个单磁盘持续写入几乎必会出现, 但是引用官方解释之后觉得大部分情况可以说得通, 后续需要注意:
RocksDB
后期导入速度变慢可能的原因很多,下面是常见的几种:
- 批量插入失败时(比如某一条数据不符合规范),loader会尝试以单条模式进行重试,如果批量插入的非法数据过多可能导致后期缓慢;(我们符合)
- 使用单块磁盘持续导入过多数据时,RocksDB因为compaction可能导致速度变慢(write stall ) ( 需要确认)
- JVM分配内存不足可能导致速度变慢。 (需要确认, 目前应该是默认给的18G)
解决方案:
- 对于case 1,请看看日志目录中的错误内容是否过多,以及后期是否进度每500条变动一次(我们不是)。针对该问题我们后续会改进loader,请关注:hugegraph/hugegraph-loader#11
- 对于case 2,请查看rocksdb日志来确认,需要具体分析哪一部分数据导致缓慢进而进行优化 , 后续可以LVM+RAID分摊写入 (日志看不懂…)
- 对于case 3,可通过调用任意查询API来查看是否server响应缓慢 (需要验证)
总之官方说的已经挺全面详细了, 如果还有其他问题再跟进.
2. Mysql写入相关问题
需要调整默认的100个连接数, 否则很快会超过, 建议至少改为1000 ,修改方法参考
需要尽量减少不合法的数据, 否则会出现大量的
broken pipe
–jason 解析错误 ,具体原因未知这样就会导致有大量的网络阻塞和停顿:
3. Cassandra读写相关问题
可以说Cassandra如果遇到了很明显的卡顿, 或者从一开始就Loader的显示就每500/s 很缓慢的变动, 都是Cassandra配置 + 代码修改的问题 (跟HG基本无关, 请再三确认)
- 确认Schema是否在所有节点完全同步( 初始化的时间长达数分钟,如果时间过短很可能二级索引没有完全构建好, 很难发现), 正常情况Cassandra写入很稳定, 几乎不会出现任何卡顿
- 确认Cassandra的配置是否合理, 如果不确定建议先使用官方配置.
- Cassandra目前读取速度是后端里最慢的. 具体原因可能还需要确定
4. HBase读写相关问题
- Failed to do request: 用loader进行数据导入时出现报错
com.baidu.hugegraph.rest.ClientException: Failed to do request
,官方解释是由于短时间内大量建立tcp连接导致的, 可以尝试开启Linux内核参数(vi /etc/sysctl.conf
):
1 | net.ipv4.tcp_tw_reuse = 1 #表示重用TIME-WAIT socket |
还有一些问题, 但是好像有点遗忘了… 想起来再补充把, 核心的应该是这些, 主要是测试的时候多级的缓存(包括内存)的干扰会严重影响测试结果, 务必注意统一测试环境..
参考资料: