neo4j 学习记录(二)

Neo4j 导入数据的几种方式对比

1.  遇到的问题

 

在使用Neo4j时遇到一个问题,需要导入上百亿数据(同时导入节点和关系),想找一个最合适的方案来导入数据。于是就想测测各种导入方式的效率以及成本。

 

 

2.  常见数据导入方式概览

 

(1) Cypher create 语句,为每一条数据写一个create

(2) Cypher load csv 语句,将数据转成CSV格式,通过LOAD CSV读取数据。

(3) 官方提供的neo4j-import工具,未来将被neo4j-adminimport代替

(4) 官方提供的Java API    BatchInserter

(5) 大牛编写的 batch-import 工具

(6) neo4j-apocload.csv +apoc.load.relationship

(7) 针对实际业务场景,定制化开发

 

这些工具有什么不同呢?速度如何?适用的场景分别是什么?

 

create语句

load csv语句

neo4j-import

BatchInster

batch-import

apoc

适用场景

 

 

初始化导入

增量更新

 

初始化导入

 

初始化导入

 

初始化导入

增量更新(有限制)

 

增量更新

导入速度

很慢1000/s

数k /s

数w/s

数w/s

数w/s

数k/s

实际测试

9.5k/s

(节点+关系)

12w/s

(节点+关系)

1w/s

(节点+关系)

1w/s

(节点+关系)

4k/s(1亿数据上增量更新) 1w/s(百万数据上增量更新)

优点

1.使用方便

2.可实时插入

1.官方ETL工具

2.可以加载本地/远程CSV

3.可实时插入

1.官方工具

2.占用资源少

1.官方API

1.可以增量更新

2.基于BatchInserter

1.官方ETL工具

2.可以增量更新

3.支持在线导入

4.支持动态传Label  RelationShip

缺点

1.速度慢

2.处理数据,拼CQL复杂

1.导入速度较慢

2.不能动态传Label  RelationShip

1.需要脱机导入 停止Neo4j数据库

2.只能用于初始化导入

1.需要脱机导入 停止Neo4j数据库

2.需要在JAVA环境中使用

 

1.需要脱机导入 停止Neo4j数据库

1.速度一般

 

注释:本次测试使用的id(不是Neo4j id)类型是String,为uuid,如果同一Label下数据不超过2^32,可以用int类型

 

3.  各种导入方法实际测试

 

3.1  create

 

未测试。

批量插入语句

./bin/neo4j-shell-c < /data/stale/data01/neo4j/neo4j_script.cypher

 

 ./bin/neo4j-shell  -path ./data/dbms/  -conf ./conf/neoo4j.conf  -file create_index.cypther

 

3.2  load csv

 

load csv 不能动态传Label、RelationShip,所以测试时Label、RelationShip是写死的

 

数据格式

uuid,name,Label

b6b0ea842890425588d4d3cfb38139a9,"文烁",Label1

5099c4f943d94fa1873165e3f6f3c2fb,"齐贺喜",Label3

c83ed0ae9fb34baa956a42ecf99c8f6e,"李雄",Label2

e62d1142937f4de994854fa1b3f0670a,"房玄龄",Label

 

3.2.1  导入10w节点

 

neo4j-sh (?)$ using periodic commit 10000 load csv with headers from "file:/data/stale/data01/neo4j/node_uuid_10w.csv" as line with line create (:Test {uuid:line.uuid, name:line.name});
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 100000
Properties set: 200000
Labels added: 100000
3412 ms

10万数据(只有节点,没有关系)导入用时3.412s

 

 

3.2.2  导入1kw节点

 

neo4j-sh (?)$ load csv from "file:/data/stale/data01/neo4j/node_uuid_1kw.csv" as line return count(*);
+----------+
| count(*) |
+----------+
| 10000010 |
+----------+
1 row
7434 ms
neo4j-sh (?)$ using periodic commit 10000 load csv with headers from "file:/data/stale/data01/neo4j/node_uuid_1kw.csv" as line with line create (:Test {uuid:line.uuid, name:line.name});
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 10000009
Properties set: 20000018
Labels added: 10000009
151498 ms

1千万数据(只有节点,没有关系)导入用时151.498s

 

 

3.2.3  导入100w关系

 

neo4j-sh (?)$ using periodic commit 100000 load csv with headers from "file:/data/stale/data01/neo4j/relathionship_uuid_100w.csv" as line with line merge (n1:Test {uuid:line.uuid1}) merge (n2:Test {uuid:line.uuid2}) with * create (n1)-[r:Relationship]->(n2);
+-------------------+
| No data returned. |
+-------------------+
Relationships created: 1000000
75737 ms

创建100w关系用时75.737s

 

因为我节点已经提前导入了,所以merge的时候节点全部存在,根据结果可以看到,只创建了100w关系,没有创建节点

但是这种方式有一个弊端,关系要写死,在只有一种关系时试用,在有多种关系时,不适用。还有一个不好的地方就是用的merge,uuid是String类型,会随着数据的正常速度变慢。

 

load csv 的速度我用的是导入节点时间+导入关系时间

导入100w 节点+数据 (Label写死,RelationShip写死,也就是只有一种Label和一种RelationShip) 共花费15.149 + 75.737 = 90.886 。load csv的速度大概在1.1w/s,但这种情况一般很少使用,仅供参考。

 

 

3.3  neo4j-import

 

3.3.1  数据格式

 

node.csv

uuid:ID(users),name:String,:Label
c63bc1e7dc594fd49fbe36dd664ff0a6,"维特",Label1
b52fb5f2266b4edbadc82b5ec4c430b8,"廖二松",Label2
d95d430cfeee47dd95f9bf5e0ec1ae93,"徐青偏",Label3
b2d1fffc8173461fa603d4fbb601b3ee,"杨础维",Label2

 

relationship.csv

1
2
3
4
5
uuid:START_ID(users),uuid:END_ID(users),:TYPE
c63bc1e7dc594fd49fbe36dd664ff0a6,b2d1fffc8173461fa603d4fbb601b3ee,RelationShip1
d95d430cfeee47dd95f9bf5e0ec1ae93,c63bc1e7dc594fd49fbe36dd664ff0a6,RelationShip2
b2d1fffc8173461fa603d4fbb601b3ee,b52fb5f2266b4edbadc82b5ec4c430b8,RelationShip3
b52fb5f2266b4edbadc82b5ec4c430b8,d95d430cfeee47dd95f9bf5e0ec1ae93,RelationShip1

 

 

3.3.2  导入1000w数据

 

IMPORT DONE in 27s 932ms. 
Imported:
  10000000 nodes
  10000000 relationships
  20000000 properties
Peak memory usage: 209.81 MB

空库初始化导入1千万数据(1kw节点 1kw关系 2kw属性,id使用integer,属性中只有数字和英文)花费27s 932ms

 

 

3.3.3  导入1000w数据

 

IMPORT DONE in 1m 50s 9ms. 
Imported:
  10000000 nodes
  10000000 relationships
  20000000 properties
Peak memory usage: 209.81 MB

空库初始化导入1千万数据(1kw节点 1kw关系 2kw属性,包含中文属性)花费1min 50s 9ms

 

 

 

3.3.4  导入1.1y数据

 

1
2
3
4
5
6
7
IMPORT DONE in 15m 9s 37ms. 
Imported:
  110000010 nodes
  110000000 relationships
  220000020 properties
Peak memory usage: 2.27 GB
There were bad entries which were skipped and logged into /data/stale/data01/neo4j/neo4j-community-3.1.0/data/databases/test_uuid_1y_graph.db/bad.log

空库初始化导入1.1亿数据(1.1亿节点 1.1关系 2.2亿属性)花费15min 9s 37ms

 

 

3.4  BatchInster

  batch-import调的BatchInserter的代码,所以BatchInserter没测,可以认为BatchInster和batch-import速度一样

 

 

3.5  batch-import

 

数据格式

 

node.csv

uuid:string:users,name:String,:label
c63bc1e7dc594fd49fbe36dd664ff0a6,"维特",Label1
b52fb5f2266b4edbadc82b5ec4c430b8,"廖二松",Label2
d95d430cfeee47dd95f9bf5e0ec1ae93,"徐青偏",Label3
b2d1fffc8173461fa603d4fbb601b3ee,"杨础维",Label2

 

relationship.csv

uuid:string:users,uuid:string:users,type
c63bc1e7dc594fd49fbe36dd664ff0a6,b2d1fffc8173461fa603d4fbb601b3ee,RelationShip1
d95d430cfeee47dd95f9bf5e0ec1ae93,c63bc1e7dc594fd49fbe36dd664ff0a6,RelationShip2
b2d1fffc8173461fa603d4fbb601b3ee,b52fb5f2266b4edbadc82b5ec4c430b8,RelationShip3
b52fb5f2266b4edbadc82b5ec4c430b8,d95d430cfeee47dd95f9bf5e0ec1ae93,RelationShip1

 

 

1
2
3
4
5
6
7
8
9
Using: Importer batch.properties /data/stale/data01/neo4j/neo4j-community-3.1.0/data/databases/test_uuid_1000w_graph.db /data/stale/data01/neo4j/node_uuid_100w.csv /data/stale/data01/neo4j/relationship_uuid_100w.csv
  
Using Existing Configuration File
..........
Importing 1000000 Nodes took 15 seconds 
..........
Importing 1000000 Relationships took 16 seconds 
  
Total import time: 92 seconds

 

在数据库中已有1kw数据的情况下,导入100w数据(100w节点 100w关系 200w属性,包含中文属性)花费92s

 

 

3.6  apoc

load csv + merge + apoc.create.relationship

 

neo4j-sh (?)$ using periodic commit 1000000
> load csv from 'file:/data/stale/data01/neo4j/relathionship_uuid_1kw.csv' as line fieldterminator ','
> merge (n1:Test {uuid: line[0]})
> merge (n2:Test {uuid: line[1]})
> with n1, n2, line
> CALL apoc.create.relationship(n1, line[2], {}, n2) YIELD rel
> return count(rel) ;
+------------+
| count(rel) |
+------------+
| 10000010   |
+------------+
1 row
Nodes created: 8645143
Properties set: 8645143
Labels added: 8645143
2395852 ms

 

在1.1亿数据上增量更新1kw数据花费2395.852s

VIRT Memory 90G RES Memory 78G

 

因为这部分也用到merge了,数据量越大,速度越慢

 

 

4.  结论

 

根据实际情况选用最好的方式

 

(1)  neo4j-import导入速度快,但是要求是空库,导入时要停止neo4j,也就是脱机导入,而且你要提前处理好数据,数据最好不要有重复,如果有重复,可以导入时跳过,然后根据bad.log来查看或者修正这部分数据

 

(2)  batch-import可以增量导入,但是要求导入时停止neo4j数据库(脱机导入),而且增量更新的数据不会和库里存在的数据对比,所以要求数据全是新的,否则会出现重复数据

 

(3)  load csv比较通用,而且可以在neo4j数据库运行时导入,但是导入速度相对较慢,要提前整理好数据,而且不能动态创建 Label RelationShip

 

(4) apoc挺好用的,可以动态创建Label、RelationShip,但是速度一般

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值