hugegraph core性能优化 - 提升插入速度35%
背景
HugeGraph是一个Java语言编写的图数据库,也是开源的项目,本文记录了一次HugeGraph早期优化性能的过程分析与结果。
HugeGraph之前使用Cassandra后端时,插入数据基本上90%时间花在写数据库操作上。随着后端存储RocksDB性能的不断优化(目前已达到 12w edges/s),HugeGraph在插入数据时core本身所占时间比重越来越大,因此core本身性能的优化又一次提上日程。
如何优化性能?
大体步骤
- 找一个性能分析工具监控程序运行状态(这里用的是hugegraph本身性能工具watched);
- 利用watched监控插入数据整个过程的状态,拿到各个方法的调用次数与时间等信息;
- 分析性能数据,找出时间比重大的方法,进行代码分析;
- 找到可改进的代码进行优化,重新运行并验证结果。
哪些地方容易成为瓶颈代码?
- 大循环中
- 同步加锁
- 频繁调用
- 申请较大内存操作
- 大集合的增加、删除、查找等操作
- 反射
哪些代码可以优化?
- 日志打印中构造的无用message
- 错误检查中构造的无用message
- 频繁申请过量内存而未充分使用
- 频繁被调用的非final|private小方法
- 频繁调用lambda函数
- 其它,如冗余代码、逻辑本身问题等
优化结果
环境
- Mac 10.11
- Java 8
- HugeGraph v0.5
- RocksDB 5.8.6(uncommitted)
- PerfExample3 thread=1 times=10000 multiple=1
PerfExample3中的性能分析基准代码如下(每次插入100个顶点,循环1万次):
protected void testInsert(GraphManager graph, int times, int multiple) {
final int TIMES = times * multiple;
final int BATCH = 100;
long total = 0;
// Insert in order
for (int i = 0; i < TIMES; i++) {
for (int j = 0; j < BATCH; j++) {
String name = String.format("p-%08d", total++);
Vertex v = graph.addVertex(T.label, "person", "name", name,
"city", "Hongkong", "age", 18);
this.vertices.add(v.id());
}
graph.tx().commit();
}
}
优化前后结果对比
第1次 | 第2次 | 第3次 | 第4次 | 第5次 | 平均 | |
---|---|---|---|---|---|---|
优化前 (vertices/s) | 44232 | 44772 | 43631 | 44849 | 45071 | 44511 |
优化后 (vertices/s) | 59262 | 60771 | 59276 | 60125 | 60602 | 60007 |
优化后平均性能提升34.81%,具体优化代码见http://github.com/hugegraph/hugegraph/3991111/files
优化过程分析
准备工作
1、埋点
首先使用性能工具watched对需要监控的方法进行埋点,比如想对addVertex
方法进行监控,则使用watched工具中的@Watched
注解对其进行装饰即可:
@Watched(prefix = "graph")
public Vertex addVertex(Object... keyValues) {
...
}
2、开启监控模式
默认情况下watched是不进行监控的(本身影响性能),需要在程序启动时打开监控模式。监控哪些类或包都可以指定,下面我们对整个com.baidu.hugegraph
包下的代码都进行监控:
import com.baidu.hugegraph.perf.PerfUtil;