本文提供了GDMBASE数据装载的实践,包括影响装载的一些关键因素和操作步骤。
cypher-loader 是用于将本地文本数据以全量/增量的方式导入到图库的高效数据装载工具。
1 数据环境
数据
- 初始化数据文件大小约100G(社交网络模型),含8类点标签、23类边标签,导入图库后预估顶点约2.8亿,边17.7亿。
- 业务数据预估单日增长100万点边。
环境
- 操作系统:Centos7.6
- CPU架构:x86
- CPU核数:16核
- 内存:64G
- 硬盘:SSD 256G
2 图库规划
根据GDMBASE分区容量推荐,结合本套数据的规模以及数据增长量,计划将图拆分为5个数据分区。
根据GDMBASE系统资源推荐,本次采用三节点的方式部署。
当然,如果单台服务器硬件资源充足,且不用考虑系统的高可用,可以采用单机方式部署,减少网络通信交互以提升部分性能。
3 装载模式选择
初始化装载推荐选择分组模式,性能更优,本方案首次装载选择分组模式。
增量装载仅支持普通模式,增量装载时修改为普通模式。
分组模式是根据边标签进行分组,对应分组的数据导入完成后会及时释放内存,系统内存要求更低。
普通模式在装载的过程中须等待所有点边入库后才会释放内存,系统内存占用更高。
通过修改cypher-loader.yaml配置实现模式的选择。
loadMod: 0 #0-普通模式 1-分组模式
4 初始化装载
初始化装载必须保证数据的正确性,若存在脏数据以及重复冗余的数据,需要对数据进行清理,若强行导入,会引入未知问题。
为了满足初始化装载的数据要求:
- 对主键进行了去重处理,保证主键非空且唯一。
- 检查每列数据的类型,确保它们与标签模型定义的字段类型一致。
经过多次实验,调整配置参数如下时导入本数据集的性能更优。
| 参数 | 值 |
|---|---|
| poolSize | 8 |
| batchSize | 2048 |
| cacheMode | 0 |
| cacheSplitCount | 512 |
| fileReadThread | 10 |
| fileParseThread | 6 |
| dataCalculateThread | 6 |
值得注意的是,这套配置仅适用于初始化装载,在执行增量装载时,由于会话管理机制的差异,系统资源占用会特别高,可能导致进程异常,在执行增量装载时,不可复用本套配置。
检查集群状态
通过cypher-shell来检测集群是否正常。
窗口打印Connected to cypher at bolt://0.0.0.0:8111 as user SYSDBA.说明集群状态正常。
集群状态检查完成后,执行装载即可。
./cypher-loader
装载完成,部分截图如下:
vertices have loaded:282637871,成功导入顶点数量为282637871。
edges have loaded:1775513811,成功导入边数量为1775513811。
skip rows of vertices:0,跳过的顶点数量为0。
error rows of vertices:0,错误的顶点数量为0。
skip rows of edges:0,跳过的边数量为0。
error rows of edges:0,错误边数量为0。
通过cypher-shell检查数据。
图空间统计:
各标签数据统计:
各关系数据统计:
添加图片注释,不超过 140 字(可选)
5 增量装载
实际业务中增量的数据可能已经存在于系统中,在导入时,需要系统完成重复校验、冲突检查。
通过调整装载参数来选择数据的覆盖策略,在主键相同时,可以选择保留旧的数据记录或新数据覆盖原有记录。
考虑到数据更新问题,本次选择覆盖策略为新数据覆盖原有旧纪录。
覆盖策略设置的参数名为 overrideModeForVertex 和 overrideModeForEdge ,分别定义顶点和边的覆盖模式。
本次增长的业务数据中,Person、Post、PersonLikesPost三个数据文件更新了数据,接下来我们将这些数据文件导入到现有20亿存量数据的ldbc100图中。
person表
post表
person_likes_post表
增量装载时,将装载的配置调整为默认配置:
| 参数 | 值 |
|---|---|
| poolSize | 2 |
| fileReadThread | 4 |
| fileParseThread | 2 |
| dataCalculateThread | 2 |
装载的结果如下。
如图:
skip rows of vertices :4 ,跳过的顶点数量为4, 经排查为类型冲突导致失败。
error rows of edges :3 ,错误的边数量为3,经排查为边找不到起点或终点导致失败。
一般地,当数据识别出错时,会在控制台直接打印错误,数据识别通过但入库失败,则会记录到错误数据文件目录下(GDMBASE/loader_error/)。
我们看到loader控制台打印了strconv.ParseInt信息,一般为类型转换失败,接下来我们去对比Person标签模型和源文件Person表的数据类型。
查询Person标签模型信息,如下图:
检查Person表的数据类型,如下图:
可以看到Person标签的属性birthday,creationDate类型为int64,而实际在源数据Person表中为字符串,类型冲突导致异常。
紧接着我们再去对比Post标签模型和源文件Post表的数据类型。
查询Post标签模型信息,如下图:
检查Post表的数据类型,如下图:
可以看到Post标签的属性length类型为int64,而实际在源数据Post表中为字符串,类型冲突导致异常。
其实控制台已经把异常数据通过日志的方式打印了出来,并且提示了类型转换失败,与我们的分析结果一致。
通过cypher-shell查看标签下数据是否正确。
源文件Person表有10行记录,其中2行记录由于类型冲突装载失败,预估导入8条,导入前Person顶点数量为448626,导入后数量为448634,实际导入8条,故导入Person标签的数据正确。
源文件Post表有10行记录,那为什么Post标签下数据没有发生变化呢?结合loader控制台提示,发现有2条数据是因为类型冲突失败,接下来我再去检查源数据文件,发现剩余未写入的8条数据,其主键和库中数据主键重复,所以Post标签下没有新数据增加,属性完成了覆盖。
loader打印边有三条error记录,但是控制台却没有给出任何提示,那么我们找到loader_error目录,进入目录中发现有个person_likes_post.csv文件,
我们打开文件看看,发现确实有3条记录,我们初步猜测是由于边找不到起点或终点导致装载失败。
接下来我们去库中,查询这3条边关联的顶点来证实猜想。
首先我们查询标签为Person,主键为c4398046620972的顶点。
其次我们查询标签为Person,主键为b4398046602614的顶点。
最后我们查询标签为Person,主键为a2199023674456的顶点。
验证三条边关联的起点都不存在,猜想正确。
6 断点续传
大数据集的增量装载一般耗时较长,长时间运行,进程可能发生非正常中断。如果每次重启都从头开始,需要耗费大量时间。
下面我们来试一试断点续传这个功能。
在使用断点续传功能前,需要开启断点续传开关,这样一来,即使装载过程中由于突发原因导致进程中断,仍可基于已有进度继续执行,节省装载时间。
breakpointResume: true
下面是本人实际操作中loader被kill掉后,继续拉起装载进行断点续传的截图。
loader进程被中断,如下图:
中断后重新拉起loader,可以看见装载进度直接到达60%,如下图:
启用断点续传功能并成功完成数据装载,如下图:
通过cypher-shell工具来检查装载结果,装载前库中存在1条顶点记录,增量装载完成显示导入顶点数量为4606215,导入边数量为6127699,装载后在库中实际查询顶点数量为4606216,边数量为6127699,故断点续传装载数据正确。
装载中断后重新拉起,装载进度从断开前的某一可靠时刻开始执行,且装载后检查实际写入数据正确,建议大家在增量装载时可以开启断点续传,提升装载的容错性。
7 小结
在本文中,我们探索了GDMBASE数据装载的各种实践方法,涵盖图库规划、装载模式选择、初始化装载、增量装载和断点续传等多个方面。
数据装载是数据库使用过程中至关重要的一环,希望本文能给使用者提供一些数据入库实操的帮助。