赞
踩
查看系统内核:uname -a
查看操作系统版本:cat /etc/redhat-release
官网地址:https://docs.docker.com/engine/install/centos/
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce-19.03.9 docker-ce-cli-19.03.9 containerd.io
sudo systemctl start docker
sudo docker run hello-world
官网地址:https://docs.docker.com/compose/install/
reference: link
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # github访问太慢用daocloud sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 还是不行把文件下载到本地,然后传到服务器 https://github.com/docker/compose/releases scp -r docker-compose-Linux-x86_64 weixiaochao1@perfsys02.bdg.shbt.qihoo.net:/home/xx mv /home/xx/docker-compose-Linux-x86_64 /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose # 添加软链 sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 验证 docker-compose --version
这个过程比较曲折,对过程不感兴趣可以直接跳到「快捷安装」
官网地址:link
# 源码clone到本地,再上传到服务器
scp -r nebula-graph xxx02.bdg.shbt.qihoo.net:/home/xx
# cmake指令安装
https://www.cnblogs.com/6b7b5fc3/p/12715954.html
# 下载文件上传到服务器,解压后进入到bin目录,执行 ./cmake -version 验证。
# 添加软链(使用绝对路径):
sudo ln -s /home/xx/cmake-3.21.1-linux-x86_64/bin/cmake /usr/bin/cmake
#使用源码安装方式行不通,cmake会去github clone nebula-common,so so so 打算换rpm方式安装,先确认支持rpm,rpm --version
「快捷安装」
xxx,前面都是歧路啊,按下面这个来。。。
https://docs.nebula-graph.com.cn/2.0.1/2.quick-start/2.deploy-nebula-graph-with-docker-compose/
# 切换到root用户 sudo su # 启动: docker-compose up -d # 关闭: docker-compose down # 连接: docker run --rm -ti --network nebula-docker-compose_nebula-net --entrypoint=/bin/sh vesoft/nebula-console:v2-nightly nebula-console -u user -p password --address=graphd --port=9669 # 可以在Studio页面创建图空间,等价于命令创建 # 查看空间: show spaces # 查看标签: show tags # 查看边: show edges # 查看标签下点: fetch prop on <tag name> <vid> # refrence: https://docs.nebula-graph.com.cn/2.0.1/2.quick-start/5.start-stop-service/
# 官网地址
https://docs.nebula-graph.com.cn/2.0.1/nebula-studio/deploy-connect/st-ug-deploy/
# 添加连接:
Host:perfsys02.bdg.shbt.qihoo.net:9669
# 用户名/密码:未设置,用默认的
# 访问地址:
http://host:7001/schema
# 先装go环境
https://github.com/vesoft-inc/nebula-importer/blob/release-v2.0.0-ga/docs/golang-install.md
# 再编译nebula importer源码
https://docs.nebula-graph.com.cn/2.0.1/nebula-importer/use-importer/#
笔者手里有一份可用验证的完整图数据,只不过是json格式,Nebula导入需要csv格式,so 先转换一波。
# 小文件可以在线直接转换
http://www.convertcsv.com/json-to-csv.htm
# 大文件只能是在本地写程序转换了~
https://github.com/alingse/jsoncsv
# 安装工具
# 先安装python运行环境,再安装jsoncsv。
pip install jsoncsv
cat accounts_filter.csv | jsoncsv | mkexcel > real_accounts_filter.csv
上述两种方式转化后格式不符,最终还是Java手写额~
public class JsonToCsv { private static String[] tagHeaderArray = new String[]{":VID(string)", "accounts.record_date:string", "accounts.record_time:string", "accounts.acct_id:string", "accounts.dsply_nm:string", "accounts.type:string", "accounts.acct_stat:string", "accounts.acct_rptng_crncy:string", "accounts.prior_sar_count:string", "accounts.branch_id:string", "accounts.open_dt:string", "accounts.close_dt:string", "accounts.initial_deposit:string", "accounts.tx_behavior_id:string", "accounts.bank_id:string", "accounts.country:string"}; private static String[] edgeHeaderArray = new String[]{":SRC_VID(string)", ":DST_VID(string)", ":RANK", "transactions.record_date:string", "transactions.record_time:string", "transactions.tran_id:string", "transactions.orig_acct:string", "transactions.bene_acct:string", "transactions.tx_type:string", "transactions.base_amt:double", "transactions.tran_timestamp:string", "transactions.is_sar:string", "transactions.alert_id:string"}; public static void main(String[] args) { System.out.println("=============== start ==============="); // 转换tag数据 accounts_filter.csv共计 1000000 条数据 // String readDataPath = "D:\\data_tmp\\account.csv"; // String writeDataPath = "D:\\data_tmp\\real_account.csv"; // String readDataPath = "D:\\Downloads\\datas\\accounts_filter.csv"; // String writeDataPath = "D:\\Downloads\\datas\\real_accounts.csv"; // readJsonWriteCsv(readDataPath, writeDataPath, tagHeaderArray, "tag"); // 转换edge数据 transactions_filter.csv共计 103080302 条数据 // String readDataPath = "D:\\data_tmp\\edge.csv"; // String writeDataPath = "D:\\data_tmp\\real_edge.csv"; String readDataPath = "D:\\Downloads\\datas\\transactions_filter.csv"; String writeDataPath = "D:\\Downloads\\datas\\real_transactions.csv"; readJsonWriteCsv(readDataPath, writeDataPath, edgeHeaderArray, "edge"); System.out.println("=============== end ==============="); } private static void writeRow(List<String> row, BufferedWriter csvWriter) throws IOException { StringBuilder rowStr = new StringBuilder(); for (int i=0; i<row.size(); i++) { if (i == row.size() -1 ) { rowStr.append(row.get(i)); } else { rowStr.append(row.get(i)).append(","); } } csvWriter.write(rowStr.toString()); csvWriter.newLine(); } public static void readJsonWriteCsv(String readDataPath, String writeDataPath, String[] headerArray, String type) { List<String> headerList = Arrays.asList(headerArray); BufferedWriter csvWriter = null; try { // 创建输出csv文件 File csvFile = new File(writeDataPath); csvFile.createNewFile(); // GB2312使正确读取分隔符"," csvWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream( csvFile), "GB2312"), 1024); // 写入文件头 writeRow(headerList, csvWriter); // 读json文件 FileReader fr = new FileReader(readDataPath); Scanner scanner = new Scanner(fr); int rowNum = 0; while (scanner.hasNextLine()) { String oneLineJson = scanner.nextLine(); // System.out.println(oneLineJson); JSONObject jsonObj = JSON.parseObject(oneLineJson); List<String> rowDataList; if ("tag".equals(type)) { rowDataList = getTagRowData(jsonObj); } else if ("edge".equals(type)){ rowDataList = getEdgeRowData(jsonObj, rowNum); } else { rowDataList = new ArrayList<>(); } // 写入文件内容 writeRow(rowDataList, csvWriter); System.out.println("================ 转换条数:" + (rowNum + 1)); rowNum++; } System.out.println("================ rowNum 总条数: " + rowNum); } catch (Exception e) { e.printStackTrace(); } finally { try { csvWriter.flush(); csvWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } private static List<String> getTagRowData(JSONObject jsonObj) { List<String> result = new ArrayList<>(); result.add(jsonObj.getString("acct_id")); result.add(jsonObj.getString("record_date")); result.add(jsonObj.getString("record_time")); result.add(jsonObj.getString("acct_id")); result.add(jsonObj.getString("dsply_nm")); result.add(jsonObj.getString("type")); result.add(jsonObj.getString("acct_stat")); result.add(jsonObj.getString("acct_rptng_crncy")); result.add(jsonObj.getString("prior_sar_count")); result.add(jsonObj.getString("branch_id")); result.add(jsonObj.getString("open_dt")); result.add(jsonObj.getString("close_dt")); result.add(jsonObj.getString("initial_deposit")); result.add(jsonObj.getString("tx_behavior_id")); result.add(jsonObj.getString("bank_id")); result.add(jsonObj.getString("country")); return result; } private static List<String> getEdgeRowData(JSONObject jsonObj, int rank) { List<String> result = new ArrayList<>(); result.add(jsonObj.getString("orig_acct")); result.add(jsonObj.getString("bene_acct")); result.add(String.valueOf(rank)); result.add(jsonObj.getString("record_date")); result.add(jsonObj.getString("record_time")); result.add(jsonObj.getString("tran_id")); result.add(jsonObj.getString("orig_acct")); result.add(jsonObj.getString("bene_acct")); result.add(jsonObj.getString("tx_type")); result.add(jsonObj.getString("base_amt")); result.add(jsonObj.getString("tran_timestamp")); result.add(jsonObj.getString("is_sar")); result.add(jsonObj.getString("alert_id")); return result; } }
可以使用命令创建,也可以在Studio页面创建。
CREATE TAG accounts(record_date string, record_time string, acct_id string, dsply_nm string, type string, acct_stat string, acct_rptng_crncy string, prior_sar_count string, branch_id string, open_dt string, close_dt string, initial_deposit string, tx_behavior_id string, bank_id string, country string);
上传导入的配置文件nebula_import.yml,创建err文件夹(yml文件中使用),上传待导入的原始数据。yml中files配置信息,limit不要设置
nebula_import.yml 配置内容如下
# 连接的Nebula Graph版本,连接2.x时设置为v2。 version: v2 description: example # 是否删除临时生成的日志和错误数据文件。 removeTempFiles: false clientSettings: # nGQL语句执行失败的重试次数。 retry: 3 # Nebula Graph客户端并发数。 concurrency: 10 # 每个Nebula Graph客户端的缓存队列大小。 channelBufferSize: 128 # 指定数据要导入的Nebula Graph图空间。 space: anti_money_laundering # 连接信息。 connection: user: user password: password address: 127.0.0.1:9669 # 错误等日志信息输出的文件路径。 logPath: /home/weixiaochao1/anti_money_laundering/vertex/err/fail.log # CSV文件相关设置。 files: # 数据文件的存放路径,如果使用相对路径,则会将路径和当前配置文件的目录拼接。本示例第一个数据文件为点的数据。 - path: /home/weixiaochao1/anti_money_laundering/vertex/real_accounts.csv # 插入失败的数据文件存放路径,以便后面补写数据。 failDataPath: /home/weixiaochao1/anti_money_laundering/vertex/err/fail_real_accounts.csv # 单批次插入数据的语句数量。 batchSize: 100 # 上传导入配置yml文件,创建err文件夹(yml文件中使用),上传待导入的原始数据。 #limit: 10 # 是否按顺序在文件中插入数据行。如果为false,可以避免数据倾斜导致的导入速率降低。 inOrder: false # 文件类型,当前仅支持csv。 type: csv csv: # 是否有表头。 withHeader: true # 是否有LABEL。 withLabel: false # 指定csv文件的分隔符。只支持一个字符的字符串分隔符。 delimiter: "," schema: # Schema的类型,可选值为vertex和edge。 type: vertex
# 进入到nebula安装目录
./nebula-importer --config /home/weixiaochao1/anti_money_laundering/vertex/accounts_import.yml
CREATE EDGE transactions(record_date string, record_time string, tran_id string, orig_acct string, bene_acct string, tx_type string, base_amt double, tran_timestamp string, is_sar string, alert_id string);
文件太大了,先压缩再上传,yml文件edge的配置和vertex不同,nebula_importer.yml配置内容如下
# 连接的Nebula Graph版本,连接2.x时设置为v2。 version: v2 description: example # 是否删除临时生成的日志和错误数据文件。 removeTempFiles: false clientSettings: # nGQL语句执行失败的重试次数。默认 3 retry: 3 # Nebula Graph客户端并发数。 concurrency: 20 # 每个Nebula Graph客户端的缓存队列大小。 channelBufferSize: 128 # 指定数据要导入的Nebula Graph图空间。 space: anti_money_laundering # 连接信息。 connection: user: user password: password address: 127.0.0.1:9669 # 错误等日志信息输出的文件路径。 logPath: /home/weixiaochao1/anti_money_laundering/edge/err/fail.log # CSV文件相关设置。 files: # 数据文件的存放路径,如果使用相对路径,则会将路径和当前配置文件的目录拼接。本示例第一个数据文件为点的数据。 - path: /home/weixiaochao1/anti_money_laundering/edge/real_transactions.csv # 插入失败的数据文件存放路径,以便后面补写数据。 failDataPath: /home/weixiaochao1/anti_money_laundering/edge/err/fail_real_transactions.csv # 单批次插入数据的语句数量。 batchSize: 200 # 读取数据的行数限制。不要限制啊,要不只能导入10条数据 # limit: 10 # 是否按顺序在文件中插入数据行。如果为false,可以避免数据倾斜导致的导入速率降低。 inOrder: true # 文件类型,当前仅支持csv。 type: csv csv: # 是否有表头。 withHeader: true # 是否有LABEL。 withLabel: false # 指定csv文件的分隔符。只支持一个字符的字符串分隔符。 delimiter: "," schema: # Schema的类型,可选值为vertex和edge。 type: edge edge: # 边类型名称。 name: transactions # 是否包含rank。 withRanking: true
# 配置:客户端并发数concurrency=20,单批次插入数据量batchSize=200
# 效果:每秒导入7W条数据
./nebula-importer --config /home/weixiaochao1/anti_money_laundering/edge/transactions_import.yml
边数据导入一半,疯狂报错,查看日志发现磁盘剩余空间不足,有点方啊~~
df -h
查看大文件目录
du -sh /* | sort -nr
du -sh /home/* | sort -nr
du -h | grep G
发现个 31G 的txt文件,删除后,空间依然不够用,没办法进行扩容吧~
fdisk -l #查看磁盘分区 df -h #查看磁盘容量 lsblk -f #查看系统分区,磁盘挂载 lsblk #查看各分区容量 lvdisplay #查看已经存在的lv信息 #eg: lvextend -L 120G /dev/mapper/centos-home #增大至120G lvextend -L +20G /dev/mapper/centos-home #增加20G lvreduce -L 50G /dev/mapper/centos-home #减小至50G lvreduce -L -8G /dev/mapper/centos-home #减小8G resize2fs /dev/mapper/centos-home #执行调整 #实操命令: lvextend -L +100G /dev/VolGroup00/LogVol03 resize2fs /dev/VolGroup00/LogVol03 #不生效,执行下面两个命令 xfs_info /dev/VolGroup00/LogVol03 xfs_growfs /dev/VolGroup00/LogVol03 reference: https://www.cnblogs.com/liyy7520/p/11905979.html
操作系统:CentOS Linux release 7.8.2003 (Core)
CPU:逻辑 48 核
内存:125G
磁盘:200G
顶点数据量 | 边数据量 |
---|---|
1000000条/128M | 103080302条/12G |
#唯一标识查询顶点速度,执行50次作为样本
fetch prop on accounts "996997";
#耗时:0.6us ~ 0.8us
#唯一标识查询边速度,执行50次作为样本
fetch prop on transactions "344527" -> "328642"@743;
#耗时:0.7us ~ 0.8us
#go拓展节点速度,执行30次作为样本
GO FROM "344527" OVER transactions;
#一跳耗时:0.7us ~ 0.9us
GO 2 steps FROM "344527" OVER transactions;
#两跳耗时:0.7us ~ 0.9us
GO 3 steps FROM "344527" OVER transactions;
#三跳耗时:0.8us ~ 0.9us
GO 4 steps FROM "344527" OVER transactions;
#四跳耗时:0.8us ~ 1us
准备工作
#创建索引后才能使用 Match 语句。
CREATE TAG INDEX i_accounts_acctId on accounts(acct_id(10));
#创建索引后不生效,执行索引重建。
REBUILD TAG INDEX i_accounts_acctId;
#查看索引状态。
SHOW TAG INDEX STATUS;
https://docs.nebula-graph.com.cn/2.0.1/3.ngql-guide/14.native-index-statements/4.rebuild-native-index/
MATCH p=(v:accounts{acct_id:"344527"})-->(v2) RETURN p;
#走一步,匹配 15 条路径,耗时:0.5us ~ 0.9us
MATCH p=(v:accounts{acct_id:"344527"})-->(v2)-->(v3) RETURN p;
#走两步,匹配 225 条路径,耗时:0.2us ~ 0.3us
MATCH p=(v:accounts{acct_id:"344527"})-->(v2)-->(v3)-->(v4) RETURN p;
#走三步,匹配 7200 条路径,耗时:0.05us ~ 0.1us
MATCH p=(v:accounts{acct_id:"344527"})-->(v2)-->(v3)-->(v4)-->(v5) RETURN p;
#走四步,匹配 65025 条路径,耗时:0.05us ~ 0.2us
MATCH p=(v:accounts{acct_id:"999978"})-->(v2) RETURN p;
#走一步,匹配 9829 条路径,耗时:0.06us ~ 0.1us
MATCH p=(v:accounts{acct_id:"999978"})-->(v2)-->(v3) RETURN p;
#未跑出结果
超级顶点 999978 关联 9829 个点
GO FROM "999978" OVER transactions;
#一跳耗时:0.09us ~ 0.14us,获取行数:9829
GO 2 steps FROM "999978" OVER transactions;
#两跳耗时:0.2us ~ 0.3us,获取行数:9365
GO 3 steps FROM "999978" OVER transactions;
#三跳耗时:0.2us ~ 0.3us,获取行数:19925
GO 4 steps FROM "999978" OVER transactions;
#四跳耗时:0.1us ~ 0.2us,获取行数:85437
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。