「HugeGraph」图形数据库 - 个人选型文档备份

308 阅读5分钟

(仅为个人操作记录使用)

安装zookeeper

这里安装的是单机模式。版本是zookeeper-3.4.9.tar.gz。已装,步骤略。(看我博客-集群安装

 

安装Hbase单机模式

配置Hbase

1.下载:mirrors.tuna.tsinghua.edu.cn/apache/hbas…

2.~$ gedit .bashrc

# hbase

export HBASE_HOME=/home/raini/app/hbase

export PATH=${HBASE_HOME}/bin:$PATH

3.~$ source .bashrc

hbase-env.sh

## 追加:

export JAVA_HOME=/home/raini/app/jdk

export HBASE_CLASSPATH=/home/raini/app/hbase/conf/

export HBASE_PID_DIR=/home/raini/app/tmp/pids

# 不使用HBase自带的zookeeper

export HBASE_MANAGES_ZK=false

 

zoo.cfg

在这里我们使用的不是HBase自带的zookeeper,而是之前已经装好的,所以需要将我们现在的zookeeper的zoo.cfg文件复制到hbase的conf目录下

hbase-site.xml

#添加如下内容:

<configuration>

  <property>

    <name>hbase.rootdir</name>   

    <value>hdfs://biyuzhe:9000/hbase</value>

  </property>

  <property>

    <name>hbase.cluster.distributed</name>   

    <value>true</value>

  </property>

  <property>

    <name>hbase.zookeeper.quorum</name>   

    <value>127.0.0.1</value>

  </property>

<!--  <property>

<name>hbase.zookeeper.property.clientPort</name>

<value>2181</value>

  </property>

  <property>

    <name>hbase.tmp.dir</name>   

    <value>/home/raini/app/tmp/hbase/</value>

  </property>

  <property>

    <name>hbase.master</name>   

    <value>biyuzhe:60000</value>

  </property>

  <property>

    <name>hbase.zookeeper.property.dataDir</name>

    <value>/home/raini/app/tmp/hbase_zoo_dataDir</value>

  </property>

  <property>

    <name>hbase.wal.provider</name>

    <value>file://home/raini/tmp/hbase-wal</value>

  </property>-->

  <property>

           <name>dfs.replication</name>

           <value>1</value>

  </property>

  <property>

        <name>hbase.master.maxclockskew</name>

        <value>150000</value>

  </property>

  <property>

 

一些注意点:

<configuration>

<property>

<name>hbase.rootdir</name>

<value>file:///usr/local/hbase-1.4.0/data-tmp</value>

</property>

   <property>

<name>hbase.zookeeper.quorum</name>  

<value>localhost</value>  

</property>

 

<property>

<name>hbase.zookeeper.property.clientPort</name>

<value>2181</value>

</property>

 

<property>

<name>hbase.zookeeper.property.dataDir</name>  

<value>/tmp/zookeeper</value>  

</property>

 

<property>

<name>hbase.cluster.distributed</name>

<value>true</value>

</property>

 

<property>

<name>zookeeper.znode.parent</name>

<value>/hbase</value>

</property>

</configuration>

注意的环节:

  1. 一定要加上“伪分布:hbase.cluster.distributed”的这个<property>标签,否则即使是单机的分布【虽然是单机,但是并没有使用HBase自带的zookeeper】,所以理论上还是应该使用伪分布式的搭配。
  2. hbase.rootdir这个属性的值在笔者的环境下是file:///usr/local/hbase-1.4.0/data-tmp,并没有使用hdfs来存储。也就意味着不需要事先启动hdfs。但是如果将这个目录改为hdfs的对应目录,则是需要在启用hbase之前启用hdfs。
  3. hbase.zookeeper.quorum指的是zookeeper服务器的地址,因为这里是单机版,所以直接填写localhost即可。有些博客建议写与hostname不同的主机ip。
  4. hbase.zookeeper.property.clientPort指的是zookeeper的端口号,如果没有修改的话,默认的则是2181。
  5. zookeeper.znode.parent ZooKeeper中的Hbase的根ZNode。所有的Hbase的ZooKeeper会用这个目录的值来配置相对路径。【znode存放root region的地址】默认情况下,所有的Hbase的ZooKeeper文件路径是用相对路径,所以他们会都去这个目录下面。默认: /hbase

---------------------

regionservers

#修改为主机名   <----建议写与hostname不同的主机ip

 

启动HBase

[raini@biyuzhe ~]# start-all.sh #启动hadoop

[raini@biyuzhe ~]# zkServer.sh start #启动zookeeper

[raini@biyuzhe ~]# zkServer.sh status #查看zookeeper状态以及角色

[raini@biyuzhe ~]# start-hbase.sh #启动Hbase

 

启动报错:Caused by: java.lang.ClassNotFoundException: org.apache.htrace.SamplerBuilder

 

解决:

cp $HBASE_HOME/lib/client-facing-thirdparty/htrace-core-3.1.0-incubating.jar $HBASE_HOME/lib/

 

[raini@biyuzhe ~]# JPS 查看hbase进程

 

 

Hbase简单操作

 

 

raini@biyuzhe:~$ hbase shell

hbase(main):001:0> status #查看HBase运行状态

1 active master, 0 backup masters, 1 servers, 0 dead, 0.0000 average load

Took 0.3634 seconds

hbase(main):002:0> exit #退出

 

遇到问题

hbase集群[部分]节点 HRegionServer 启动后自动关闭的问题

注释掉hbase-size.xml这部分得以解决:

<!--  <property>

<name>hbase.zookeeper.property.clientPort</name>

<value>2181</value>

  </property>

  <property>

    <name>hbase.tmp.dir</name>   

    <value>/home/raini/app/tmp/hbase/</value>

  </property>

  <property>

    <name>hbase.master</name>   

    <value>biyuzhe:60000</value>

  </property>

  <property>

    <name>hbase.zookeeper.property.dataDir</name>

    <value>/home/raini/app/tmp/hbase_zoo_dataDir</value>

  </property>

  <property>

    <name>hbase.wal.provider</name>

    <value>file://home/raini/tmp/hbase-wal</value>

  </property>-->

:应该是旧数据的影响,可删除掉这些临时文件

安装hugegraph

下载

wget github.com/hugegraph/h…

tar -zxvf hugegraph-${version}.tar.gz

配置(HBase)

(如果需要快速启动HugeGraph仅用于测试,那么只需要进行少数几个配置项的修改即可)

注:Huge版本低于0.74不支持Hbase后端

修改 hugegraph.properties

backend=hbase

serializer=hbase

 

# hbase backend config

hbase.hosts=localhost

hbase.port=2481

rest-server.properties

修改以被占用端口8080为8686

初始化数据库

(仅第一次启动时需要)

cd hugegraph-${version}

bin/init-store.sh

启动 server

bin/start-hugegraph.sh

Starting HugeGraphServer...

Connecting to HugeGraphServer (http://127.0.0.1:8680/graphs)....OK

 

 

 

问题

(1)

Will not attempt to authenticate using SASL (unknown error)
NoNode for /hbase/meta-region-server, details=row 'hugegraph:schema_si' on table 'hbase:meta' at null
NoNode for /hbase/master, details=row 'hugegraph:schema_si' on table 'hbase:meta' at null

 

解决:

Hbase未成功启动(也可能是假启动-看log有保存,进程启动着), 检查Hbase配置。

 

安装HugeGraph-Loader

下载解压即可使用:

wget github.com/hugegraph/h…

tar zxvf hugegraph-loader-${version}-bin.tar.gz

 

Ps:

其实hugegraph-loader只是简单实现了client提交到hugegraph-server的rest-full,因为不清楚配置,所以hugegraph的服务端口须为8080(与spark相冲--我们安装时设置成了8680),关掉hugegraph之后临时改为8080即可。

使用

../hugegraph-loader-0.8.0/bin/hugegraph-loader ..

 

 

编写schema:

在设计好了图模型之后,我们可以用groovy编写出schema的定义,并保存至文件中,这里命名为schema.groovy。

 

 

gremlin-console

 

安装hugegraph-studio

HugeGraph-Studio是HugeGraph的前端展示工具,是基于Web的图形化IDE环境。通过HugeGraph-Studio,用户可以执行Gremlin语句,并及时获得图形化的展示结果。

 

下载地址:https://github.com/hugegraph/hugegraph-studio/releases/

配置hugegraph-studio.properties

修改graph.server.port=8680       // hugegraph服务的端口

 

启动服务 ${hugegraph-studio_home}/bin/hugegraph-studio.sh

访问 http://${hugegraph-studio_IP}:8688/

创建数据

// 创建属性类型(PropertyKey)

graph.schema().propertyKey("name").asText().ifNotExist().create()

graph.schema().propertyKey("age").asInt().ifNotExist().create()

graph.schema().propertyKey("city").asText().ifNotExist().create()

graph.schema().propertyKey("lang").asText().ifNotExist().create()

graph.schema().propertyKey("date").asText().ifNotExist().create()

graph.schema().propertyKey("price").asInt().ifNotExist().create()

// 创建顶点类型(VertexLabel)

person = graph.schema().vertexLabel("person").properties("name", "age", "city").primaryKeys("name").ifNotExist().create()

software = graph.schema().vertexLabel("software").properties("name", "lang", "price").primaryKeys("name").ifNotExist().create()

//创建边类型(EdgeLabel)

knows = graph.schema().edgeLabel("knows").sourceLabel("person").targetLabel("person").properties("date").ifNotExist().create()

created = graph.schema().edgeLabel("created").sourceLabel("person").targetLabel("software").properties("date", "city").ifNotExist().create()

// 创建顶点(Vertex)和边(Edge)

marko = graph.addVertex(T.label, "person", "name", "marko", "age", 29, "city", "Beijing")

vadas = graph.addVertex(T.label, "person", "name", "vadas", "age", 27, "city", "Hongkong")

marko.addEdge("knows", vadas, "date", "20160110")


输入上面,运行,得到:

 

Hugegraph 数据导入导出 总结

单节点与边的导入方式

1. restful api

POST http://localhost:8080/graphs/${graphname}/graph/vertices

sample:graphname=wikibaikegraph

Request Body

{

    "id":"markold",

     "label":"person"

     "properties":{

            "name":"marko",

            "age":29

            }

}

 

POST http://localhost:8080/graphs/hugegraph/graph/edges

{

    "label": "created",

    "outV": "1:peter",

    "inV": "2:lop",

    "outVLabel": "person",

    "inVLabel": "software",

    "properties": {

        "date": "2017-5-18",

        "weight": 0.2

    }

}

 

2. hugegraph client

Vertex vertex=new Vertex("vertexLabel");

vertex.id(id);

vertex.property("name","value");

new HugeClient(UTL,GraphName).graph().addVertex(vertex);//add Edge

vertex.addEdge(label,targetVertex,"name","value");//the other way

graph.addEdge(sourceId,label,target,property,value);

 

  1. hugegraph-studio
  2. 在Web端运行Gremlin并写代码执行单条插入。

graph.addVertex(T.label,"person,T.id,"id”,"name","midcial")

graph.addEdge(sourceId,label,target,property,value)

数据多节点的批量导入

  1. hugeGraph client

通过Gremlin Java API 进行增加数据。

  1.  

new HugeClient(UTL,GraphName).graph().addVertices(vertex)

new HugeClient(UTL,GraphName).graph().addEdges(edges,false)

Default max size is 300

2. HugeGraph-Loader

测试:

  1. 使用真实交易数据进行操作(未成功)
  2. 通过自己修改数据制作模拟数据逐个排查问题(发现数据”交易帐号”等不满足如下长度、类型等条件),并得到如下使用经验总结:

使用要求:

    1.schema需要提前创建

    2.节点文件需要为csv类型,且节点不可重复

3.边文件,同上,不同的label需要在不同的文件中,所有属性名称固定映射

(无意在github找到的说明方法,不解其意)

    4.需要写一个映射json文件

 

缺点:

1.不可包含非数字字符,字符长度不可过千万

2.通过hugegraph-loader工具进行批量数据导入(不可修改一切配置,端口与Spark默认端口冲突)。PS:其实这个工具只是简单封装了Gremlin的导入方式而已,缺少教学文档,反倒成了黑箱操作;

3.未提供导入数据后的一切操作文档(如何读取等),想通过Gremlin去操作它也找不到如何配置的文档。

4.不支持指定图存储(也可能是我没找到方法,反正文档没有,网上也没有),重新存储会覆盖原图,schema不匹配可能报错,如下疑惑

疑惑:

  经过亲自实验,该方法与所有方法并没有发现有指定GraphName,也就是说所有的导入数据都会存储到默认的”hugegraph”图中(安装hugegraph时在配置中设置的)。

 

 

3. restful api

POST http://localhost:8080/graphs/hugegraph/graph/vertices/batch

[

    {

        "label": "person",

        "properties": {

            "name": "marko",

            "age": 29

        }

    },

    {

        "label": "software",

        "properties": {

            "name": "ripple",

            "lang": "java",

            "price": 199

        }

    }

]

 

POST http://localhost:8080/graphs/hugegraph/graph/edges/batch

[

    {

        "label": "created",

        "outV": "1:peter",

        "inV": "2:lop",

        "outVLabel": "person",

        "inVLabel": "software",

        "properties": {

            "date": "2017-5-18",

            "weight": 0.2

        }

    },

    {

        "label": "knows",

        "outV": "1:marko",

        "inV": "1:vadas",

        "outVLabel": "person",

        "inVLabel": "person",

        "properties": {

            "date": "2016-01-10",

            "weight": 0.5

        }

    }

]

数据节点的导出

所有数据导出

使用hugegraph-tools

bin/hugegraph dump

把整张图的顶点和边全部导出,默认以vertex vertex-edge1 vertex-edge2...JSON格式存储。

dump      Dump graph to files

      Usage: dump [options]

        Options:

          --directory, -d

            Directory to store graph data

            Default: ./

          --formatter, -f

            Formatter to customize format of vertex/edge

            Default: JsonFormatter

          --retry

            Retry times, default is 3

            Default: 3

 

或者可以使用backup

 

基于查询的数据导出

  1. 使用restful api 发送查询请求,获得的Response可作为导出的数据

POST http://localhost:8080/gremlin

Request Body{

    "gremlin": "hugegraph.traversal().V('1:marko')",

    "bindings": {},

    "language": "gremlin-groovy",

    "aliases": {}

}

 

  1. 使用hugegraph-client 查询,使用gson导出

查询

GremlinManager gremlin = hugeClient.gremlin();

ResultSet resultSet =gremlin.gremlin("g.V().outE().path()").execute();

Iterator<Result> results = resultSet.iterator();

导出

new GsonBuilder().create().toJson(vertexs,new FileWriter(path));

 

​```

#### 整理出使用Gremlin以及JAVA API的方法

​```

连接

HugeClient hugeClient = new HugeClient(url, graphName);

 

修改创建schema

SchemaManager schema = hugeClient.schema();

 

创建Property

schema.propertyKey("name").asText().ifNotExist().create();

 

创建Vertex schema

schema.vertexLabel("person").properties("name", "age", "city").primaryKeys("name").ifNotExist().create();

 

创建Edge schema

schema.edgeLabel("created").sourceLabel("person").targetLabel("software").properties("date", "weight").ifNotExist().create();

 

查询

GremlinManager gremlin = hugeClient.gremlin();

ResultSet resultSet = gremlin.gremlin("g.V().outE().path()").execute();

 

删除节点或边

graph.removeVertex(StringId)

graph.removeEdge(StringId)

 

删除schema

schema.removeVertexLabel(LabelName)

导入导出

见之前的说明