大家好,我是洋仔,JanusGraph图解系列文章,`实时更新`~
图数据库文章总目录:
- 整理所有图相关文章,请移步(超链):图数据库系列-文章总目录
- 地址:https://liyangyang.blog.csdn.net/article/details/111031257
源码分析相关可查看github(求star~~): https://github.com/YYDreamer/janusgraph
下述流程高清大图地址:https://www.processon.com/view/link/5f471b2e7d9c086b9903b629
版本:JanusGraph-0.5.2
转载文章请保留以下声明: >作者:洋仔聊编程 >微信公众号:匠心Java >原文地址:[https://liyangyang.blog.csdn.net/](https://liyangyang.blog.csdn.net/)
源码分析 的第一步就是要先编译好源代码,才能进行debug跟踪流程查看,本文总结了janusgraph源码编译
的全流程!
主要介绍了janusgraph hbase es
的本地源码编译过程,最后介绍了janusgraph berkeleyje es
的编译过程。
源码已经上传个人github:https://github.com/YYDreamer/janusgraph
欢迎star和fork~
本文所有的 janusgraph源码项目文件 hadoop安装包 hadoop在windows的辅助安装包 hbase安装包 es安装包全部整合放到了公众号“匠心Java”中,微信搜索“匠心Java
”,回复“图库资源
”四个字即可
一 本地安装依赖环境
本机安装hbase
环境,这里我后台存储使用的是 hbase,这里为了更好的符合正常的使用情况,没有用janusgraph自带的inmemory
存储形式
ps:如果你在其他服务器有hbase和es环境,就不用自己本地搭建了,如果没有的话,我们在本地搭建一个自己的hbase和es,这种网上特别多,下面也给出了我自己搭建看的博客连接
1. 安装hadoop 并 启动
hbase依赖于hadoop环境,所以我们在安装hbase前,先安装hadoop环境
安装:参考博客:hadoop安装教程
启动:
- 管理员方式打开
cmd
- 转到对应的hadoop的sbin目录下,例如我的:
D:appapp_develophadoop-2.7.7sbin
- 使用命令
start-all
* 出现四个黑框框:hadoop namenode、hadoop datanode、yarn resourcemanager、yarn nodemanager
即可 - 访问
http://localhost:50070
,可以访问即为成功!
2. 安装hbase 并 启动
注意:在选择安装hbase的版本时,需要查看自己下载的janusgraph源码的版本支持hbase的什么版本
这里我们选择的是janusgraph-0.5.2版本,支持hbase-2.1.x版本,所以这里我下载的hbase-2.1.5版本
安装:参考博客:hbase安装教程
启动:
- 管理员方式打开
cmd
- 转到对应的hadoop目录下,例如我的:
D:appapp_develophbase-2.1.5bin
- 输入命令,回车
start-hbase.cmd
- 出现一个黑框框,如下
- 在hbase的bin目录下,输入命令
hbase shell
,能成功连接hbase shell,即为成功!
如果启动报错:java.lang.ClassNotFoundException: org.apache.htrace.core.HTraceConfiguration
解决方法: 将本地hbase-2.1.5目录下的libclient-facing-thirdparty
目录下的htrace-core-3.1.0-incubating.jar
和htrace-core4-4.2.0-incubating.jar
赋值到路径lib
下,重新start-hbase.cmd
命令,启动成功!
3. 安装es 并 启动
安装:参考博客:es安装教程
启动:
- 管理员方式打开
cmd
- 转到对应的hadoop目录下,例如我的:
D:appapp_developelasticsearch-6.8.3bin
- 输入命令,回车
elasticsearch.bat
- 输入完命令后,当前的黑框中会启动es,最终出现下述:
- 访问
http://localhost:9200/
,出现下述json即为成功!
{
"name" : "99Xn4Vd",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "YpMeVAlzQRuzuVis1JzHpA",
"version" : {
"number" : "6.8.3",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "0c48c0e",
"build_date" : "2019-08-29T19:05:24.312154Z",
"build_snapshot" : false,
"lucene_version" : "7.7.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
最终,我们使用jps
可以看到我们刚才启动的进程,如下图:
经过上述步骤,我们
- 编译好了janusgraph-0.5.2的源代码
- 在本地安装了hbase、es的环境并启动
二. 配置文件修改和添加对应的依赖
1. 修改对应的配置文件
上述代码使用的是hbase 和 es作为底层存储和索引后端的, 这里我们找到对应的源码中janusgraph-dist
模块下的srcassemblycfilterconfjanusgraph-hbase-es.properties
下的这个文件:
ps: 这里我用的是自己的绝对路径,其实这个文件是在janusgraph-dist
模块下的一个文件,如下图:
将下面的代码注释删除掉,并删除JANUSGRAPHCFG
字段和对应的大括号,下面默认使用的是本地的hbase和es 如果你需要配置远程的hbase和es注意修改对应的ip,修改后如下:
gremlin.graph=org.janusgraph.core.JanusGraphFactory
storage.backend=hbase
storage.hostname=127.0.0.1
cache.db-cache = true
cache.db-cache-clean-wait = 20
cache.db-cache-time = 180000
cache.db-cache-size = 0.5
index.search.backend=elasticsearch
index.search.hostname=127.0.0.1
2. 添加相应依赖
我们在janusgrap-test
模块编写自己的单测并运行,因为在janusgraph-test
模块中使用的是inmory
也就是内存作为存储后端的,没有对应的hbase和es
依赖
而我们上述使用的是es 和 hbase所以添加了对应的依赖,根据你使用的在janusgraph-test
模块的pom
文件下添加对应依赖即可
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-hbase</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-hbase-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-hbase-10</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-hbase-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-es</artifactId>
<version>${project.version}</version>
</dependency>
三:下载janusgraph源码并编译
1. 下载janusgraph的源码到本地编译器
方式一:
使用git的话,可以直接使用git clone
从janusgraph的github仓库来clone一份远程代码到本地
janusgraph 的 github地址: https://github.com/JanusGraph/janusgraph
代码语言:javascript复制git clone https://github.com/JanusGraph/janusgraph
方式二:
也可以直接下载源码的zip包,本地解压之后,用idea打开也可以
然后 git init
初始化为git项目做版本控制,关联到clone到自己的远程仓库即可
注意修改为自己的maven仓库
我的github中janusgraph对应的地址:https://github.com/YYDreamer/janusgraph,会将源码分析过程中相关修改提交到该仓库!
1.经过上述的步骤,我们在idea中便有了一个一个janusgraph源码的项目,我们首先去除对应的maven插件
- 将项目
最外层
的pom.xml
中的插件maven-enforcer-plugin
部分注释掉,不然会出现Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M2:enforce enforce-dependency-convergence) on project janusgraph-test: Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed.
错误! - 将
janusgraph-dist
模块中的pom.xml
文件下的download-maven-plugin
插件注释掉,不然会出现org.apache.http.conn.HttpHostConnectException: Connect to artifacts.elastic.co:443 [artifacts.elastic.co/151.101.110.222] failed: Connectiontimed out: connect
错误!
2.接下来,进行编译,点击idea下面的Terminal
,输入命令:
编译项目全部模块:
mvn clean install -DskipTests -Drat.skip=true
或者单独编译一个模块,下面以janusgraph-test
模块示例:
mvn -pl janusgraph-test -am clean install -Dlicense.skip=true -DskipTests -P prod
这里,我们使用全部编译的语句,将项目全部编译!
3.最后全部success
即可! 过程可能有点慢,如果看到编译过程在下载es等组件的话,可以先将下面讲的环境搭建起来,再用上述语句进行编译,成功图如下:
错误解决:
- 打开项目后,可能会发现有的pom文件报错,一是看看你的maven有没有正确配置,二是可能是maven的本地仓库索引没有更新,可以参考博客:pom问题解决,超链接直接点击即可
四. 编写单测 并 运行
1. 编写单测
在janusgraph-test
模块下的test
目录下,新建一个’mytest’文件夹,编写一个单元测试JanusGraphFirstTest
,如下:
public class JanusGraphFirstTest {
@Test
public void firstTest() {
// 创建图实例,存储使用hbase,索引使用es
// TODO 注意!文件路径修改为自己当前电脑下的绝对路径
JanusGraph graph = JanusGraphFactory
.open("D:\code\janusgraph-0.5.2\janusgraph-dist\src\assembly\cfilter\conf\janusgraph-hbase-es.properties");
// 使用GraphOfTheGodsFactory加载“The Graph of the Gods”图,这是JanusGraph用于测试自定义的一个图
GraphOfTheGodsFactory.load(graph);
// 获取图遍历对象实例
GraphTraversalSource g = graph.traversal();
// 获取属性"name"为"saturn"的节点
Vertex saturn = g.V().has("name", "saturn").next();
// 获取上述节点对应的所有属性的kv
GraphTraversal<Vertex, Map<Object, Object>> vertexMapGraphTraversal = g.V(saturn).valueMap();
// 输出
List<Map<Object, Object>> saturnProMaps = vertexMapGraphTraversal.toList();
for (Map<Object, Object> proMap : saturnProMaps) {
proMap.forEach((key,value) -> System.out.println(key ":" value));
}
// 获取上述节点的father的father的姓名,也就是grandfather的姓名
GraphTraversal<Vertex, Object> values = g.V(saturn).in("father").in("father").values("name");
String name = String.valueOf(values.next());
System.out.println("grandfather name:" name);
// 获取在(latitude:37.97 and long:23.72)50km内的所有节点
GraphTraversal<Edge, Edge> place = g.E().has("place", geoWithin(Geoshape.circle(37.97, 23.72, 50)));
// 获取边对应的节点
GraphTraversal<Edge, Map<String, Object>> node = place.as("source")
.inV().as("god2")
.select("source")
.outV().as("god1")
.select("god1", "god2").by("name");
// 输出
List<Map<String, Object>> maps = node.toList();
for (Map<String, Object> map : maps) {
map.forEach((key,value) -> System.out.println(key ":" value));
}
}
}
注意!!!!!! 在上述新添加的JanusGraphFirstTest
文件中最上面
添加下面的注释,不然会因为不符合开源规则编译会报错!
并且! 我们在源码分析过程中,添加了任何的文件或者修改了原有的文件,下面的注释都是必须要加在文件最上面并且不可以删除!!
代码语言:javascript复制// Copyright 2020 JanusGraph Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
运行上述单测,前提保证hadoop、hbase、es都在启动状态!
2. 运行成功后
首先,cmd
进入hbase的bin
目录下,运行hbase shell
命令,进入到hbase 的 shell界面:
2.1 输入list
命令,如下,可以发现存在一个叫做janusgraph
的表,这就是我们刚才运行的单测生成的一个默认table,用来存储对应的图数据
hbase(main):005:0> list
TABLE
janusgraph
1 row(s)
Took 0.0070 seconds
=> ["janusgraph"]
hbase(main):006:0>
2.2 输入desc 'janusgraph'
命令,如下,查看对应的table schema,我们可以看到表状态为ENABLE
可用状态,并且下面跟着好大一坨列簇和列的信息
其中的列簇efghilmst
都存了对应的图信息,具体存了图的什么信息,我们下面的博文会分享,这里不做描述了
hbase(main):012:0* desc 'janusgraph'
Table janusgraph is ENABLED
janusgraph
COLUMN FAMILIES DESCRIPTION
{NAME => 'e', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEH
AVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false',
DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATI
ON_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMOR
Y => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'fals
e', COMPRESSION => 'GZ', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
# 省略了一部分...
注意:
单测中包含GraphOfTheGodsFactory.load(graph)
代码,是将janusgraph自带的一个测试图导入到hbase中,供我们测试使用,首次运行单测成功后,我们要把这个语句GraphOfTheGodsFactory.load(graph)
注释掉,不需要重新load这个测试图!
五. 底层存储使用berkeleyje
数据库和es
索引后端
我们只需要将上述单测代码中的配置文件路径配置文件修改为相同位置
下的janusgraph-berkeleyje-es.properties
即可,将对应配置的注释去掉!
然后,将对应的依赖放到janusgraph-test
对应的pom文件中:
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-es</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.janusgraph</groupId>
<artifactId>janusgraph-berkeleyje</artifactId>
<version>${project.version}</version>
</dependency>
运行即可!