跳转到主要内容

1 - HugeGraph (OLTP)

DeepWiki 提供实时更新的项目文档,内容更全面准确,适合快速了解项目最新情况。

📖 https://deepwiki.com/apache/hugegraph

GitHub 访问: https://github.com/apache/hugegraph

1.1 - HugeGraph Server 快速开始

1 HugeGraph Server 概述

apache/hugegraph 是 HugeGraph 图数据库的主仓库,包含 hugegraph-serverhugegraph-pdhugegraph-store 等一级模块。本页介绍其中的 hugegraph-server 模块及其运行服务。

hugegraph-server 模块包含 hugegraph-corehugegraph-apihugegraph-dist 和存储适配等子模块。Core 实现属性图模型、事务与 TinkerPop 接口,API 提供 HTTP 服务并将客户端请求交给 Core 处理。图数据由 RocksDB(单机默认)、HStore(分布式)或 HBase 后端保存。

⚠️ 版本说明:本文以 HugeGraph 1.7.0 至 master 分支的代码为参考,仅介绍 RocksDB、HStore 和 HBase。其他旧后端的使用与配置请参考 HugeGraph 1.5.x 文档

名称说明:HugeGraph 表示整个项目或主仓库,hugegraph-server 表示仓库中的 Server 模块,HugeGraphServer 是服务进程的 Java 类名。下文的 Server 服务指运行中的图数据库服务。

2 依赖

2.1 安装 Java 11 (JDK 11)

HugeGraph 1.7.0 中的 hugegraph-server 模块使用 Java 11 编译,运行和源码构建均需使用 Java 11 或更高版本。

在继续阅读前,请先执行 java -version 命令确认 JDK 版本。

1.7.0 起不再支持 Java 8。bin/hugegraph-server.sh 在低于 Java 11 的环境下会直接拒绝启动。

安全检查默认开启,会安装 HugeSecurityManager,它要求 Java 11 到 23。JDK 24 移除了 Security Manager(JEP 486),因此在 Java 24 及更高版本上必须关闭该检查后再启动服务:bin/start-hugegraph.sh -s false

源码构建还需要 Maven 3.5.0 或更高版本。

3 部署

有四种方式可以部署 Server 服务:

  1. 使用 Docker 容器进行测试或开发。
  2. 下载二进制 tar 包。
  3. 从源码编译。
  4. 使用已过时的一键部署工具。

不要把 Gremlin、Cypher 等查询接口直接暴露到公网。生产环境应启用认证与授权,限制网络访问并保留审计日志;部署建议见安全指南

3.1 使用 Docker 容器 (便于测试)

可参考 Docker 部署方式

可以使用 docker run -itd --name=server -p 8080:8080 -e PASSWORD=xxx hugegraph/hugegraph:1.7.0 快速启动一个使用 RocksDB 后端的 Server 实例。

可选项:

  1. 可以使用 docker exec -it server bash 进入容器执行运维或调试操作。
  2. 可以使用 docker run -itd --name=server -p 8080:8080 -e PRELOAD="true" hugegraph/hugegraph:1.7.0 在启动时预加载一个内置样例图。可通过 RESTful API 进行验证,具体步骤可参考 5.1.4
  3. 可以使用 -e PASSWORD=xxx 开启鉴权模式并设置 admin 密码,具体步骤可参考 Config Authentication

如果使用 Docker Desktop,则可以按如下方式设置相关选项:

Docker Desktop 中 HugeGraph 容器的运行设置

注意:Docker Compose 文件使用桥接网络(hg-net),适用于 Linux 和 Mac(Docker Desktop)。如需运行 3 节点分布式集群,请为 Docker Desktop 分配至少 12 GB 内存(设置 → 资源 → 内存)。Linux 上 Docker 直接使用宿主机内存。

如果希望通过一个配置文件统一管理 HugeGraph 的多个服务实例,则可以使用 docker composedocker/ 目录下提供了四个 compose 文件:

拓扑compose 文件服务
单机(推荐从这里开始)docker-compose.yml1 个 RocksDB Server + 1 个 Hubble
最小 HStoredocker-compose-hstore.yml1 PD + 1 Store + 1 Server + 1 Hubble
HA 参考docker-compose-3pd-3store-3server.yml3 PD + 3 Store + 3 Server + 1 Hubble
最小 HStore 拓扑的源码构建覆盖文件docker-compose.dev.yml(需与 docker-compose-hstore.yml 一起使用)
cd hugegraph/docker
# 注意版本号请随时保持更新 → 1.x.0
HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose.yml up -d --wait

单机拓扑将 Server 暴露在 8080 端口,Hubble 暴露在 127.0.0.1:8088HUGEGRAPH_VERSION 决定 Server、PD 和 Store 的镜像 tag,Hubble 由 HUBBLE_IMAGE 单独选择。

compose 文件从 HUGEGRAPH_ADMIN_PASSWORD 读取管理员密码,从 HUGEGRAPH_AUTH_TOKEN_SECRET 读取 JWT 密钥,通常放在 docker/.env 文件中。HUGEGRAPH_ADMIN_PASSWORD 非空即开启鉴权,Hubble 会自动识别该模式。若直接使用 docker run,则改为传入 -e PASSWORD=xxx

完整的部署指南请参阅 docker/README.md

注意:

  1. HugeGraph 的 Docker 镜像主要用于便捷地快速启动 HugeGraph,并不是 ASF 官方发布物料包。你可以从 ASF Release Distribution Policy 中了解更多细节。

  2. 推荐使用 release tag (如 1.7.0/1.x.0) 以获取稳定版。使用 latest tag 可以使用开发中的最新功能。

3.2 下载 tar 包

download-release.sh
# 1.7.0 是项目孵化期发布的历史版本,因此文件名仍带 incubating
wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz
tar zxf apache-hugegraph-incubating-1.7.0.tar.gz

3.3 源码编译

源码编译前请确保本机有安装 wget/curl 命令

下载 HugeGraph 源代码

build-from-source.sh
git clone https://github.com/apache/hugegraph.git

编译打包生成 tar 包

cd hugegraph
# (Optional) use "-P stage" param if you build failed with the latest code(during pre-release period)
mvn package -DskipTests

构建成功时日志中会出现:

[INFO] BUILD SUCCESS

执行成功后,在 hugegraph 目录下生成 *hugegraph-*.tar.gz 文件,就是编译生成的 tar 包。

默认构建会打包 rocksdbhbasehstore 三个后端模块,并把它们记录在 hugegraph-dist jar 内的 backend.properties 资源的 backends 配置项中。若只需要包含 RocksDB 的精简发布包,可加上 -Drocksdb-only

mvn package -DskipTests -ntp -Drocksdb-only
过时的 tools 工具安装

3.4 使用 tools 工具部署 (Outdated)

HugeGraph-Tools 提供一键部署命令,可以下载、解压、配置并启动 Server 服务和 HugeGraph-Hubble。HugeGraph-Toolchain 发布包中已包含这些工具。

# download toolchain package, it includes loader + tool + hubble, please check the latest version (here is 1.7.0)
wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-toolchain-incubating-1.7.0.tar.gz
tar zxf *hugegraph-*.tar.gz
# enter the tool's package
cd *hugegraph*/*tool*

注:${version} 为版本号,最新版本号可参考 Download 页面,或直接从 Download 页面点击链接下载

HugeGraph-Tools 的总入口脚本是 bin/hugegraph,用户可以使用 help 子命令查看其用法,这里只介绍一键部署的命令。

bin/hugegraph deploy -v {hugegraph-version} -p {install-path} [-u {download-path-prefix}]

{hugegraph-version} 表示要部署的 Server 服务及 HugeGraphStudio 版本,可在 conf/version-mapping.yaml 中查看版本信息。{install-path} 指定安装目录,{download-path-prefix} 可选,用于指定 tar 包下载地址。例如部署 0.6 版本时,可以执行 bin/hugegraph deploy -v 0.6 -p services

4 配置

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

详细的配置介绍请参考配置文档配置项介绍

5 启动

5.1 使用启动脚本启动

启动流程分为首次启动和非首次启动两种情况。首次启动前需要先初始化后端数据库,然后再启动服务。

如果服务曾被手动停止,或因其他原因需要再次启动,由于后端数据库已持久化存在,通常可以直接启动服务。

HugeGraphServer 启动时会连接后端存储并检查其版本信息。如果后端尚未初始化,或者已初始化但版本不匹配(例如存在旧版本数据),HugeGraphServer 会启动失败并给出错误信息。

如果需要外部访问 HugeGraphServer,请修改 rest-server.propertiesrestserver.url 配置项(默认为 http://127.0.0.1:8080),修改成机器名或 IP 地址。

由于各种后端所需的配置(hugegraph.properties)及启动步骤略有不同,下面逐一对各后端的配置及启动做介绍。

注: 如果想要开启 HugeGraph 权限系统,在启动 Server 之前应按照 Server 鉴权配置 进行配置。(尤其是生产环境/外网环境须开启)

5.1.1 分布式存储 (HStore)

点击展开/折叠 分布式存储 配置及启动方法

分布式存储是 HugeGraph 1.5.0 之后推出的新特性,它基于 HugeGraph-PD 和 HugeGraph-Store 组件实现了分布式的数据存储和计算。

要使用分布式存储引擎,需要先部署 HugeGraph-PD 和 HugeGraph-Store,详见 HugeGraph-PD 快速入门HugeGraph-Store 快速入门

确保 PD 和 Store 服务均已启动后

  1. 修改 Server 服务的 hugegraph.properties 配置:
backend=hstore
serializer=binary

# PD 服务地址,多个 PD 地址用逗号分割,配置 PD 的 RPC 端口
pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
# 简单示例(带鉴权)
gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy

# 指定存储 hstore(必须)
backend=hstore
serializer=binary
store=hugegraph

# pd config
pd.peers=127.0.0.1:8686

发布包中自带该后端的模板文件 conf/graphs/hstore.properties.template,可将其复制覆盖 conf/graphs/hugegraph.properties 后修改 pd.peers

任务调度器由后端决定,无需配置 task.scheduler_typehstore 使用分布式调度器,其余后端使用本地调度器。为兼容旧配置,该键仍可存在,但会被忽略并打印一条警告日志。

  1. 修改 Server 服务的 rest-server.properties 配置:
usePD=true
# 从 graphs 目录加载上面的 hugegraph.properties;源码默认值为 false
graph.load_from_local_config=true
# 注意,1.7.0 必须在 rest-server.properties 配置 pd.peers
pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688

# 若需要 auth 
# auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator

如果配置多个 Server 节点,需要为每个节点修改 rest-server.properties 配置文件,例如:

节点 1(主节点):

usePD=true
restserver.url=http://127.0.0.1:8081
gremlinserver.url=http://127.0.0.1:8181
pd.peers=127.0.0.1:8686

rpc.server_host=127.0.0.1
rpc.server_port=8091

server.id=server-1
server.role=master

节点 2(工作节点):

usePD=true
restserver.url=http://127.0.0.1:8082
gremlinserver.url=http://127.0.0.1:8182
pd.peers=127.0.0.1:8686

rpc.server_host=127.0.0.1
rpc.server_port=8092

server.id=server-2
server.role=worker

同时,还需要修改每个节点的 gremlin-server.yaml 中的端口配置:

节点 1:

host: 127.0.0.1
port: 8181

节点 2:

host: 127.0.0.1
port: 8182

启动 Server:

bin/start-hugegraph.sh

使用分布式存储引擎的启动顺序为:

  1. 启动 HugeGraph-PD
  2. 启动 HugeGraph-Store
  3. 启动 Server 服务

HStore 的元数据和存储由 PD、Store 管理,init-store 会跳过该后端。开启鉴权时,执行 init-store 仍会创建内置的 admin 账号。如果该账号已由存储侧持有,可在 rest-server.properties 中设置 init_store.enabled=false 以整体跳过这一步,Docker 的 HStore 拓扑即采用这种方式。

验证服务是否正常启动:

curl http://localhost:8081/graphspaces/DEFAULT/graphs
# 应返回:{"graphs":["hugegraph"]}

停止服务的顺序应该与启动顺序相反:

  1. 停止 Server 服务
  2. 停止 HugeGraph-Store
  3. 停止 HugeGraph-PD
bin/stop-hugegraph.sh
Docker 分布式集群

通过 Docker-Compose 运行完整的分布式集群(3 PD + 3 Store + 3 Server):

cd hugegraph/docker
HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose-3pd-3store-3server.yml up -d --wait

服务通过 hg-net 桥接网络上的容器主机名进行通信。配置通过环境变量注入:

# Server 配置,server0、server1、server2 共用
HG_SERVER_BACKEND: hstore
HG_SERVER_PD_PEERS: pd0:8686,pd1:8686,pd2:8686
HG_SERVER_CLUSTER: hg
HG_SERVER_USE_PD: "true"
HG_SERVER_MIN_FREE_MEMORY: "0"
HG_SERVER_INIT_STORE_ENABLED: "false"
HG_SERVER_REQUIRE_AUTH_TOKEN_SECRET: "true"
STORE_REST: store0:8520
# 每个节点单独设置,例如 server0
HG_SERVER_REST_URL: http://server0:8080

该拓扑设置了 HG_SERVER_REQUIRE_AUTH_TOKEN_SECRET: "true",因此在只提供密码而没有共享 JWT 密钥时 Server 会拒绝启动。启动前请在 docker/.env 中同时写入 HUGEGRAPH_ADMIN_PASSWORDHUGEGRAPH_AUTH_TOKEN_SECRET。完整的变量说明见 Docker 集群指南

验证集群:

curl http://localhost:8080/versions
curl http://localhost:8620/v1/stores

运行时日志可通过 docker logs <container-name>(如 docker logs hg-pd0)直接查看,无需进入容器。

完整的环境变量参考、端口表和故障排查指南请参阅 docker/README.md

5.1.2 RocksDB / ToplingDB

以下从本地 properties 文件启动图的示例要求在 conf/rest-server.properties 中设置:

graph.load_from_local_config=true

当前源码默认值是 false,上游发布模板尚未写出该选项。

点击展开/折叠 RocksDB 配置及启动方法

RocksDB 是一个嵌入式的数据库,不需要手动安装部署,要求 GCC 版本 >= 4.3.0(GLIBCXX_3.4.10),如不满足,需要提前升级 GCC

修改 hugegraph.properties

backend=rocksdb
serializer=binary
rocksdb.data_path=.
rocksdb.wal_path=.

初始化数据库(第一次启动时或在 conf/graphs/ 下手动添加了新配置时需要进行初始化)

cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-server-incubating-1.7.0
bin/init-store.sh

启动 server

bin/start-hugegraph.sh
Starting HugeGraphServer in daemon mode...
Connecting to HugeGraphServer (http://127.0.0.1:8080/graphs)....OK
Started [pid 21614]

提示的 url 与 rest-server.properties 中配置的 restserver.url 一致

ToplingDB (Beta): 作为 RocksDB 的高性能替代方案,配置方式请参考: ToplingDB Quick Start

5.1.3 HBase

点击展开/折叠 HBase 配置及启动方法

用户需自行安装 HBase,要求版本 2.0 以上,下载地址

修改 hugegraph.properties

backend=hbase
serializer=hbase

# hbase backend config
hbase.hosts=localhost
hbase.port=2181
# Note: recommend to modify the HBase partition number by the actual/env data amount & RS amount before init store
# it may influence the loading speed a lot
#hbase.enable_partition=true
#hbase.vertex_partitions=10
#hbase.edge_partitions=30

初始化数据库(第一次启动时或在 conf/graphs/ 下手动添加了新配置时需要进行初始化)

cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-server-incubating-1.7.0
bin/init-store.sh

启动 server

bin/start-hugegraph.sh
Starting HugeGraphServer in daemon mode...
Connecting to HugeGraphServer (http://127.0.0.1:8080/graphs)....OK
Started [pid 21614]

更多其它后端配置可参考配置项介绍

5.1.4 启动 server 的时候创建示例图

在启动脚本时携带 -p true 参数,表示开启 preload,即创建示例图。

bin/start-hugegraph.sh -p true
Starting HugeGraphServer in daemon mode...
Connecting to HugeGraphServer (http://127.0.0.1:8080/graphs)......OK

并且使用 RESTful API 请求 HugeGraphServer 得到如下结果:

> curl "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices" | gunzip

{"vertices":[{"id":"2:lop","label":"software","type":"vertex","properties":{"name":"lop","lang":"java","price":328}},{"id":"1:josh","label":"person","type":"vertex","properties":{"name":"josh","age":32,"city":"Beijing"}},{"id":"1:marko","label":"person","type":"vertex","properties":{"name":"marko","age":29,"city":"Beijing"}},{"id":"1:peter","label":"person","type":"vertex","properties":{"name":"peter","age":35,"city":"Shanghai"}},{"id":"1:vadas","label":"person","type":"vertex","properties":{"name":"vadas","age":27,"city":"Hongkong"}},{"id":"2:ripple","label":"software","type":"vertex","properties":{"name":"ripple","lang":"java","price":199}}]}

代表创建示例图成功。

5.1.5 启动脚本的参数

bin/start-hugegraph.sh 支持以下参数。每个参数都需要带值,即写作 -d false,不能只写 -d

参数取值默认值作用
-dtruefalsetrue守护进程模式。-d false 时脚本留在前台,并把 SIGTERM/SIGINT 转发给服务进程
-gzgcZGC不填则用 G1GC选择垃圾回收器。只接受 ZGC,其他取值会直接终止启动;ZGC 需要 Java 11 及以上
-mtruefalsefalse安装基于 crontab 的监控任务(bin/start-monitor.sh),仅用于虚拟机和物理机部署
-ptruefalsefalse预加载示例图,见 5.1.4
-struefalsetrue开启安全检查(HugeSecurityManager)。要求 Java 11 到 23,且 conf/java-security.properties 可读
-jJVM 参数追加到服务命令行的额外 JVM 参数
-t30判定启动失败前等待服务响应的时长
-ytruefalsefalse开启 OpenTelemetry agent 上报链路追踪

bin/stop-hugegraph.sh 支持 -m true|false(默认 true),用于控制停止服务时是否同时移除 crontab 监控任务。

5.2 使用 Docker

3.1 使用 Docker 容器 中,我们已经介绍了如何使用 docker 部署 Server 服务。还可以通过切换后端存储或设置参数,在 Server 启动时加载样例图。

5.2.1 启动 server 的时候创建示例图

在 Docker 启动时设置环境变量 PRELOAD=true,即可在启动脚本执行过程中加载样例数据。

  1. 使用docker run

    使用 docker run -itd --name=server -p 8080:8080 -e PRELOAD=true hugegraph/hugegraph:1.7.0

  2. 使用docker-compose

    创建docker-compose.yml,具体文件如下,在环境变量中设置 PRELOAD=true。其中,example.groovy 是一个预定义的脚本,用于预加载样例数据。如果有需要,可以通过挂载新的 example.groovy 脚本改变预加载的数据。

    version: '3'
    services:
      server:
        image: hugegraph/hugegraph:1.7.0
        container_name: server
        environment:
          - PRELOAD=true
          - PASSWORD=xxx
        volumes:
          - /path/to/yourscript:/hugegraph-server/scripts/example.groovy
        ports:
          - 8080:8080

    使用命令 docker compose up -d 启动容器

使用 RESTful API 请求 HugeGraphServer 得到如下结果:

> curl "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices" | gunzip

{"vertices":[{"id":"2:lop","label":"software","type":"vertex","properties":{"name":"lop","lang":"java","price":328}},{"id":"1:josh","label":"person","type":"vertex","properties":{"name":"josh","age":32,"city":"Beijing"}},{"id":"1:marko","label":"person","type":"vertex","properties":{"name":"marko","age":29,"city":"Beijing"}},{"id":"1:peter","label":"person","type":"vertex","properties":{"name":"peter","age":35,"city":"Shanghai"}},{"id":"1:vadas","label":"person","type":"vertex","properties":{"name":"vadas","age":27,"city":"Hongkong"}},{"id":"2:ripple","label":"software","type":"vertex","properties":{"name":"ripple","lang":"java","price":199}}]}

代表创建示例图成功。

6 访问 Server

6.1 服务启动状态校验

jps 查看服务进程

jps
6475 HugeGraphServer

curl 请求 RESTful API

echo `curl -o /dev/null -s -w %{http_code} "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices"`

返回结果 200,代表 server 启动正常

6.2 请求 Server

HugeGraphServer 的 RESTful API 包括多种类型的资源,典型的包括 graph、schema、gremlin、traverser 和 task

  • graph 包含 verticesedges
  • schema 包含 vertexlabelspropertykeysedgelabelsindexlabels
  • gremlin 包含各种 Gremlin 语句,如 g.v(),可以同步或者异步执行
  • traverser 包含各种高级查询,包括最短路径、交叉点、N 步可达邻居等
  • task 包含异步任务的查询和删除

6.2.1 获取 hugegraph 的顶点及相关属性

curl http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices

说明

  1. 由于图的点和边很多,对于 list 型的请求,比如获取所有顶点,获取所有边等,Server 会将数据压缩再返回,所以使用 curl 时得到一堆乱码,可以重定向至 gunzip 进行解压。推荐使用 Chrome 浏览器 + Restlet 插件发送 HTTP 请求进行测试。

    curl "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices" | gunzip
  2. 当前 HugeGraphServer 的默认配置只能是本机访问,可以修改配置,使其能在其他机器访问。

    vim conf/rest-server.properties
    
    restserver.url=http://0.0.0.0:8080

响应体如下:

{
    "vertices": [
        {
            "id": "2lop",
            "label": "software",
            "type": "vertex",
            "properties": {
                "price": [
                    {
                        "id": "price",
                        "value": 328
                    }
                ],
                "name": [
                    {
                        "id": "name",
                        "value": "lop"
                    }
                ],
                "lang": [
                    {
                        "id": "lang",
                        "value": "java"
                    }
                ]
            }
        },
        {
            "id": "1josh",
            "label": "person",
            "type": "vertex",
            "properties": {
                "name": [
                    {
                        "id": "name",
                        "value": "josh"
                    }
                ],
                "age": [
                    {
                        "id": "age",
                        "value": 32
                    }
                ]
            }
        },
        ...
    ]
}

详细的 API 请参考 RESTful-API 文档。

另外也可以通过访问 localhost:8080/swagger-ui/index.html 查看 API。

Swagger UI 中的 HugeGraph RESTful API 接口列表

在使用 Swagger UI 调试 HugeGraph 提供的 API 时,如果 HugeGraph Server 开启了鉴权模式,可以在 Swagger 页面输入鉴权信息。

HugeGraph Swagger UI 中的 Authorize 按钮

当前 HugeGraph 支持基于 Basic 和 Bearer 两种形式设置鉴权信息。

Swagger UI 授权对话框中的 Basic 和 Bearer 凭据输入框

7 停止 Server

cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-server-incubating-1.7.0
bin/stop-hugegraph.sh

8 使用 IntelliJ IDEA 调试 Server

请参考在 IDEA 中配置 Server 开发环境

1.2 - HugeGraph-PD Quick Start

1 HugeGraph-PD 概述

HugeGraph-PD(Placement Driver)是 HugeGraph 分布式版本的元数据管理组件,负责管理图数据的分布和存储节点的协调。它在分布式 HugeGraph 中扮演着核心角色,维护集群状态并协调 HugeGraph-Store 存储节点。

PD 将集群元数据保存在 pd.data-path 下的内嵌 RocksDB 中,并通过 Raft 在各 PD 节点之间复制,因此 3 节点或 5 节点的 PD 集群在少数节点宕机时仍可继续提供服务。在此基础上,PD 还负责注册和激活 Store 节点、分配与再平衡分区、跟踪 Store 心跳,并响应来自 Store 和 Server 的服务发现请求。

PD 监听三个端口:

端口默认值配置项使用方
gRPC8686grpc.portStore 和 Server 客户端
REST8620server.port管理接口、健康检查、监控指标
Raft8610raft.address仅其他 PD 节点

2 依赖

2.1 前置条件

  • 操作系统:Linux 或 macOS(Windows 尚未经过完整测试)
  • Java 版本:≥ 11
  • Maven 版本:≥ 3.5.0

3 部署

有两种方式可以部署 HugeGraph-PD 组件:

  • 方式 1:下载 tar 包
  • 方式 2:源码编译

3.1 下载 tar 包

从 Apache HugeGraph 官方下载页面下载最新版本的 HugeGraph-PD:

# 1.7.0 是项目孵化期发布的历史版本,因此文件名和目录名仍带 incubating
wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz
tar zxf apache-hugegraph-incubating-1.7.0.tar.gz
cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-pd-incubating-1.7.0

3.2 源码编译

# 1. 克隆源代码
git clone https://github.com/apache/hugegraph.git

# 2. 编译项目
cd hugegraph
mvn clean install -DskipTests=true

# 3. 编译成功后,PD 目录和发布包分别位于
#    hugegraph-pd/apache-hugegraph-pd-{version}          (解压后的 PD 发布目录)
#    hugegraph-pd/apache-hugegraph-pd-{version}.tar.gz   (仅含 PD 的发布包,只在 Linux 构建机上生成)
#    target/apache-hugegraph-{version}.tar.gz            (PD + Store + Server 的完整发布包)

只编译 PD 发布包及其依赖模块:

mvn clean package -pl hugegraph-pd/hg-pd-dist -am -DskipTests

解压后的发布目录只包含三个子目录:bin(启停脚本)、confapplication.ymlapplication.yml.templatelog4j2.xmlverify-license.json)和 libhg-pd-service jar 包)。

3.3 Docker 部署

HugeGraph-PD Docker 镜像已发布在 Docker Hub,镜像名为 hugegraph/pd

注: 后续步骤皆假设你本地已拉取 hugegraph 主仓库代码 (至少是 docker 目录)

使用 docker-compose 模式部署完整的 3 节点集群(PD + Store + Server):

cd hugegraph/docker
# 注意版本号请随时保持更新 → 1.x.0
HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose-3pd-3store-3server.yml up -d

单 PD、单 Store、单 Server 的最小拓扑对应 docker-compose-hstore.yml

通过 docker run 运行单个 PD 节点时,通过环境变量提供配置:

docker run -d \
  -p 8620:8620 \
  -p 8686:8686 \
  -p 8610:8610 \
  -e HG_PD_GRPC_HOST=<your-ip> \
  -e HG_PD_RAFT_ADDRESS=<your-ip>:8610 \
  -e HG_PD_RAFT_PEERS_LIST=<your-ip>:8610 \
  -e HG_PD_INITIAL_STORE_LIST=<store-ip>:8500 \
  -v /path/to/data:/hugegraph-pd/pd_data \
  --name hugegraph-pd \
  hugegraph/pd:1.7.0

环境变量参考:

变量必填默认值对应配置项描述
HG_PD_GRPC_HOSTgrpc.host本节点的 gRPC 主机名/IP(Docker 中使用 pd0,裸机使用 192.168.1.10
HG_PD_RAFT_ADDRESSraft.address本节点的 Raft 地址(如 pd0:8610
HG_PD_RAFT_PEERS_LISTraft.peers-list所有 PD 节点的 Raft 地址(如 pd0:8610,pd1:8610,pd2:8610
HG_PD_INITIAL_STORE_LISTpd.initial-store-list预期的 Store gRPC 地址(如 store0:8500,store1:8500,store2:8500
HG_PD_GRPC_PORT8686grpc.portgRPC 服务端口
HG_PD_REST_PORT8620server.portREST API 端口
HG_PD_DATA_PATH/hugegraph-pd/pd_datapd.data-path元数据存储路径
HG_PD_INITIAL_STORE_COUNT1pd.initial-store-count集群可用所需的最小 Store 数量

缺少上述四个必填变量中的任意一个时,entrypoint 会拒绝启动。它把这些值转换成 SPRING_APPLICATION_JSON 覆盖项,因此无需修改镜像内的 conf/application.yml;未被 HG_PD_* 变量覆盖的配置项仍沿用该文件中的值。JAVA_OPTS 会透传给 JVM。

注意:在 Docker 桥接网络中,HG_PD_GRPC_HOSTHG_PD_RAFT_ADDRESS 应使用容器主机名(如 pd0)而非 IP 地址。

已弃用的别名GRPC_HOSTRAFT_ADDRESSRAFT_PEERSPD_INITIAL_STORE_LIST 仍可使用,但会输出弃用警告。新部署请使用 HG_PD_* 名称。

镜像内置 HEALTHCHECK,每 15 秒探测 8620 端口上的 GET /v1/health,启动宽限期 90 秒、重试 3 次,因此 docker ps 能反映真实的 PD 健康状态。entrypoint 以 -d false 调用启动脚本,容器进程就是 Java 进程本身,Java 退出时容器随之退出并触发 Docker 的重启策略。镜像还设置了 STDOUT_MODE=true,因此运行时日志可通过 docker logs <container-name>(如 docker logs hg-pd0)直接查看,无需进入容器。

完整的集群部署指南请参阅 docker/README.md

4 配置

PD 的主要配置文件为 conf/application.yml,以下是发布包中自带的内容:

spring:
  application:
    name: hugegraph-pd

management:
  metrics:
    export:
      prometheus:
        enabled: true
  endpoints:
    web:
      exposure:
        include: "*"

logging:
  config: 'file:./conf/log4j2.xml'

license:
  verify-path: ./conf/verify-license.json
  license-path: ./conf/hugegraph.license

grpc:
  # 集群模式下的 gRPC 端口
  port: 8686
  # 部署时需改为本机实际的 IPv4 地址
  host: 127.0.0.1

server:
  # REST 服务端口号
  port: 8620

pd:
  # 存储路径
  data-path: ./pd_data
  # 自动扩容的检查周期(秒)
  patrol-interval: 1800
  # 集群可用所需的最小 Store 数量
  initial-store-count: 1
  # store 的配置信息,格式为 IP:gRPC端口
  initial-store-list: 127.0.0.1:8500

raft:
  # 本节点的 raft 地址
  address: 127.0.0.1:8610
  # 集群中所有 PD 节点的 raft 地址
  peers-list: 127.0.0.1:8610

store:
  # store 下线时间(秒)。超过该时间,认为 store 永久不可用,分配副本到其他机器
  max-down-time: 172800
  # 是否开启 store 监控数据存储
  monitor_data_enabled: true
  # 监控数据的间隔
  monitor_data_interval: 1 minute
  # 监控数据的保留时间
  monitor_data_retention: 1 day

partition:
  # 默认每个分区副本数
  default-shard-count: 1
  # 默认每机器最大副本数
  store-max-shard-count: 12

conf/application.yml.template 是另一份带占位符($GRPC_PORT$$RAFT_ADDRESS$ 等)的副本,供自动生成配置的部署工具使用,PD 本身不读取它。启动脚本通过 -Dspring.config.location 指定的始终是 conf/application.yml

4.1 配置项参考

conf/application.yml 中未出现的配置项会回退到下表的内置默认值;没有内置默认值的配置项必须存在,否则 PD 无法启动。

gRPC 与 REST

配置项发布包中的值内置默认值描述
grpc.host127.0.0.1无,必填本 PD 对外公布的 gRPC 地址。Store 和 Server 会连到这个地址,因此分布式部署时必须填可访问的 IPv4 地址或主机名,不能用 127.0.0.10.0.0.0
grpc.port8686无,必填gRPC 端口。
server.port8620无,必填REST API 端口,同时也是 Raft 成员信息中公布的 REST 端口。

application.yml.template 中还有 grpc.netty-server.max-inbound-message-size: 100MB,但 PD 在代码中把 gRPC 服务端的入站消息上限固定为 1 GB,该配置项实际不生效。

Raft

配置项发布包中的值内置默认值描述
raft.address127.0.0.1:8610无,必填本节点的 Raft 地址,格式为 host:port。每个节点必须不同,且必须出现在 raft.peers-list 中。
raft.peers-list127.0.0.1:8610无,必填逗号分隔的全部 PD 节点 Raft 地址(含本节点)。所有节点上必须完全一致。
raft.enable未设置true为 true 时元数据写入经过 Raft 状态机;为 false 时 PD 直接写本地存储,不做复制。
raft.ip-whitelist.enabled未设置true为 true 时 Raft RPC 端口只接受由 raft.peers-list 解析出的地址的连接,其他连接会被断开并记录 Blocked connection from <ip>。peer 列表变更时白名单会重新解析,但主机名不变而 IP 变化的情况(例如容器重启)仍需重启 PD。
raft.snapshotInterval未设置300Raft 快照生成间隔(秒)。
raft.rpc-timeout未设置10000Raft RPC 的连接、请求和安装快照超时时间(毫秒)。

PD 核心

配置项发布包中的值内置默认值描述
pd.data-path./pd_data无,必填元数据目录。rocksdb/ 子目录存放 RocksDB 数据,pd_raft/ 子目录存放 Raft 日志、元信息和快照。
pd.patrol-interval1800300巡检周期(秒)。巡检会检查各 Store 上的分区健康状况并平衡分区数量。
pd.initial-store-count13活跃 Store 节点的最小数量。低于该值时集群状态变为 Cluster_Not_Ready,整个集群视为不可用。建议设为实际部署的 Store 数量。
pd.initial-store-list127.0.0.1:8500逗号分隔的 Store gRPC 地址(ip:port),列表中的 Store 注册后自动激活。条目也可以带分组 id,写作 store_address/group_id
pd.cluster_id未设置1集群 id,用于区分不同的 PD 集群。

Store 管理

配置项发布包中的值内置默认值描述
store.keepAlive-timeout未设置300心跳超时时间(秒)。超过该时间未收到心跳,Store 视为临时不可用,其分区 leader 转移到其他副本。
store.max-down-time1728001800超过该时间(秒)后 Store 视为永久不可用,其副本重新分配到其他机器。
store.monitor_data_enabledtruefalse是否持久化 Store 监控采样数据。
store.monitor_data_interval1 minute1 minute采样间隔,格式为 <数字> <单位>,单位为 secondminutehourdaymonthyear 之一;省略数字时按 1 计。
store.monitor_data_retention1 day1 day监控数据保留时长,格式同上。

分区

配置项发布包中的值内置默认值描述
partition.default-shard-count13每个分区的副本数。生产集群建议设为 3
partition.store-max-shard-count1224单个 Store 最多承载的分区副本数。

初始分区数由这两个配置项和 pd.initial-store-list 的长度推导得出:

初始分区数 = Store 数量 * partition.store-max-shard-count / partition.default-shard-count

服务发现、License 与监控

配置项发布包中的值内置默认值描述
discovery.heartbeat-try-count未设置3客户端注册后连续丢失多少次心跳就删除其注册信息。
license.verify-path./conf/verify-license.json无,必填License 校验描述文件路径,由 /v1/license 接口读取。
license.license-path./conf/hugegraph.license无,必填License 文件路径。发布包只带 verify-license.json,不带 license 文件,因此在提供该文件之前 license 接口会返回错误。
auth.secret-key未设置内置常量用于给内部客户端签发 PD token 的 HS256 密钥。
management.metrics.export.prometheus.enabledtrueSpring Boot 默认值是否暴露 /actuator/prometheus
management.endpoints.web.exposure.include"*"Spring Boot 默认值需要暴露的 actuator 端点。
logging.configfile:./conf/log4j2.xmlLog4j2 配置文件,会写出 logs/hugegraph-pd.loglogs/hugegraph-pd_raft.loglogs/audit-hugegraph-pd.log

线程池

配置项内置默认值描述
thread.pool.grpc.core600处理 gRPC 请求的线程池核心线程数。
thread.pool.grpc.max1000该线程池的最大线程数。
thread.pool.grpc.queue无上限该线程池的队列容量。
job.uninterruptibleThreadPool.core0元数据后台任务线程池的核心线程数。小于等于 0 时取可用处理器数的一半。
job.uninterruptibleThreadPool.max256该线程池的最大线程数。
job.uninterruptibleThreadPool.queue无上限该线程池的队列容量。

4.2 单节点配置

发布包自带的 conf/application.yml 本身就是一份可用的单节点配置,适用于开发和测试:单节点 PD 不存在 Raft 多数派可失,partition.default-shard-count: 1 表示每个分区只有一个副本。

grpc:
  host: 127.0.0.1
  port: 8686
server:
  port: 8620
raft:
  address: 127.0.0.1:8610
  peers-list: 127.0.0.1:8610
pd:
  data-path: ./pd_data
  initial-store-count: 1
  initial-store-list: 127.0.0.1:8500
partition:
  default-shard-count: 1

4.3 三节点集群配置

生产环境请部署 3 个或 5 个 PD 节点,节点数取奇数以保证 Raft 总能形成多数派。3 节点集群可容忍 1 个节点故障。raft.peers-list 必须列出全部节点,并且在所有节点上逐字节一致;grpc.hostraft.address 每个节点各不相同。

节点 1(192.168.1.10):

grpc:
  host: 192.168.1.10
  port: 8686
server:
  port: 8620
raft:
  address: 192.168.1.10:8610
  peers-list: 192.168.1.10:8610,192.168.1.11:8610,192.168.1.12:8610
pd:
  data-path: /data/pd
  initial-store-count: 3
  initial-store-list: 192.168.1.20:8500,192.168.1.21:8500,192.168.1.22:8500
partition:
  default-shard-count: 3

节点 2(192.168.1.11)和节点 3(192.168.1.12)使用同一份配置,只把 grpc.hostraft.address 换成自己的地址:

# 节点 2
grpc:
  host: 192.168.1.11
raft:
  address: 192.168.1.11:8610
  peers-list: 192.168.1.10:8610,192.168.1.11:8610,192.168.1.12:8610

# 节点 3
grpc:
  host: 192.168.1.12
raft:
  address: 192.168.1.12:8610
  peers-list: 192.168.1.10:8610,192.168.1.11:8610,192.168.1.12:8610

若要在同一台机器上启动 3 个 PD 节点做测试,需为每个节点分别指定 pd.data-path 和各自的端口,例如 raft 端口 8610/8611/8612、gRPC 端口 8686/8687/8688、REST 端口 8620/8621/8622

在 Docker 桥接网络中,同样的配置来自环境变量,并使用容器主机名而非 IP 地址:

# pd0
HG_PD_GRPC_HOST: pd0
HG_PD_RAFT_ADDRESS: pd0:8610
HG_PD_RAFT_PEERS_LIST: pd0:8610,pd1:8610,pd2:8610
HG_PD_INITIAL_STORE_LIST: store0:8500,store1:8500,store2:8500
HG_PD_INITIAL_STORE_COUNT: 3

# pd1
HG_PD_GRPC_HOST: pd1
HG_PD_RAFT_ADDRESS: pd1:8610
HG_PD_RAFT_PEERS_LIST: pd0:8610,pd1:8610,pd2:8610

# pd2
HG_PD_GRPC_HOST: pd2
HG_PD_RAFT_ADDRESS: pd2:8610
HG_PD_RAFT_PEERS_LIST: pd0:8610,pd1:8610,pd2:8610

5 启动与停止

5.1 启动 PD

在 PD 安装目录下执行:

./bin/start-hugegraph-pd.sh

脚本要求 PATHJAVA_HOME 中有 11 及以上版本的 JDK;如果发现已有 Java 进程在使用本安装目录的 conf 目录,脚本会直接退出,不做任何事。

支持的参数:

参数取值默认值描述
-dtruefalsetrue守护进程模式,详见下文。
-gzgcZGC不设置垃圾回收器。不带该参数即使用默认的 G1GC;填其他值(包括 g1)会导致启动中止。
-jJVM 参数额外的 JVM 参数,例如 -j "-Xmx8g -Xms8g"
-ytruefalsefalse挂载 OpenTelemetry Java agent。首次使用时会把 agent 下载到 plugins/ 并校验 MD5,trace 通过 gRPC 上报到 http://127.0.0.1:4317

-d 参数控制守护进程模式:

  • -d true(默认):以后台守护进程方式运行,脚本立即返回。
  • -d false:以前台模式运行,脚本通过 exec 替换为 Java 进程,容器/进程管理器的进程即为 Java 本身。在 Docker 或进程管理器(systemd、supervisord)下运行时请使用此参数,以便在崩溃时自动检测并重启服务。

每个参数都有对应的环境变量:DAEMONGC_OPTIONUSER_OPTIONOPEN_TELEMETRY。设置 JAVA_OPTIONS 会完全替换脚本计算出的堆参数,否则脚本会根据可用内存在 512 MB 到 32 GB 之间选择堆大小。设置 STDOUT_MODE=true 时 JVM 输出保留在 stdout,不再重定向到 logs/hugegraph-pd-stdout.log,Docker 镜像正是这样做的。

启动成功后,可以在 logs/hugegraph-pd-stdout.log 中看到类似以下的日志:

YYYY-mm-dd xx:xx:xx [main] [INFO] o.a.h.p.b.HugePDServer - Started HugePDServer in x.xxx seconds (JVM running for x.xxx)

进程号会写入 bin/pid

5.2 停止 PD

在 PD 安装目录下执行:

./bin/stop-hugegraph-pd.sh

脚本读取 bin/pid,向该进程发送终止信号,最多等待 30 秒直到进程退出,然后删除 pid 文件。如果 bin/pid 不存在,脚本会提示并正常退出。

6 分布式集群的启动顺序

请按以下顺序启动各组件:

  1. 全部 PD 节点。它们组成 Raft 组并选出 leader。等到每个节点都能响应 GET /v1/health 再继续。
  2. 全部 Store 节点。每个 Store 通过 gRPC 向 PD 注册,PD 会自动激活 pd.initial-store-list 中列出的 Store。等到 GET /v1/stores 中每个 Store 的 state 都是 Up 再继续。
  3. 全部 Server 节点。Server 读取 pd.peers,并依赖 PD 报告至少有一个存活的 Store 才能完成分区分配。

Docker Compose 的各个拓扑正是这样编排的:Store 容器通过 depends_oncondition: service_healthy 等待 PD 的 /v1/health 健康检查,Server 容器以同样方式等待 Store 的健康检查,Server 的 entrypoint 还会轮询 PD 的 /v1/stores,直到有 Store 报告 Up 才启动 HugeGraph。

停止时顺序相反:先停 Server,再停 Store,最后停 PD。

7 验证

7.1 REST API 认证

/actuator/*/v1/health/v1/prom/targets/* 之外,PD 的所有 REST 路径都要求带 HTTP Basic Authorization 头,且用户名必须是内部服务名 hgstorehubblevermeer 之一。不带该头的请求会得到:

{"status": -1, "error": "Unauthorized!"}

目前不校验密码,任意值均可。Server 自带的 bin/wait-storage.sh 使用 store:admin,并支持用 PD_AUTH_USERPD_AUTH_PASSWORD 覆盖,因此下面的示例使用同样的凭据:

curl -u store:admin http://localhost:8620/v1/stores

警告:该校验只用于区分 HugeGraph 自身组件与其他流量。请勿把 PD 的 REST 或 gRPC 端口暴露到不可信网络,应通过防火墙规则或安全组加以限制,并保持 raft.ip-whitelist.enabled 开启,使 Raft 端口只接受配置中的 peer。

7.2 健康检查

GET /v1/health 不需要凭据,Docker 健康检查用的就是它。它返回 200 且响应体为空:

curl -i http://localhost:8620/v1/health

Spring Boot actuator 端点同样可用,输出更直观:

curl http://localhost:8620/actuator/health

如果返回 {"status":"UP"},则表示 PD 服务已成功启动。

7.3 集群与成员状态

查看 PD 成员以及当前的 Raft leader:

curl -u store:admin http://localhost:8620/v1/members

响应中包含 pdList、选出的 pdLeadernumOfServicenumOfNormalServicestateCountMap。健康的 3 节点 PD 集群中,numOfServicenumOfNormalService 都应为 3,且恰好有一个成员的 roleLeader

GET /v1/cluster 在成员列表之外还返回 Store 列表、图列表和集群整体状态;GET / 返回一份简要汇总(leader 地址、集群状态、成员数、Store 数、图数量、分区数)。

7.4 Store 状态

也可以通过 PD API 查看 Store 节点状态:

curl -u store:admin http://localhost:8620/v1/stores

如果响应中 stateUp,说明对应的 Store 节点运行正常。下面的示例只有一个 Store 节点。在一个健康的 3 节点部署中,storeId 列表应包含 3 个 ID,且 stateCountMap.UpnumOfServicenumOfNormalService 都应为 3

{
  "message": "OK",
  "data": {
    "stores": [
      {
        "storeId": 8319292642220586694,
        "address": "127.0.0.1:8500",
        "raftAddress": "127.0.0.1:8510",
        "version": "",
        "state": "Up",
        "deployPath": "/Users/{your_user_name}/hugegraph/apache-hugegraph-incubating-1.7.0/apache-hugegraph-store-incubating-1.7.0/lib/hg-store-node-1.7.0.jar",
        "dataPath": "./storage",
        "startTimeStamp": 1754027127969,
        "registedTimeStamp": 1754027127969,
        "lastHeartBeat": 1754027909444,
        "capacity": 494384795648,
        "available": 346535829504,
        "partitionCount": 0,
        "graphSize": 0,
        "keyCount": 0,
        "leaderCount": 0,
        "serviceName": "127.0.0.1:8500-store",
        "serviceVersion": "",
        "serviceCreatedTimeStamp": 1754027127000,
        "partitions": []
      }
    ],
    "stateCountMap": {
      "Up": 1
    },
    "numOfService": 1,
    "numOfNormalService": 1
  },
  "status": 0
}

7.5 其他 REST 接口

下表中的路径均相对于 http://<pd-host>:8620,除注明外都需要 7.1 中的 Basic 认证头。

方法与路径描述
GET /集群简要统计:leader、状态、成员数、Store 数、图数量、分区数
GET /v1/health健康检查,无需认证
GET /v1/cluster集群完整统计:PD 成员、Store、图、分区
GET /v1/membersPD 成员列表,含角色和选出的 leader
POST /v1/members/change修改 Raft peer 列表,请求体 {"peerList": "..."}
GET /v1/stores已注册的 Store 节点及其状态和统计信息
GET /v1/store/{storeId}单个 Store 节点
POST /v1/store/{storeId}修改 Store 状态,请求体 {"storeState": "..."}
DELETE /v1/store/{storeId}从集群中移除 Store
POST /v1/store/logStore 状态变更日志,请求体 {"startTime": "...", "endTime": "..."}
GET /v1/storesAndStatsStore 原始元数据,用于调试
GET /v1/store_monitor/{storeId}Store 监控采样数据(文本)
GET /v1/store_monitor/json/{storeId}Store 监控采样数据(JSON)
GET /v1/shards所有分区的所有副本,含 store id、角色、状态和进度
GET /v1/shardGroupsShard 分组
GET /v1/shardGroupsCachePD 内存缓存中的 shard 分组
GET /v1/shardLeaders按 Store raft 地址分组的分区 leader
GET /v1/balanceLeaders在各 Store 之间重新平衡分区 leader
GET /v1/partitions分区列表及其状态和统计信息
GET /v1/highLevelPartitions分区列表,含各图的 key 数量和数据大小
GET /v1/partitionsAndStats分区原始元数据,用于调试
POST /v1/partitions/log分区变更日志,请求体 {"startTime": "...", "endTime": "..."}
GET /v1/resetPartitionState重置所有分区的状态
GET /v1/graphs图列表
GET /v1/graph/**按名称查询单个图
POST /v1/graph/**修改图的分区数,请求体 {"partitionCount": N}
GET /v1/graph/partitionSizeRange集群允许的分区数上下限
GET /v1/graph-spaces图空间列表
GET /v1/graph-spaces/**单个图空间
POST /v1/graph-spaces/**修改图空间
POST /v1/registry注册一个服务实例用于服务发现
POST /v1/registryInfo查询已注册的实例
GET /v1/allInfo所有已注册的实例
GET /v1/licenseLicense 信息
GET /v1/license/machineInfoLicense 校验看到的 IP 和 MAC 地址
GET /v1/task/patrolStores立即执行 Store 巡检任务
GET /v1/task/patrolPartitions立即执行分区巡检任务
GET /v1/task/balancePartitions在各 Store 之间重新平衡分区
GET /v1/task/splitPartitions立即执行自动分区拆分
GET /v1/task/balanceLeaders重新平衡分区 leader
GET /v1/task/compact让 Store 节点对其分区的 RocksDB 文件做 compaction
GET /v1/prom/targets/{appName}Prometheus 服务发现目标,无需认证
GET /v1/prom/targets-all所有应用类型的 Prometheus 目标
GET /v1/prom/sd_configPrometheus HTTP 服务发现配置
GET /actuator/healthSpring Boot 健康检查,无需认证
GET /actuator/metricsSpring Boot 监控指标,无需认证
GET /actuator/prometheusPrometheus 抓取端点,无需认证

两个 log 接口接受形如 {"startTime": "...", "endTime": "..."} 的时间范围,yyyy-MM-dd HH:mm:ssyyyy-MM-dd 都是可接受的格式。

PD 以 hg 前缀注册自己的指标,因此 /actuator/prometheus 除标准 JVM 指标外还会暴露 hg_uphg_graphshg_storeshg_terms,在存在图之后还会有按图统计的分区和大小指标。

1.3 - HugeGraph-Store Quick Start

1 HugeGraph-Store 概述

HugeGraph-Store 是 HugeGraph 分布式版本的存储节点组件,负责实际存储和管理图数据。它与 HugeGraph-PD 协同工作,共同构成 HugeGraph 的分布式存储引擎,提供高可用性和水平扩展能力。

每个 Store 节点使用 RocksDB 保存图数据,并通过 Raft(JRaft)进行复制:每个分区是一个独立的 Raft 组,因此分区在丢失少数副本时仍可继续工作。Store 节点之间并不直接感知彼此,它们向 PD 注册,由 PD 下发分区分配,并通过心跳上报状态。HugeGraph-Server 先从 PD 查询分区位置,再通过 gRPC 访问 Store。

2 依赖

2.1 前置条件

  • 操作系统:Linux 或 macOS(Windows 尚未经过完整测试)
  • Java 版本:≥ 11(编译期强制校验,bin/start-hugegraph-store.sh 启动时会再次检查)
  • Maven 版本:≥ 3.5.0
  • 如需进行多节点部署,请先部署 HugeGraph-PD

3 部署

有两种方式可以部署 HugeGraph-Store 组件:

  • 方式 1:下载 tar 包
  • 方式 2:源码编译

3.1 下载 tar 包

从 Apache HugeGraph 官方下载页面下载最新版本的 HugeGraph-Store:

# 1.7.0 是项目孵化期发布的历史版本,因此文件名和目录名仍带 incubating
wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz
tar zxf apache-hugegraph-incubating-1.7.0.tar.gz
cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-store-incubating-1.7.0

3.2 源码编译

# 1. 克隆源代码
git clone https://github.com/apache/hugegraph.git

# 2. 编译项目
cd hugegraph
mvn clean install -DskipTests=true

# 3. 编译成功后,Store 目录和完整发布包分别位于
#    hugegraph-store/apache-hugegraph-store-{version}
#    target/apache-hugegraph-{version}.tar.gz

如果只想单独编译 Store 而不是整个仓库,需要先编译 hugegraph-struct,因为 Store 依赖它:

mvn install -pl hugegraph-struct -am -DskipTests
mvn clean package -pl hugegraph-store/hg-store-dist -am -DskipTests

生成的目录只包含 bin/conf/lib/hg-store-node-{version}.jar

3.3 Docker 部署

HugeGraph-Store Docker 镜像已发布在 Docker Hub,镜像名是 hugegraph/store

注: 后续步骤皆假设你本地已拉取 hugegraph 主仓库代码 (至少是 docker 目录)

有两个 compose 文件包含 Store:

Compose 文件拓扑用途
docker-compose-hstore.yml1 PD + 1 Store + 1 Server + 1 Hubble最小分布式部署
docker-compose-3pd-3store-3server.yml3 PD + 3 Store + 3 Server + 1 Hubble多节点参考部署
cd hugegraph/docker
# 注意版本号请随时保持更新 → 1.x.0

# 最小分布式部署
HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose-hstore.yml up -d --wait

# 或者多节点集群
HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose-3pd-3store-3server.yml up -d

通过 docker run 运行单个 Store 节点:

docker run -d \
  -p 8520:8520 \
  -p 8500:8500 \
  -p 8510:8510 \
  -e HG_STORE_PD_ADDRESS=<pd-ip>:8686 \
  -e HG_STORE_GRPC_HOST=<your-ip> \
  -e HG_STORE_RAFT_ADDRESS=<your-ip>:8510 \
  -v /path/to/storage:/hugegraph-store/storage \
  --name hugegraph-store \
  hugegraph/store:1.7.0

环境变量参考:

变量必填默认值对应配置项描述
HG_STORE_PD_ADDRESSn/apdserver.addressPD gRPC 地址(如 pd0:8686,pd1:8686,pd2:8686
HG_STORE_GRPC_HOSTn/agrpc.host本节点的 gRPC 主机名/IP(如 store0
HG_STORE_RAFT_ADDRESSn/araft.address本节点的 Raft 地址(如 store0:8510
HG_STORE_GRPC_PORT8500grpc.portgRPC 服务端口
HG_STORE_REST_PORT8520server.portREST API 端口
HG_STORE_DATA_PATH/hugegraph-store/storageapp.data-path数据存储路径

入口脚本会把这些变量转换为 SPRING_APPLICATION_JSON,覆盖在 conf/application.yml 之上,然后执行 bin/start-hugegraph-store.sh -d false -j "$JAVA_OPTS"。上表未覆盖的配置项仍需要修改 conf/application.yml,或者自行提供 SPRING_APPLICATION_JSON

镜像细节:

  • JAVA_OPTS 默认值为 -XX:+UnlockExperimentalVMOptions -XX:+UseContainerSupport -XX:MaxRAMPercentage=50 -XshowSettings:vm
  • STDOUT_MODE=true,因此 Java 日志输出到容器 stdout,而不是 logs/hugegraph-store-server.log
  • HEALTHCHECK 在 90 秒启动期后每 15 秒访问一次 GET http://localhost:8520/v1/health
  • 镜像只声明了 EXPOSE 8520;如果需要从 Docker 网络之外访问 8500 和 8510,请自行发布这两个端口

注意:在 Docker 桥接网络中,HG_STORE_GRPC_HOST 应使用容器主机名(如 store0)而非 IP 地址。

已弃用的别名PD_ADDRESSGRPC_HOSTRAFT_ADDRESS 仍可使用,但会输出弃用警告。新部署请使用 HG_STORE_* 名称。

4 配置

Store 从 conf/ 读取两个配置文件:

  • application.yml,主配置文件(PD 地址、各端口、Raft、数据路径)
  • application-pd.yml,由 application.yml 中的 spring.profiles.include: pd 引入,包含 RocksDB 内存设置和 Actuator 暴露配置

4.1 application.yml

发布包中自带的文件内容如下:

pdserver:
  # PD service address, multiple PD addresses separated by commas
  address: localhost:8686

management:
  metrics:
    export:
      prometheus:
        enabled: true
  endpoints:
    web:
      exposure:
        include: "*"

grpc:
  # grpc service address
  host: 127.0.0.1
  port: 8500
  netty-server:
    max-inbound-message-size: 1000MB
raft:
  # raft cache queue size
  disruptorBufferSize: 1024
  address: 127.0.0.1:8510
  max-log-file-size: 600000000000
  # Snapshot generation interval, in seconds
  snapshotInterval: 1800
server:
  # rest service address
  port: 8520

app:
  # Storage path, support multiple paths, separated by commas
  data-path: ./storage
  #raft-path: ./storage

spring:
  application:
    name: store-node-grpc-server
  profiles:
    active: default
    include: pd

logging:
  config: 'file:./conf/log4j2.xml'
  level:
    root: info

4.2 application-pd.yml

management:
  metrics:
    export:
      prometheus:
        enabled: true
  endpoints:
    web:
      exposure:
        include: "*"

rocksdb:
  # rocksdb total memory usage, force flush to disk when reaching this value
  total_memory_size: 32000000000
  # memtable size used by rocksdb
  write_buffer_size: 32000000
  # For each rocksdb, the number of memtables reaches this value for writing to disk.
  min_write_buffer_number_to_merge: 16

4.3 配置项参考

下表中「模板值」是上面两个文件中的取值,「代码默认值」是配置项缺失时节点使用的回退值;模板未列出的配置项应以代码默认值为准。

核心

配置项模板值代码默认值说明
pdserver.addresslocalhost:8686必填PD gRPC 地址,多个地址用逗号分隔。Store 在此注册并获取分区分配。必须填写 PD 的 grpc.port,不是 PD 的 REST 端口。
grpc.host127.0.0.1必填本节点对外公布的 gRPC 地址。应设置为可路由的 IP 或主机名,127.0.0.1 只适用于单机部署。
grpc.port8500必填gRPC 端口,Server 和 Store 客户端连接此端口。
grpc.netty-server.max-inbound-message-size1000MBgRPC 默认值单个入站 gRPC 消息的最大大小,由 grpc-spring-boot-starter 的 Netty 服务端读取。
grpc.server.wait-time未设置3600扫描流等待客户端消费一页数据的秒数,超时后服务端中止该流。
server.port8520必填REST 和 Actuator 端口,同时以 rest.port 标签上报给 PD。

Raft

配置项模板值代码默认值说明
raft.address127.0.0.1:8510必填本节点的 Raft 服务地址,格式为 host:port,必须能被其他 Store 节点访问。这里不需要配置 peer 列表:分区 Raft 组的成员由 PD 下发。
raft.disruptorBufferSize10240Raft 任务队列大小。设为 0 时按 rocksdb.total_memory_size 推导:将该内存量的 GB 数取最接近的 2 的幂,再乘以 32。
raft.max-log-file-size60000000000050000000000Raft 日志的最大字节数。
raft.snapshotInterval1800300生成 Raft 快照的时间间隔,单位秒。
raft.snapshotLogIndexMargin未设置0距上次快照的最小 applied index 差值,达到后才真正生成快照。设为 0 关闭该判断。
raft.rpc-timeout未设置10000Raft RPC 超时时间,单位毫秒。
raft.metrics未设置true采集 JRaft 节点指标,可通过 /metrics/raft 读取。
raft.useRocksDBSegmentLogStorage未设置true使用 RocksDB 分段日志存储保存 Raft 日志。
raft.maxSegmentFileSize未设置67108864分段日志文件大小,单位字节(64 MB)。
raft.maxReplicatorInflightMsgs未设置256每个 follower 的最大在途复制请求数。
raft.maxEntriesSize未设置256单次 AppendEntries 请求包含的最大条目数。
raft.maxBodySize未设置524288单次 AppendEntries 请求的最大字节数。
ave-logEntry-size-ratio未设置0.95估算日志条目平均大小时的平滑系数。注意该配置项位于顶层,不在 raft 下。

存储与标签

配置项模板值代码默认值说明
app.data-path./storagestoreRocksDB 数据目录。用逗号分隔多个路径可将分区分散到多块磁盘。
app.raft-path已注释Raft 日志和快照目录。为空时回退到 app.data-path
app.fake-pd未设置false内置 PD 模式,仅用于单机测试,不要用于生产。
app.placeholder-size未设置10启动时在每个数据路径下创建的 placeholder 占位文件大小,单位 GB,便于紧急情况下释放空间。设为 0 关闭。
app.label.<name>未设置随 store 心跳上报给 PD 的自定义键值标签。节点会自动追加 rest.port

RocksDB

配置项模板值代码默认值说明
rocksdb.total_memory_size3200000000051539607552本节点所有 RocksDB 实例共享的内存预算。缺失或为 0 时使用 JVM 最大堆内存。
rocksdb.write_buffer_size3200000033554432memtable 大小,单位字节。缺失或为 0 时取 total_memory_size / 1000
rocksdb.min_write_buffer_number_to_merge1616落盘前合并的 memtable 数量。
rocksdb.write_buffer_ratio未设置0.66total_memory_size 中分配给写缓存的比例,其余作为 block cache。

org/apache/hugegraph/rocksdb/access/RocksDBOptions.java 中定义的其他选项都可以加在同一个 rocksdb: 块下,例如 rocksdb.max_background_jobsrocksdb.level0_file_num_compaction_triggerrocksdb.bloom_filter_bits_per_key

线程池

配置项代码默认值说明
thread.pool.grpc.core600处理 gRPC 请求的核心线程数。
thread.pool.grpc.max1000gRPC 最大线程数。
thread.pool.grpc.queue2147483647gRPC 任务队列容量。
thread.pool.scan.core128处理扫描的核心线程数。设为 0 时取 CPU 核数的 4 倍。
thread.pool.scan.max1000扫描最大线程数。
thread.pool.scan.queue0扫描任务队列容量。

查询下推

配置项代码默认值说明
query.push-down.threads1500下推查询的线程池大小。
query.push-down.fetch_batch20000单次请求拉取的行数。
query.push-down.fetch_timeout300000拉取超时时间,单位毫秒。
query.push-down.memory_limit_count50000排序等内存操作的行数上限。
query.push-down.index_size_limit_count50000索引 sst 文件大小上限,单位 kB。

后台任务

配置项代码默认值说明
job.interruptableThreadPool.core128TTL 清理线程池的核心线程数。设为 0 时取 CPU 核数。
job.interruptableThreadPool.max256TTL 清理线程池的最大线程数。设为 0 时取 CPU 核数的 4 倍。
job.interruptableThreadPool.queue2147483647TTL 清理线程池的队列容量。
job.uninterruptibleThreadPool.core0存储引擎不可中断任务线程池的核心线程数。设为 0 时取 CPU 核数。
job.uninterruptibleThreadPool.max256不可中断任务线程池的最大线程数。
job.uninterruptibleThreadPool.queue2147483647不可中断任务线程池的队列容量。
job.cleaner.batch.size10000TTL 清理任务每批删除的 key 数量。
job.start-time0每日 TTL 清理执行的小时数(0 到 23)。超出该范围时回退为 19。

内置 PD 模式

仅用于单机开发调试,通过 app.fake-pd: true 开启。此时节点自行扮演 PD 角色,并忽略 pdserver.address

配置项代码默认值说明
fake-pd.store-list''伪集群中各 Store 节点的 gRPC 地址。
fake-pd.peers-list''同一批节点的 Raft 地址。
fake-pd.partition-count3分区数量。
fake-pd.shard-count3每个分区的副本数。

诊断

配置项代码默认值说明
arthas.telnetPort8566调用 /v1/arthasstart 后 Arthas 的 telnet 端口。
arthas.httpPort8565Arthas HTTP 端口。
arthas.ip0.0.0.0Arthas 监听地址。
arthas.disabledCommandsjad需要禁用的 Arthas 命令。

4.4 各节点需要区分的配置

对于多节点部署,需要为每个 Store 节点修改以下配置:

  1. grpc.hostgrpc.port(其他组件访问本节点的地址)
  2. raft.address(Raft 协议地址)
  3. server.port(REST 端口)
  4. app.data-path(数据存储路径)

pdserver.address 在所有节点上保持一致,它列出的是整个 PD 集群。

5 启动与停止

5.1 启动 Store

确保 PD 服务已经启动,然后在 Store 安装目录下执行:

./bin/start-hugegraph-store.sh

启动脚本支持四个参数:

参数取值默认值说明
-dtruefalsetrue守护进程模式,见下文。
-gZGCzgc未设置垃圾回收器。不传该参数即使用默认的 G1。除 ZGCzgc 之外的任何取值都会直接退出,包括 g1,尽管脚本自身的用法提示里写了它。
-jJVM 参数字符串附加的 JVM 参数,例如 -j "-Xmx16g -Xms8g"
-ytruefalsefalse挂载 OpenTelemetry Java agent(首次使用时下载到 plugins/),并将 trace 导出到 127.0.0.1:4317

守护进程模式:

  • -d true(默认):以后台守护进程方式运行,脚本立即返回,并把 Java 进程号写入 bin/pid
  • -d false:以前台模式运行,脚本通过 exec 替换为 Java 进程,容器或进程管理器的进程即为 Java 本身。在 Docker 或进程管理器(systemd、supervisord)下运行时请使用此参数,以便在崩溃时自动检测并重启服务。

JVM 内存方面,如果没有自行设置 JAVA_OPTIONS-Xms512m-Xmx 取空闲内存的一半并限制在 512 MB 到 2048 MB 之间。脚本还会加上 -XX:MetaspaceSize=256M、OOM 时把堆转储写入 logs/,以及滚动的 GC 日志 logs/gc.log。生产节点通常需要大得多的堆,请显式指定,例如 -j "-Xmx32g -Xms32g"

ulimit -nulimit -u 低于 1024 时脚本会拒绝启动;在 x86_64 和 arm64 上,如果能成功下载并校验对应的动态库,脚本会预加载 jemalloc。

启动成功后,可以在 logs/hugegraph-store-server.log 中看到类似以下的日志:

YYYY-mm-dd xx:xx:xx [main] [INFO] o.a.h.s.n.StoreNodeApplication - Started StoreNodeApplication in x.xxx seconds (JVM running for x.xxx)

5.2 停止 Store

在 Store 安装目录下执行:

./bin/stop-hugegraph-store.sh

脚本读取 bin/pid,向该进程发送信号,最多等待 30 秒直至进程退出,然后删除 pid 文件。如果 bin/pid 不存在,脚本直接退出且不做任何操作。

5.3 重启 Store

./bin/restart-hugegraph-store.sh

该脚本依次 source 停止脚本和启动脚本,并转发 5.1 中的参数。

5.4 启动顺序

  1. 先启动 PD。每个 Store 的 grpc.host:grpc.port 都应出现在 PD 的 pd.initial-store-list 中,否则 PD 只会把该节点登记为 Pending 而不会置为 Up,分区分配也就无法完成。
  2. 再启动 Store。Store 早于 PD 启动并不致命:心跳线程会持续重试注册,并在 PD 可用之前打印 store heartbeat error: PD UNREACHABLE
  3. 最后启动 HugeGraph-Server,此时所有 Store 节点都应上报 state: "Up"。Server 需要分区就绪之后才能初始化或打开图。

compose 文件用 depends_on: condition: service_healthy 表达同样的顺序:Store 等待所有 PD 健康检查通过,Server 等待所有 Store 健康检查通过。

6 多节点部署示例

以下是一个三节点部署的配置示例:

6.1 三节点配置参考

  • 3 PD 节点
    • raft 端口:8610, 8611, 8612
    • rpc 端口:8686, 8687, 8688
    • rest 端口:8620, 8621, 8622
  • 3 Store 节点
    • raft 端口:8510, 8511, 8512
    • rpc 端口:8500, 8501, 8502
    • rest 端口:8520, 8521, 8522

6.2 Store 节点配置

对于三个 Store 节点,每个节点的主要配置差异如下:

节点 A:

grpc:
  port: 8500
raft:
  address: 127.0.0.1:8510
server:
  port: 8520
app:
  data-path: ./storage-a

节点 B:

grpc:
  port: 8501
raft:
  address: 127.0.0.1:8511
server:
  port: 8521
app:
  data-path: ./storage-b

节点 C:

grpc:
  port: 8502
raft:
  address: 127.0.0.1:8512
server:
  port: 8522
app:
  data-path: ./storage-c

所有节点都应该指向相同的 PD 集群:

pdserver:
  address: 127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688

同时每个 PD 节点都应列出三个 Store 的 gRPC 地址:

pd:
  initial-store-list: 127.0.0.1:8500,127.0.0.1:8501,127.0.0.1:8502

6.3 Docker 分布式集群配置

3 节点 Store 集群包含在 docker/docker-compose-3pd-3store-3server.yml 中。每个 Store 节点拥有独立的主机名和环境变量:

# store0,宿主机端口 8500(gRPC)、8510(Raft)、8520(REST)
HG_STORE_PD_ADDRESS: pd0:8686,pd1:8686,pd2:8686
HG_STORE_GRPC_HOST: store0
HG_STORE_GRPC_PORT: "8500"
HG_STORE_REST_PORT: "8520"
HG_STORE_RAFT_ADDRESS: store0:8510
HG_STORE_DATA_PATH: /hugegraph-store/storage

# store1,宿主机端口 8501、8511、8521
HG_STORE_GRPC_HOST: store1
HG_STORE_RAFT_ADDRESS: store1:8510

# store2,宿主机端口 8502、8512、8522
HG_STORE_GRPC_HOST: store2
HG_STORE_RAFT_ADDRESS: store2:8510

每个节点的容器内端口都是 8500/8510/8520,只有映射到宿主机的端口不同。PD 节点相应地设置 HG_PD_INITIAL_STORE_LIST: store0:8500,store1:8500,store2:8500

Store 节点仅在所有 PD 节点通过健康检查后才会启动,其中 docker-compose 中的 healthcheck 实际访问的是 PD 的 REST 接口 /v1/health(也可以通过 Actuator 暴露的 /actuator/health 进行手动检查),并通过 depends_on: condition: service_healthy 强制执行依赖关系。

运行时日志可通过 docker logs <container-name>(如 docker logs hg-store0)直接查看,无需进入容器。

完整的部署指南请参阅 docker/README.md

7 验证 Store 服务

确认 Store 服务是否正常运行:

curl http://localhost:8520/actuator/health

如果返回 {"status":"UP"},则表示 Store 服务已成功启动。

GET /v1/health 是 Docker 镜像和 compose 文件使用的轻量检查接口,它返回 HTTP 200 且响应体为空,因此应使用 curl -fsS 并检查退出码,而不是检查输出内容:

curl -fsS http://localhost:8520/v1/health && echo OK

7.1 Store REST 接口

Store 节点在 server.port 上提供以下只读接口:

方法路径描述
GET/v1/health存活探测,HTTP 200 且响应体为空
GET/actuator/healthSpring Boot Actuator 健康检查,返回 {"status":"UP"}
GET/actuator/prometheusPrometheus 抓取接口
GET/节点概览,包含 leaderCountpartitionCount
GET/-/state节点状态,取值为 STARTINGONLINESTOPPING
GET/-/echo?name=<text>回显检查
GET/-/scan当前扫描流的状态
GET/v1/partitions本节点上的所有 Raft 组及分区指标。加上 ?flags=accurate 可获取精确的 key 数量,但更慢。
GET/v1/partition/{id}按分区 id 查询单个 Raft 组,包含角色、leader、peers 和已提交索引
GET/metrics/system主机 CPU 和内存指标
GET/metrics/drive数据路径所在磁盘的指标
GET/metrics/raftJRaft 节点指标,需要 raft.metrics: true

Actuator 和 Prometheus 之所以可访问,是因为自带配置设置了 management.endpoints.web.exposure.include: "*"management.metrics.export.prometheus.enabled: true

节点还提供一批会修改状态或执行重负载操作的运维接口:PUT /-/stateGET /-/cleanerGET /v1/partition/dump/{id}GET /v1/partition/clean/{id}POST /v1/compat?id=<partition>GET /v1/arthasstartPOST /raft/options,以及 /fix/*/test/* 两组接口。请仅在排查问题时使用,并且不要把 REST 端口暴露到不可信网络。

7.2 通过 PD 检查注册结果

也可以通过 PD API 查看集群中的 Store 节点状态:

curl -u store:admin http://localhost:8620/v1/stores

PD 的 REST 端口默认开启 basic 认证:用户名必须是 hgstorehubblevermeer 之一,密码目前还不校验。不带凭据的请求会返回 {"status":-1,"error":"Unauthorized!"}。只有 /v1/health/actuator/*/v1/prom/targets/* 不需要认证。

如果 Store 配置成功,上述接口响应中应包含当前节点的状态信息,其中 stateUp 表示节点运行正常。如果节点长期停留在 Pending,通常是因为它没有出现在 PD 的 pd.initial-store-list 中。

下方示例仅展示 1 个 Store 节点的返回结果。如果 3 个节点都已正确配置并正在运行,则响应中的 storeId 列表应包含 3 个 ID,且 stateCountMap.UpnumOfServicenumOfNormalService 都应为 3

{
  "message": "OK",
  "data": {
    "stores": [
      {
        "storeId": 8319292642220586694,
        "address": "127.0.0.1:8500",
        "raftAddress": "127.0.0.1:8510",
        "version": "",
        "state": "Up",
        "deployPath": "/Users/{your_user_name}/hugegraph/hugegraph-store/apache-hugegraph-store-{version}/lib/hg-store-node-{version}.jar",
        "dataPath": "./storage",
        "startTimeStamp": 1754027127969,
        "registedTimeStamp": 1754027127969,
        "lastHeartBeat": 1754027909444,
        "capacity": 494384795648,
        "available": 346535829504,
        "partitionCount": 0,
        "graphSize": 0,
        "keyCount": 0,
        "leaderCount": 0,
        "serviceName": "127.0.0.1:8500-store",
        "serviceVersion": "",
        "serviceCreatedTimeStamp": 1754027127000,
        "partitions": []
      }
    ],
    "stateCountMap": {
      "Up": 1
    },
    "numOfService": 1,
    "numOfNormalService": 1
  },
  "status": 0
}

2 - HugeGraph ToolChain

测试指南:如需在本地运行工具链测试,请参考 HugeGraph 工具链本地测试指南

HugeGraph Toolchain 包含 Java/Go 客户端、Loader、Hubble、Tools、Spark Connector 和 SeaTunnel Sink/Source。先按任务选择入口,再查看对应组件的配置与命令。

任务推荐入口适合场景
图可视化Hubble在 Web 界面查看和管理图
图导入LoaderSeaTunnel SinkSpark Connector直接导入数据,或接入已有数据管道
图导出/迁移ToolsSeaTunnel Source备份、导出、跨图迁移和持续读取

DeepWiki 提供实时更新的项目文档,内容更全面准确,适合快速了解项目最新情况。

📖 https://deepwiki.com/apache/hugegraph-toolchain

源码仓库: apache/hugegraph-toolchain

2.1 - HugeGraph-Hubble Quick Start

部署 HugeGraph-Hubble,进行图可视化、元数据管理、数据导入,以及 Gremlin 或 Cypher 查询。

1 HugeGraph-Hubble 概述

⚠️ 安全提醒:Hubble 监听的是明文 HTTP 端口,请勿将其暴露在公网或不受信任的网络中;应在其前面终结 HTTPS,并使用 IP/端口白名单限制访问。Hubble 自身不保存账号库:当所连接的 HugeGraph Server 开启了鉴权时,Hubble 会显示登录页并把凭据转发给 Server;当 Server 允许匿名访问时,则没有登录环节,账号相关页面也会隐藏。

版本说明:本页对应 hugegraph-toolchain master。下文标注了依赖较新 Server、PD 或 Store 版本的功能,这些功能在旧版 Server 上不可用。

测试指南:如需在本地运行 Hubble 测试,请参考 工具链本地测试指南

HugeGraph-Hubble 是 HugeGraph 的 Web 管理界面。它连接到一个 HugeGraph Server(直连,或在分布式集群中通过 PD 发现),管理图空间(GraphSpace)、图和 Schema,导入数据,执行 Gremlin 与 Cypher 查询以及内置图算法,并将结果图形化展示。

平台主要包括以下模块:

图概览

图概览列出图空间(PD 模式)和图,可以创建、克隆和清空图,加载 Demo 图,打开包含统计信息与 Schema 的图详情页,并跳转到查询工作台。

元数据建模

元数据建模用于管理单个图的 PropertyKey、VertexLabel、EdgeLabel 和 IndexLabel,提供列表与图两种视图。Schema 模板按图空间保存可复用的 Groovy Schema,可在创建图时直接套用。

数据导入

数据导入页面适合小规模试用。大批量或生产导入请使用 HugeGraph Loader

数据源支持 FILE、HDFS、JDBC 和 KAFKA 四种类型。导入任务分四步配置,可以执行一次、按 cron 周期执行,或对 Kafka 源持续实时执行。

图查询

图查询可以按立即查询或异步任务两种模式执行 Gremlin 与 Cypher 语句,并以图(2D 或 3D)、表格或 JSON 展示结果,同时保存执行记录与收藏语句。

内置图算法

内置图算法为 Server 的 OLTP traverser 接口(交互式探索)以及 OLAP 任务(通过 HugeGraph Computer 或 Vermeer 进行集群批量计算)提供参数表单。

异步任务

异步任务列出后台任务,包括 Gremlin 与 Cypher 任务、算法任务、删除元数据、创建与重建索引、Vermeer 图加载与图计算任务,并支持查看详情、取消和删除。

系统与运维

系统与运维包含个人中心、带图空间权限预设的账号管理,以及 PD 模式下的集群概览与节点详情。

1.1 版本兼容性

Hubble 会自动探测所连接 Server 的鉴权模式与能力,自身没有单独的鉴权开关。支持的组合如下:

HugeGraph Server / PD部署方式Hubble 兼容性范围与限制
Server 1.5.x单机,通常不开启鉴权最低兼容仅支持基础的图、Schema、数据和 Gremlin 流程。图空间、账号权限、PD/Store 拓扑、集群运维和较新的算法均不可用。
Server 1.7.x 搭配同版本 PD/Store 1.7.x单机或分布式通过兼容适配达到最低可用核心管理与查询流程仍可使用,但旧版 REST/Gremlin 鉴权、权限语义、指标和算法能力的体验会有所降级。
Server、PD 和 Store 1.8.x 及以上推荐分布式部署完整且推荐的体验图空间、账号权限预设、集群运维、异步任务和算法能力处理都是针对这一代设计并验证的。

分布式集群中请使用版本号一致的 Server、PD 和 Store。

2 部署

有三种方式可以部署hugegraph-hubble

  • 使用 docker (便于测试)
  • 下载 toolchain 二进制包
  • 源码编译

Hubble 运行在 Java 11 上:后端以 java.version=11 编译,Docker 镜像基于 eclipse-temurin:11-jrebin/start-hubble.sh 只检查 PATH 中是否存在 java,因此请自行确认选用的是正确的 JDK。

2.1 使用 Docker (便于测试)

特别注意:Hubble 已不再在页面上填写 Server 的主机名和端口。Server 地址来自 conf/hugegraph-hubble.propertiespd.enabled=false 时使用 server.direct_urlpd.enabled=true 时通过 pd.peers 由 PD 发现。容器内的 127.0.0.1 指向 hubble 容器自身,因此打包默认值 server.direct_url=http://127.0.0.1:8080 无法访问到另一个容器里的 Server。

若 hubble 和 server 在同一 docker 网络下,推荐直接使用container_name (如下例的 server) 作为主机名。或者也可以使用 宿主机 IP 作为主机名,此时端口号为宿主机给 server 配置的端口

镜像会把打包产物复制到 /hubble,把 /hubble/conf/hugegraph-hubble.properties 中的 server.host 改写为 0.0.0.0、清空 dashboard.address,暴露 8088 端口,并以 ./bin/start-hubble.sh -f 前台方式启动。

先准备一份指向你的 Server、并让容器监听所有网卡的 hugegraph-hubble.properties

server.host=0.0.0.0
server.port=8088
pd.enabled=false
server.direct_url=http://server:8080

然后把该文件挂载覆盖打包配置来启动 hubble

docker run -itd --name=hubble -p 8088:8088 \
  -v "$PWD/hugegraph-hubble.properties:/hubble/conf/hugegraph-hubble.properties" \
  hugegraph/hubble:1.7.0

或者使用 docker-compose 启动 hubble,另外如果 hubble 和 server 在同一个 docker 网络下,可以使用 server 的 container_name 进行访问,而不需要宿主机的 ip

使用docker-compose up -ddocker-compose.yml如下:

version: '3'
services:
  server:
    image: hugegraph/hugegraph:1.7.0
    container_name: server
    environment:
      - PASSWORD=xxx
    ports:
      - 8080:8080

  hubble:
    image: hugegraph/hubble:1.7.0
    container_name: hubble
    ports:
      - 8088:8088
    volumes:
      - ./hugegraph-hubble.properties:/hubble/conf/hugegraph-hubble.properties

注意:

  1. hugegraph-hubble 的 docker 镜像是一个便捷发布版本,用于快速测试试用 hubble,并非ASF 官方发布物料包的方式。你可以从 ASF Release Distribution Policy 中得到更多细节。

  2. 生产环境推荐使用 release tag(如 1.7.0) 稳定版。使用 latest tag 默认对应 master 最新代码。

2.2 下载 toolchain 二进制包

hubble项目在toolchain项目中,首先下载toolchain的 tar 包

export VERSION=1.7.0
export ARCHIVE="apache-hugegraph-toolchain-incubating-${VERSION}"
wget "https://downloads.apache.org/hugegraph/${VERSION}/${ARCHIVE}.tar.gz"
tar -xvf "${ARCHIVE}.tar.gz"
cd "${ARCHIVE}/apache-hugegraph-hubble-incubating-${VERSION}"

先修改 conf/hugegraph-hubble.properties,把 Server 地址配置正确,然后运行hubble

bin/start-hubble.sh

start-hubble.sh 支持以下参数:

参数说明
-f--foreground [true|false]前台运行而不是以守护进程方式运行,Docker 镜像使用 -f
-d--debug8787 端口开启 JDWP 调试(server=y,suspend=n

脚本以 -Xms512m -Dfile.encoding=UTF-8 -Dhubble.home.path=<安装目录> 启动 JVM,把 PID 写入 bin/pid,日志输出到 logs/hugegraph-hubble.log,并最多等待 30 秒直到 http://<server.host>:<server.port>/about 有响应后才返回。

打包默认值为 server.host=localhost,即在修改之前只接受本机回环访问。启动完成后访问 http://<host>:8088

停止服务时执行 bin/stop-hubble.sh:它先发送 SIGTERM,让关闭钩子暂停正在运行的导入任务并干净地关闭内置 H2 数据库;只有在 STOP_TIMEOUT 秒(环境变量,默认 30)后进程仍然存活时,才会升级为 SIGKILL

2.3 源码编译

Hubble 的构建由 hugegraph-hubble/hubble-dist/pom.xml 中的 frontend-maven-plugin 安装 Node.js v18.20.8 和 Yarn v1.22.21,无需预先安装这两个工具。此外需要 JDK 11 和 Maven。

下载 toolchain 源码包

git clone https://github.com/apache/hugegraph-toolchain.git

编译hubble, 它依赖 loader 和 client, 编译时需提前构建这些依赖 (后续可跳)

cd hugegraph-toolchain
python -m pip install -r hugegraph-hubble/hubble-dist/assembly/travis/requirements.txt
mvn install -pl hugegraph-client,hugegraph-loader -am -Dmaven.javadoc.skip=true -DskipTests -ntp

cd hugegraph-hubble
mvn -e package -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp
cd apache-hugegraph-hubble-*

启动hubble

bin/start-hubble.sh -d

前端开发时可在 hubble-fe 目录下执行 yarn dev。后端 POM 未配置 spring-boot:run,请改为从 hubble-be/target/classes 启动 org.apache.hugegraph.HugeGraphHubble,并用 -Dhubble.home.path 指向一个可写目录。

3 平台使用流程

首页把各模块归纳为三条主线:图概览、图导入和图查询,同时显示当前运行在 PD / 集群模式还是 non-PD 单机模式。平台的模块使用流程如下:

image

4 平台使用说明

4.1 图管理

在 PD 模式下,【图空间管理】列出集群中的所有图空间,并可创建或编辑图空间,包括别名、可选的 Kubernetes 命名空间与计算任务,以及资源上限。在 non-PD 单机模式下只有一个名为 DEFAULT 的图空间,图空间列表会被跳过。

4.1.1 图创建

图管理模块下,点击【新建图】,填写图名称、可选的别名、可选的 Schema 模板和示例数据。图名称在其所属图空间内唯一,创建后不可修改。

image

创建图填写内容如下:

image

注意:Server 连接不在此页面配置,而是来自 conf/hugegraph-hubble.properties,通过 server.direct_url 或 PD 发现获得,Docker 下的主机名规则见 2.1 节。只有当所连接的 Server 提供建图能力(REST API 0.67 及以上)时才会显示新建图入口,旧版 Server 上图列表为只读。

4.1.2 图访问

实现图空间的信息访问,进入后,可进行图的多维查询分析、元数据管理、数据导入、算法分析等操作。【进入图分析平台】打开查询工作台,【元数据配置】打开 Schema 页面,图详情页展示顶点/边统计信息和 Schema。

image
4.1.3 图管理
  1. 图列表提供卡片视图和列表视图,搜索按图名称匹配。
  2. 单图操作包括:查看 schema(可【导出 Groovy Schema】)、元数据配置、克隆图(仅 Schema,或 Schema 与数据)、清空 Schema 与数据、删除,以及 PD 模式下的设为默认。
  3. 【示例数据与资源】可在当前图中构建 Demo 图:红楼梦 Demo 图、人物与软件 Demo 图、迷你电影 Rank Demo。这些 Demo 只补齐缺失的 Schema 和元素,不会清空已有数据。
image

4.2 元数据建模(列表 + 图模式)

4.2.1 模块入口

从图列表进入【元数据配置】,或直接访问图的元数据页面 /graphspace/<graphspace>/graph/<graph>/meta。页面包含属性、顶点类型、边类型、顶点索引、边索引五个标签页,并可在列表视图和图视图之间切换。

image
4.2.2 属性类型
4.2.2.1 创建
  1. 填写或选择属性名称、数据类型、基数,完成属性的创建。
  2. 创建的属性可作为顶点类型和边类型的属性。

列表模式:

image

图模式:

image
4.2.2.2 管理
  1. 在属性列表中可进行单条删除或批量删除操作,已被顶点类型或边类型使用的属性无法删除。
  2. 删除元数据会以异步任务方式执行,可在异步任务中查看进度。
4.2.3 顶点类型
4.2.3.1 创建
  1. 填写或选择顶点类型名称、ID 策略、关联属性、主键属性,顶点样式、查询结果中顶点下方展示的内容,以及索引的信息:包括是否创建类型索引,及属性索引的具体内容,完成顶点类型的创建。

列表模式:

image

图模式:

image
4.2.3.2 管理
  1. 可进行编辑操作,顶点样式、关联属性、顶点展示内容、属性索引可编辑,其余不可编辑。图模式下双击顶点类型即可编辑。

  2. 可进行单条删除或批量删除操作。

image
4.2.4 边类型
4.2.4.1 创建
  1. 填写或选择边类型名称、类型(普通类型、父边类型或子边类型,用于边类型的层级关系)、起点类型、终点类型、关联属性、是否允许多次连接、边样式、查询结果中边下方展示的内容,以及索引的信息:包括是否创建类型索引,及属性索引的具体内容,完成边类型的创建。

列表模式:

image

图模式:

image
4.2.4.2 管理
  1. 可进行编辑操作,边样式、关联属性、边展示内容、属性索引可编辑,其余不可编辑,同顶点类型。
  2. 可进行单条删除或批量删除操作。
4.2.5 索引类型

展示顶点类型和边类型的顶点索引和边索引,支持二级索引、范围索引、全文索引和唯一索引。

4.2.6 Schema 模板

【Schema 模板】(/graphspace/<graphspace>/schema)按图空间维护一份可复用的模板库。示例模板由 Hubble 内置,可以使用、移除和恢复,在保存之前不会写入 Server;用户模板以 Groovy Schema 形式保存在 Server 上,可以创建、编辑和删除。创建图时可以选择已有模板,使其 Schema 立即生效。

4.3 数据导入

注意:目前推荐使用 hugegraph-loader 进行正式数据导入,hubble 内置的导入用来做测试简单上手

数据导入的使用流程如下:

image
4.3.1 模块入口

左侧导航「图导入」下的【数据源管理】和【数据导入】:

image
4.3.2 数据源
  1. 【数据源管理】用于登记导入任务的读取来源,支持四种类型:FILE(本地上传)、HDFS、Kafka 和 JDBC。
  2. FILE 类型需要上传需要构图的文件,可接受的格式由 upload_file.format_list 决定,默认为 csvtxt
  3. 单文件与总大小上限默认分别为 1 GB 和 10 GB,未完成的上传分片会在 upload_file.max_uploading_time(默认 12 小时)后被清理。
image
4.3.3 创建任务
  1. 【数据导入】>【创建任务】分四步配置:输入基础信息、选择源端字段、选择映射字段、输入调度信息。
  2. 基础信息包括任务名称(1 到 48 个中文、字母、数字或 _)、目标图空间与图、源端类型和数据源。
  3. 可创建多个导入任务,并行导入。
image
4.3.4 设置数据映射
  1. 对选定的数据源设置数据映射,包括文件设置和类型设置

  2. 文件设置:勾选或填写是否包含表头、分隔符、编码格式等源端本身的设置内容,均设置默认值,无需手动填写

  3. 类型设置:

    1. 顶点映射和边映射:

      【顶点类型】 :选择顶点类型,并为其 ID 映射源端中的列数据;

      【边类型】:选择边类型,为其起点类型和终点类型的 ID 列映射源端的列数据;

    2. 映射设置:为选定的顶点类型的属性映射源端中的列数据,此处,若属性名称与文件的表头名称一致,可自动匹配映射属性,无需手动填选

    3. 完成设置后,显示设置列表,方可进行下一步操作,支持映射的新增、编辑、删除操作

设置映射的填写内容:

image

映射列表:

image
4.3.5 导入数据

最后一步选择任务的执行方式:执行一次表示一次性导入,周期执行使用 Quartz cron 表达式(例如 0 0/5 * * * ?),实时执行用于 Kafka 数据源。

  1. 导入设置
  • 导入设置参数项如下图所示,均设置默认值,无需手动填写
image
  1. 导入详情
  • 在任务列表中运行任务即可开始导入,也可在同一列表中暂停、编辑或删除任务
  • 任务的执行历史提供每次执行的执行实例 ID、导入记录数、平均速率(条/秒)、导入耗时和状态
  • 若导入失败,可查看具体原因
image

4.4 图查询

4.4.1 模块入口

左侧导航「图查询」下的【GQL 图遍历】:

image
4.4.2 多图切换

顶部栏承载当前图空间和图,可在不离开页面的情况下灵活切换多图的操作空间

image
4.4.3 图分析与处理

HugeGraph 支持 Apache TinkerPop3 的图遍历查询语言 Gremlin,Gremlin 是一种通用的图数据库查询语言,通过输入 Gremlin 语句,点击执行,即可执行图数据的查询分析操作,并可实现顶点/边的创建及删除、顶点/边的属性修改等。当所连接的 Server 支持 Cypher 时,Gremlin 旁边会出现 Cypher 页签。Text2GQL 页签仅为界面预览,并未接入任何模型或查询服务,其中输入的内容不会被发送或执行。

每条语句可以按两种模式执行:立即查询直接返回结果,适合 30 秒内可完成的小规模分析;异步执行则提交一个任务,进度和结果在异步任务中查看。Ctrl/Command + Enter 可执行当前语句。

查询后,下方为图结果展示区域,提供 3 种图结果展示方式,分别为:【图模式】、【表格模式】、【Json 模式】。图画布支持 2D 与 3D 渲染。

⚠️ SEC 提醒:Hubble 允许在网页端直接输入并执行 Gremlin 原生查询语句,这赋予了使用者较高的操作权限。请避免将 Hubble 服务暴露在公网环境,建议在使用时确保图数据库服务端已开启 鉴权体系 (Auth) 并配合 IP 白名单进行严格的权限控制,防止未授权访问或恶意代码执行风险。

支持缩放、居中、全屏、布局与样式配置、图例、缩略图、撤销与重做、导出等操作。画布可导出为 JSON、CSV 或图片,导出的画布也可以再次导入。

【图模式】

image

【表格模式】

image

【Json 模式】

image
4.4.4 数据详情

点击顶点/边实体,可查看顶点/边的数据详情,包括:顶点/边类型,顶点 ID,属性及对应值,拓展图的信息展示维度,提高易用性。

4.4.5 图结果的多维路径查询

除了全局的查询外,可针对查询结果中的顶点进行深度定制化查询以及隐藏操作,实现图结果的定制化挖掘。

右击顶点,出现顶点的菜单入口,可进行展示、查询、隐藏等操作。

  • 展开:点击后,展示与选中点关联的顶点。
  • 查询:通过选择与选中点关联的边类型及边方向,在此条件下,再选择其属性及相应筛选规则,可实现定制化的路径展示。
  • 隐藏:点击后,隐藏选中点及与之关联的边。

双击顶点,也可展示与选中点关联的顶点。

image
4.4.6 新增顶点/边
4.4.6.1 新增顶点

在图区可通过两个入口,动态新增顶点,如下:

  1. 点击图区面板,出现添加顶点入口
  2. 点击右上角的操作栏中的首个图标

通过选择或填写顶点类型、ID 值、属性信息,完成顶点的增加。

入口如下:

image

添加顶点内容如下:

image
4.4.6.2 新增边

右击图结果中的顶点,可增加该点的出边或者入边。

4.4.7 执行记录与收藏的查询
  1. 图区下方记载每次查询记录,包括:查询时间、执行类型、内容、状态、耗时、以及【收藏】和【加载】操作,实现图执行的全方位记录,有迹可循,并可对执行内容快速加载复用
  2. 提供语句的收藏功能,可对常用语句进行收藏操作,方便高频语句快速调用
image

4.5 异步任务

4.5.1 模块入口

左侧导航「图查询」下的【异步任务】:

image
4.5.2 任务管理
  1. 提供异步任务的统一的管理与结果查看,任务类型包括:
  • gremlin:Gremlin 任务
  • cypher:Cypher 任务
  • computer-dis:算法任务
  • remove_schema:删除元数据
  • create_index:创建索引
  • rebuild_index:重建索引
  • vermeer-task:load:Vermeer 图加载任务
  • vermeer-task:compute:Vermeer 图计算任务
  1. 列表显示当前图的异步任务信息,包括:任务 ID,任务名称,任务类型,创建时间,耗时,状态,操作,实现对异步任务的管理。列表每 5 秒自动刷新一次。
  2. 支持对任务类型和状态进行筛选
  3. 支持搜索任务 ID 和任务名称
  4. 运行中的任务可以取消,异步任务可进行删除或批量删除操作
image
4.5.3 Gremlin 异步任务

1.创建任务

  • 图查询模块支持两种执行方式:立即查询和异步任务;若用户切换到异步方式,点击执行后,在异步任务中心会建立一条异步任务;Cypher 语句同理会建立一条 Cypher 任务; 2.任务提交
  • 任务提交成功后,图区部分返回提交结果和任务 ID 3.任务详情
  • 提供【查看】入口,可跳转到任务详情查看当前任务具体执行情况跳转到任务中心后,直接显示当前执行的任务行
image

点击查看入口,跳转到任务管理列表,如下:

image

4.查看结果

  • 结果通过 json 形式展示,较长的结果可以就地展开
4.5.4 算法任务

从【内置图算法】提交的批量算法会在这里以算法任务的形式出现,Vermeer 的图加载与图计算任务同理。可在列表中通过 ID 找到相应任务,打开后查看进度与结果等。算法表单本身见 4.6 节。

4.5.5 删除元数据、重建索引

1.创建任务

  • 在元数据建模模块中,删除元数据时,可建立删除元数据的异步任务
image
  • 在编辑已有的顶点/边类型操作中,新增索引时,可建立创建索引的异步任务
image

2.任务详情

  • 确认/保存后,可跳转到任务中心查看当前任务的详情
image

4.6 内置图算法

「图查询」下的【内置图算法】为 Server 提供的算法给出参数表单,并按用途分组:探索邻居、寻找路径与连接、比较与排序、度量重要性、发现社区、分析图结构。每个算法都提供指向官方 API 文档的链接。

支持两种执行方式:

  • 交互式探索调用 Server 的 OLTP traverser 接口并直接返回结果,覆盖 K-out 与 K-neighbor,单源、带权和多点形式的最短路径,路径与全部路径,定制化路径与模板路径,环与射线,交点与定制化交点,共同邻居,Jaccard 相似度,Fusiform 相似度,Adamic-Adar,资源分配,Egonet,以及 rank 与 neighbor rank 接口。
  • 集群批量计算提交一个覆盖全图的异步任务,结果在异步任务中查看,覆盖 PageRank 与个性化 PageRank,度中心性、接近中心性与介数中心性,K-core,弱连通分量,标签传播,Louvain,三角形计数,聚类系数,环检测,子图匹配与 Links;在提供 Vermeer 的部署中还有对应的 Vermeer 版本。

批量算法需要 HugeGraph Computer 环境,部署要求时还包括 Kubernetes。当无法访问 Computer 时,页面会直接提示而不会提交任务。

4.7 登录与账号管理

当所连接的 Server 开启了鉴权时,Hubble 会打开 /login 登录页。请使用 HugeGraph Server 账号登录:Hubble 会把凭据转发给 Server,并在浏览器会话中保存返回的 token,自身不存储任何账号。登录尝试受限流保护,同一账号与地址连续失败三次之后,后续尝试会开始退避,初始 5 秒并逐次翻倍,最长 600 秒。当 Server 允许匿名访问时,/login 会重定向到首页,个人中心和账号管理页面也会隐藏。

【个人中心】展示账号信息并可修改密码。【账号管理】面向具备账号管理或图空间成员管理能力的账号,可创建账号并分配四种权限预设之一:超级管理员、GraphSpace 只读、GraphSpace 读写、GraphSpace 管理员。界面上不再暴露底层的 role、target、access、belong 记录。

4.8 集群运维

在 PD 模式下,【系统与运维】会为具备相应能力的账号提供【集群概览】和【节点详情】。集群概览展示拓扑、各层级的节点状态,以及在线 Store 数、PD Leader、容量、数据量、图数、分区数、副本数等集群概况。节点详情列出所有发现到的节点,支持按类型和状态筛选,并可打开单个节点查看指标、Leader 角色和 Raft 分片。节点详情在单机模式下同样可用,集群概览则需要 PD。

导航页还可以通过 dashboard.address 链接一个可选的外部监控面板。它是独立的监控入口,不配置也不会影响集群概览和节点详情。

5 配置说明

HugeGraph-Hubble 可以通过 conf/hugegraph-hubble.properties 文件进行配置。

5.1 服务配置

配置项默认值说明
server.hostlocalhostHubble 服务绑定的地址,Docker 镜像会改写为 0.0.0.0
server.port8088Hubble 服务监听的端口
server.protocolhttp访问 HugeGraphServer 使用的协议,可选 httphttps
ssl.client_truststore_fileconf/hugegraph.truststore客户端 truststore 路径,server.protocol=https 时使用
ssl.client_truststore_passwordhugegraph客户端 truststore 密码,server.protocol=https 时使用

5.2 Server 与 PD

配置项默认值说明
pd.enabledfalse是否通过 PD 发现服务;单机 Server 保持为 false
server.direct_urlhttp://127.0.0.1:8080pd.enabled=false 时连接的 Server 地址
pd.peers127.0.0.1:8686PD 节点地址
pd.server127.0.0.1:8620PD 服务地址
clusterhgHubble 连接的集群名称
route.typeNODE_PORT服务路由方式,可选 NODE_PORTDDSBOTH
client.request_timeout60HugeGraph 客户端请求超时时间(秒)
client.url_cache_max_entries1024保留用于回退的已发现 URL 数量上限

5.3 Gremlin 查询限制

这些设置控制查询结果限制,防止内存问题:

配置项默认值说明
gremlin.suffix_limit250查询后缀最大长度
gremlin.vertex_degree_limit100显示的最大顶点度数
gremlin.edges_total_limit500返回的最大边数
gremlin.batch_query_ids100ID 批量查询大小
execute-history.show_limit500展示的执行记录条数上限

5.4 文件上传

以下配置项不在打包的配置文件中,如需覆盖默认值请自行添加。

配置项默认值说明
upload_file.locationupload-files存放上传文件的目录
upload_file.format_listcsv,txt允许上传的文件格式
upload_file.single_file_size_limit1 GB单个上传文件的大小上限
upload_file.total_file_size_limit10 GB上传文件的总大小上限
upload_file.max_uploading_time43200超过该秒数后清理未完成的上传分片

5.5 集群运维

以下配置项用于集群概览和节点详情页面。

配置项默认值说明
operations.connect_timeout_ms1500每个运维上游的连接超时
operations.read_timeout_ms2500每个运维上游的读取超时
operations.max_response_bytes1048576接受的运维上游响应体大小上限
operations.cache_ttl_seconds5运维快照缓存的有效期
operations.cache_max_entries1024跨凭据保留的运维快照数量
operations.store_threads16Store 指标采集的并发任务数
operations.store_deadline_ms5000一轮 Store 指标采集的截止时间
operations.store.allowed_targets[http://127.0.0.1:8520,http://[::1]:8520]Hubble 允许访问的 Store 指标来源(精确匹配)
operations.pd.username / operations.pd.passwordhubble / 空仅后端使用的 PD 服务身份
operations.store.username / operations.store.passwordhubble / 空仅后端使用的 Store 服务身份
dashboard.address127.0.0.1:8092可选的外部监控面板地址,留空则隐藏入口

operations.store.allowed_targets 的默认值仅适用于本地测试。生产部署必须显式列出每一个受信任的 Store 协议、主机和端口,服务发现不会向该白名单追加来源。HTTPS 来源会保留其配置的主机名用于 TLS SNI 与证书校验。PD 和 Store 的密码请通过受保护的部署配置提供,不要写入打包的配置文件。

2.2 - 图可视化

需要在浏览器中查看图、执行 Gremlin 或管理图连接时,使用 Hubble。Hubble 提供图数据、Schema 和任务的可视化界面。

2.3 - HugeGraph-Loader Quick Start

1 HugeGraph-Loader 概述

HugeGraph-Loader 是 HugeGraph 的数据导入组件,能够将多种数据源的数据转化为图的顶点和边并批量导入到图数据库中。

目前支持的数据源包括:

  • 本地磁盘文件或目录,支持 TEXT、CSV 和 JSON 格式的文件,支持压缩文件
  • HDFS 文件或目录,支持压缩文件
  • 主流关系型数据库,如 MySQL、PostgreSQL、Oracle、SQL Server
  • Kafka topic
  • 已有的 HugeGraph 图,用于把数据从一个图复制到另一个图

本地磁盘文件和 HDFS 文件支持断点续传。

后面会具体说明。

注意:使用 HugeGraph-Loader 需要依赖 HugeGraph Server 服务,下载和启动 Server 请参考 HugeGraph-Server Quick Start

测试指南:如需在本地运行 Loader 测试,请参考 工具链本地测试指南

2 获取 HugeGraph-Loader

可以通过以下三种方式获取 HugeGraph-Loader:

  • 使用 Docker 镜像 (便于测试)
  • 下载已编译的压缩包
  • 克隆源码编译安装

2.1 使用 Docker 镜像 (便于测试)

我们可以使用 docker run -itd --name loader hugegraph/loader:1.7.0 部署 loader 服务。对于需要加载的数据,则可以通过挂载 -v /path/to/data/file:/loader/file 或者 docker cp 的方式将文件复制到 loader 容器内部。

或者使用 docker-compose 启动 loader, 启动命令为 docker-compose up -d, 样例的 docker-compose.yml 如下所示:

version: '3'

services:
  server:
    image: hugegraph/hugegraph:1.7.0
    container_name: server
    environment:
      - PASSWORD=xxx
    ports:
      - 8080:8080

  hubble:
    image: hugegraph/hubble:1.7.0
    container_name: hubble
    ports:
      - 8088:8088

  loader:
    image: hugegraph/loader:1.7.0
    container_name: loader
    # mount your own data here
    # volumes:
      # - /path/to/data/file:/loader/file

具体的数据导入流程可以参考 4.5 使用 docker 导入

注意:

  1. hugegraph-loader 的 docker 镜像是一个便捷版本,用于快速启动 loader,并不是官方发布物料包方式。你可以从 ASF Release Distribution Policy 中得到更多细节。

  2. 推荐使用 release tag (如 1.7.0) 以获取稳定版。使用 latest tag 可以使用开发中的最新功能。

2.2 下载已编译的压缩包

下载最新版本的 HugeGraph-Toolchain Release 包,里面包含了 loader + tool + hubble 全套工具,如果你已经下载,可跳过重复步骤

export VERSION=1.7.0
export ARCHIVE="apache-hugegraph-toolchain-incubating-${VERSION}"
wget "https://downloads.apache.org/hugegraph/${VERSION}/${ARCHIVE}.tar.gz"
tar zxf "${ARCHIVE}.tar.gz"

2.3 克隆源码编译安装

克隆最新版本的 HugeGraph-Loader 源码包:

# 1. get from github
git clone https://github.com/apache/hugegraph-toolchain.git

# 2. 下载发布版源码包
export VERSION=1.7.0
export ARCHIVE="apache-hugegraph-toolchain-incubating-${VERSION}"
wget "https://downloads.apache.org/hugegraph/${VERSION}/${ARCHIVE}-src.tar.gz"
点击展开/折叠 手动安装 ojdbc 方法

由于 Oracle ojdbc license 的限制,需要手动安装 ojdbc 到本地 maven 仓库。 访问 Oracle jdbc 下载 页面。选择 Oracle Database 12c Release 2 (12.2.0.1) drivers,如下图所示。

打开链接后,选择“ojdbc8.jar”

把 ojdbc8 安装到本地 maven 仓库,进入ojdbc8.jar所在目录,执行以下命令。

mvn install:install-file -Dfile=./ojdbc8.jar -DgroupId=com.oracle -DartifactId=ojdbc8 -Dversion=12.2.0.1 -Dpackaging=jar

编译生成 tar 包:

cd hugegraph-toolchain
mvn clean package -pl hugegraph-loader -am -DskipTests -ntp

3 使用流程

使用 HugeGraph-Loader 的基本流程分为以下几步:

  • 编写图模型
  • 准备数据文件
  • 编写输入源映射文件
  • 执行命令导入

3.1 编写图模型

这一步是建模的过程,用户需要对自己已有的数据和想要创建的图模型有一个清晰的构想,然后编写 schema 建立图模型。

比如想创建一个拥有两类顶点及两类边的图,顶点是"人"和"软件",边是"人认识人"和"人创造软件",并且这些顶点和边都带有一些属性,比如顶点"人"有:“姓名”、“年龄"等属性, “软件"有:“名字”、“售卖价格"等属性;边"认识"有:“日期"属性等。

由“认识”和“创建”边连接人物与软件顶点的示例图

示例图模型

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

// 创建一些属性
schema.propertyKey("name").asText().ifNotExist().create();
schema.propertyKey("age").asInt().ifNotExist().create();
schema.propertyKey("city").asText().ifNotExist().create();
schema.propertyKey("date").asText().ifNotExist().create();
schema.propertyKey("price").asDouble().ifNotExist().create();

// 创建 person 顶点类型,其拥有三个属性:name, age, city,主键是 name
schema.vertexLabel("person").properties("name", "age", "city").primaryKeys("name").ifNotExist().create();
// 创建 software 顶点类型,其拥有两个属性:name, price,主键是 name
schema.vertexLabel("software").properties("name", "price").primaryKeys("name").ifNotExist().create();

// 创建 knows 边类型,这类边是从 person 指向 person 的
schema.edgeLabel("knows").sourceLabel("person").targetLabel("person").ifNotExist().create();
// 创建 created 边类型,这类边是从 person 指向 software 的
schema.edgeLabel("created").sourceLabel("person").targetLabel("software").ifNotExist().create();

关于 schema 的详细说明请参考 hugegraph-client 中对应部分。

3.2 准备数据

目前 HugeGraph-Loader 支持的数据源包括:

  • 本地磁盘文件或目录
  • HDFS 文件或目录
  • 部分关系型数据库
  • Kafka topic
  • 已有的 HugeGraph 图
3.2.1 数据源结构
3.2.1.1 本地磁盘文件或目录

用户可以指定本地磁盘文件作为数据源,如果数据分散在多个文件中,也支持以某个目录作为数据源,但暂时不支持以多个目录作为数据源。

比如:我的数据分散在多个文件中,part-0、part-1 … part-n,要想执行导入,必须保证它们是放在一个目录下的。然后在 loader 的映射文件中,将path指定为该目录即可。

支持的文件格式包括:

  • TEXT
  • CSV
  • JSON

TEXT 是自定义分隔符的文本文件,第一行通常是标题,记录了每一列的名称,也允许没有标题行(在映射文件中指定)。其余的每行代表一条记录,会被转化为一个顶点/边;行的每一列对应一个字段,会被转化为顶点/边的 id、label 或属性;

示例如下:

id|name|lang|price|ISBN
1|lop|java|328|ISBN978-7-107-18618-5
2|ripple|java|199|ISBN978-7-100-13678-5

CSV 是分隔符为逗号,的 TEXT 文件,当列值本身包含逗号时,该列值需要用双引号包起来,如:

marko,29,Beijing
"li,nary",26,"Wu,han"

JSON 文件要求每一行都是一个 JSON 串,且每行的格式需保持一致。

{"source_name": "marko", "target_name": "vadas", "date": "20160110", "weight": 0.5}
{"source_name": "marko", "target_name": "josh", "date": "20130220", "weight": 1.0}
3.2.1.2 HDFS 文件或目录

用户也可以指定 HDFS 文件或目录作为数据源,上面关于本地磁盘文件或目录的要求全部适用于这里。除此之外,鉴于 HDFS 上通常存储的都是压缩文件,loader 也提供了对压缩文件的支持,并且本地磁盘文件或目录同样支持压缩文件。

目前支持的压缩文件类型包括:GZIP、BZ2、XZ、LZMA、SNAPPY_RAW、SNAPPY_FRAMED、Z、DEFLATE、LZ4_BLOCK、LZ4_FRAMED、ORC 和 PARQUET。

3.2.1.3 主流关系型数据库

loader 还支持以部分关系型数据库作为数据源,目前支持 MySQL、PostgreSQL、Oracle 和 SQL Server。

但目前对表结构要求较为严格,如果导入过程中需要做关联查询,这样的表结构是不允许的。关联查询的意思是:在读到表的某行后,发现某列的值不能直接使用(比如外键),需要再去做一次查询才能确定该列的真实值。

举个例子:假设有三张表,person、software 和 created

// person 表结构
id | name | age | city 
// software 表结构
id | name | lang | price
// created 表结构
id | p_id | s_id | date

如果在建模(schema)时指定 person 或 software 的 id 策略是 PRIMARY_KEY,选择以 name 作为 primary keys(注意:这是 hugegraph 中 vertexlabel 的概念),在导入边数据时,由于需要拼接出源顶点和目标顶点的 id,必须拿着 p_id/s_id 去 person/software 表中查到对应的 name,这种需要做额外查询的表结构的情况,loader 暂时是不支持的。这时可以采用以下两种方式替代:

  1. 仍然指定 person 和 software 的 id 策略为 PRIMARY_KEY,但是以 person 表和 software 表的 id 列作为顶点的主键属性,这样导入边时直接使用 p_id 和 s_id 和顶点的 label 拼接就能生成 id 了;
  2. 指定 person 和 software 的 id 策略为 CUSTOMIZE,然后直接以 person 表和 software 表的 id 列作为顶点 id,这样导入边时直接使用 p_id 和 s_id 即可;

关键点就是要让边能直接使用 p_id 和 s_id,不要再去查一次。

3.2.2 准备顶点和边数据
3.2.2.1 顶点数据

顶点数据文件由一行一行的数据组成,一般每一行作为一个顶点,每一列会作为顶点属性。下面以 CSV 格式作为示例进行说明。

  • person 顶点数据(数据本身不包含 header)
Tom,48,Beijing
Jerry,36,Shanghai
  • software 顶点数据(数据本身包含 header)
name,price
Photoshop,999
Office,388
3.2.2.2 边数据

边数据文件由一行一行的数据组成,一般每一行作为一条边,其中有部分列会作为源顶点和目标顶点的 id,其他列作为边属性。下面以 JSON 格式作为示例进行说明。

  • knows 边数据
{"source_name": "Tom", "target_name": "Jerry", "date": "2008-12-12"}
  • created 边数据
{"source_name": "Tom", "target_name": "Photoshop"}
{"source_name": "Tom", "target_name": "Office"}
{"source_name": "Jerry", "target_name": "Office"}

3.3 编写数据源映射文件

3.3.1 映射文件概述

输入源的映射文件用于描述如何将输入源数据与图的顶点类型/边类型建立映射关系,以JSON格式组织,由多个映射块组成,其中每一个映射块都负责将一个输入源映射为顶点和边。

具体而言,每个映射块包含一个输入源和多个顶点映射边映射块,输入源块对应上面介绍的本地磁盘文件或目录HDFS 文件或目录关系型数据库,负责描述数据源的基本信息,比如数据在哪,是什么格式的,分隔符是什么等。顶点映射/边映射与该输入源绑定,可以选择输入源的哪些列,哪些列作为 id、哪些列作为属性,以及每一列映射成什么属性,列的值映射成属性的什么值等等。

以最通俗的话讲,每一个映射块描述了:要导入的文件在哪,文件的每一行要作为哪一类顶点/边,文件的哪些列是需要导入的,以及这些列对应顶点/边的什么属性等。

注意:0.11.0 版本以前的映射文件与 0.11.0 以后的格式变化较大,为表述方便,下面称 0.11.0 以前的映射文件(格式)为 1.0 版本,0.11.0 以后的为 2.0 版本。并且若无特殊说明,“映射文件”表示的是 2.0 版本的。

点击展开/折叠 2.0 版本的映射文件的框架
{
  "version": "2.0",
  "structs": [
    {
      "id": "1",
      "input": {
      },
      "vertices": [
        {},
        {}
      ],
      "edges": [
        {},
        {}
      ]
    }
  ]
}

这里直接给出两个版本的映射文件(描述了上面图模型和数据文件)

点击展开/折叠 2.0 版本的映射文件
{
  "version": "2.0",
  "structs": [
    {
      "id": "1",
      "skip": false,
      "input": {
        "type": "FILE",
        "path": "vertex_person.csv",
        "file_filter": {
          "extensions": [
            "*"
          ]
        },
        "format": "CSV",
        "delimiter": ",",
        "date_format": "yyyy-MM-dd HH:mm:ss",
        "time_zone": "GMT+8",
        "skipped_line": {
          "regex": "(^#|^//).*|"
        },
        "compression": "NONE",
        "header": [
          "name",
          "age",
          "city"
        ],
        "charset": "UTF-8",
        "list_format": {
          "start_symbol": "[",
          "elem_delimiter": "|",
          "end_symbol": "]"
        }
      },
      "vertices": [
        {
          "label": "person",
          "skip": false,
          "id": null,
          "unfold": false,
          "field_mapping": {},
          "value_mapping": {},
          "selected": [],
          "ignored": [],
          "null_values": [
            ""
          ],
          "update_strategies": {}
        }
      ],
      "edges": []
    },
    {
      "id": "2",
      "skip": false,
      "input": {
        "type": "FILE",
        "path": "vertex_software.csv",
        "file_filter": {
          "extensions": [
            "*"
          ]
        },
        "format": "CSV",
        "delimiter": ",",
        "date_format": "yyyy-MM-dd HH:mm:ss",
        "time_zone": "GMT+8",
        "skipped_line": {
          "regex": "(^#|^//).*|"
        },
        "compression": "NONE",
        "header": null,
        "charset": "UTF-8",
        "list_format": {
          "start_symbol": "",
          "elem_delimiter": ",",
          "end_symbol": ""
        }
      },
      "vertices": [
        {
          "label": "software",
          "skip": false,
          "id": null,
          "unfold": false,
          "field_mapping": {},
          "value_mapping": {},
          "selected": [],
          "ignored": [],
          "null_values": [
            ""
          ],
          "update_strategies": {}
        }
      ],
      "edges": []
    },
    {
      "id": "3",
      "skip": false,
      "input": {
        "type": "FILE",
        "path": "edge_knows.json",
        "file_filter": {
          "extensions": [
            "*"
          ]
        },
        "format": "JSON",
        "delimiter": null,
        "date_format": "yyyy-MM-dd HH:mm:ss",
        "time_zone": "GMT+8",
        "skipped_line": {
          "regex": "(^#|^//).*|"
        },
        "compression": "NONE",
        "header": null,
        "charset": "UTF-8",
        "list_format": null
      },
      "vertices": [],
      "edges": [
        {
          "label": "knows",
          "skip": false,
          "source": [
            "source_name"
          ],
          "unfold_source": false,
          "target": [
            "target_name"
          ],
          "unfold_target": false,
          "field_mapping": {
            "source_name": "name",
            "target_name": "name"
          },
          "value_mapping": {},
          "selected": [],
          "ignored": [],
          "null_values": [
            ""
          ],
          "update_strategies": {}
        }
      ]
    },
    {
      "id": "4",
      "skip": false,
      "input": {
        "type": "FILE",
        "path": "edge_created.json",
        "file_filter": {
          "extensions": [
            "*"
          ]
        },
        "format": "JSON",
        "delimiter": null,
        "date_format": "yyyy-MM-dd HH:mm:ss",
        "time_zone": "GMT+8",
        "skipped_line": {
          "regex": "(^#|^//).*|"
        },
        "compression": "NONE",
        "header": null,
        "charset": "UTF-8",
        "list_format": null
      },
      "vertices": [],
      "edges": [
        {
          "label": "created",
          "skip": false,
          "source": [
            "source_name"
          ],
          "unfold_source": false,
          "target": [
            "target_name"
          ],
          "unfold_target": false,
          "field_mapping": {
            "source_name": "name",
            "target_name": "name"
          },
          "value_mapping": {},
          "selected": [],
          "ignored": [],
          "null_values": [
            ""
          ],
          "update_strategies": {}
        }
      ]
    }
  ]
}

点击展开/折叠 1.0 版本的映射文件
{
  "vertices": [
    {
      "label": "person",
      "input": {
        "type": "file",
        "path": "vertex_person.csv",
        "format": "CSV",
        "header": ["name", "age", "city"],
        "charset": "UTF-8"
      }
    },
    {
      "label": "software",
      "input": {
        "type": "file",
        "path": "vertex_software.csv",
        "format": "CSV"
      }
    }
  ],
  "edges": [
    {
      "label": "knows",
      "source": ["source_name"],
      "target": ["target_name"],
      "input": {
        "type": "file",
        "path": "edge_knows.json",
        "format": "JSON"
      },
      "field_mapping": {
        "source_name": "name",
        "target_name": "name"
      }
    },
    {
      "label": "created",
      "source": ["source_name"],
      "target": ["target_name"],
      "input": {
        "type": "file",
        "path": "edge_created.json",
        "format": "JSON"
      },
      "field_mapping": {
        "source_name": "name",
        "target_name": "name"
      }
    }
  ]
}

映射文件 1.0 版本是以顶点和边为中心,设置输入源;而 2.0 版本是以输入源为中心,设置顶点和边映射。有些输入源(比如一个文件)既能生成顶点,也能生成边,如果用 1.0 版的格式写,就需要在 vertex 和 edge 映射块中各写一次 input 块,这两次的 input 块是完全一样的;而 2.0 版本只需要写一次 input。所以 2.0 版相比于 1.0 版,能省掉一些 input 的重复书写。

在 hugegraph-loader-{version} 的 bin 目录下,有一个脚本工具 mapping-convert.sh 能直接将 1.0 版本的映射文件转换为 2.0 版本的,使用方式如下:

bin/mapping-convert.sh struct.json

会在 struct.json 的同级目录下生成一个 struct-v2.json。

bin 目录下还提供了 utf8-bom-to-utf8.sh,用于去掉单个数据文件、或目录下所有文件开头的 UTF-8 BOM。当 Windows 工具导出的 CSV 或 TEXT 文件因为首列表头带有不可见的 BOM 而解析失败时,可以用它处理:

bin/utf8-bom-to-utf8.sh /path/to/file-or-dir
3.3.2 输入源

输入源目前分为五类:FILE、HDFS、JDBC、KAFKA 和 GRAPH,由type节点区分,我们称为本地文件输入源、HDFS 输入源、JDBC 输入源和 KAFKA 输入源,图数据源,下面分别介绍。

3.3.2.1 本地文件输入源
  • id: 输入源的 id,该字段用于支持一些内部功能,非必填(未填时会自动生成),强烈建议写上,对于调试大有裨益;
  • skip: 是否跳过该输入源,由于 JSON 文件无法添加注释,如果某次导入时不想导入某个输入源,但又不想删除该输入源的配置,则可以设置为 true 将其跳过,默认为 false,非必填;
  • input: 输入源映射块,复合结构
    • type: 输入源类型,必须填 file 或 FILE;
    • path: 本地文件或目录的路径,绝对路径或相对于映射文件的相对路径,建议使用绝对路径,必填;
    • file_filter: 从path中筛选复合条件的文件,复合结构,目前只支持配置扩展名,用子节点extensions表示,默认为”*",表示保留所有文件;
    • format: 本地文件的格式,可选值为 CSV、TEXT 及 JSON,必须大写,默认为 CSV,选填;
    • header: 文件各列的列名,如不指定则会以数据文件第一行作为 header;当文件本身有标题且又指定了 header,文件的第一行会被当作普通的数据行;JSON 文件不需要指定 header,选填;
    • has_header: 对 CSV 和 TEXT 格式,如果某个文件的首行与 header 完全相同,该行会被丢弃,这样目录下每个分片文件重复的表头不会被当作数据导入。如果分片文件的首行是恰好与 header 相同的真实数据,可以设为 false 关闭这个检查,选填;
    • delimiter: 文件行的列分隔符。默认值取决于format:CSV 为逗号",",TEXT 为制表符"\t";CSV 只接受逗号。JSON文件不需要指定,选填;
    • charset: 文件的编码字符集,默认UTF-8,选填;
    • date_format: 自定义的日期格式,默认值为 yyyy-MM-dd HH:mm:ss,选填;如果日期是以时间戳的形式呈现的,此项须写为timestamp(固定写法);
    • extra_date_formats: 备用日期格式列表,当某个值不符合date_format时会逐个尝试,默认为空,选填;
    • time_zone: 设置日期数据是处于哪个时区的,默认值为GMT+8,选填;
    • skipped_line: 想跳过的行,复合结构,目前只能配置要跳过的行的正则表达式,用子节点regex描述。默认正则为(^#|^//).*|,即跳过以#//开头的行以及空行;如果需要保留这类行,把regex改为一个不匹配任何行的表达式即可,选填;
    • compression: 文件的压缩格式,可选值为 NONE、GZIP、BZ2、XZ、LZMA、SNAPPY_RAW、SNAPPY_FRAMED、Z、DEFLATE、LZ4_BLOCK、LZ4_FRAMED、ORC 和 PARQUET,默认为 NONE,表示非压缩文件,选填;ORC 和 PARQUET 的 header 匹配不区分大小写;
    • list_format: 当文件 (非 JSON ) 的某列是集合结构时(对应图中的 PropertyKey 的 Cardinality 为 Set 或 List),可以用此项设置该列的起始符、分隔符、结束符,复合结构:
      • start_symbol: 集合结构列的起始符 (默认值是空字符串 "", JSON 格式目前不支持指定)
      • elem_delimiter: 集合结构列的分隔符 (默认值是 |, 且不能与delimiter相同; JSON 格式目前只支持原生,分隔)
      • end_symbol: 集合结构列的结束符 (默认值是空字符串 "", JSON 格式目前不支持指定)
      • ignored_elems: 拆分之后要丢弃的元素,默认值是 [""],即忽略空元素
3.3.2.2 HDFS 输入源

上述本地文件输入源的节点及含义这里基本都适用,下面仅列出 HDFS 输入源不一样的和特有的节点。

  • type: 输入源类型,必须填 hdfs 或 HDFS,必填;
  • path: HDFS 文件或目录的路径,必须是 HDFS 的绝对路径,必填;
  • core_site_path: HDFS 集群的 core-site.xml 文件路径,重点要指明 NameNode 的地址(fs.default.name),以及文件系统的实现(fs.hdfs.impl),必填;
  • hdfs_site_path: HDFS 集群的 hdfs-site.xml 文件路径,选填;
  • dir_filter: 当path是目录时,决定递归进入哪些子目录,复合结构,选填:
    • include_regex: 只读取目录名匹配该正则的目录,默认为空,即不作限制;
    • exclude_regex: 跳过目录名匹配该正则的目录,默认为空;
  • kerberos_config: 访问开启了 Kerberos 认证的 HDFS 集群时的配置,复合结构,选填:
    • enable: 是否使用 Kerberos 认证,默认为 false;
    • krb5_conf: krb5.conf 文件路径,enable 为 true 时必填;
    • principal: Kerberos principal,enable 为 true 时必填;
    • keytab: keytab 文件路径,enable 为 true 时必填;
3.3.2.3 JDBC 输入源

前面说到过支持多种关系型数据库,但由于它们的映射结构非常相似,故统称为 JDBC 输入源,然后用vendor节点区分不同的数据库。

  • type: 输入源类型,必须填 jdbc 或 JDBC,必填;
  • vendor: 数据库类型,可选项为 [MySQL、PostgreSQL、Oracle、SQLServer],不区分大小写,必填;
  • driver: JDBC driver 类名,选填;不填时使用vendor对应的默认 driver,见下面各表;
  • url: jdbc 要连接的数据库的 url,必填;
  • database: 要连接的数据库名,必填;
  • schema: 要连接的 schema 名,不同的数据库要求不一样,下面详细说明;
  • table: 要连接的表名,custom_sqltable 参数必须填其中一个;
  • custom_sql: 自定义 SQL 语句,custom_sqltable 参数必须填其中一个;
  • username: 连接数据库的用户名,必填;
  • password: 连接数据库的密码,必填;
  • where: 附加到生成的 select 语句上的过滤条件,不需要写 where 关键字,选填;
  • batch_size: 按页获取表数据时的一页的大小,默认为 500,选填;

MYSQL

节点固定值或常见值
vendorMYSQL
drivercom.mysql.cj.jdbc.Driver
urljdbc:mysql://127.0.0.1:3306

schema: 可空,若填写必须与 database 的值一样

POSTGRESQL

节点固定值或常见值
vendorPOSTGRESQL
driverorg.postgresql.Driver
urljdbc:postgresql://127.0.0.1:5432

schema: 可空,默认值为“public”

ORACLE

节点固定值或常见值
vendorORACLE
driveroracle.jdbc.driver.OracleDriver
urljdbc:oracle:thin:@127.0.0.1:1521

schema: 可空,默认值为大写形式的用户名

SQLSERVER

节点固定值或常见值
vendorSQLSERVER
drivercom.microsoft.sqlserver.jdbc.SQLServerDriver
urljdbc:sqlserver://127.0.0.1:1433

schema: 必填

3.3.2.4 Kafka 输入源
  • type:输入源类型,必须填 kafkaKAFKA,必填;
  • bootstrap_server:kafka bootstrap server 列表,必填;
  • topic:订阅的 topic,必填;
  • group:Kafka 消费者组,必填;
  • from_beginning:是否从 topic 最早的 offset 开始读取(auto.offset.reset=earliest),否则从最新 offset 开始,默认为 false,选填;
  • format:每条消息的格式,可选值为 CSV、TEXT 及 JSON,必须大写,必填;
  • header:消息各列的列名;loader 不会从 topic 中读取表头行,因此 CSV 和 TEXT 格式必须指定,JSON 消息则不需要;
  • delimiter:消息的列分隔符,仅 TEXT 格式使用,CSV 固定以,分隔,选填;
  • charset:消息的编码字符集,默认 UTF-8,选填;
  • date_format:自定义的日期格式,默认值为 yyyy-MM-dd HH:mm:ss,选填;如果日期是以时间戳的形式呈现的,此项须写为 timestamp(固定写法);
  • extra_date_formats:自定义的其他日期格式列表,默认为空,选填;列表中每一项都是一个 date_format 指定日期格式的备用日期格式;
  • time_zone:置日期数据是处于哪个时区的,默认值为 GMT+8,选填;
  • skipped_line:想跳过的行,复合结构,目前只能配置要跳过的行的正则表达式,用子节点 regex 描述,默认不跳过任何行,选填;
  • batch_size:单次拉取的最大记录数(max.poll.records),默认为 500,选填;
  • early_stop:某次从 Kafka broker 拉取的记录为空,停止任务,默认为 false,仅用于调试,选填;
3.3.2.5 GRAPH 输入源

GRAPH 输入源从另一个 HugeGraph 图(通过 HugeGraph-PD 访问)读取顶点和边,并写入目标图。当映射文件中出现 GRAPH 输入源时,该文件中所有未被跳过的输入源都必须是 GRAPH 类型,并且导入期间 loader 会把目标图切换为 RESTORING 模式。

  • type:输入源类型,必须填 graphGRAPH,必填;
  • graphspace:源图空间名称,必填;
  • graph: 源图名称,必填;
  • username:HugeGraph 用户名;为空时使用命令行参数 --username
  • password:HugeGraph 密码;为空时使用命令行参数 --password
  • selected_vertices:要复制的顶点 label 列表,每一项形如 {"label": "...", "properties": [...], "query": {...}},其中 properties 限定要复制的属性,query 是传给源图的可选过滤条件;
  • ignored_vertices:要跳过的顶点 label 列表,每一项形如 {"label": "...", "properties": [...]}
  • selected_edges:要复制的边 label 列表,每一项结构与 selected_vertices 相同;
  • ignored_edges:要跳过的边 label 列表,每一项结构与 ignored_vertices 相同;
  • pd-peers:源集群的 HugeGraph-PD 节点地址;为空时使用 --pd-peers
  • meta-endpoints:源集群 Meta 服务端点;为空时使用 --meta-endpoints
  • cluster:源集群名称;为空时使用 --cluster
  • batch_size:批量读取源图数据的批次大小,默认为500;
3.3.3 顶点和边映射

顶点和边映射的节点(JSON 文件中的一个 key)有很多相同的部分,下面先介绍相同部分,再分别介绍顶点映射边映射的特有节点。

相同部分的节点

  • label: 待导入的顶点/边数据所属的label,必填;
  • skip: 是否跳过该顶点/边映射,输入源和其他映射不受影响,默认为 false,选填;
  • field_mapping: 将输入源列的列名映射为顶点/边的属性名,选填;
  • value_mapping: 将输入源的数据值映射为顶点/边的属性值,选填;
  • selected: 选择某些列插入,其他未选中的不插入,不能与ignored同时存在,选填;
  • ignored: 忽略某些列,使其不参与插入,不能与selected同时存在,选填;
  • null_values: 可以指定一些字符串代表空值,比如"NULL”,如果该列对应的顶点/边属性又是一个可空属性,那在构造顶点/边时不会设置该属性的值,选填;
  • update_strategies: 如果数据需要按特定方式批量更新时可以对每个属性指定具体的更新策略 (具体见下),选填;
  • unfold: 是否将列展开,展开的每一列都会与其他列一起组成一行,相当于是展开成了多行;比如文件的某一列(id 列)的值是[1,2,3],其他列的值是18,Beijing,当设置了 unfold 之后,这一行就会变成 3 行,分别是:1,18,Beijing2,18,Beijing3,18,Beijing。需要注意的是此项只会展开被选作为 id 的列。默认 false,选填;

更新策略支持 8 种 : (需要全大写)

  1. 数值累加 : SUM
  2. 两个数字/日期取更大的: BIGGER
  3. 两个数字/日期取更小: SMALLER
  4. Set属性取并集:UNION
  5. Set属性取交集:INTERSECTION
  6. List属性追加元素:APPEND
  7. List/Set属性删除元素:ELIMINATE
  8. 覆盖已有属性:OVERRIDE

注意: 如果新导入的属性值为空,会采用已有的旧数据而不会采用空值,效果可以参考如下示例

// JSON 文件中以如下方式指定更新策略
{
  "vertices": [
    {
      "label": "person",
      "update_strategies": {
        "age": "SMALLER",
        "set": "UNION"
      },
      "input": {
        "type": "file",
        "path": "vertex_person.txt",
        "format": "TEXT",
        "header": ["name", "age", "set"]
      }
    }
  ]
}

// 1.写入一行带 OVERRIDE 更新策略的数据 (这里 null 代表空)
'a b null null'

// 2.再写一行
'null null c d'

// 3.最后可以得到
'a b c d'   

// 如果没有更新策略,则会得到
'null null c d'

注意 : 采用了批量更新的策略后, 磁盘读请求数会大幅上升, 导入速度相比纯写覆盖会慢数倍 (此时HDD磁盘IOPS会成为瓶颈, 建议采用SSD以保证速度)

顶点映射的特有节点

  • id: 指定某一列作为顶点的 id 列,当顶点 id 策略为CUSTOMIZE时,必填;当 id 策略为PRIMARY_KEY时,必须为空;

边映射的特有节点

  • source: 选择输入源某几列作为源顶点的 id 列,当源顶点的 id 策略为 CUSTOMIZE时,必须指定某一列作为顶点的 id 列;当源顶点的 id 策略为 PRIMARY_KEY时,必须指定一列或多列用于拼接生成顶点的 id,也就是说,不管是哪种 id 策略,此项必填;
  • target: 指定某几列作为目标顶点的 id 列,与 source 类似,不再赘述;
  • unfold_source: 是否展开文件的 source 列,效果与顶点映射中的类似,不再赘述;
  • unfold_target: 是否展开文件的 target 列,效果与顶点映射中的类似,不再赘述;

3.4 执行命令导入

准备好图模型、数据文件以及输入源映射关系文件后,接下来就可以将数据文件导入到图数据库中。

导入过程由用户提交的命令控制,用户可以通过不同的参数控制执行的具体流程。

3.4.1 参数说明
参数默认值是否必传描述信息
-f--fileY配置脚本的路径
-g--graphhugegraph图名称
--graphspaceDEFAULT图空间
-s--schemaschema 文件路径;已有 Schema 时可以不传
-h--host-ilocalhostHugeGraphServer 的地址
-p--port8080HugeGraphServer 的端口号
--usernamenull当 HugeGraphServer 开启了权限认证时,当前图的 username
--passwordnull当 HugeGraphServer 开启了权限认证时,当前图的 password
--create-graphfalse是否在图不存在时自动创建
--tokennull当 HugeGraphServer 开启了权限认证时,当前图的 token
--protocolhttp向服务端发请求的协议,可选 http 或 https
--pd-peersPD 服务节点地址
--pd-token访问 PD 服务的 token
--meta-endpoints元信息存储服务地址
--directfalse是否直连 HugeGraph-Store
--route-typeNODE_PORT路由选择方式(可选值:NODE_PORT / DDS / BOTH)
--clusterhg集群名
--trust-store-file请求协议为 https 时,客户端的证书文件路径
--trust-store-password请求协议为 https 时,客户端证书密码
--clear-all-datafalse导入数据前是否清除服务端的原有数据
--clear-timeout240导入数据前清除服务端的原有数据的超时时间
--incremental-modefalse是否使用断点续导模式,仅输入源为 FILE 和 HDFS 支持该模式,启用该模式能从上一次导入停止的地方开始导入
--failure-modefalse失败模式为 true 时,会导入之前失败了的数据,一般来说失败数据文件需要在人工更正编辑好后,再次进行导入
--batch-insert-threadsCPUs批量插入线程池大小 (CPUs 是当前 OS 可用逻辑核个数)
--single-insert-threads8单条插入线程池的大小
--max-conn4 * CPUsHugeClient 与 HugeGraphServer 的最大 HTTP 连接数;保持默认值时会自动提升到 4 * --batch-insert-threads
--max-conn-per-route2 * CPUsHugeClient 与 HugeGraphServer 每个路由的最大 HTTP 连接数;保持默认值时会自动提升到 2 * --batch-insert-threads
--batch-size500导入数据时每个批次包含的数据条数
--max-parse-errors1最多允许多少行数据解析错误,达到该值则程序退出
--max-insert-errors500最多允许多少行数据插入错误,达到该值则程序退出
--timeout60插入结果返回的超时时间(秒)
--shutdown-timeout10多线程停止的等待时间(秒)
--retry-times3发生超时时的最大重试次数
--retry-interval10重试之前的间隔时间(秒)
--check-vertexfalse插入边时是否检查边所连接的顶点是否存在
--print-progresstrue是否在控制台实时打印导入条数
--dry-runfalse打开该模式,只解析不导入,通常用于测试
--help-helpfalse打印帮助信息
--parser-threads--parallel-countmax(2,CPUs/2)并行读取管线数;--parallel-count 已弃用
--start-file0用于部分(分片)导入的起始文件索引
--end-file-1用于部分导入的截止文件索引
--scatter-sourcesfalse分散(并行)读取多个数据源以优化 I/O 性能
--cdc-flush-interval30000Flink CDC 的数据刷新间隔
--cdc-sink-parallelism1Flink CDC 写入端(Sink)的并行度
--max-read-errors1程序退出前允许的最大读取错误行数
--max-read-lines-1L最大读取行数限制;一旦达到此行数,导入任务将停止
--test-modefalse是否开启测试模式
--use-prefilterfalse是否预先过滤顶点
--short-id将自定义顶点 ID 映射为更短的生成 ID,格式为 label:field:type,其中 type 可选 boolean、byte、int、long、float、double、text、blob、date、uuid;可以重复指定以覆盖多个 label
--vertex-edge-limit-1L单个顶点的最大边数限制
--sink-typetruespark-loader 使用:true 通过 HugeGraph server API 写入,false 生成 HFile 并直接 bulkload 到 HBase
--vertex-partitions64HBase 顶点表的预分区数量,配合 --sink-type false 使用
--edge-partitions64HBase 边表的预分区数量,配合 --sink-type false 使用
--vertex-table-nameHBase 顶点表名称,配合 --sink-type false 使用
--edge-table-nameHBase 边表名称,配合 --sink-type false 使用
--hbase-zk-quorumHBase Zookeeper 集群地址,配合 --sink-type false 使用
--hbase-zk-portHBase Zookeeper 端口号,配合 --sink-type false 使用
--hbase-zk-parentHBase Zookeeper 根路径,配合 --sink-type false 使用
--restorefalse将图模式设置为恢复模式 (RESTORING)
--backendhstore自动创建图(如果不存在)时的后端存储类型
--serializerbinary自动创建图(如果不存在)时的序列化器类型
--scheduler-typedistributed自动创建图(如果不存在)时的任务调度器类型
--batch-failure-fallbacktrue批量插入失败时是否回退至单条插入模式

参数少于三个时 loader 会直接打印用法并退出,因此只传 -f struct.json 是不够的。

3.4.2 断点续导模式

通常情况下,Loader 任务都需要较长时间执行,如果因为某些原因导致导入中断进程退出,而下次希望能从中断的点继续导,这就是使用断点续导的场景。

用户设置命令行参数 –incremental-mode 为 true 即打开了断点续导模式。断点续导的关键在于进度文件,导入进程退出的时候,会把退出时刻的导入进度 记录到进度文件中,进度文件位于 ${struct} 目录下,文件名形如 load-progress_${timestamp} ,${struct} 为映射文件的前缀,${timestamp} 为导入开始 的时刻,格式为 yyyyMMdd-HHmmss。比如:在 2019-10-10 12:30:30 开始的一次导入任务,使用的映射文件为 struct-example.json,则进度文件的路径为与 struct-example.json 同级的 struct-example/load-progress_20191010-123030。当目录下存在多个进度文件时,续导会读取按文件名排序的最后一个,也就是最新的那个。

注意:进度文件的生成与 –incremental-mode 是否打开无关,每次导入结束都会生成一个进度文件。

如果数据文件格式都是合法的,是用户自己停止(CTRL + C 或 kill,kill -9 不支持)的导入任务,也就是说没有错误记录的情况下,下一次导入只需要设置 为断点续导即可。

但如果是因为太多数据不合法或者网络异常,达到了 –max-read-errors、–max-parse-errors 或 –max-insert-errors 的限制,Loader 会把这些失败的原始行记录到 失败文件中,用户对失败文件中的数据行修改后,设置 –failure-mode 为 true 即可把这些"失败文件"也当作输入源进行导入(不影响正常的文件的导入), 当然如果修改后的数据行仍然有问题,则会被再次记录到失败文件中(不用担心会有重复行,关闭文件时会去重)。失败模式下上述三个错误上限会被解除,因此会扫描整个失败文件。

每个输入源(即映射文件 structs 中的每一项)都会有自己的失败文件,文件名为该输入源的 id 加后缀 .error,保存在 ${struct}/failure-data 目录下。 每一条失败记录写为两行:一行以 #### READ ERROR:#### PARSE ERROR:#### INSERT ERROR: 开头的提示行,紧接着是原始数据行。当输入源有 header 时,header 会以 JSON 形式写入同目录下的 ${id}.header 文件,以便失败文件能按正确的列重新读取。 比如映射文件中 id 为 1 的输入源包含顶点映射 person,id 为 3 的输入源包含边映射 knows,它们各有一些错误行,当 Loader 退出后,在 ${struct}/failure-data 目录下会看到如下文件:

  • 1.error: 输入源 1 的失败数据行,每行前面都有对应的提示行
  • 1.header: 输入源 1 的 header,仅当该输入源有 header 时才会生成
  • 3.error: 输入源 3 的失败数据行
  • 3.header: 输入源 3 的 header

内容为空的 .error 文件会在 Loader 退出时删除,因此只有真正出现失败行的输入源才会留下文件。增量模式下新的失败行会追加到已有文件,其他模式下该文件会被重新写入。

3.4.3 logs 目录文件说明

程序执行过程中各日志及错误数据会写入 hugegraph-loader.log 文件中。

3.4.4 执行命令

运行 bin/hugegraph-loader.sh 并传入参数

bin/hugegraph-loader.sh -g {GRAPH_NAME} -f ${INPUT_DESC_FILE} -s ${SCHEMA_FILE} -h {HOST} -p {PORT}

脚本在设置了 JAVA_HOME 时使用其中的 JVM,否则使用 PATH 上的 java。它会把 JVM_OPTS 环境变量的内容,以及 -Xmx10g 和由 lib/ 生成的 classpath 一起传给 JVM,因此需要追加 JVM 参数时可以设置 JVM_OPTS。日志由 conf/log4j2.xml 配置。

4 完整示例

下面给出的是 hugegraph-loader 包中 example 目录下的例子。(GitHub 地址)

4.1 准备数据

顶点文件:example/file/vertex_person.csv

marko,29,Beijing
vadas,27,Hongkong
josh,32,Beijing
peter,35,Shanghai
"li,nary",26,"Wu,han"
tom,null,NULL

顶点文件:example/file/vertex_software.txt

id|name|lang|price|ISBN
1|lop|java|328|ISBN978-7-107-18618-5
2|ripple|java|199|ISBN978-7-100-13678-5

边文件:example/file/edge_knows.json

{"source_name": "marko", "target_name": "vadas", "date": "20160110", "weight": 0.5}
{"source_name": "marko", "target_name": "josh", "date": "20130220", "weight": 1.0}

边文件:example/file/edge_created.json

{"aname": "marko", "bname": "lop", "date": "20171210", "weight": 0.4}
{"aname": "josh", "bname": "lop", "date": "20091111", "weight": 0.4}
{"aname": "josh", "bname": "ripple", "date": "20171210", "weight": 1.0}
{"aname": "peter", "bname": "lop", "date": "20170324", "weight": 0.2}

4.2 编写 schema

点击展开/折叠 schema 文件:example/file/schema.groovy
schema.propertyKey("name").asText().ifNotExist().create();
schema.propertyKey("age").asInt().ifNotExist().create();
schema.propertyKey("city").asText().ifNotExist().create();
schema.propertyKey("weight").asDouble().ifNotExist().create();
schema.propertyKey("lang").asText().ifNotExist().create();
schema.propertyKey("date").asText().ifNotExist().create();
schema.propertyKey("price").asDouble().ifNotExist().create();

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

schema.indexLabel("personByAge").onV("person").by("age").range().ifNotExist().create();
schema.indexLabel("personByCity").onV("person").by("city").secondary().ifNotExist().create();
schema.indexLabel("personByAgeAndCity").onV("person").by("age", "city").secondary().ifNotExist().create();
schema.indexLabel("softwareByPrice").onV("software").by("price").range().ifNotExist().create();

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

schema.indexLabel("createdByDate").onE("created").by("date").secondary().ifNotExist().create();
schema.indexLabel("createdByWeight").onE("created").by("weight").range().ifNotExist().create();
schema.indexLabel("knowsByWeight").onE("knows").by("weight").range().ifNotExist().create();

4.3 编写输入源映射文件example/file/struct.json

点击展开/折叠 源映射文件 example/file/struct.json
{
  "vertices": [
    {
      "label": "person",
      "input": {
        "type": "file",
        "path": "example/file/vertex_person.csv",
        "format": "CSV",
        "header": ["name", "age", "city"],
        "charset": "UTF-8",
        "skipped_line": {
          "regex": "(^#|^//).*"
        }
      },
      "null_values": ["NULL", "null", ""]
    },
    {
      "label": "software",
      "input": {
        "type": "file",
        "path": "example/file/vertex_software.txt",
        "format": "TEXT",
        "delimiter": "|",
        "charset": "GBK"
      },
      "id": "id",
      "ignored": ["ISBN"]
    }
  ],
  "edges": [
    {
      "label": "knows",
      "source": ["source_name"],
      "target": ["target_name"],
      "input": {
        "type": "file",
        "path": "example/file/edge_knows.json",
        "format": "JSON",
        "date_format": "yyyyMMdd"
      },
      "field_mapping": {
        "source_name": "name",
        "target_name": "name"
      }
    },
    {
      "label": "created",
      "source": ["source_name"],
      "target": ["target_id"],
      "input": {
        "type": "file",
        "path": "example/file/edge_created.json",
        "format": "JSON",
        "date_format": "yyyy-MM-dd"
      },
      "field_mapping": {
        "source_name": "name"
      }
    }
  ]
}

4.4 执行命令导入

sh bin/hugegraph-loader.sh -g hugegraph -f example/file/struct.json -s example/file/schema.groovy

导入结束后,会出现类似如下统计信息:

vertices/edges has been loaded this time : 8/6
--------------------------------------------------
count metrics
     input read success            : 14
     input read failure            : 0
     vertex parse success          : 8
     vertex parse failure          : 0
     vertex insert success         : 8
     vertex insert failure         : 0
     edge parse success            : 6
     edge parse failure            : 0
     edge insert success           : 6
     edge insert failure           : 0

4.5 使用 docker 导入

4.5.1 使用 docker exec 直接导入数据
4.5.1.1 数据准备

如果仅仅尝试使用 loader, 我们可以使用内置的 example 数据集进行导入,无需自己额外准备数据

如果使用自定义的数据,则在使用 loader 导入数据之前,我们需要将数据复制到容器内部。

首先我们可以根据 4.1-4.3 的步骤准备数据,将准备好的数据通过 docker cp 复制到 loader 容器内部。

假设我们已经按照上述的步骤准备好了对应的数据集,存放在 hugegraph-dataset 文件夹下,文件结构如下:

tree -f hugegraph-dataset/

hugegraph-dataset
├── hugegraph-dataset/edge_created.json
├── hugegraph-dataset/edge_knows.json
├── hugegraph-dataset/schema.groovy
├── hugegraph-dataset/struct.json
├── hugegraph-dataset/vertex_person.csv
└── hugegraph-dataset/vertex_software.txt

将文件复制到容器内部

docker cp hugegraph-dataset loader:/loader/dataset
docker exec -it loader ls /loader/dataset

edge_created.json  edge_knows.json  schema.groovy  struct.json  vertex_person.csv  vertex_software.txt
4.5.1.2 数据导入

以内置的 example 数据集为例,我们可以使用以下的命令对数据进行导入。

如果需要导入自己准备的数据集,则只需要修改 -f 配置脚本的路径 以及 -s schema 文件路径即可。

其他的参数可以参照 3.4.1 参数说明

docker exec -it loader bin/hugegraph-loader.sh -g hugegraph -f example/file/struct.json -s example/file/schema.groovy -h server -p 8080

如果导入用户自定义的数据集,按照刚才的例子,则使用:

docker exec -it loader bin/hugegraph-loader.sh -g hugegraph -f /loader/dataset/struct.json -s /loader/dataset/schema.groovy -h server -p 8080

如果 loaderserver位于同一 docker 网络,则可以指定 -h {server_container_name}, 否则需要指定 server的宿主机的 ip (在我们的例子中, server_container_nameserver).

然后我们可以观察到结果:

HugeGraphLoader worked in NORMAL MODE
vertices/edges loaded this time : 8/6
--------------------------------------------------
count metrics
    input read success            : 14                  
    input read failure            : 0                   
    vertex parse success          : 8                   
    vertex parse failure          : 0                   
    vertex insert success         : 8                   
    vertex insert failure         : 0                   
    edge parse success            : 6                   
    edge parse failure            : 0                   
    edge insert success           : 6                   
    edge insert failure           : 0                   
--------------------------------------------------
meter metrics
    total time                    : 0.199s              
    read time                     : 0.046s              
    load time                     : 0.153s              
    vertex load time              : 0.077s              
    vertex load rate(vertices/s)  : 103                 
    edge load time                : 0.112s              
    edge load rate(edges/s)       : 53   

也可以使用 curl 或者 hubble观察导入结果,此处以 curl 为例:

> curl "http://localhost:8080/graphs/hugegraph/graph/vertices" | gunzip
{"vertices":[{"id":1,"label":"software","type":"vertex","properties":{"name":"lop","lang":"java","price":328.0}},{"id":2,"label":"software","type":"vertex","properties":{"name":"ripple","lang":"java","price":199.0}},{"id":"1:tom","label":"person","type":"vertex","properties":{"name":"tom"}},{"id":"1:josh","label":"person","type":"vertex","properties":{"name":"josh","age":32,"city":"Beijing"}},{"id":"1:marko","label":"person","type":"vertex","properties":{"name":"marko","age":29,"city":"Beijing"}},{"id":"1:peter","label":"person","type":"vertex","properties":{"name":"peter","age":35,"city":"Shanghai"}},{"id":"1:vadas","label":"person","type":"vertex","properties":{"name":"vadas","age":27,"city":"Hongkong"}},{"id":"1:li,nary","label":"person","type":"vertex","properties":{"name":"li,nary","age":26,"city":"Wu,han"}}]}

如果想检查边的导入结果,可以使用 curl "http://localhost:8080/graphs/hugegraph/graph/edges" | gunzip

4.5.2 进入 docker 容器进行导入

除了直接使用 docker exec 导入数据,我们也可以进入容器进行数据导入,基本流程与 4.5.1 相同

使用 docker exec -it loader bash进入容器内部,并执行命令

sh bin/hugegraph-loader.sh -g hugegraph -f example/file/struct.json -s example/file/schema.groovy -h server -p 8080

执行的结果如 4.5.1 所示

4.6 使用 spark-loader 导入

Spark 版本:Spark 3+,其他版本未测试。 当前源码使用 Spark 3.2.2 和 Scala 2.12;其他组合需自行验证。

spark-loader 的参数分为两部分,注意:因二者参数名缩写存在重合部分,请使用参数全称。两种参数之间无需保证先后顺序。

示例:

sh bin/hugegraph-spark-loader.sh --master yarn \
--deploy-mode cluster --name spark-hugegraph-loader --file ./hugegraph.json \
--username admin --token admin --host xx.xx.xx.xx --port 8093 \
--graph graph-test --num-executors 6 --executor-cores 16 --executor-memory 15g

bin/hugegraph-spark-loader.sh 通过 ${SPARK_HOME}/bin/spark-submit 提交 org.apache.hugegraph.loader.spark.HugeGraphSparkLoader,因此 SPARK_HOME 必须指向一个 Spark 安装目录。lib/ 下的所有 jar 都会加入 classpath。Spark 应用名默认为 hugegraph-spark-loader,可以通过 APP_NAME 环境变量修改。

bin/get-params.sh 负责拆分命令行:只有下列参数会交给 loader,其余参数原样传给 spark-submit。该拆分只识别参数全称,因此 -f-g 这类缩写不会被识别。

--graph --schema --host --port --username --token --protocol
--trust-store-file --trust-store-password --clear-all-data --clear-timeout
--incremental-mode --failure-mode --batch-insert-threads --single-insert-threads
--max-conn --max-conn-per-route --batch-size --max-parse-errors --max-insert-errors
--timeout --shutdown-timeout --retry-times --retry-interval --check-vertex
--print-progress --dry-run --sink-type --vertex-partitions --edge-partitions --help

--file 单独处理:使用 --deploy-mode cluster 时,映射文件会通过 --files 分发到 executor,loader 只收到它的文件名;其他情况下路径原样传入。

该模式下 loader 只读取 FILE、HDFS 和 JDBC 输入源,KAFKA 和 GRAPH 输入源会被拒绝。

默认情况下(--sink-type true),每个 Spark 分区各自创建一个 HugeClient,通过 HugeGraph server API 写入顶点和边。使用 --sink-type false 时,loader 会生成 HFile 并直接 bulkload 到 HBase,此时表名和 ZooKeeper 配置取自 --vertex-table-name--edge-table-name--hbase-zk-quorum--hbase-zk-port--hbase-zk-parent--vertex-partitions--edge-partitions

当前源码使用 Flink 1.13.5、flink-connector-mysql-cdc 2.2.1 和 Scala 2.12;其他组合需自行验证。

bin/hugegraph-flinkcdc-loader.sh 通过 ${FLINK_HOME}/bin/flink run 提交 org.apache.hugegraph.loader.flink.HugeGraphFlinkCDCLoader,因此必须设置 FLINK_HOME。该任务用 Flink CDC 捕获 MySQL 的变更事件并应用到图上,从而让图与源表保持同步。

映射文件格式与命令行 loader 相同,但每个输入源都必须是 MySQL 的 JDBC 输入源:loader 从中读取 urldatabasetableusernamepassword,并从 url 解析出主机和端口。顶点和边映射的用法不变。3.4.1 中的 --cdc-flush-interval--cdc-sink-parallelism 只在该模式下生效。

命令行同样由 bin/get-params.sh 按 4.6 的方式拆分,非 loader 参数会传给 flink run

示例:

sh bin/hugegraph-flinkcdc-loader.sh --file ./mysql-cdc.json \
--host xx.xx.xx.xx --port 8080 --graph hugegraph --username admin --token admin

2.4 - 图导入

需要把文件、数据库或消息数据写入 HugeGraph 时,从这里选择工具。直接导入可使用 Loader;已有 Source、Transform、Sink 管道时使用 SeaTunnel Sink;Spark 作业可使用 Spark Connector。

2.4.1 - 使用 SeaTunnel Sink 导入图数据

SeaTunnel 可以把数据库、Kafka 等数据源接入 HugeGraph。连接器分为两部分:Source 负责读取,Sink 负责写入[1][2],中间可以接 SeaTunnel 的数据转换组件。需要从 HugeGraph 导出或迁移数据时,请查看SeaTunnel Source 导出与迁移文档

版本要求:本文面向 SeaTunnel 3.0+ 所有示例使用 mappings

Loader 与 SeaTunnel 的工作流对比:直接导入图数据与复用 Source、Transform、Sink 管道

点击配图可查看原图。

1 与 Loader 和 Tools 的区别

HugeGraph-Loader 适合把常见数据直接导入 HugeGraph;HugeGraph-Tools 主要用于单机图管理、备份和导出;SeaTunnel 则把任务组织成 Source → Transform → Sink,适合复用已有的连接器、转换步骤和数据处理管道。

表格标记

✅ 原生支持;⚠️ 有条件支持,或需要额外组件/外部平台;❌ 不提供该能力

对比点LoaderToolsSeaTunnel
任务覆盖✅ 直接导入图数据✅ 备份、恢复和导出✅ 导入、导出与迁移,可组合 Source、Transform、Sink
任务配置JSON 映射文件,描述输入源、顶点和边命令行参数和运维命令HOCON 作业文件[3],组合 Source、Transform 和 Sink
默认部署✅ 单机 CLI;⚠️ 可借助 Spark Loader 扩展✅ 单机 CLI✅ 单机;✅ 分布式
执行引擎⚠️ 以 CLI 为主,Spark Loader 是独立扩展❌ 不提供 Spark/Flink 执行引擎✅ HugeGraph Source/Sink 支持 Zeta、Spark、Flink[1][2][7][8][9][10]
前端与可观测性❌ 无内置前端,查看 CLI 日志❌ 无内置前端,查看 CLI 日志✅ 内置 Web UI 作业面板,方便查看任务状态和运行情况
输入与输出⚠️ 围绕图导入,支持常见文件、JDBC、Kafka 等⚠️ 围绕图数据和备份文件,支持常见存储✅ 数十种连接器,含 JDBC、Kafka、SQL-CDC 等
调度与资源管理❌ 无统一的跨任务调度和资源分配机制❌ 无统一的跨任务调度和资源分配机制⚠️ 可结合 DolphinScheduler 做调度和任务管理
易用性✅ 专注导入,配置简单;后续提供二进制 CLI 后更方便快速使用✅ 命令直接,适合单机运维⚠️ 配置和运行组件较多,适合长期数据管道
高性能导入✅ 支持 bypass-server 等优化;特定后端和硬件条件下,实测峰值可达 100~200 万条/秒,需按实际场景压测⚠️ 重点是备份和导出,不以批量导入吞吐为主要目标✅ 依靠并行度、分布式引擎和连接器扩展吞吐

SeaTunnel 覆盖 Loader 的图导入和 Tools 的导出、迁移场景,可以把两类任务放进同一条可扩展管道,还支持 SQL-CDC 和数十种输入输出类型。默认情况下,Loader 和 Tools 都在单机运行;SeaTunnel 同时支持单机和分布式部署,可随着数据量和任务数量扩展。Tools 的 schedule-backup 可以创建 crontab 任务,但它不负责统一的任务编排和资源管理。

已有 Spark/Flink 每日任务

HugeGraph Source 和 Sink 在 SeaTunnel 3.0.0-release 中都支持 SeaTunnel Engine(Zeta)、Spark 和 Flink。若把每日任务改成 SeaTunnel 作业,并用对应引擎提交,数据可以在 Source → Transform → Sink 之间直接传递,不需要先落盘再交给 Loader。若保留现有 Spark/Flink DAG,SeaTunnel 不会自动接管内存中的 DataFrame 或 Stream,需要改造成 SeaTunnel 作业,或让 Source 读取已有系统中的数据

Loader 和 Tools 的优势是专注、直接、上手快。需要直接导入图数据时可先用 Loader;需要备份、恢复、导出或日常运维时可用 Tools。如果已经有 SeaTunnel 作业,通常在原管道中接入 HugeGraph 更方便。需要更高导入吞吐时,Loader 的 bypass-server 和其他导入优化更合适;Loader 在特定后端、数据规模和硬件条件下实测峰值可达 100~200 万条/秒,不能直接当作通用性能承诺,仍需单独压测。新建 SeaTunnel 任务使用 3.0+mappings。使用其他版本时,请重新核对连接器配置。

2 准备环境

2.1 获取 SeaTunnel 3.0+

SeaTunnel 3.0+ 官方开发文档列出 JDK 8 和 JDK 11;本文统一使用 JDK 11,并设置 JAVA_HOME。从 SeaTunnel 3.0+[4] 获取源码,按上游开发环境文档[5]构建发行包:

git clone --branch 3.0.0-release https://github.com/apache/seatunnel.git
cd seatunnel
./mvnw clean package -pl seatunnel-dist -am -Dmaven.test.skip=true

解压 seatunnel-dist/target/ 中生成的二进制包,后续命令都在解压后的 SeaTunnel 安装目录执行。需要更新功能时,可以切换到其他版本;引擎与连接器插件应来自同一次构建,避免混用不同版本的 JAR。

本文使用 SeaTunnel 自带的 Zeta 引擎和 local 模式[6][7]。确认安装目录的 connectors/ 中包含 HugeGraph,以及所需的 JDBC 或 Kafka 连接器[11][12];如果自定义构建没有包含它们,需补齐同一次构建产出的插件。JDBC 示例还需要将 MySQL 驱动 JAR 放入 lib/,驱动类为 com.mysql.cj.jdbc.Driver

2.2 准备 HugeGraph 和数据源

先启动 HugeGraph Server,创建可用于测试的图。本文示例使用 hugegraph 图、DEFAULT 图空间,请按服务端实际配置修改;图空间名称区分大小写。启用了身份验证时,在 HugeGraph Source 和 Sink 中填写 usernamepassword

下面的图模型贯穿 JDBC 和 Kafka 示例。mappings 默认会创建缺失的 PropertyKey、VertexLabel 和 EdgeLabel;已有图模型必须与配置兼容。

图元素名称与属性
属性name 为 Text,agesince 为 Int
顶点person,主键为 name,属性为 nameage
knows,从 person 指向 person,属性为 since

所有示例中的 mysqlkafkahugegraph 都是占位主机名,需替换为 SeaTunnel 运行环境可访问的地址。容器中的 127.0.0.1 指向容器自身;同一 Docker 网络可使用服务名。host 只填主机名或 IP,端口单独填写。

3 从关系库导入(sql2graph)

用两个任务完成导入:先把 person 表写成顶点,再把 knows 表写成边。这样写边时,两个端点都已经存在。

从关系表记录生成顶点和边:person 表映射为顶点,knows 表映射为有向边

3.1 导入顶点

在 MySQL 的 demo 数据库中准备示例数据,并让配置中的账号有读取权限:

CREATE TABLE person (
  name VARCHAR(64) PRIMARY KEY,
  age INT NOT NULL
);
INSERT INTO person VALUES ('marko', 29), ('vadas', 27);

保存为 config/sql2graph-person.conf,将数据库账号和密码替换为实际值:

env {
  job.mode = "BATCH"
}

source {
  Jdbc {
    url = "jdbc:mysql://mysql:3306/demo?useSSL=false&serverTimezone=UTC"
    driver = "com.mysql.cj.jdbc.Driver"
    username = "seatunnel"
    password = "change_me"
    query = "SELECT name, age FROM person ORDER BY name"
  }
}

sink {
  HugeGraph {
    host = "hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    batch_failure_fallback = false
    mappings = [
      {
        type = "VERTEX"
        label = "person"
        idStrategy = "PRIMARY_KEY"
        idFields = ["name"]
        properties = ["name", "age"]
      }
    ]
  }
}
./bin/seatunnel.sh --config ./config/sql2graph-person.conf -m local

在 Hubble 或 Gremlin 中检查结果,应能查到 markovadas 及其年龄:

g.V().hasLabel('person').valueMap('name', 'age')

idFields = ["name"] 表示使用名字生成主键。重复导入同一个 name 会写到同一个顶点;properties 指定要写入的源字段。

3.2 导入边

准备关系表,其中两个端点字段对应前面导入的 person.name

CREATE TABLE knows (
  source_name VARCHAR(64) NOT NULL,
  target_name VARCHAR(64) NOT NULL,
  since INT NOT NULL
);
INSERT INTO knows VALUES ('marko', 'vadas', 2010);
展开配置,保存为 config/sql2graph-knows.conf
env {
  job.mode = "BATCH"
}

source {
  Jdbc {
    url = "jdbc:mysql://mysql:3306/demo?useSSL=false&serverTimezone=UTC"
    driver = "com.mysql.cj.jdbc.Driver"
    username = "seatunnel"
    password = "change_me"
    query = "SELECT source_name, target_name, since FROM knows ORDER BY source_name, target_name"
  }
}

sink {
  HugeGraph {
    host = "hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    batch_failure_fallback = false
    check_vertex = true
    mappings = [
      {
        type = "EDGE"
        label = "knows"
        sourceConfig = {
          label = "person"
          idFields = ["source_name"]
        }
        targetConfig = {
          label = "person"
          idFields = ["target_name"]
        }
        fieldMapping = {
          source_name = "name"
          target_name = "name"
        }
        properties = ["since"]
      }
    ]
  }
}

确认顶点任务成功后,再执行边任务:

./bin/seatunnel.sh --config ./config/sql2graph-knows.conf -m local

下面的查询应返回 markovadasknows 边,属性 since2010

g.V().has('person', 'name', 'marko').outE('knows').where(inV().has('name', 'vadas')).valueMap()

sourceConfigtargetConfig 指定端点字段,fieldMapping 将它们对应到顶点主键 nameproperties = ["since"] 只写边属性。示例启用 check_vertex = true,并关闭失败后逐条跳过的回退(batch_failure_fallback = false);端点不存在或写入失败时,任务会报错。

如果关系表只有数字外键,而图的主键使用姓名,请先在 SQL 中关联出姓名,再交给 Sink。MySQL CDC 接入方式见 MySQL CDC Source[13]

4 从 Kafka 导入(kafka2graph)

Kafka 适合持续接收事件。先创建 user-events topic,再写入以下 JSON 消息,每条消息对应一个 person 顶点:

{"name":"marko","age":29}

保存为 config/kafka2graph.conf

env {
  job.mode = "STREAMING"
  checkpoint.interval = 10000
  sink.flush.interval = 5000
}

source {
  Kafka {
    bootstrap.servers = "kafka:9092"
    topic = "user-events"
    consumer.group = "hugegraph-import"
    start_mode = "earliest"
    format = "json"
    schema = {
      fields = {
        name = "string"
        age = "int"
      }
    }
  }
}

sink {
  HugeGraph {
    host = "hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    batch_failure_fallback = false
    mappings = [
      {
        type = "VERTEX"
        label = "person"
        idStrategy = "PRIMARY_KEY"
        idFields = ["name"]
        properties = ["name", "age"]
      }
    ]
  }
}
./bin/seatunnel.sh --config ./config/kafka2graph.conf -m local

用第 3.1 节的 Gremlin 查询检查数据。流式任务会持续运行;checkpoint.interval 每 10 秒保存一次任务状态,sink.flush.interval 让 Zeta 每 5 秒触发一次刷新,避免少量消息一直等到批次填满。

HugeGraph Sink 是 at-least-once(至少一次) 写入,故障恢复可能重放记录。使用 PRIMARY_KEY 能让相同 name 落到同一个顶点,但不等于所有更新操作都具备 exactly-once 语义。定时刷新由 Zeta 提供,不适用于 Spark 或 Flink 引擎。

5 常用配置与排错

下表适用于本文使用的 SeaTunnel 3.0+ 版本:

配置用途
hostport分别指定 HugeGraph 主机和端口
graph_namegraph_space选择已创建的图与图空间
mappings定义输入字段如何生成顶点或边
properties每个 mapping 内要写入的源字段列表
schema_save_modemappings 默认自动创建缺失的 Schema;已有 Schema 仍需兼容
batch_size单批记录数,默认 500
env.sink.flush.intervalZeta 定时刷新间隔,单位毫秒
check_vertex写边时检查端点,本文的边任务设为 true
batch_failure_fallback[2]默认 true,批量失败后逐条重试,最多跳过 max_insert_errors 条失败记录;本文示例显式设为 false,让批量失败直接终止任务
max_insert_errors逐条回退时允许跳过的失败记录数;默认 500-1 表示不限制,仅在开启 batch_failure_fallback 时生效

遇到问题时可按下面检查:

  • 不识别 mappings 或找不到 HugeGraph Source:检查引擎与 HugeGraph connector 是否来自同一次 3.0+ 构建。
  • 连接失败:检查主机、端口、图空间、认证信息,以及 SeaTunnel 所在环境能否访问服务。
  • Schema 不兼容:检查标签的 ID 策略、属性类型和边端点。自动创建不会把已有 PRIMARY_KEY 标签改成 CUSTOMIZE_STRING
  • Kafka 少量数据未及时出现:确认使用 Zeta,并在 env 中设置 sink.flush.interval。此版本的 batch_interval_ms 仅为兼容保留,不能代替它。

6 选型小结

选工具时,先看要完成的工作:图管理、Gremlin、备份或克隆可用 Tools;直接导入图可先看 Loader;需要复用 Source、Transform、Sink 管道时选 SeaTunnel。使用 SeaTunnel 的图读取和迁移能力时,请按本文使用的 3.0+ 版本准备环境。

按工作流选择工具:图管理用 Tools,直接导入用 Loader,复用数据管道用 SeaTunnel

7 参考文档

HugeGraph 连接器

[1] HugeGraph Source
[2] HugeGraph Sink

配置与部署

[3] HOCON 作业文件配置说明
[4] SeaTunnel 3.0.0-release 分支
[5] SeaTunnel 开发环境文档
[6] SeaTunnel 本地部署

执行引擎

[7] SeaTunnel 引擎概览
[8] SeaTunnel Spark 引擎
[9] SeaTunnel Flink 引擎
[10] Connector V2 多引擎说明

数据源连接器

[11] JDBC Source
[12] Kafka Source
[13] MySQL CDC Source

旧版本兼容

[14] SeaTunnel 2.3.13 HugeGraph Sink

旧版本说明

本文面向 SeaTunnel 3.0+,文中的 Source、mappings 和图迁移示例不适用于 2.3.13。2.3.13 已过时,仅提供 HugeGraph Sink,配置使用 schema_config,并且需要提前创建图模型。如必须使用 2.3.13,请参考官方 Sink 文档[14],不要套用本文配置

2.5 - Tools Quick Start

1 HugeGraph-Tools概述

HugeGraph-Tools 是 HugeGraph 的自动化部署、管理和备份/还原组件。

测试指南:如需在本地运行 Tools 测试,请参考 工具链本地测试指南

2 获取 HugeGraph-Tools

HugeGraph-Tools 包含在 Toolchain 发布包中,可以下载发布包,也可以从源码编译。

  • 下载二进制tar包
  • 下载源码编译安装

2.1 下载二进制tar包

下载最新版本的 HugeGraph-Toolchain 包, 然后进入 tools 子目录

export VERSION=1.7.0
export ARCHIVE="apache-hugegraph-toolchain-incubating-${VERSION}"
wget "https://downloads.apache.org/hugegraph/${VERSION}/${ARCHIVE}.tar.gz"
tar zxf "${ARCHIVE}.tar.gz"
# hugegraph-tools 位于 toolchain 发布包的子目录中,
# 其版本后缀与发布包本身一致
cd "${ARCHIVE}/apache-hugegraph-tools-incubating-${VERSION}"

2.2 下载源码编译安装

源码编译前请确保安装了wget命令

下载最新版本的 HugeGraph-Toolchain 源码包, 然后根目录编译或者单独编译 tool 子模块:

# 1. get from github
git clone https://github.com/apache/hugegraph-toolchain.git

# 2. 下载发布版源码包
export VERSION=1.7.0
export ARCHIVE="apache-hugegraph-toolchain-incubating-${VERSION}"
wget "https://downloads.apache.org/hugegraph/${VERSION}/${ARCHIVE}-src.tar.gz"

编译生成 tar 包:

cd hugegraph-toolchain
mvn package -pl hugegraph-tools -am -DskipTests -ntp

生成的 tar 包位于 hugegraph-tools/target/apache-hugegraph-tools-${version}.tar.gz,同时会在 hugegraph-tools/apache-hugegraph-tools-${version} 生成解压后的目录(包含 bin/lib/

3 使用

3.1 功能概览

解压后,进入 apache-hugegraph-tools-${version} 目录,可以使用bin/hugegraph或者bin/hugegraph help来查看 usage 信息,使用bin/hugegraph help <子命令>查看单个子命令的 usage。主要分为:

  • 图管理类,graph-mode-set、graph-mode-get、graph-list、graph-get、graph-clear、graph-create、graph-clone 和 graph-drop
  • 异步任务管理类,task-list、task-get、task-delete、task-cancel 和 task-clear
  • Gremlin类,gremlin-execute 和 gremlin-schedule
  • 备份/恢复类,backup、restore、migrate、schedule-backup 和 dump
  • 认证数据备份/恢复类,auth-backup 和 auth-restore
  • 安装部署类,deploy、clear、start-all 和 stop-all
Usage: hugegraph [options] [command] [command options]
3.2 [options]-全局变量

options是 HugeGraph-Tools 的全局变量,可以在 hugegraph-tools/bin/hugegraph 中配置,包括:

  • –graph,HugeGraph-Tools 操作的图的名字,默认值是 hugegraph
  • –url,HugeGraph-Server 的服务地址,默认是 http://127.0.0.1:8080
  • –user,当 HugeGraph-Server 开启认证时,传递用户名
  • –password,当 HugeGraph-Server 开启认证时,传递用户的密码
  • –timeout,连接 HugeGraph-Server 时的超时时间,默认是 30s
  • –trust-store-file,证书文件的路径,当 –url 使用 https 时,HugeGraph-Client 使用的 truststore 文件,默认为空,代表使用 hugegraph-tools 内置的 truststore 文件 conf/hugegraph.truststore
  • –trust-store-password,证书文件的密码,当 –url 使用 https 时,HugeGraph-Client 使用的 truststore 的密码,默认为空,代表使用 hugegraph-tools 内置的 truststore 文件的密码
  • –throw-mode,HugeGraph-Tools 出错时是否直接抛出异常,而不是打印错误信息后退出,默认为 false(主要用于测试)

连接协议由 –url 的 scheme 决定:使用 https://... 即通过 https 连接。–trust-store-file 和 –trust-store-password 只能在 –url 使用 https 时设置,–user 和 –password 必须同时提供或同时省略。

上述全局变量,也可以通过环境变量来设置。一种方式是在命令行使用 export 设置临时环境变量,在该命令行关闭之前均有效

全局变量环境变量示例
–urlHUGEGRAPH_URLexport HUGEGRAPH_URL=http://127.0.0.1:8080
–graphHUGEGRAPH_GRAPHexport HUGEGRAPH_GRAPH=hugegraph
–userHUGEGRAPH_USERNAMEexport HUGEGRAPH_USERNAME=admin
–passwordHUGEGRAPH_PASSWORDexport HUGEGRAPH_PASSWORD=test
–timeoutHUGEGRAPH_TIMEOUTexport HUGEGRAPH_TIMEOUT=30
–trust-store-fileHUGEGRAPH_TRUST_STORE_FILEexport HUGEGRAPH_TRUST_STORE_FILE=/tmp/trust-store
–trust-store-passwordHUGEGRAPH_TRUST_STORE_PASSWORDexport HUGEGRAPH_TRUST_STORE_PASSWORD=xxxx

另一种方式是在 bin/hugegraph 脚本中设置环境变量:

#!/bin/bash

# Set environment here if needed
#export HUGEGRAPH_URL=
#export HUGEGRAPH_GRAPH=
#export HUGEGRAPH_USERNAME=
#export HUGEGRAPH_PASSWORD=
#export HUGEGRAPH_TIMEOUT=
#export HUGEGRAPH_TRUST_STORE_FILE=
#export HUGEGRAPH_TRUST_STORE_PASSWORD=

bin/hugegraph 还会读取 JAVA_HOME(未设置时打印警告,https 需要它)和 JAVA_OPTIONS(JVM 参数,为空时脚本使用 -Xms512m,并根据机器空闲内存计算 -Xmx)。

3.3 图管理类,graph-mode-set、graph-mode-get、graph-list、graph-get、graph-clear、graph-create、graph-clone和graph-drop
  • graph-mode-set,设置图的 restore mode
    • –graph-mode 或者 -m,必填项,指定将要设置的模式,合法值包括 [NONE, RESTORING, MERGING, LOADING]
  • graph-mode-get,获取图的 restore mode
  • graph-list,列出某个 HugeGraph-Server 中全部的图
  • graph-get,获取某个图及其存储后端类型
  • graph-clear,清除某个图的全部 schema 和 data
    • –confirm-message 或者 -c,必填项,删除确认信息,需要手动输入,二次确认防止误删,“I’m sure to delete all data”,包括双引号
  • graph-create,使用配置文件创建新图
    • –name 或者 -n,选填项,新图的名称,默认为 g
    • –file 或者 -f,图配置文件的路径,文件内容会作为新图的配置发送给 HugeGraph-Server
  • graph-clone,克隆已存在的图
    • –name 或者 -n,选填项,新克隆图的名称,默认为 g
    • –clone-graph-name,选填项,要克隆的源图名称,默认为 hugegraph
  • graph-drop,删除图(不同于 graph-clear,这会完全删除图)
    • –confirm-message 或者 -c,必填项,确认消息 “I’m sure to drop the graph”,包括双引号

graph-create、graph-clone、graph-clear 和 graph-drop 会将 –timeout 提升到至少 300 秒。

当需要把备份的图原样恢复到一个新的图中的时候,需要先将图模式设置为 RESTORING 模式;当需要将备份的图合并到已存在的图中时,需要先将图模式设置为 MERGING 模式。

3.4 异步任务管理类,task-list、task-get、task-delete、task-cancel 和 task-clear
  • task-list,列出某个图中的异步任务,可以根据任务的状态过滤
    • –status,选填项,指定要查看的任务的状态,即按状态过滤任务,合法值包括 [UNKNOWN, NEW, QUEUED, RESTORING, RUNNING, SUCCESS, CANCELLED, FAILED](不区分大小写)
    • –limit,选填项,指定要获取的任务的数目,默认为 -1,意思为获取全部符合条件的任务,显式传入的值必须为正数
  • task-get,获取某个异步任务的详细信息
    • –task-id,必填项,指定异步任务的 ID
  • task-delete,删除某个异步任务的信息
    • –task-id,必填项,指定异步任务的 ID
  • task-cancel,取消某个异步任务的执行
    • –task-id,必填项,要取消的异步任务的 ID
  • task-clear,清理完成的异步任务
    • –force,选填项,设置时,表示清理全部异步任务,未执行完成的先取消,然后清除所有异步任务。默认只清理已完成的异步任务
3.5 Gremlin类,gremlin-execute和gremlin-schedule
  • gremlin-execute,发送 Gremlin 语句到 HugeGraph-Server 来执行查询或修改操作,同步执行,结束后返回结果
    • –file 或者 -f,指定要执行的脚本文件,UTF-8编码,与 –script 互斥
    • –script 或者 -s,指定要执行的脚本字符串,与 –file 互斥
    • –aliases 或者 -a,Gremlin 别名设置,格式为:key1=value1,key2=value2,…
    • –bindings 或者 -b,Gremlin 绑定设置,格式为:key1=value1,key2=value2,…
    • –language 或者 -l,Gremlin 脚本的语言,默认为 gremlin-groovy

    –file 和 –script 二者互斥,必须设置其中之一

  • gremlin-schedule,发送 Gremlin 语句到 HugeGraph-Server 来执行查询或修改操作,异步执行,任务提交后立刻返回异步任务id
    • –file 或者 -f,指定要执行的脚本文件,UTF-8编码,与 –script 互斥
    • –script 或者 -s,指定要执行的脚本字符串,与 –file 互斥
    • –bindings 或者 -b,Gremlin 绑定设置,格式为:key1=value1,key2=value2,…
    • –language 或者 -l,Gremlin 脚本的语言,默认为 gremlin-groovy

    –file 和 –script 二者互斥,必须设置其中之一

3.6 备份/恢复类
  • backup,将某张图中的 schema 或者 data 备份到 HugeGraph 系统之外,以 JSON 形式存在本地磁盘或者 HDFS
    • –format,备份的格式,可选值包括 [json, text],默认为 json
    • –all-properties,是否备份顶点/边全部的属性,仅在 –format 为 text 是有效,默认 false
    • –label,要备份的顶点 label 或者边 label,仅在 –format 为 text 时生效;设置该项时,–huge-types 必须只包含一种类型,且该类型必须是 vertex 或者 edge,否则命令会失败
    • –properties,要备份的顶点/边的属性,逗号分隔,仅在 –format 为 text 是有效,只有备份顶点或者边的时候有效
    • –compress,备份时是否压缩数据,默认为 true
    • –directory 或者 -d,存储 schema 或者 data 的目录,本地目录时,默认为’./{graphName}’,HDFS 时,默认为 ‘{fs.default.name}/{graphName}’
    • –huge-types 或者 -t,要备份的数据类型,逗号分隔,可选值为 ‘all’ 或者 一个或多个 [vertex,edge,vertex_label,edge_label,property_key,index_label] 的组合,‘all’ 代表全部6种类型,即顶点、边和所有schema,‘schema’ 代表 4 种 schema 类型 [vertex_label, edge_label, property_key, index_label]
    • –log 或者 -l,指定日志目录,默认为 ./logs
    • –retry,指定失败重试次数,默认为 3
    • –thread-num 或者 -T,使用的线程数,默认为 Math.min(10, Math.max(4, CPUs / 2))
    • –split-size 或者 -s,指定在备份时对顶点或者边分块的大小,默认为 1048576,且不能小于 1048576(1M)
    • -D,用 -Dkey=value 的模式指定动态参数,用来备份数据到 HDFS 时,指定 HDFS 的配置项,例如:-Dfs.default.name=hdfs://localhost:9000

    当 –timeout 小于 120 秒时,backup(以及 migrate 中的备份步骤)会使用 120 秒

  • restore,将 JSON 格式存储的 schema 或者 data 恢复到一个新图中(RESTORING 模式)或者合并到已存在的图中(MERGING 模式)
    • –directory 或者 -d,存储 schema 或者 data 的目录,本地目录时,默认为’./{graphName}’,HDFS 时,默认为 ‘{fs.default.name}/{graphName}’
    • –clean,是否在恢复图完成后删除 –directory 指定的目录,默认为 false
    • –huge-types 或者 -t,要恢复的数据类型,逗号分隔,可选值为 ‘all’ 或者 一个或多个 [vertex,edge,vertex_label,edge_label,property_key,index_label] 的组合,‘all’ 代表全部6种类型,即顶点、边和所有schema,‘schema’ 代表 4 种 schema 类型 [vertex_label, edge_label, property_key, index_label]
    • –log 或者 -l,指定日志目录,默认为 ./logs
    • –retry,指定失败重试次数,默认为 3
    • –thread-num 或者 -T,使用的线程数,默认为 Math.min(10, Math.max(4, CPUs / 2))
    • -D,用 -Dkey=value 的模式指定动态参数,用来从 HDFS 恢复图时,指定 HDFS 的配置项,例如:-Dfs.default.name=hdfs://localhost:9000

    只有当 –format 为 json 执行 backup 时,才可以使用 restore 命令恢复 restore 要求图处于 RESTORING 或 MERGING 模式(先用 graph-mode-set 设置),否则命令会失败

  • migrate,将当前连接的图迁移至另一个 HugeGraphServer 中
    • –target-graph,目标图的名字,默认为 hugegraph
    • –target-url,目标图所在的 HugeGraphServer,默认为 http://127.0.0.1:8081
    • –target-user,访问目标图的用户名
    • –target-password,访问目标图的密码
    • –target-timeout,访问目标图的超时时间
    • –target-trust-store-file,访问目标图使用的 truststore 文件
    • –target-trust-store-password,访问目标图使用的 truststore 的密码
    • –directory 或者 -d,迁移过程中,存储源图的 schema 或者 data 的目录,本地目录时,默认为’./{graphName}’,HDFS 时,默认为 ‘{fs.default.name}/{graphName}’
    • –huge-types 或者 -t,要迁移的数据类型,逗号分隔,可选值为 ‘all’ 或者 一个或多个 [vertex,edge,vertex_label,edge_label,property_key,index_label] 的组合,‘all’ 代表全部6种类型,即顶点、边和所有schema,‘schema’ 代表 4 种 schema 类型 [vertex_label, edge_label, property_key, index_label]
    • –log 或者 -l,指定日志目录,默认为 ./logs
    • –retry,指定失败重试次数,默认为 3
    • –thread-num 或者 -T,使用的线程数,默认为 Math.min(10, Math.max(4, CPUs / 2))
    • –split-size 或者 -s,指定迁移过程中对源图进行备份时顶点或者边分块的大小,默认为 1048576,且不能小于 1048576(1M)
    • -D,用 -Dkey=value 的模式指定动态参数,用来在迁移图过程中需要备份数据到 HDFS 时,指定 HDFS 的配置项,例如:-Dfs.default.name=hdfs://localhost:9000
    • –graph-mode 或者 -m,将源图恢复到目标图时将目标图设置的模式,合法值包括 [RESTORING, MERGING],默认为 RESTORING。迁移期间目标图会被切换到该模式,迁移结束后恢复为原来的模式
    • –keep-local-data,是否保留在迁移图的过程中产生的源图的备份,默认为 false,即默认迁移图结束后不保留产生的源图备份
  • schedule-backup,周期性对图执行备份操作,并保留一定数目的最新备份(目前仅支持本地文件系统)
    • –directory 或者 -d,必填项,指定备份数据的目录
    • –backup-num,选填项,指定保存的最新的备份的数目,默认为 3
    • –interval,选填项,指定进行备份的周期,格式同 Linux crontab 格式,默认为 “0 0 * * *"(每天 00:00)

    schedule-backup 会添加一条 crontab 任务,定期执行 backup -t all 并写入 {directory}/{graph}/hugegraph-backup-{yyMMddHHmm}/,只保留最新的 –backup-num 份备份。相对路径的 –directory 会相对于 hugegraph-tools 的根目录解析,且 {directory}/{graph} 必须尚不存在

  • dump,把整张图的顶点和边全部导出,默认以 vertex vertex-edge1 vertex-edge2... 的 JSON 格式存储。 用户也可以自定义存储格式。在 hugegraph-tools/src/main/java/org/apache/hugegraph/formatter 下实现一个继承自 Formatter 的类,例如 CustomFormatter,使用时指定该类为 formatter: bin/hugegraph dump -f CustomFormatter
    • –formatter 或者 -f,指定使用的 formatter,默认为 JsonFormatter
    • –directory 或者 -d,存储 schema 或者 data 的目录,本地目录时,默认为’./{graphName}’,HDFS 时,默认为 ‘{fs.default.name}/{graphName}’
    • –log 或者 -l,指定日志目录,默认为 ./logs
    • –retry,指定失败重试次数,默认为 3
    • –thread-num 或者 -T,使用的线程数,默认为 Math.min(10, Math.max(4, CPUs / 2))
    • –split-size 或者 -s,指定在备份时对顶点或者边分块的大小,默认为 1048576,且不能小于 1048576(1M)
    • -D,用 -Dkey=value 的模式指定动态参数,用来备份数据到 HDFS 时,指定 HDFS 的配置项,例如:-Dfs.default.name=hdfs://localhost:9000
3.7 认证数据备份/恢复类
  • auth-backup,备份认证数据到指定目录
    • –types 或者 -t,要备份的认证数据类型,逗号分隔,可选值为 ‘all’ 或者一个或多个 [user, group, target, belong, access] 的组合,‘all’ 代表全部5种类型;包含 ‘belong’ 时必须同时包含 ‘user’ 和 ‘group’,包含 ‘access’ 时必须同时包含 ‘group’ 和 ’target’
    • –directory,备份数据存储目录,本地目录时,默认为 ‘./auth-backup-restore’,HDFS 时,默认为 ‘{fs.default.name}/auth-backup-restore’(该选项没有 -d 短写)
    • –retry,指定失败重试次数,默认为 3
    • -D,用 -Dkey=value 的模式指定动态参数,用来备份数据到 HDFS 时,指定 HDFS 的配置项,例如:-Dfs.default.name=hdfs://localhost:9000
  • auth-restore,从指定目录恢复认证数据
    • –types 或者 -t,要恢复的认证数据类型,逗号分隔,可选值为 ‘all’ 或者一个或多个 [user, group, target, belong, access] 的组合,‘all’ 代表全部5种类型;包含 ‘belong’ 时必须同时包含 ‘user’ 和 ‘group’,包含 ‘access’ 时必须同时包含 ‘group’ 和 ’target’
    • –directory,备份数据存储目录,本地目录时,默认为 ‘./auth-backup-restore’,HDFS 时,默认为 ‘{fs.default.name}/auth-backup-restore’(该选项没有 -d 短写)
    • –retry,指定失败重试次数,默认为 3
    • –strategy,冲突处理策略,可选值为 [stop, ignore],默认为 stop。stop 表示遇到冲突时停止恢复,ignore 表示忽略冲突继续恢复
    • –init-password,恢复用户时设置的初始密码,当 –types 包含 user 时必填
    • -D,用 -Dkey=value 的模式指定动态参数,用来从 HDFS 恢复数据时,指定 HDFS 的配置项,例如:-Dfs.default.name=hdfs://localhost:9000
3.8 安装部署类
  • deploy,一键下载、安装和启动 HugeGraph-Server 和 HugeGraph-Studio
    • -v,必填项,指定要安装的 HugeGraph-Server 和 HugeGraph-Studio 版本,必须是 bin/version-map.yaml 中列出的版本之一(0.6、0.7、0.8、0.9、0.10),脚本据此映射到对应的 server 和 studio 发布版本
    • -p,必填项,指定安装的 HugeGraph-Server 和 HugeGraph-Studio 目录
    • -u,选填项,指定下载 HugeGraph-Server 和 HugeGraph-Studio 压缩包的链接
  • clear,清理 HugeGraph-Server 和 HugeGraph-Studio 目录和tar包(若对应的 server 或 studio 进程仍在运行则拒绝执行,删除每一项前都会提示确认)
    • -p,必填项,指定要清理的 HugeGraph-Server 和 HugeGraph-Studio 的目录
  • start-all,一键启动 HugeGraph-Server 和 HugeGraph-Studio
    • -v,必填项,指定已安装的 HugeGraph-Server 和 HugeGraph-Studio 版本,取值同 deploy
    • -p,必填项,指定安装了 HugeGraph-Server 和 HugeGraph-Studio 的目录
  • stop-all,一键关闭 HugeGraph-Server 和 HugeGraph-Studio

deploy、start-all、clear 和 stop-all 由 bin/hugegraph 直接转交给 bin/deploy.shbin/start-all.shbin/clear.shbin/stop-all.sh 执行,因此 3.2 中的全局变量和环境变量对它们不生效。

deploy命令中有可选参数 -u,提供时会使用指定的下载地址替代默认下载地址下载 tar 包,并且将地址写入~/hugegraph-download-url-prefix文件中;之后如果不指定地址时,会优先从~/hugegraph-download-url-prefix指定的地址下载 tar 包;如果 -u 和~/hugegraph-download-url-prefix都没有时,会从默认下载地址 https://github.com/hugegraph 进行下载

3.9 具体命令参数

各子命令的具体参数如下:

Usage: hugegraph [options] [command] [command options]
  Options:
    --graph
      Name of graph
      Default: hugegraph
    --password
      Password of user
    --throw-mode
      Whether the hugegraph-tools work to throw an exception
      Default: false
    --timeout
      Connection timeout
      Default: 30
    --trust-store-file
      The path of client truststore file used when https protocol is enabled
    --trust-store-password
      The password of the client truststore file used when the https protocol 
      is enabled
    --url
      The URL of HugeGraph-Server
      Default: http://127.0.0.1:8080
    --user
      Name of user
  Commands:
    graph-create      Create graph with config
      Usage: graph-create [options]
        Options:
          --file, -f
            Creating graph config file
          --name, -n
            The name of new created graph, default is g
            Default: g

    graph-clone      Clone graph
      Usage: graph-clone [options]
        Options:
          --clone-graph-name
            The name of cloned graph, default is hugegraph
            Default: hugegraph
          --name, -n
            The name of new created graph, default is g
            Default: g

    graph-list      List all graphs
      Usage: graph-list

    graph-get      Get graph info
      Usage: graph-get

    graph-clear      Clear graph schema and data
      Usage: graph-clear [options]
        Options:
        * --confirm-message, -c
            Confirm message of graph clear is "I'm sure to delete all data". 
            (Note: include "")

    graph-drop      Drop graph
      Usage: graph-drop [options]
        Options:
        * --confirm-message, -c
            Confirm message of graph clear is "I'm sure to drop the graph". 
            (Note: include "")

    graph-mode-set      Set graph mode
      Usage: graph-mode-set [options]
        Options:
        * --graph-mode, -m
            Graph mode, include: [NONE, RESTORING, MERGING]
            Possible Values: [NONE, RESTORING, MERGING, LOADING]

    graph-mode-get      Get graph mode
      Usage: graph-mode-get

    task-list      List tasks
      Usage: task-list [options]
        Options:
          --limit
            Limit number, no limit if not provided
            Default: -1
          --status
            Status of task

    task-get      Get task info
      Usage: task-get [options]
        Options:
        * --task-id
            Task id
            Default: 0

    task-delete      Delete task
      Usage: task-delete [options]
        Options:
        * --task-id
            Task id
            Default: 0

    task-cancel      Cancel task
      Usage: task-cancel [options]
        Options:
        * --task-id
            Task id
            Default: 0

    task-clear      Clear completed tasks
      Usage: task-clear [options]
        Options:
          --force
            Force to clear all tasks, cancel all uncompleted tasks firstly, 
            and delete all completed tasks
            Default: false

    gremlin-execute      Execute Gremlin statements
      Usage: gremlin-execute [options]
        Options:
          --aliases, -a
            Gremlin aliases, valid format is: 'key1=value1,key2=value2...'
            Default: {}
          --bindings, -b
            Gremlin bindings, valid format is: 'key1=value1,key2=value2...'
            Default: {}
          --file, -f
            Gremlin Script file to be executed, UTF-8 encoded, exclusive to 
            --script 
          --language, -l
            Gremlin script language
            Default: gremlin-groovy
          --script, -s
            Gremlin script to be executed, exclusive to --file

    gremlin-schedule      Execute Gremlin statements as asynchronous job
      Usage: gremlin-schedule [options]
        Options:
          --bindings, -b
            Gremlin bindings, valid format is: 'key1=value1,key2=value2...'
            Default: {}
          --file, -f
            Gremlin Script file to be executed, UTF-8 encoded, exclusive to 
            --script 
          --language, -l
            Gremlin script language
            Default: gremlin-groovy
          --script, -s
            Gremlin script to be executed, exclusive to --file

    backup      Backup graph schema/data. If directory is on HDFS, use -D to 
            set HDFS params. For example: 
            -Dfs.default.name=hdfs://localhost:9000 
      Usage: backup [options]
        Options:
          --all-properties
            All properties to be backup flag
            Default: false
          --compress
            compress flag
            Default: true
          --directory, -d
            Directory of graph schema/data, default is './{graphname}' in 
            local file system or '{fs.default.name}/{graphname}' in HDFS
          --format
            File format, valid is [json, text]
            Default: json
          --huge-types, -t
            Type of schema/data. Concat with ',' if more than one. Other types 
            include 'all' and 'schema'. 'all' means all vertices, edges and 
            schema. In other words, 'all' equals with 'vertex, edge, 
            vertex_label, edge_label, property_key, index_label'. 'schema' 
            equals with 'vertex_label, edge_label, property_key, index_label'.
            Default: [PROPERTY_KEY, VERTEX_LABEL, EDGE_LABEL, INDEX_LABEL, VERTEX, EDGE]
          --label
            Vertex label or edge label, only valid when type is vertex or edge
          --log, -l
            Directory of log
            Default: ./logs
          --properties
            Vertex or edge properties to backup, only valid when type is 
            vertex or edge
            Default: []
          --retry
            Retry times, default is 3
            Default: 3
          --split-size, -s
            Split size of shard
            Default: 1048576
          --thread-num, -T
            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
            2)) 
            Default: 0
          -D
            HDFS config parameters
            Syntax: -Dkey=value
            Default: {}

    schedule-backup      Schedule backup task
      Usage: schedule-backup [options]
        Options:
          --backup-num
            The number of latest backups to keep
            Default: 3
        * --directory, -d
            The directory of backups stored
          --interval
            The interval of backup, format is: "a b c d e". 'a' means minute 
            (0 - 59), 'b' means hour (0 - 23), 'c' means day of month (1 - 
            31), 'd' means month (1 - 12), 'e' means day of week (0 - 6) 
            (Sunday=0), "*" means all
            Default: "0 0 * * *"

    dump      Dump graph to files
      Usage: dump [options]
        Options:
          --directory, -d
            Directory of graph schema/data, default is './{graphname}' in 
            local file system or '{fs.default.name}/{graphname}' in HDFS
          --formatter, -f
            Formatter to customize format of vertex/edge
            Default: JsonFormatter
          --log, -l
            Directory of log
            Default: ./logs
          --retry
            Retry times, default is 3
            Default: 3
          --split-size, -s
            Split size of shard
            Default: 1048576
          --thread-num, -T
            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
            2)) 
            Default: 0
          -D
            HDFS config parameters
            Syntax: -Dkey=value
            Default: {}

    restore      Restore graph schema/data. If directory is on HDFS, use -D to 
            set HDFS params if needed. For 
            example:-Dfs.default.name=hdfs://localhost:9000 
      Usage: restore [options]
        Options:
          --clean
            Whether to remove the directory of graph data after restored
            Default: false
          --directory, -d
            Directory of graph schema/data, default is './{graphname}' in 
            local file system or '{fs.default.name}/{graphname}' in HDFS
          --huge-types, -t
            Type of schema/data. Concat with ',' if more than one. Other types 
            include 'all' and 'schema'. 'all' means all vertices, edges and 
            schema. In other words, 'all' equals with 'vertex, edge, 
            vertex_label, edge_label, property_key, index_label'. 'schema' 
            equals with 'vertex_label, edge_label, property_key, index_label'.
            Default: [PROPERTY_KEY, VERTEX_LABEL, EDGE_LABEL, INDEX_LABEL, VERTEX, EDGE]
          --log, -l
            Directory of log
            Default: ./logs
          --retry
            Retry times, default is 3
            Default: 3
          --thread-num, -T
            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
            2)) 
            Default: 0
          -D
            HDFS config parameters
            Syntax: -Dkey=value
            Default: {}

    migrate      Migrate graph
      Usage: migrate [options]
        Options:
          --directory, -d
            Directory of graph schema/data, default is './{graphname}' in 
            local file system or '{fs.default.name}/{graphname}' in HDFS
          --graph-mode, -m
            Mode used when migrating to target graph, include: [RESTORING, 
            MERGING] 
            Default: RESTORING
            Possible Values: [NONE, RESTORING, MERGING, LOADING]
          --huge-types, -t
            Type of schema/data. Concat with ',' if more than one. Other types 
            include 'all' and 'schema'. 'all' means all vertices, edges and 
            schema. In other words, 'all' equals with 'vertex, edge, 
            vertex_label, edge_label, property_key, index_label'. 'schema' 
            equals with 'vertex_label, edge_label, property_key, index_label'.
            Default: [PROPERTY_KEY, VERTEX_LABEL, EDGE_LABEL, INDEX_LABEL, VERTEX, EDGE]
          --keep-local-data
            Whether to keep the local directory of graph data after restored
            Default: false
          --log, -l
            Directory of log
            Default: ./logs
          --retry
            Retry times, default is 3
            Default: 3
          --split-size, -s
            Split size of shard
            Default: 1048576
          --target-graph
            The name of target graph to migrate
            Default: hugegraph
          --target-password
            The password of target graph to migrate
          --target-timeout
            The timeout to connect target graph to migrate
            Default: 0
          --target-trust-store-file
            The trust store file of target graph to migrate
          --target-trust-store-password
            The trust store password of target graph to migrate
          --target-url
            The url of target graph to migrate
            Default: http://127.0.0.1:8081
          --target-user
            The username of target graph to migrate
          --thread-num, -T
            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
            2)) 
            Default: 0
          -D
            HDFS config parameters
            Syntax: -Dkey=value
            Default: {}

    deploy      Install HugeGraph-Server and HugeGraph-Studio
      Usage: deploy [options]
        Options:
        * -p
            Install path of HugeGraph-Server and HugeGraph-Studio
          -u
            Download url prefix path of HugeGraph-Server and HugeGraph-Studio
        * -v
            Version of HugeGraph-Server and HugeGraph-Studio

    start-all      Start HugeGraph-Server and HugeGraph-Studio
      Usage: start-all [options]
        Options:
        * -p
            Install path of HugeGraph-Server and HugeGraph-Studio
        * -v
            Version of HugeGraph-Server and HugeGraph-Studio

    clear      Clear HugeGraph-Server and HugeGraph-Studio
      Usage: clear [options]
        Options:
        * -p
            Install path of HugeGraph-Server and HugeGraph-Studio

    stop-all      Stop HugeGraph-Server and HugeGraph-Studio
      Usage: stop-all

    auth-backup      null
      Usage: auth-backup [options]
        Options:
          --directory
            Directory of auth information, default is 
            './{auth-backup-restore}' in local file system or 
            '{fs.default.name}/{auth-backup-restore}' in HDFS
          --retry
            Retry times, default is 3
            Default: 3
          --types, -t
            Type of auth data to restore and backup, concat with ',' if more 
            than one. 'all' means all auth information. In other words, 'all' 
            equals with 'user, group, target, belong, access'. In addition, 
            'belong' or 'access' can not backup or restore alone, if type 
            contains 'belong' then should contains 'user' and 'group'. If type 
            contains 'access' then should contains 'group' and 'target'.
            Default: [TARGET, GROUP, USER, ACCESS, BELONG]
          -D
            HDFS config parameters
            Syntax: -Dkey=value
            Default: {}

    auth-restore      null
      Usage: auth-restore [options]
        Options:
          --directory
            Directory of auth information, default is 
            './{auth-backup-restore}' in local file system or 
            '{fs.default.name}/{auth-backup-restore}' in HDFS
          --init-password
            Init user password, if restore type include 'user', please specify 
            the init-password of users.
            Default: <empty string>
          --retry
            Retry times, default is 3
            Default: 3
          --strategy
            The strategy needs to be chosen in the event of a conflict when 
            restoring. Valid strategies include 'stop' and 'ignore', default 
            is 'stop'. 'stop' means if there a conflict, stop restore. 
            'ignore' means if there a conflict, ignore and continue to 
            restore. 
            Default: STOP
            Possible Values: [STOP, IGNORE]
          --types, -t
            Type of auth data to restore and backup, concat with ',' if more 
            than one. 'all' means all auth information. In other words, 'all' 
            equals with 'user, group, target, belong, access'. In addition, 
            'belong' or 'access' can not backup or restore alone, if type 
            contains 'belong' then should contains 'user' and 'group'. If type 
            contains 'access' then should contains 'group' and 'target'.
            Default: [TARGET, GROUP, USER, ACCESS, BELONG]
          -D
            HDFS config parameters
            Syntax: -Dkey=value
            Default: {}

    help      Print usage
      Usage: help
3.10 具体命令示例
1. gremlin语句
# 同步执行gremlin
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph gremlin-execute --script 'g.V().count()'

# 异步执行gremlin
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph gremlin-schedule --script 'g.V().count()'
2. 查看task情况
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph task-list

./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph task-list --limit 5

./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph task-list --status success
3. 图模式查看和设置
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-set -m RESTORING

./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-get

./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-list
4. 清理图
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-clear -c "I'm sure to delete all data"
5. 图备份
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph backup -t all --directory ./backup-test
6. 周期性的备份
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph schedule-backup -d ./backup --interval "*/2 * * * *"
7. 图恢复
# 设置图模式
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-set -m RESTORING

# 恢复图
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph restore -t all --directory ./backup-test

# 恢复图模式
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-set -m NONE
8. 图迁移
./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph migrate --target-url http://127.0.0.1:8090 --target-graph hugegraph

2.6 - 图导出/迁移

需要备份、导出或在两张图之间迁移数据时,从这里选择工具。Tools 适合单机运维和备份;SeaTunnel Source 适合把图数据接入可扩展的数据管道。

2.6.1 - 使用 SeaTunnel Source 导出与迁移图数据

如果你需要把数据从一张 HugeGraph 图复制到另一张图,使用 graph2graph:HugeGraph Source 从源图(A 图)读取顶点和边,数据经过可选的 Transform 后,由 HugeGraph Sink 写入目标图(B 图)。数据方向是 A 图 → HugeGraph Source →(可选 Transform)→ HugeGraph Sink → B 图。如果要把图数据导出到文件、JDBC、Kafka 等其他系统,则使用 graph2any,由下游 Sink 接收 Source 读取的数据。本文介绍这两类任务。

版本要求:本文面向 SeaTunnel 3.0+

开始前请先完成导入页中的通用环境准备和配置,其中包含 JDK、HOCON、插件安装和图模型说明。

1 迁移 HugeGraph 图(graph2graph)

下面从源图迁移 person 顶点和 knows 边。请使用独立的目标图:本节采用 CUSTOMIZE_STRING 保留顶点 ID,不要复用前面已经创建为 PRIMARY_KEYperson 标签。

这两个任务只迁移指定标签和属性,不会完整复制源图的索引、TTL 等全部 Schema 配置。运行期间应暂停源图写入,避免两个任务读到不同时间的数据;完成后核对顶点、边数量及抽样属性。

跨图迁移时重建主键可能改变顶点 ID;使用 CUSTOMIZE_STRING 保留原 ID,确保边端点匹配

1.1 先迁移顶点

Source 自动补充 ~id 保留列,Sink 把原 ID 作为字符串保存。无需在 schema.fields 中声明 ~id,手动声明保留列会被拒绝。

展开配置,保存为 config/graph2graph-person.conf
env {
  job.mode = "BATCH"
}

source {
  HugeGraph {
    host = "source-hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    label = "person"
    label_type = "VERTEX"
    schema = {
      fields = {
        name = "string"
        age = "int"
      }
    }
  }
}

sink {
  HugeGraph {
    host = "target-hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    batch_failure_fallback = false
    mappings = [
      {
        type = "VERTEX"
        label = "person"
        idStrategy = "CUSTOMIZE_STRING"
        idFields = ["~id"]
        properties = ["name", "age"]
      }
    ]
  }
}
./bin/seatunnel.sh --config ./config/graph2graph-person.conf -m local

1.2 再迁移边

确认顶点任务成功后,使用 Source 自动补充的 ~source_id~target_id 定位端点。因为上一任务保留了原 ID,这两列可以直接引用目标图中的顶点。

展开配置,保存为 config/graph2graph-knows.conf
env {
  job.mode = "BATCH"
}

source {
  HugeGraph {
    host = "source-hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    label = "knows"
    label_type = "EDGE"
    schema = {
      fields = {
        since = "int"
      }
    }
  }
}

sink {
  HugeGraph {
    host = "target-hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    check_vertex = true
    batch_failure_fallback = false
    mappings = [
      {
        type = "EDGE"
        label = "knows"
        sourceConfig = {
          label = "person"
          idFields = ["~source_id"]
        }
        targetConfig = {
          label = "person"
          idFields = ["~target_id"]
        }
        properties = ["since"]
      }
    ]
  }
}
./bin/seatunnel.sh --config ./config/graph2graph-knows.conf -m local

本例打开端点检查,并让写入错误直接导致任务失败。默认的 check_vertex = false 不保证最终一致:缺少端点可能产生悬空边,因此不能用任务成功代替迁移结果检查。

为什么保留 ID? HugeGraph 的 PRIMARY_KEY ID 包含顶点标签的内部 ID,两张图可能不同。例如源图顶点是 1:marko,目标图重新按主键生成的可能是 2:marko。如果重新生成顶点 ID 后仍复用源图的边端点,边就会连错。本例将原 ID 保存为字符串,因此会改变目标图的 ID 策略

若要一次读取全部标签,省略 Source 的 label 后会读取 label_type(默认 VERTEX)下的全部 label,每个 label 输出一张表。这时需用 sourceTable 将各 Sink 映射绑定到对应表,例如 sourceTable = "default.person";具体值以 Writer 日志中的完整表名为准。不能直接套用本节的单标签配置。其他限制见 HugeGraph Source 文档

2 导出到其他系统(graph2any)

graph2any 使用 HugeGraph Source[1] 读取顶点或边,再交给下游 Sink。下面示例将 person 顶点导出为本地 JSON 文件;导出到 JDBC、Kafka 等系统时,替换 LocalFile[2] 及其配置即可。

env {
  job.mode = "BATCH"
}

source {
  HugeGraph {
    host = "hugegraph"
    port = 8080
    graph_name = "hugegraph"
    graph_space = "DEFAULT"
    label = "person"
    label_type = "VERTEX"
    schema = {
      fields = {
        name = "string"
        age = "int"
      }
    }
  }
}

sink {
  LocalFile {
    path = "/tmp/hugegraph-export/${table_name}"
    file_format_type = "json"
  }
}

保存为 config/graph2file-person.conf,在 SeaTunnel 安装目录执行:

./bin/seatunnel.sh --config ./config/graph2file-person.conf -m local

导出边时,将 Source 的 label 改为边标签、label_type 改为 EDGE,并在 schema.fields 中声明边属性。Source 会额外输出 ~source_id~source_label~target_id~target_label,这些保留列可直接写入文件或交给下游转换步骤。

本页只介绍数据行的读取和写出,不会自动复制源图的索引、TTL 或其他 Schema 设置。完整 Source 参数和通用环境说明请回到SeaTunnel 图导入文档[3]

3 参考文档

连接器

[1] HugeGraph Source
[2] LocalFile Sink

关联文档

[3] SeaTunnel 图导入文档

2.7 - HugeGraph-Spark-Connector Quick Start

1 HugeGraph-Spark-Connector 概述

HugeGraph-Spark-Connector 使用 Spark DataFrame API 将批量数据写入 HugeGraph。当前实现提供顶点和边的写入器。

目前尚未实现从 HugeGraph 读取数据:表只实现了 SupportsWrite,因此不支持 spark.read.format(...)。连接器支持 CUSTOMIZEPRIMARY_KEY 两种顶点 id 策略,AUTOMATIC 策略会被拒绝。

2 环境要求

  • Java 8+
  • Maven 3.6+
  • Spark 3.2.x(模块基于 Spark 3.2.2 编译,依赖范围为 provided,因此需要由 Spark 运行环境提供 Spark 的 jar)
  • Scala 2.12(基于 Scala 2.12.11 编译)

3 编译

3.1 不执行测试的编译

以下命令均在仓库根目录执行。

git clone https://github.com/apache/hugegraph-toolchain.git
cd hugegraph-toolchain
mvn clean package -pl hugegraph-spark-connector -am -DskipTests -ntp

3.2 执行默认测试的编译

mvn clean package -pl hugegraph-spark-connector -am -ntp

两条命令都会在 hugegraph-spark-connector/target/hugegraph-spark-connector-${revision}-jar-with-dependencies.jar 生成一个包含依赖的 jar(不包含 Spark 本身)。如果不通过 Maven 管理依赖,可以把它传给 spark-submit --jars

4 使用方法

先在 pom.xml 中添加依赖,并将 ${revision} 换成实际使用的发布版本:

<dependency>
    <groupId>org.apache.hugegraph</groupId>
    <artifactId>hugegraph-spark-connector</artifactId>
    <version>${revision}</version>
</dependency>

format 必须写完整类名 org.apache.hugegraph.spark.connector.DataSource,连接器没有通过 Spark 的 DataSourceRegister 服务注册短名称。当 HugeGraphServer 开启鉴权时,需要在下面的示例中加上 .option("username", ...).option("token", ...)

4.1 Schema 定义示例

假设我们有一个图,其 schema 定义如下:

schema.propertyKey("name").asText().ifNotExist().create()
schema.propertyKey("age").asInt().ifNotExist().create()
schema.propertyKey("city").asText().ifNotExist().create()
schema.propertyKey("weight").asDouble().ifNotExist().create()
schema.propertyKey("lang").asText().ifNotExist().create()
schema.propertyKey("date").asText().ifNotExist().create()
schema.propertyKey("price").asDouble().ifNotExist().create()

schema.vertexLabel("person")
        .properties("name", "age", "city")
        .useCustomizeStringId()
        .nullableKeys("age", "city")
        .ifNotExist()
        .create()

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

schema.edgeLabel("knows")
        .sourceLabel("person")
        .targetLabel("person")
        .properties("date", "weight")
        .ifNotExist()
        .create()

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

4.2 写入顶点数据(Scala)

val df = sparkSession.createDataFrame(Seq(
  Tuple3("marko", 29, "Beijing"),
  Tuple3("vadas", 27, "HongKong"),
  Tuple3("Josh", 32, "Beijing"),
  Tuple3("peter", 35, "ShangHai"),
  Tuple3("li,nary", 26, "Wu,han"),
  Tuple3("Bob", 18, "HangZhou"),
)) toDF("name", "age", "city")

df.show()

df.write
  .format("org.apache.hugegraph.spark.connector.DataSource")
  .option("host", "127.0.0.1")
  .option("port", "8080")
  .option("graph", "hugegraph")
  .option("data-type", "vertex")
  .option("label", "person")
  .option("id", "name")
  .option("batch-size", 2)
  .mode(SaveMode.Overwrite)
  .save()

4.3 写入边数据(Scala)

val df = sparkSession.createDataFrame(Seq(
  Tuple4("marko", "vadas", "20160110", 0.5),
  Tuple4("peter", "Josh", "20230801", 1.0),
  Tuple4("peter", "li,nary", "20130220", 2.0)
)).toDF("source", "target", "date", "weight")

df.show()

df.write
  .format("org.apache.hugegraph.spark.connector.DataSource")
  .option("host", "127.0.0.1")
  .option("port", "8080")
  .option("graph", "hugegraph")
  .option("data-type", "edge")
  .option("label", "knows")
  .option("source-name", "source")
  .option("target-name", "target")
  .option("batch-size", 2)
  .mode(SaveMode.Overwrite)
  .save()

4.4 写入 PRIMARY_KEY id 策略的顶点(Scala)

对于使用 primaryKeys(...) 的顶点标签,不要设置 id 选项:id 由主键列拼接生成。不属于 schema 的列可以通过 ignored-fields 丢弃。

val df = sparkSession.createDataFrame(Seq(
  Tuple4("lop", "java", 328L, "ISBN978-7-107-18618-5"),
  Tuple4("ripple", "python", 199L, "ISBN978-7-100-13678-5"),
)).toDF("name", "lang", "price", "ISBN")

df.write
  .format("org.apache.hugegraph.spark.connector.DataSource")
  .option("host", "127.0.0.1")
  .option("port", "8080")
  .option("graph", "hugegraph")
  .option("data-type", "vertex")
  .option("label", "software")
  .option("ignored-fields", "ISBN")
  .option("batch-size", 2)
  .mode(SaveMode.Overwrite)
  .save()

4.5 写入两端 id 策略不同的边(Scala)

source-nametarget-name 各自遵循对应顶点标签的 id 策略。下面的例子中,person 使用自定义字符串 id(一列),software 使用主键(其 name 列):

val df = sparkSession.createDataFrame(Seq(
  Tuple4("marko", "lop", "20171210", 0.5),
  Tuple4("Josh", "lop", "20091111", 0.4),
  Tuple4("peter", "ripple", "20171210", 1.0),
  Tuple4("vadas", "lop", "20171210", 0.2)
)).toDF("source", "name", "date", "weight")

df.write
  .format("org.apache.hugegraph.spark.connector.DataSource")
  .option("host", "127.0.0.1")
  .option("port", "8080")
  .option("graph", "hugegraph")
  .option("data-type", "edge")
  .option("label", "created")
  .option("source-name", "source") // 自定义 id
  .option("target-name", "name")   // 主键
  .option("batch-size", 2)
  .mode(SaveMode.Overwrite)
  .save()

关于保存模式:SaveMode.OverwriteSaveMode.Append 都只是插入数据,overwrite 路径不会先删除图中已有的数据。

5 配置参数

选项名匹配时不区分大小写并会去掉首尾空格。data-typelabel 必填;当 data-typeedgesource-nametarget-name 必填;其余选项都有默认值。

5.1 客户端配置

客户端配置用于配置 hugegraph-client。

参数默认值说明
hostlocalhostHugeGraphServer 的地址,可以是主机名或 IP,也可以带 http:// / https:// 前缀
port8080HugeGraphServer 的端口
graphhugegraph图名称
protocolhttp向服务器发送请求的协议,可选 httphttps
usernamenull当 HugeGraphServer 开启权限认证时,当前图的用户名。未设置时使用图名称作为用户名
tokennull当 HugeGraphServer 开启权限认证时,当前图的 token
timeout60插入结果返回的超时时间(秒)
max-connCPUS * 4HugeClient 与 HugeGraphServer 之间的最大 HTTP 连接数
max-conn-per-routeCPUS * 2HugeClient 与 HugeGraphServer 之间每个路由的最大 HTTP 连接数
trust-store-filenull当请求协议为 https 时,客户端的证书文件路径。https 下未设置时,连接器会读取 JVM 系统属性 connector.home.path 指向目录下的 conf/hugegraph.truststore,此时该属性必须设置
trust-store-tokennull当请求协议为 https 时,客户端的证书密码。https 下未设置时使用 hugegraph

5.2 图数据配置

图数据配置用于说明 DataFrame 如何映射到顶点或边。

参数默认值说明
data-type必填。图数据类型,必须是 vertexedge
label必填。要导入的顶点/边数据所属的标签
id指定某一列作为顶点的 id 列。当顶点 id 策略为 CUSTOMIZE 时,必填;当 id 策略为 PRIMARY_KEY 时,必须为空。不支持 AUTOMATIC id 策略
source-namedata-typeedge 时必填。选择输入源的某些列作为源顶点的 id 列。当源顶点的 id 策略为 CUSTOMIZE 时,必须指定某一列作为顶点的 id 列;当源顶点的 id 策略为 PRIMARY_KEY 时,必须指定一列或多列用于拼接生成顶点的 id,即无论使用哪种 id 策略,此项都是必填的。多列之间用 , 分隔(delimiter 选项对此项不生效)
target-namedata-typeedge 时必填。指定某些列作为目标顶点的 id 列,与 source-name 类似
selected-fields选择某些列进行插入,其他未选择的列不插入,不能与 ignored-fields 同时存在
ignored-fields忽略某些列使其不参与插入,不能与 selected-fields 同时存在
batch-size500导入数据时每批数据的条目数。按 Spark task 生效:每个分区的写入器在缓冲区累积到该数量的顶点/边时向服务端提交一次,commit 时再提交剩余部分

5.3 通用配置

通用配置包含一些常用的配置项。

参数默认值说明
delimiter,selected-fieldsignored-fields 的分隔符。source-nametarget-name 始终按 , 拆分

6 注意事项与限制

  • 每个 Spark 写入 task 会创建自己的 HugeClient,写入前把图切换到 LOADING 模式,commit 或 abort 时恢复为 NONE 模式。
  • 顶点 id 长度限制为 128 字节(UTF-8),对自定义字符串 id 和由主键拼接出的 id 都生效。
  • 不支持 AUTOMATIC 顶点 id 策略,创建写入器时会抛出 IllegalArgumentException,写入失败。
  • 暂不支持 SETLIST 基数的属性,只会转换 SINGLE 基数的值。
  • 日期属性:字符串值必须使用 yyyy-MM-dd HH:mm:ss 格式,按 GMT+8 时区解析;数值会被当作毫秒时间戳。
  • 以字符串形式给出的布尔属性接受 true1yesyfalse0non(不区分大小写)。
  • 自定义字符串 id 或任一主键值为空字符串的行会被跳过;为 null 时则会报错。

7 许可证

与 HugeGraph 一样,hugegraph-spark-connector 也采用 Apache 2.0 许可证。

3 - HugeGraph-AI

hugegraph-ai 提供 HugeGraph 的 Python 客户端、图机器学习工具,以及面向知识图谱构建和 GraphRAG 的 LLM 工具。

Apache License 2.0 · Ask DeepWiki

模块

仓库使用 uv workspace,其成员是 hugegraph-llmhugegraph-python-clienthugegraph-mlvermeer-python-client 是可编辑的路径依赖,不在 workspace members 中。当前仓库版本为 1.7.0

环境要求

  • HugeGraph-LLM:Python 3.10 或 3.11(>=3.10,<3.12
  • HugeGraph-ML:Python 3.10 或更高版本
  • HugeGraph Python 客户端、Vermeer Python 客户端:Python 3.9 或更高版本
  • uv 0.7 或更高版本
  • HugeGraph Server 1.3 或更高版本(推荐 1.5 或更高版本)

可选依赖组

根项目为每个模块声明一个 extra,另有几个组合项:

Extra安装内容
llmhugegraph-llm
mlhugegraph-ml
python-clienthugegraph-python-client
vermeervermeer-python-client
devpytest、pytest-cov、coverage、pylint、ruff、mypy、ty、pre-commit
nk-llmhugegraph-llmhugegraph-python-client,以及编译镜像所需的 Nuitka
all四个模块包

hugegraph-llm 自身还声明了 vectordb extra,用于安装 pymilvusqdrant-client

Docker Compose 部署

仓库提供同时启动 HugeGraph Server 和 RAG 服务的 Compose 文件:

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
cp docker/env.template docker/.env
# 编辑 docker/.env,将 PROJECT_PATH 改为当前仓库的绝对路径
touch hugegraph-llm/.env
cd docker
docker compose -f docker-compose-network.yml up -d

默认地址:

  • HugeGraph Server:http://localhost:8080
  • RAG 服务和 Web 界面:http://localhost:8001

从源码启动 RAG 服务

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
uv sync --extra llm
source .venv/bin/activate
cd hugegraph-llm
python -m hugegraph_llm.demo.rag_demo.app

uv sync 会创建根目录下的 .venv。不要在 hugegraph-llm 子目录另建一套环境,否则容易绕过 workspace 锁定的依赖。

安装 ML 依赖

cd hugegraph-ai
uv sync --extra ml
source .venv/bin/activate
cd hugegraph-ml/src

示例脚本位于 hugegraph-ml/src/hugegraph_ml/examples/

后续阅读

3.1 - HugeGraph-LLM

HugeGraph-LLM 用于知识图谱构建、GraphRAG 和自然语言图查询。演示服务把 Gradio 页面和 FastAPI 接口挂在同一个进程上,默认监听 8001 端口。

环境要求

AI 总结项目文档:Ask DeepWiki

  • Python 3.10 或 3.11(>=3.10,<3.12
  • uv 0.7 或更高版本
  • HugeGraph Server 1.3 或更高版本(推荐 1.5 或更高版本)

Docker Compose 部署

在 HugeGraph-AI 仓库根目录准备环境文件:

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
cp docker/env.template docker/.env
# 编辑 docker/.env,将 PROJECT_PATH 改为当前仓库的绝对路径
touch hugegraph-llm/.env
cd docker
docker compose -f docker-compose-network.yml up -d
docker compose -f docker-compose-network.yml ps

启动后可访问:

  • HugeGraph Server:http://localhost:8080
  • RAG 服务和 Web 页面:http://localhost:8001

Compose 文件会把 ${PROJECT_PATH}/hugegraph-llm/.env 挂载到容器内的 /home/work/hugegraph-llm/.env,因此该文件必须在容器启动前存在。资源目录 hugegraph-llm/src/hugegraph_llm/resources 也可以用同样方式挂载,该挂载默认被注释掉。

容器镜像

镜像构建文件内容
hugegraph/ragdocker/Dockerfile.llm包含源码的 Python 3.10 运行环境,入口是 python -m hugegraph_llm.demo.rag_demo.app --host 0.0.0.0 --port 8001
hugegraph/rag-bindocker/Dockerfile.nk基于 nk-llm extra 用 Nuitka 编译的二进制,入口是 ./app.dist/app.bin

两个镜像都暴露 8001 端口,以非 root 用户 work 运行,为 hugegraph-llm/src/hugegraph_llm/resources 声明数据卷,并使用 curl -f http://localhost:8001/ 作为健康检查。

scripts/build_llm_image.sh 会用 docker/Dockerfile.llm 构建并打上 hugegraph/graphrag:1.7.0 标签。

Kubernetes 部署

docker/charts/hg-llm 是 RAG 服务的 Helm chart,部署 hugegraph/graphrag 镜像。默认发布 NodePort 类型的 Service,把节点端口 8039 和服务端口 8080 映射到容器端口 8001,名称固定为 hg-llm-service。Ingress 和水平自动扩缩容已定义但默认关闭。

chart 中 image.tag 仍默认为 v0.0.1,因此需要通过 --set image.tag=1.7.0 或修改 values.yaml 指向实际构建的标签。

chart 的 values.yaml 中,.env 和提示词 YAML 的挂载默认被注释掉。要使用自定义配置,先创建两个 ConfigMap,再取消对应 volumesvolumeMounts 段落的注释:

kubectl create configmap hugegraph-llm-env --from-file=/path/to/.env
kubectl create configmap hugegraph-llm-prompt-config --from-file=/path/to/config_prompt.yaml

从源码启动

依赖应从仓库根目录按 workspace 安装:

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
uv sync --extra llm
source .venv/bin/activate
cd hugegraph-llm
python -m hugegraph_llm.demo.rag_demo.app

自定义监听地址和端口:

python -m hugegraph_llm.demo.rag_demo.app \
  --host 127.0.0.1 \
  --port 18001

设置 HG_DEV_RELOAD=1 可让 uvicorn 以自动重载方式启动,便于开发调试。

服务以 hugegraph-llm/.env 保存模型、HugeGraph 和登录配置。提示词放在 hugegraph-llm/src/hugegraph_llm/resources/demo/config_prompt.yaml。缺少文件时,配置代码会按默认值创建。

.env 路径按以下顺序解析:先看是否设置了 HUGEGRAPH_LLM_ENV_PATH;未设置时,从源码运行则使用 hugegraph-llm/.env;否则使用当前工作目录下的 .env

主要功能

构建 RAG 索引

Web 页面的第一个标签页可以处理文本或文件,并执行以下操作:

  1. 切分文本并写入 chunk 向量索引。
  2. 按给定 Schema 从文本抽取顶点和边。
  3. 将抽取结果写入 HugeGraph,并更新顶点向量索引。

文本可以在 text 子页直接输入,也可以在 file 子页上传。上传支持 .txt.docx.pdf,并可一次选择多个文件。加密 PDF 以及没有可提取文本层的扫描件 PDF 会被拒绝。

Schema 可以是内联 JSON,也可以是现有图名。通过 REST API 使用图名时,必须同时传入匹配的 client_config.graph;内联 JSON 不会连接 HugeGraph,也不能附带 client_config

该标签页还提供两个生成器。Graph Schema Generator 根据查询示例和少样本示例生成 Schema。Graph Extraction Prompt Generator 根据描述的场景和选定的参考示例生成抽取提示词。Graph Extraction Split Type 下拉框可在抽取前选择 documentparagraphsentence 粒度。

GraphRAG

查询流程可以组合直接回答、chunk 向量召回和图召回。图召回先抽取关键词并匹配顶点,再尝试 Text2Gremlin;生成或执行失败时可回退到预定义的图遍历方式。请求参数可控制返回数量、向量距离阈值、模板数量和重排序方式。

同一标签页还有批量回归测试面板,可从 .xlsx.csv 文件读取问题、逐条作答,并返回可下载的结果文件。上传控件旁提供模板文件下载。

知识图谱构建器

Text2Gremlin

POST /text2gremlin 根据自然语言、图 Schema 和可选示例生成 Gremlin。自定义提示词必须保留 {query}{schema}{example}{vertices} 四个占位符。

对应的页面标签可以先用问题与 Gremlin 对照文件(.json.csv)构建示例向量索引。未上传文件时使用内置的 resources/demo/text2gremlin.csv

图工具与管理工具

Graph Tools 标签页可直接执行 Gremlin 查询、手动触发图备份,以及初始化 HugeGraph 演示数据。Admin Tools 标签页在校验 ADMIN_TOKEN 后展示 logs/llm-server.log 的末尾内容,并可刷新或清空该文件。

进程运行期间还有两个后台任务:每天 01:00 执行图备份的定时任务,以及持续更新顶点 id 向量的任务。

模型与向量后端

聊天、信息抽取和 Text2Gremlin 可以分别使用 OpenAI 兼容接口、Ollama 或 LiteLLM。嵌入模型可独立选择,同样支持这三种提供方。重排序支持 Cohere 和 SiliconFlow。

默认向量索引使用 FAISS。CUR_VECTOR_INDEX 可选 FaissMilvusQdrant,Web 页面的 5. Set up the vector engine. 面板提供同样的选择。Milvus 和 Qdrant 需要安装可选依赖:

cd hugegraph-ai
uv sync --package hugegraph-llm --extra vectordb

页面操作流程见使用流程,完整环境变量见配置参考,HTTP 请求格式见REST API

程序化调用

原有的 RAGPipelineKgBuilder 类已被流水线调度器取代。通过 SchedulerSingleton 按名称调用流程:

from hugegraph_llm.flows.scheduler import SchedulerSingleton

scheduler = SchedulerSingleton.get_instance()
res = scheduler.schedule_flow(
    "rag_graph_only",
    query="Tell me about Al Pacino.",
    graph_only_answer=True,
    vector_only_answer=False,
    raw_answer=False,
    gremlin_tmpl_num=-1,
    gremlin_prompt=None,
)
print(res.get("graph_only_answer"))

已注册的流程名包括 rag_rawrag_vector_onlyrag_graph_onlyrag_graph_vectortext2gremlinbuild_examples_indexbuild_vector_indexgraph_extractimport_graph_dataupdate_vid_embeddingsget_graph_index_infobuild_schemaprompt_generateschedule_stream_flow 是对应的异步流式版本。

开发检查

先在仓库根目录安装模块和开发工具,再运行与 CI 一致的检查:

cd hugegraph-ai
uv sync --extra llm --extra dev
uv run ruff format --check .
uv run ruff check .

cd hugegraph-llm
SKIP_EXTERNAL_SERVICES=true uv run pytest src/tests/config/ src/tests/document/ src/tests/middleware/ \
  src/tests/operators/ src/tests/models/ src/tests/indices/ src/tests/test_utils.py -v --tb=short
SKIP_EXTERNAL_SERVICES=true uv run pytest src/tests/integration/test_graph_rag_pipeline.py \
  src/tests/integration/test_kg_construction.py src/tests/integration/test_rag_pipeline.py -v --tb=short

Git hook 通过 pre-commit 启用:

cd hugegraph-ai
pre-commit install
pre-commit run --all-files

3.2 - HugeGraph-ML

HugeGraph-ML 从 HugeGraph 读取图数据并转换为 DGL 图,供节点嵌入、节点分类、图分类、链接预测和欺诈检测等任务使用。模型实现位于 hugegraph-ml/src/hugegraph_ml/models/

环境要求

  • Python 3.10 或更高版本
  • HugeGraph Server 1.0 或更高版本,推荐 1.5 及以上版本
  • uv 0.7 或更高版本

所有服务端访问都通过同一仓库中的 hugegraph-python-client(即 pyhugegraph 包)完成。HugeGraph2DGL 使用 Gremlin 接口的 g.V().hasLabel(...)g.E().hasLabel(...) 拉取点边,数据集导入函数则通过 schema 接口和顶点、边的批量接口写入,每批 500 条。

ML 依赖在仓库根目录的 [tool.uv] constraint-dependencies 中固定版本:

依赖版本约束
torch==2.2.0
dgl~=2.1.0
ogb~=1.3.6
torchdata~=0.7.0
catboost~=1.2.3
category-encoders~=2.6.3
numpy~=1.24.4
pandas~=2.2.3

上述约束安装的是 CPU 版本。每个任务都有 gpu 参数,默认值 -1 表示使用 CPU;只有自行安装 CUDA 版的 torchdgl 之后,才可以传入设备编号。

安装

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
uv sync --extra ml
source .venv/bin/activate
cd hugegraph-ml/src

HugeGraph-ML 是根项目的路径依赖,但不属于 uv workspace members。应在仓库根目录选择 ml extra,不要在子目录建立另一套锁文件。

已实现模型

下列模块均位于 hugegraph-ml/src/hugegraph_ml/models/models/__init__.py 不做任何再导出,需要直接从模块文件导入。

模型模块入口类用途论文
AGNNagnn.pyAGNN节点分类1803.03735
APPNPappnp.pyAPPNP节点分类1810.05997
ARMAarma.pyARMA4NC节点分类1901.01343
BGNNbgnn.pyBGNNPredictor梯度提升与 GNN 结合处理节点特征,自带示例执行回归任务2101.08543
BGRLbgrl.pyBGRL自监督节点嵌入2102.06514
CARE-GNNcare_gnn.pyCAREGNN欺诈检测2008.08692
Cluster-GCNcluster_gcn.pySAGE基于子图采样的节点分类1905.07953
C&Scorrect_and_smooth.pyMLPCorrectAndSmoothLabelPropagation对基础预测结果做校正与平滑2010.13993
DAGNNdagnn.pyDAGNN节点分类2007.09296
DeeperGCNdeepergcn.pyDeeperGCN带边特征的节点分类2006.07739
DGIdgi.pyDGI自监督节点嵌入1809.10341
DiffPooldiffpool.pyDiffPool图分类1806.08804
GATNEgatne.pyDGLGATNE异构网络嵌入1905.01669
GINgin_global_pool.pyGIN图分类
GRACEgrace.pyGRACE自监督节点嵌入2006.04131
GRANDgrand.pyGRAND节点分类2005.11079
JKNetjknet.pyJKNet节点分类1806.03536
MLPmlp.pyMLPClassifier基于已学习嵌入的下游分类器
P-GNNpgnn.pyPGNN链接预测you19b
SEALseal.pyDGCNNSEALData链接预测1802.09691

GINpooling 参数可取 sum(默认)、meanmaxglobal_attentionset2set

读取图数据

hugegraph-ml/src/hugegraph_ml/data/hugegraph2dgl.py 中的 HugeGraph2DGL 会创建 PyHugeClient,并把查询结果转换为 DGL 对象:

from hugegraph_ml.data.hugegraph2dgl import HugeGraph2DGL

hg2d = HugeGraph2DGL(
    url="http://127.0.0.1:8080",
    graph="hugegraph",
    user="",
    pwd="",
    graphspace=None,
)
方法返回值说明
convert_graph(vertex_label, edge_label, feat_key="feat", label_key="label", mask_keys=None)dgl.DGLGraphmask_keys 为空时取 ["train_mask", "val_mask", "test_mask"]
convert_hetero_graph(vertex_labels, edge_labels, feat_key="feat", label_key="label", mask_keys=None)DGL 异构图参数为标签列表
convert_graph_dataset(graph_vertex_label, vertex_label, edge_label, feat_key="feat", label_key="label")HugeGraphDatasetinfo 中写入 n_graphsmax_n_nodesn_feat_dimn_classes
convert_graph_nx(vertex_label, edge_label)networkx.GraphP-GNN 使用
convert_graph_with_edge_feat(vertex_label, edge_label, node_feat_key="feat", edge_feat_key="edge_feat", label_key="label", mask_keys=None)dgl.DGLGraph同时填充 edata["feat"]
convert_graph_ogb(vertex_label, edge_label, split_label)(dgl.DGLGraph, split_edge)SEAL 使用
convert_hetero_graph_bgnn(vertex_labels, edge_labels, feat_key="feat", label_key="class", cat_key="cat_features", mask_keys=None)DGL 异构图BGNN 使用

节点特征写入 ndata["feat"],标签写入 ndata["label"],各掩码写入 ndata[<mask key>]NodeEmbed 只要求 featNodeClassifyNodeClassifyWithEdgeNodeClassifyWithSample 要求 featlabeltrain_maskval_masktest_mask,缺少任意一项都会抛出 ValueError

导入示例数据集

hugegraph_ml.utils.dgl2hugegraph_utils 负责把 DGL、OGB 和 NetworkX 数据集写入 HugeGraph,供转换层读取。这些函数都接受与 HugeGraph2DGL 相同的 urlgraphuserpwdgraphspace 参数,并且多数会先把数据集名转为大写再匹配。

函数支持的数据集创建的标签
import_graph_from_dglCORACITESEERPUBMED<NAME>_vertex<NAME>_edge
import_graphs_from_dglMUTAGCOLLABNCI1PROTEINSPTCENZYMESDD<NAME>_graph_vertex<NAME>_vertex<NAME>_edge
import_hetero_graph_from_dglACM<NAME>_<ntype>_v<NAME>_<etype>_e
import_hetero_graph_from_dgl_no_featAMAZONGATNE<NAME>_<ntype>_v<NAME>_<etype>_e
import_hetero_graph_from_dgl_bgnnAVAZU<NAME>_<ntype>_v<NAME>_<etype>_e
import_graph_from_nxCAVEMAN<NAME>_vertex<NAME>_edge
import_graph_from_dgl_with_edge_featCORACITESEERPUBMED<NAME>_edge_feat_vertex<NAME>_edge_feat_edge
import_graph_from_ogbogbl-collab,不做大写转换<NAME>_vertex<NAME>_edge
import_split_edge_from_ogbogbl-collab,不做大写转换<NAME>_split_edge

传入其他名称会抛出 ValueError("dataset not supported")import_split_edge_from_ogb 还需要顶点导入返回的 idx_to_vertex_id 映射和 max_nodes 上限。

clear_all_data() 会清空目标图中的全部点和边。测试 fixture 先调用它,再导入 CORAMUTAGACM,结束时再次调用。

AMAZONGATNEAVAZU 不会自动下载,压缩包地址写在 import_hetero_graph_from_dgl_no_featimport_hetero_graph_from_dgl_bgnn 上方的注释里。

任务

任务类位于 hugegraph-ml/src/hugegraph_ml/tasks/,均接收转换后的图和模型实例。

模块入口方法
NodeEmbednode_embed.pytrain_and_embed(add_self_loop=True, lr=1e-3, weight_decay=0, n_epochs=200, patience=inf, gpu=-1),返回 ndata["feat"] 被替换为嵌入结果的图
NodeClassifynode_classify.pytrain(lr, weight_decay, n_epochs, patience, early_stopping_monitor, gpu),再 evaluate() 返回 {"accuracy": ..., "loss": ...}
NodeClassifyWithEdgenode_classify_with_edge.py结构相同,适用于同时读取 edata["feat"] 的模型
NodeClassifyWithSamplenode_classify_with_sample.py基于 ClusterGCNSampler 分区的训练,仅使用 CPU,没有 gpu 参数
GraphClassifygraph_classify.pytrain(batch_size=20, lr, weight_decay, n_epochs, patience, early_stopping_monitor, clip=2.0, gpu),在 HugeGraphDataset 上按 70/20/10 划分
DetectorCaregnnfraud_detector_caregnn.pyCARE-GNN 训练,evaluate() 输出 recall 和 ROC AUC,并读取 ndata["feature"] 而非 ndata["feat"]
HeteroSampleEmbedGATNEhetero_sample_embed_gatne.pytrain_and_embed(lr=1e-3, n_epochs=200, gpu=-1)
LinkPredictionPGNNlink_prediction_pgnn.pytrain(lr, weight_decay, n_epochs, gpu)
LinkPredictionSeallink_prediction_seal.py构造函数内部已调用 data_prepare(),随后执行 train(lr=1e-3, n_epochs=200, gpu=-1)

patience 默认值为 float("inf")utils/early_stopping.py 中的 EarlyStopping 可以监控 lossaccuracy,保存最优权重并在训练结束时恢复。

可运行示例

脚本位于 hugegraph-ml/src/hugegraph_ml/examples/。在 hugegraph-ml/src 目录下执行:

python ./hugegraph_ml/examples/dgi_example.py

每个脚本同时提供同名函数,可以导入后用较小的 epoch 数调用。

脚本模型任务读取的标签
agnn_example.pyAGNNNodeClassifyCORA_vertexCORA_edge
appnp_example.pyAPPNPNodeClassifyCORA_vertexCORA_edge
arma_example.pyARMA4NCNodeClassifyCORA_vertexCORA_edge
bgnn_example.pyBGNNPredictor模型自带的 fit()AVAZU__N_vAVAZU__E_e
bgrl_example.pyBGRLNodeEmbedNodeClassifyCORA_vertexCORA_edge
care_gnn_example.pyCAREGNNDetectorCaregnnAMAZON_user_v 以及 AMAZON_net_upu_eAMAZON_net_usu_eAMAZON_net_uvu_e
cluster_gcn_example.pySAGENodeClassifyWithSampleCORA_vertexCORA_edge
correct_and_smooth_example.pycorrect_and_smooth 中的 MLPNodeClassifyCORA_vertexCORA_edge
dagnn_example.pyDAGNNNodeClassifyCORA_vertexCORA_edge
deepergcn_example.pyDeeperGCNNodeClassifyWithEdge通过 convert_graph_with_edge_feat 读取 CORA_vertexCORA_edge
dgi_example.pyDGINodeEmbedNodeClassifyCORA_vertexCORA_edge
diffpool_example.pyDiffPoolGraphClassifyMUTAG_graph_vertexMUTAG_vertexMUTAG_edge
gatne_example.pyDGLGATNEHeteroSampleEmbedGATNEAMAZONGATNE__N_vAMAZONGATNE_1_eAMAZONGATNE_2_e
gin_example.pyGINGraphClassifyMUTAG_graph_vertexMUTAG_vertexMUTAG_edge
grace_example.pyGRACENodeEmbedNodeClassifyCORA_vertexCORA_edge
grand_example.pyGRANDNodeClassifyCORA_vertexCORA_edge
jknet_example.pyJKNetNodeClassifyCORA_vertexCORA_edge
pgnn_example.pyPGNNLinkPredictionPGNNCAVEMAN_vertexCAVEMAN_edge
seal_example.pyDGCNNLinkPredictionSealogbl-collab_vertexogbl-collab_edgeogbl-collab_split_edge

DGI 节点嵌入示例

先把 DGL 的 Cora 数据集导入 HugeGraph。数据集名会先转为大写,因此 coraCORA 都会生成 CORA_vertexCORA_edge 标签:

from hugegraph_ml.utils.dgl2hugegraph_utils import import_graph_from_dgl

import_graph_from_dgl("cora")

读取图并训练 DGI:

from hugegraph_ml.data.hugegraph2dgl import HugeGraph2DGL
from hugegraph_ml.models.dgi import DGI
from hugegraph_ml.models.mlp import MLPClassifier
from hugegraph_ml.tasks.node_classify import NodeClassify
from hugegraph_ml.tasks.node_embed import NodeEmbed

hg2d = HugeGraph2DGL()
graph = hg2d.convert_graph(
    vertex_label="CORA_vertex",
    edge_label="CORA_edge",
)

embed_model = DGI(n_in_feats=graph.ndata["feat"].shape[1])
embed_task = NodeEmbed(graph=graph, model=embed_model)
embedded_graph = embed_task.train_and_embed(
    add_self_loop=True,
    n_epochs=300,
    patience=30,
)

classifier = MLPClassifier(
    n_in_feat=embedded_graph.ndata["feat"].shape[1],
    n_out_feat=embedded_graph.ndata["label"].unique().shape[0],
)
classify_task = NodeClassify(graph=embedded_graph, model=classifier)
classify_task.train(lr=1e-3, n_epochs=400, patience=40)
print(classify_task.evaluate())

evaluate() 返回类似 {'accuracy': 0.82, 'loss': 0.5714246034622192} 的字典。完整脚本是 hugegraph-ml/src/hugegraph_ml/examples/dgi_example.py

GRAND 节点分类示例

from hugegraph_ml.data.hugegraph2dgl import HugeGraph2DGL
from hugegraph_ml.models.grand import GRAND
from hugegraph_ml.tasks.node_classify import NodeClassify

hg2d = HugeGraph2DGL()
graph = hg2d.convert_graph(
    vertex_label="CORA_vertex",
    edge_label="CORA_edge",
)
model = GRAND(
    n_in_feats=graph.ndata["feat"].shape[1],
    n_out_feats=graph.ndata["label"].unique().shape[0],
)
task = NodeClassify(graph, model)
task.train(lr=1e-2, weight_decay=5e-4, n_epochs=2000, patience=100)
print(task.evaluate())

GRAND 每次增强采样都会返回一组 logits,NodeClassify 会对列表中的每个元素分别应用掩码后再计算损失。完整脚本是 hugegraph-ml/src/hugegraph_ml/examples/grand_example.py

排查问题

  • 连接失败:检查 HugeGraph Server 地址、端口和认证信息。
  • Schema 不匹配:示例默认使用 CORA_vertexCORA_edge,自有数据需要传入实际标签。
  • ValueError: Graph is missing required node attribute ...:节点分类任务需要 ndata 中包含 featlabeltrain_maskval_masktest_mask。请导入带掩码的数据集,或给 convert_graph 传入自定义的 mask_keys
  • ValueError: dataset not supported:导入函数只接受上表列出的名称,且 import_graph_from_ogb 匹配 ogbl-collab 时不做大写转换。
  • DGL 或 PyTorch 导入失败:回到仓库根目录重新执行 uv sync --extra ml,并确认当前 Python 来自根目录 .venv
  • bgrl_example.py 目前在导入阶段就会失败:它从 hugegraph_ml.models.bgrl 导入 MLP_Predictor,而该模块中的类名是 MLPPredictor
  • care_gnn_example.py 读取 AMAZON_user_v 和三个 AMAZON_net_*_e 边标签,仓库内没有对应的导入函数,需要自行准备该数据集后再运行。

3.3 - HugeGraph-LLM 使用流程

本文说明 HugeGraph-LLM Web 页面的处理流程。服务启动方式见 HugeGraph-LLM

0. 配置面板

标签页上方是可折叠的配置面板,共五个部分:1. Set up the HugeGraph server.2. Set up the LLM.3. Set up the Embedding.4. Set up the Reranker.5. Set up the vector engine.。每部分都有独立的应用按钮,应用后会把受支持的字段写回 .env。页面顶部还会显示当前提示词语言。

1. 构建 RAG 索引

第一个标签页负责两类索引:

  • 将文档切分后写入 chunk 向量索引。
  • 按 Schema 从文档抽取顶点和边,写入 HugeGraph,并维护顶点向量索引。
flowchart TD
    A[输入文档] --> B[文本切分]
    B --> C[生成 chunk 向量]
    C --> D[写入向量索引]
    B --> E[LLM 按 Schema 抽取顶点和边]
    E --> F[写入 HugeGraph]
    F --> G[更新顶点向量索引]

输入来自 text 子页或 file 子页。上传支持 .txt.docx.pdf,可一次选择多个文件。

页面包含文档、Schema、抽取提示词和结果区域。常用操作有:

  1. Import into Vector:切分文档并建立 chunk 向量索引。
  2. Extract Graph Data (1):按 Schema 抽取图数据。
  3. Load into GraphDB (2):把抽取结果写入 HugeGraph,并自动更新顶点向量。
  4. Update Vid Embedding:重新生成顶点向量,通常只在图中已有数据时才需要单独执行。

这些按钮旁的 Graph Extraction Split Type 下拉框可选 documentparagraphsentencedocument 把输入整体作为一个单元,另外两种会在抽取前先切分长文档。

页面还可以查看或清除 chunk 索引、顶点索引和图数据。清除操作会删除已有数据,执行前先确认当前图和索引是否仍被其他查询使用。

主控件下方还有两个折叠的辅助工具:

  • Graph Schema Generator:根据查询示例和少样本示例生成 Schema,填入 Graph Schema 字段。
  • Graph Extraction Prompt Generator:根据期望场景(例如社交关系、金融知识图谱)和选定的参考示例生成 Graph Extract Prompt Header。

2. GraphRAG 查询

第二个标签页提供四种回答范围:

  • 直接使用 LLM 回答。
  • 只使用 chunk 向量召回。
  • 只使用图召回。
  • 合并图召回与向量召回。
flowchart TD
    Q[问题] --> V[查询 chunk 向量索引]
    Q --> K[抽取关键词]
    K --> M[匹配图顶点]
    M --> T[生成并执行 Gremlin]
    T -->|失败| B[BFS 图遍历回退]
    T --> R[整理图结果]
    B --> R
    V --> S[合并与重排序]
    R --> S
    S --> A[生成答案]

图召回先用关键词精确匹配 HugeGraph 顶点,找不到时再用顶点向量做近似匹配。匹配结果会进入 Text2Gremlin;生成或执行失败时,流程可以回退到预定义的图遍历。

Template Num 控制 Text2Gremlin 在图召回中的参与方式:

  • 小于 0:完全跳过 Text2Gremlin,图召回直接使用预定义的图遍历。
  • 等于 0:不带任何示例生成 Gremlin(zero-shot)。
  • 大于 0:从示例索引中取相应数量的相近示例,并采用带模板的生成结果。示例数量会被限制在 0 到 10 之间。

该标签页的其他控件还有 Rerank methodbleureranker)、Graph RatioNear neighbor firstQuery related information,以及可编辑的 Query PromptKeywords Extraction Prompt

单条问答面板下方是批量回归测试面板。上传 .xlsx.csv 问题文件,设置 Max Lines To Show,点击 Generate Answer (Batch)。答案会显示在预览表格中,并可下载为文件。上传控件旁提供模板文件下载。

3. Text2Gremlin

第三个标签页分为两部分。上半部分用问题与 Gremlin 对照文件(.json.csv)构建示例向量索引;未上传文件时使用内置的 resources/demo/text2gremlin.csv

下半部分把自然语言转换成 Gremlin:

  1. 读取当前图的 Schema。
  2. 从示例向量索引取回相近的自然语言与 Gremlin 对。
  3. 把问题、Schema、示例和已匹配顶点填入提示词。
  4. 调用 LLM 生成 Gremlin,并按所选输出类型决定是否执行。

Number of refer examples 设置取回的示例数量,范围 0 到 10,默认 2。结果显示在四个字段中:带模板的 Gremlin、不带模板的 Gremlin,以及两者各自的执行输出。

RAG 查询范围选择

自定义提示词必须包含 {query}{schema}{example}{vertices}。缺少任一占位符时,REST API 会拒绝请求。

4. 图工具与管理工具

Graph Tools 标签页可直接对当前图执行 Gremlin 查询、手动触发图备份,并通过 beta 操作初始化 HugeGraph 演示数据。后台还有两个任务:每天 01:00 自动备份图数据,以及在进程运行期间持续更新顶点 id 向量。

Admin Tools 需要密码。输入已配置的 ADMIN_TOKEN 后可查看 logs/llm-server.log 的末尾内容(每 60 秒自动刷新),并可手动刷新或清空该文件。ADMIN_TOKEN 为空或仍是占位值 xxxx 时,访问会被拒绝。

设置 ENABLE_LOGIN=True 后,Web 页面会要求基础认证,用户名固定为 rag,密码是 USER_TOKEN;REST API 则要求把 USER_TOKEN 作为 Bearer token。日志接口还要求单独配置安全的 ADMIN_TOKEN

RAG 界面中抽取的关键词

5. 提示词语言

hugegraph-llm/.env 中设置:

# 英文提示词
LANGUAGE=EN

# 中文提示词
LANGUAGE=CN

修改后重启服务。该配置选择内置提示词语言,不会自动翻译输入文档,也不是 /rag 请求体字段。

6. REST 调用

Web 页面和 REST API 使用同一套流程。需要程序集成时使用 /rag/rag/graph/graph/extract/text2gremlin;请求结构见 REST API

3.4 - 配置参考

HugeGraph-LLM 从 hugegraph-llm/.env 读取运行配置。提示词单独保存在 hugegraph-llm/src/hugegraph_llm/resources/demo/config_prompt.yaml,不会写入 .env

.env 路径按以下顺序解析:

  1. 若设置了环境变量 HUGEGRAPH_LLM_ENV_PATH,则使用该路径,开头的 ~ 会被展开。
  2. 从源码运行时,使用 hugegraph-llm/.env
  3. 以已安装的包运行时,使用当前工作目录下的 .env

运行以下命令可按配置类的默认值创建或更新文件:

cd hugegraph-ai/hugegraph-llm
python -m hugegraph_llm.config.generate --update

--update 默认开启,因此不带参数运行效果相同。该命令会写入 HugeGraph、管理员、LLM 和索引配置,然后重新生成提示词 YAML。若 .env 已存在,会先询问是否覆盖。

.env 包含密钥和密码,不要提交到版本库。

基础选项

配置项默认值说明
LANGUAGEEN提示词语言,可选 ENCN
CHAT_LLM_TYPEopenai回答模型,可选 openailitellmollama/local
EXTRACT_LLM_TYPEopenai信息抽取模型,取值同上
TEXT2GQL_LLM_TYPEopenaiText2Gremlin 模型,取值同上
EMBEDDING_TYPEopenai嵌入模型,取值同上,也可以留空
RERANKER_TYPE可选 coheresiliconflow
KEYWORD_EXTRACT_TYPEllm可选 llmtextrankhybrid
WINDOW_SIZE3TextRank 滑窗,范围 1 到 10
HYBRID_LLM_WEIGHTS0.5hybrid 模式中 LLM 结果的权重,范围 0 到 1

OpenAI 兼容接口

聊天、抽取和 Text2Gremlin 可以使用不同端点、密钥和模型。

用途API 地址密钥模型最大 token 默认值
回答OPENAI_CHAT_API_BASEOPENAI_CHAT_API_KEYOPENAI_CHAT_LANGUAGE_MODELOPENAI_CHAT_TOKENS=8192
抽取OPENAI_EXTRACT_API_BASEOPENAI_EXTRACT_API_KEYOPENAI_EXTRACT_LANGUAGE_MODELOPENAI_EXTRACT_TOKENS=256
Text2GremlinOPENAI_TEXT2GQL_API_BASEOPENAI_TEXT2GQL_API_KEYOPENAI_TEXT2GQL_LANGUAGE_MODELOPENAI_TEXT2GQL_TOKENS=4096
嵌入OPENAI_EMBEDDING_API_BASEOPENAI_EMBEDDING_API_KEYOPENAI_EMBEDDING_MODEL不适用

API 地址默认是 https://api.openai.com/v1;三个语言模型默认是 gpt-4.1-mini,嵌入模型默认是 text-embedding-3-small

OPENAI_BASE_URLOPENAI_API_KEY 可作为通用回退值。嵌入模型另有 OPENAI_EMBEDDING_BASE_URLOPENAI_EMBEDDING_API_KEY 回退值。

LiteLLM

用途API 地址密钥模型最大 token 默认值
回答LITELLM_CHAT_API_BASELITELLM_CHAT_API_KEYLITELLM_CHAT_LANGUAGE_MODELLITELLM_CHAT_TOKENS=8192
抽取LITELLM_EXTRACT_API_BASELITELLM_EXTRACT_API_KEYLITELLM_EXTRACT_LANGUAGE_MODELLITELLM_EXTRACT_TOKENS=256
Text2GremlinLITELLM_TEXT2GQL_API_BASELITELLM_TEXT2GQL_API_KEYLITELLM_TEXT2GQL_LANGUAGE_MODELLITELLM_TEXT2GQL_TOKENS=4096
嵌入LITELLM_EMBEDDING_API_BASELITELLM_EMBEDDING_API_KEYLITELLM_EMBEDDING_MODEL不适用

三个语言模型默认是 openai/gpt-4.1-mini,嵌入模型默认是 openai/text-embedding-3-small。模型名通常使用 供应商/模型 格式,具体取值由 LiteLLM 服务决定。

Ollama

用途主机端口模型
回答OLLAMA_CHAT_HOSTOLLAMA_CHAT_PORTOLLAMA_CHAT_LANGUAGE_MODEL
抽取OLLAMA_EXTRACT_HOSTOLLAMA_EXTRACT_PORTOLLAMA_EXTRACT_LANGUAGE_MODEL
Text2GremlinOLLAMA_TEXT2GQL_HOSTOLLAMA_TEXT2GQL_PORTOLLAMA_TEXT2GQL_LANGUAGE_MODEL
嵌入OLLAMA_EMBEDDING_HOSTOLLAMA_EMBEDDING_PORTOLLAMA_EMBEDDING_MODEL

主机默认是 127.0.0.1,端口默认是 11434,模型名没有默认值。使用前先在 Ollama 中拉取对应模型。

重排序

配置项默认值说明
COHERE_BASE_URLhttps://api.cohere.com/v1/rerankCohere rerank 接口;CO_API_URL 可作为回退值
RERANKER_API_KEYCohere 或 SiliconFlow 密钥
RERANKER_MODEL服务端支持的模型名

HugeGraph 连接与召回限制

配置项默认值说明
GRAPH_URL127.0.0.1:8080HugeGraph 地址,不拆分为 IP 和端口
GRAPH_NAMEhugegraph图名
GRAPH_USERadmin用户名
GRAPH_PWDxxx密码
GRAPH_SPACEGraphSpace 名称
LIMIT_PROPERTYFalse是否限制返回属性;配置类按字符串读取
MAX_GRAPH_PATH10最大图路径长度
MAX_GRAPH_ITEMS30图召回的最大项目数
EDGE_LIMIT_PRE_LABEL8每个边标签的返回上限
VECTOR_DIS_THRESHOLD0.9向量距离阈值;超过阈值的结果会被忽略
TOPK_PER_KEYWORD1每个关键词的候选数
TOPK_RETURN_RESULTS20重排序后返回的结果数

向量索引后端

配置项默认值说明
CUR_VECTOR_INDEXFaiss当前使用的向量库:FaissMilvusQdrant
QDRANT_HOST
QDRANT_PORT6333
QDRANT_API_KEY
MILVUS_HOST
MILVUS_PORT19530
MILVUS_USER
MILVUS_PASSWORD

FAISS 在本地运行,无需额外依赖。未安装可选依赖就选择 MilvusQdrant 时,会报错并指出缺少的包,因此需要先安装:

cd hugegraph-ai
uv sync --package hugegraph-llm --extra vectordb

Web 页面的 5. Set up the vector engine. 面板提供同样的选择,并会保存所选引擎的连接配置。

登录与日志接口

配置项默认值说明
ENABLE_LOGINFalse是否要求 Bearer token;配置类按字符串读取
USER_TOKEN4321Web 页面和普通 API 的 token
ADMIN_TOKENxxxx/logs 使用的管理员 token

ADMIN_TOKEN 为空或仍为 xxxx 时,/logs 会直接返回 403。生产环境应同时替换用户 token 和管理员 token。

最小 OpenAI 配置

LANGUAGE=CN
CHAT_LLM_TYPE=openai
EXTRACT_LLM_TYPE=openai
TEXT2GQL_LLM_TYPE=openai
EMBEDDING_TYPE=openai

OPENAI_API_KEY=your-api-key
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_CHAT_LANGUAGE_MODEL=gpt-4.1-mini
OPENAI_EXTRACT_LANGUAGE_MODEL=gpt-4.1-mini
OPENAI_TEXT2GQL_LANGUAGE_MODEL=gpt-4.1-mini
OPENAI_EMBEDDING_MODEL=text-embedding-3-small

GRAPH_URL=127.0.0.1:8080
GRAPH_NAME=hugegraph
GRAPH_USER=admin
GRAPH_PWD=your-password

配置加载

配置类先提供代码默认值,再从 .env 和进程环境读取覆盖值。Web 页面和配置 API 可以在运行时更新当前设置,并把受支持的字段同步回 .env。手工改动 .env 后应重启服务;提示词 YAML 可由页面加载逻辑刷新。

.env 中的未知键会被忽略而不是报错,空值会回退到代码默认值,键名匹配不区分大小写。

配置定义位于:

  • hugegraph-llm/src/hugegraph_llm/config/llm_config.py
  • hugegraph-llm/src/hugegraph_llm/config/hugegraph_config.py
  • hugegraph-llm/src/hugegraph_llm/config/index_config.py
  • hugegraph-llm/src/hugegraph_llm/config/admin_config.py
  • hugegraph-llm/src/hugegraph_llm/config/prompt_config.py
  • hugegraph-llm/src/hugegraph_llm/config/models/base_config.py:加载与文件同步逻辑

3.5 - HugeGraph-LLM REST API

HugeGraph-LLM 演示进程同时提供 Web 页面和 REST API。默认地址是 http://localhost:8001

cd hugegraph-ai/hugegraph-llm
python -m hugegraph_llm.demo.rag_demo.app \
  --host 127.0.0.1 \
  --port 8001

所有接口都使用 POST

路径成功状态码用途
/rag200按所选召回方式回答问题
/rag/graph200只做图召回,不生成最终答案
/graph/extract200从文本抽取顶点和边
/text2gremlin200由自然语言生成 Gremlin
/config/graph201更新 HugeGraph 连接
/config/llm201更新语言模型
/config/embedding201更新嵌入模型
/config/rerank201更新重排序模型
/logs200流式返回服务日志

认证

.env 中启用登录:

ENABLE_LOGIN=True
USER_TOKEN=replace-with-a-secret

启用后,请求需要 Bearer token:

Authorization: Bearer replace-with-a-secret

同一开关也会给 Gradio 页面加上基础认证,用户名固定为 rag,密码是 USER_TOKEN。token 不正确时返回 401,并带上 WWW-Authenticate: Bearer 响应头。ENABLE_LOGIN 保持 False 时所有接口都不做鉴权。

RAG

POST /rag

根据开关返回一种或多种回答。未显式指定时只启用 graph_only

curl -X POST http://localhost:8001/rag \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "Al Pacino 出演过哪些电影?",
    "raw_answer": false,
    "vector_only": false,
    "graph_only": true,
    "graph_vector_answer": false,
    "max_graph_items": 30,
    "topk_return_results": 20,
    "vector_dis_threshold": 0.9,
    "topk_per_keyword": 1,
    "gremlin_tmpl_num": 1,
    "client_config": {
      "url": "127.0.0.1:8080",
      "graph": "hugegraph",
      "user": "admin",
      "pwd": "admin",
      "gs": "DEFAULT"
    }
  }'

响应只包含已启用的回答字段:

{
  "query": "Al Pacino 出演过哪些电影?",
  "graph_only": "..."
}

其他可选参数包括 graph_ratio(默认 0.5)、rerank_methodbleureranker,默认 bleu)、near_neighbor_first(默认 false)、custom_priority_info,以及三个自定义提示词字段 answer_promptkeywords_extract_promptgremlin_prompt。省略提示词字段时使用 config_prompt.yaml 中的值。

gremlin_tmpl_num 决定图召回阶段 Text2Gremlin 的执行方式:小于 0 表示跳过 Text2Gremlin,直接使用预定义的图遍历;等于 0 表示不带示例生成 Gremlin;大于 0 表示从示例索引中取相应数量的示例。

query 为空或只有空白字符时返回 400。

POST /rag/graph

只执行图召回,不生成最终自然语言答案:

curl -X POST http://localhost:8001/rag/graph \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "Al Pacino 出演过哪些电影?",
    "get_vertex_only": false,
    "gremlin_tmpl_num": 1,
    "rerank_method": "bleu"
  }'

响应的 graph_recall 可能包含 querykeywordsmatch_vidsgraph_result_flaggremlingraph_resultvertex_degree_list。设置 get_vertex_only=true 可在顶点匹配后提前返回,此时接口会把 match_vids 替换为完整的顶点详情。

query 为空返回 400,请求类型错误返回 400,其他失败返回 500。

图抽取

POST /graph/extract

使用内联 Schema 时不会连接 HugeGraph:

curl -X POST http://localhost:8001/graph/extract \
  -H 'Content-Type: application/json' \
  -d '{
    "texts": ["Alice 在 Acme 工作。"],
    "schema": {
      "vertexlabels": [
        {"name": "person", "properties": ["name"]},
        {"name": "company", "properties": ["name"]}
      ],
      "edgelabels": [
        {
          "name": "works_at",
          "source_label": "person",
          "target_label": "company",
          "properties": []
        }
      ]
    },
    "language": "zh",
    "split_type": "sentence",
    "include_meta": true
  }'

请求字段:

字段默认值说明
texts必填字符串或字符串数组;空白项会被丢弃,全部为空时报错
schema必填内联 JSON 对象或字符串,或现有图名
example_prompt提示词 YAML 中的值抽取提示词头部
extract_typeproperty_graph目前仅接受该值
languagezhzhen,用于文本切分
split_typedocumentdocumentparagraphsentence
include_metafalsemeta 中加入 vertex_countedge_counttext_count
client_config仅在 schema 为图名时允许传入

内联 Schema 必须是包含 vertexlabelsedgelabels 两个列表的对象。每个顶点标签需要非空的 name 和非空的 properties 列表;每条边标签需要非空的 namesource_labeltarget_labelpropertykeys 可选,若存在必须是列表。

schema 传现有图名,必须同时传入 client_config,且 client_config.graph 必须和图名相同。这里的 client_config 只接受 graphuserpwdgs,未知字段会被拒绝,且没有 url 字段:

{
  "texts": "Alice 在 Acme 工作。",
  "schema": "hugegraph",
  "client_config": {
    "graph": "hugegraph",
    "user": "admin",
    "pwd": "admin",
    "gs": "DEFAULT"
  }
}

成功响应固定包含 status(始终为 succeeded)、result.verticesresult.edgeswarningsmetainclude_meta 不为 truemeta 为空。

Text2Gremlin

POST /text2gremlin

curl -X POST http://localhost:8001/text2gremlin \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "查找所有 person 顶点",
    "example_num": 1,
    "output_types": ["template_gremlin", "template_execution_result"]
  }'

output_types 可包含:

  • match_result
  • template_gremlin
  • raw_gremlin
  • template_execution_result
  • raw_execution_result

省略该字段时默认只返回 template_gremlin;传空数组表示由实现返回全部输出。自定义 gremlin_prompt 必须包含 {query}{schema}{example}{vertices},缺少占位符时请求校验失败,并会列出缺失的占位符。

example_num 默认是 0,表示不使用模板,取值会被限制在 0 到 10 之间。client_config 只在单次请求内覆盖 HugeGraph 连接,生成时使用的 Schema 是当前生效的图名。query 为空返回 400,生成失败返回 500。

运行时配置

POST /config/graph

{
  "url": "127.0.0.1:8080",
  "graph": "hugegraph",
  "user": "admin",
  "pwd": "admin",
  "gs": "DEFAULT"
}

userpwd 默认是空字符串,gs 可选。

POST /config/llmPOST /config/embedding

两个端点使用同一个请求模型。/config/llm 会把 chat_llm_typeextract_llm_typetext2gql_llm_type 一起设为相同的值;要分别设置各任务的类型,只能通过 .env 或 Web 页面。OpenAI 或 LiteLLM 示例:

{
  "llm_type": "openai",
  "api_key": "your-key",
  "api_base": "https://api.openai.com/v1",
  "language_model": "gpt-4.1-mini",
  "max_tokens": "4096"
}

Ollama 请求仍要提供公共字段;api_keyapi_base 可传空字符串:

{
  "llm_type": "ollama/local",
  "api_key": "",
  "api_base": "",
  "language_model": "qwen2.5:7b",
  "host": "127.0.0.1",
  "port": "11434"
}

POST /config/rerank

{
  "reranker_type": "siliconflow",
  "reranker_model": "BAAI/bge-reranker-v2-m3",
  "api_key": "your-key"
}

reranker_type 可选 coheresiliconflow。Cohere 还可以传 cohere_base_url

四个配置端点成功时都返回 201。它们会改动进程当前配置,并可能同步到 .env/config/llm/config/embedding/config/rerank 在应用过程中抛出异常时会回滚到原有取值,/config/graph 不会。

/rag/rag/graph/text2gremlinclient_config 只在单次请求期间覆盖 HugeGraph 连接,且仅应用请求中实际出现的字段。当前实现仍会临时改动进程全局设置,不适合用不同连接并发发起长请求。

日志

POST /logs

该接口要求 .env 中的 ADMIN_TOKEN 已改成安全值。请求体示例:

{
  "admin_token": "replace-with-an-admin-secret",
  "log_file": "llm-server.log"
}

log_file 默认是 llm-server.log,只能是 logs/ 目录下的文件名,不能是绝对路径、不能包含路径分隔符,也不能解析为 ...。非法文件名返回 400。

ADMIN_TOKEN 未设置或仍是占位值时,在比对 token 之前就返回 403;token 不匹配时返回内容为 Invalid admin_token 的 403 响应。

成功时返回 text/plain 流:先回放文件末尾 125 行,然后像 tail -f 一样持续输出新内容。

3.6 - Vermeer Python 客户端

vermeer-python-clientVermeer 的 Python SDK。Vermeer 是使用 Go 编写、以内存计算为主的图计算引擎。该 SDK 封装了 Vermeer master 的 REST API,可以在 Python 中列出图、提交加载和计算任务、读取任务状态。导入时使用的包名是 pyvermeer

模块没有固定 Vermeer 服务端版本,它通过 HTTP 访问 Vermeer master,调用的接口见 API 概览

环境要求

  • 单独使用该模块需要 Python 3.9 或更高版本;HugeGraph-AI 仓库整体要求 Python 3.10 或更高版本
  • 一个可通过 HTTP 访问的 Vermeer master。默认 HTTP 端口为 6688;Docker 部署需发布 6688:6688,见 Vermeer 快速开始
  • uv(推荐)或 pip

运行时依赖:requestsurllib3python-dateutildecoratorrichsetuptools

安装

打包元数据中的发行包名是 vermeer-python-client,其版本号独立于仓库版本号管理。该包尚未发布到 PyPI,请从源码安装。

在 HugeGraph-AI 仓库根目录,使用 vermeer extra 把它安装到共用的虚拟环境中:

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
uv sync --extra vermeer
source .venv/bin/activate

vermeer-python-client 是以可编辑路径依赖的方式接入的,并不是 uv workspace member,因此在仓库根目录直接执行 uv sync 不会安装它,必须显式指定该 extra(或使用 --all-extras)。

单独安装该模块:

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai/vermeer-python-client
uv sync
source .venv/bin/activate

连接 Vermeer master

from pyvermeer.client.client import PyVermeerClient

client = PyVermeerClient(
    ip="127.0.0.1",
    port=6688,
    token="",
    timeout=(0.5, 15.0),
    log_level="INFO",
)

构造函数参数:

参数类型默认值说明
ipstr必填Vermeer master 的主机名或 IP 地址
portint必填Vermeer master 的 REST 端口
tokenstr必填原样作为 Authorization 请求头发送
timeout(float, float)NoneNone连接超时和读取超时,单位为秒
log_levelstr"INFO"应用到共享 VermeerClient 日志器的级别

连接前需要了解的行为:

  • 当 master 不校验鉴权时,token 可以是空字符串,但不能是 None,否则会话会抛出 ValueError("Vermeer Token must be provided.")
  • timeout(连接超时, 读取超时) 二元组。VermeerConfig 自身的默认值是 (0.5, 15.0),但客户端总是把自己的参数传下去,因此不传 timeout 时实际存入的是 None,请求会一直等待。需要超时就显式传入该二元组。
  • 基础 URL 固定拼接为 http://{ip}:{port}/,即客户端只使用明文 HTTP。
  • 每个请求都会设置 Content-Type: application/json,并把 params 序列化进请求体,GET 请求也是如此。
  • 底层会话在 HTTP 500、502、504 时最多重试 3 次,退避系数为 0.1
  • log_level 设置的是名为 VermeerClient 的共享日志器的级别。它的控制台 handler 固定为 INFO,因此目前 DEBUG 级别的记录不会打印到控制台。

端到端示例

模块自带一个可运行的示例:vermeer-python-client/src/pyvermeer/demo/task_demo.py。下面的版本在其基础上增加了带超时和失败处理的任务状态轮询,等待加载成功后再读取图,并从环境变量读取 HugeGraph 密码:

import os
import time

from pyvermeer.client.client import PyVermeerClient
from pyvermeer.structure.task_data import TaskCreateRequest

client = PyVermeerClient(
    ip="127.0.0.1",
    port=6688,
    token="",
    timeout=(0.5, 15.0),
    log_level="INFO",
)

# 列出 master 上的任务
tasks = client.tasks.get_tasks()
print(tasks.to_dict())

# 从 HugeGraph 把图数据加载到 Vermeer
create_response = client.tasks.create_task(
    create_task=TaskCreateRequest(
        task_type="load",
        graph_name="DEFAULT-example",
        params={
            "load.hg_pd_peers": '["127.0.0.1:8686"]',
            "load.hugegraph_name": "DEFAULT/example/g",
            "load.hugegraph_username": "admin",
            "load.hugegraph_password": os.environ["HUGEGRAPH_PASSWORD"],
            "load.parallel": "10",
            "load.type": "hugegraph",
        },
    )
)
print(create_response.errcode, create_response.message)
if create_response.errcode != 0:
    raise RuntimeError(f"Could not create load task: {create_response.message}")

# 轮询本次创建的加载任务,直到成功、失败或超时
task_id = create_response.task.id
poll_timeout = 300.0
deadline = time.monotonic() + poll_timeout
while time.monotonic() < deadline:
    task = client.tasks.get_task(task_id)
    if task.errcode != 0:
        raise RuntimeError(f"Could not read task {task_id}: {task.message}")
    state = task.task.state
    print(task_id, state)
    if state == "loaded":
        break
    if state in ("error", "canceled"):
        raise RuntimeError(f"Load task {task_id} ended with state {state}")
    remaining = deadline - time.monotonic()
    if remaining > 0:
        time.sleep(min(1.0, remaining))
else:
    raise TimeoutError(f"Load task {task_id} did not finish within {poll_timeout}s")

# 图加载完成后查看图信息
print(client.graph.get_graph("DEFAULT-example").to_dict())

加载任务以 loaded 表示成功;errorcanceled 会中止示例,不再读取图。可按数据量调整 poll_timeout(此处为 300 秒)。轮询期限与 HTTP 连接、读取超时相互独立,已发出的请求及 SDK 重试可能使实际等待时间超过该期限。超时只停止客户端等待,不会取消服务端任务。

不要把真实的 HugeGraph 密码写死在脚本或配置文件中,请像上面这样从环境变量或凭据管理系统读取。

模块自带的 task_demo.py 使用 8688。运行前,请将其中 PyVermeerClientport 改为 6688,与默认 master HTTP 端口保持一致。根据安装后所在的目录选择对应命令:

仓库根目录安装(在 hugegraph-ai/ 下运行):

python vermeer-python-client/src/pyvermeer/demo/task_demo.py

独立安装(在 hugegraph-ai/vermeer-python-client/ 下运行):

python src/pyvermeer/demo/task_demo.py

API 概览

PyVermeerClient 以属性的方式暴露各个 API 组,目前注册了 graphtasks 两个组。

client.graph

方法Vermeer 接口返回值
get_graphs()GET /graphsGraphsResponse
get_graph(graph_name)GET /graphs/{graph_name}GraphResponse

client.tasks

方法Vermeer 接口返回值
get_tasks()GET /tasksTasksResponse
get_task(task_id)GET /task/{task_id}TaskResponse
create_task(create_task)POST /tasks/createTaskCreateResponse

pyvermeer/api/master.pypyvermeer/api/worker.py 目前只有许可证头,也没有注册到客户端上。因此尽管 pyvermeer/structure/ 下已经有 MasterResponseWorkersResponse,master 和 worker 信息暂时还无法通过客户端获取。

client.send_request(method, endpoint, params) 是这两个组共用的请求入口。对于还没有封装的 Vermeer 接口,可以直接调用它,返回值是解析后的 JSON 字典。

请求与响应对象

TaskCreateRequest(task_type, graph_name, params) 序列化为 {"task_type": ..., "graph": ..., "params": ...}。注意 graph_name 在报文中的字段名是 graph,与 Vermeer REST API 的请求体一致。

所有响应类型都继承 BaseResponse,提供 errcodemessage 属性和 to_dict() 方法。errcode0 表示成功,1 表示错误,-1 表示响应体中没有该字段。

  • GraphsResponse.graphsGraphResponse.graph 返回 VermeerGraph 对象,包含 namespace_namestatuscreate_timeupdate_timevertex_countedge_countworkersworker_groupuse_out_edgesuse_propertyuse_out_degreeuse_undirectedon_diskbackend_option
  • TasksResponse.tasksTaskResponse.taskTaskCreateResponse.task 返回 TaskInfo 对象,包含 idstatecreate_usercreate_typecreate_timestart_timeupdate_timegraph_namespace_nametypeparamsworkers
  • 时间字段由 python-dateutil 解析为 datetime 对象,空字符串会解析为 None

任务参数

客户端不会校验 params,键和值都会原样传给 Vermeer,因此可用的参数名由引擎决定,而不是由 SDK 决定。加载参数以及各算法的参数请参考 Vermeer 快速开始

使用流程与直接调用 REST API 相同:先创建 load 任务把图读入 Vermeer,等待任务完成,再针对已加载的图创建计算任务。

异常

pyvermeer.utils.exception 定义了四种异常,都由底层的 requests 或 JSON 解析失败包装而来:

异常触发场景
ConnectErrorrequests.ConnectionError,无法连接 master
TimeOutErrorrequests.Timeout,连接或读取超时
JsonDecodeError响应体不是合法的 JSON
UnknownError请求过程中的其他失败
from pyvermeer.utils.exception import ConnectError, TimeOutError

try:
    graphs = client.graph.get_graphs()
except (ConnectError, TimeOutError) as error:
    print(error)

客户端不检查响应的 HTTP 状态码,请通过返回对象的 errcodemessage 判断是成功还是 Vermeer 端返回了错误。

代码检查

在 HugeGraph-AI 仓库根目录执行格式化和静态检查:

./style/code_format_and_analysis.sh

源码位于 vermeer-python-client/src/pyvermeer/。该模块目前没有测试用例。

参考

4 - HugeGraph 图计算(OLAP)

HugeGraph-Computer 仓库包含两套 OLAP 系统:Go 实现的内存图计算平台 Vermeer,以及 Java 实现的分布式 BSP 框架 Computer。

DeepWiki 提供实时更新的项目文档,内容更全面准确,适合快速了解项目最新情况。

📖 https://deepwiki.com/apache/hugegraph-computer/

4.1 - HugeGraph-Vermeer Quick Start

一、Vermeer 概述

1.1 运行架构

Vermeer 是一个 Go编写的高性能内存优先的图计算框架 (一次启动,任意执行),支持 15+ OLAP 图算法的极速计算 (大部分秒~分钟级别完成执行),包含 master 和 worker 两种角色。master 目前只有一个 (可增加 HA),worker 可以有多个。

master 是负责通信、转发、汇总的节点,计算量和占用资源量较少。worker 是计算节点,用于存储图数据和运行计算任务,占用大量内存和 cpu。grpc 和 rest 模块分别负责内部通信和外部调用。

该框架的运行配置可以通过命令行参数传入,也可以通过位于 config/ 目录下的配置文件指定,--env 参数可以指定使用哪个配置文件,例如 --env=master 指定使用 master.ini。需要注意 master 需要指定监听的端口号,worker 需要指定监听端口号和 master 的 ip:port

master 默认 HTTP 端口为 6688,用于 REST API 和 Python 客户端;worker 连接 master 使用 gRPC 端口 6689。下面的 Docker 示例通过 6688:6688 发布 HTTP 端口,请保留 master 配置中的 http_peer=0.0.0.0:6688

1.2 运行方法

下面两种 Docker 启动方式都需要先准备一个宿主机配置目录,包含项目提供的 master.iniworker.ini。在 worker.ini 已有的 [default] 节中修改 master_peer,保留其余配置:

[default]
master_peer=vermeer-master:6689

在 worker 容器内,默认的 127.0.0.1:6689 指向 worker 自身。两个示例中的 vermeer-master 都会在共享 Docker 网络内解析到 master 容器。请保留 master.ini 中的 grpc_peer=0.0.0.0:6689,并将上述配置目录挂载到两个容器的 /go/bin/config。仅发布 HTTP 端口 6688 不会配置 worker 的 gRPC 连接。

  1. 方案一:Docker Compose(推荐)

在 Vermeer 根目录执行以下步骤。可以使用仓库已有的 docker-compose.yaml,也可以根据下面的示例创建。无论使用哪一种,都必须在启动服务前完成下文要求的端口和挂载配置修改:

services:
  vermeer-master:
    image: hugegraph/vermeer
    container_name: vermeer-master
    ports:
      - "6688:6688"
    volumes:
      - ~/.config:/go/bin/config # Change here to your actual config path
    command: --env=master
    networks:
      vermeer_network:
        ipv4_address: 172.20.0.10 # Assign a static IP for the master

  vermeer-worker:
    image: hugegraph/vermeer
    container_name: vermeer-worker
    volumes:
      - ~/.config:/go/bin/config # Change here to your actual config path
    command: --env=worker
    networks:
      vermeer_network:
        ipv4_address: 172.20.0.11 # Assign a static IP for the worker

networks:
  vermeer_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24 # Define the subnet for your network

启动前,无论使用仓库自带的文件还是上面的示例,都需要修改 docker-compose.yaml

  • Ports:在 services.vermeer-master 下补上 ports: ["6688:6688"](如果尚无此映射),让宿主机上的 curl 和 Python 客户端能够访问 master 的 HTTP API。
  • Volumes:将 vermeer-mastervermeer-worker 中挂载到 /go/bin/config 的条目都设为 /home/user/config:/go/bin/config,其中 /home/user/config 应替换为上面准备的配置目录的绝对路径。不论原挂载使用的是 ~/(仓库自带文件)还是 ~/.config(上面的示例),都需要替换。
  • Subnet:根据实际情况修改子网IP。请注意,每个容器需要访问的端口在config文件中指定,具体请参照项目config文件夹下内容。

在项目目录构建镜像并启动(或者先用 docker build 再 docker-compose up)

# 构建镜像(在项目根 vermeer 目录)
docker build -t hugegraph/vermeer .

# 启动(在 vermeer 根目录)
docker-compose up -d
# 或使用新版 CLI:
# docker compose up -d

查看日志 / 停止 / 删除:

docker-compose logs -f
docker-compose down
  1. 方案二:通过 docker run 单独启动(手动创建网络并分配静态 IP)

CONFIG_DIR 设为上面准备的配置目录,其中 worker.ini 已设置 master_peer=vermeer-master:6689。确保该目录对 Docker 进程具有适当的读取/执行权限。

构建镜像:

docker build -t hugegraph/vermeer .

创建自定义 bridge 网络(一次性操作):

docker network create --driver bridge \
  --subnet 172.20.0.0/24 \
  vermeer_network

运行 master(调整 CONFIG_DIR 为您的绝对配置路径,可以根据实际情况调整IP):

CONFIG_DIR=/home/user/config

docker run -d \
  --name vermeer-master \
  --network vermeer_network --ip 172.20.0.10 \
  -p 6688:6688 \
  -v ${CONFIG_DIR}:/go/bin/config \
  hugegraph/vermeer \
  --env=master

运行 worker:

docker run -d \
  --name vermeer-worker \
  --network vermeer_network --ip 172.20.0.11 \
  -v ${CONFIG_DIR}:/go/bin/config \
  hugegraph/vermeer \
  --env=worker

查看日志 / 停止 / 删除:

docker logs -f vermeer-master
docker logs -f vermeer-worker

docker stop vermeer-master vermeer-worker
docker rm vermeer-master vermeer-worker

# 删除自定义网络(如果需要)
docker network rm vermeer_network
  1. 方案三:从源码构建

构建。具体请参照 Vermeer Readme

go build

在进入文件夹目录后输入 ./vermeer --env=master./vermeer --env=worker01

启动 master 后,在宿主机验证 HTTP 端口:

curl --fail --show-error http://localhost:6688/graphs

请求应返回 HTTP 200,JSON 响应中的 errcode0

二、任务创建类 rest api

2.1 简介

此类 rest api 提供所有创建任务的功能,包括读取图数据和多种计算功能,提供异步返回和同步返回两种接口。返回的内容均包含所创建任务的信息。使用 vermeer 的整体流程是先创建读取图的任务,待图读取完毕后创建计算任务执行计算。图不会自动被删除,在一个图上运行多个计算任务无需多次重复读取,如需删除可用删除图接口。任务状态可分为读取任务状态和计算任务状态。通常情况下客户端仅需了解创建、任务中、任务结束和任务错误四种状态。图状态是图是否可用的判断依据,若图正在读取中或图状态错误,无法使用该图创建计算任务。图删除接口仅在 loaded 和 error 状态且该图无计算任务时可用。

可以使用的 url 如下:

  • 异步返回接口 POST http://master_ip:port/tasks/create 仅返回任务创建是否成功,需通过主动查询任务状态判断是否完成。
  • 同步返回接口 POST http://master_ip:port/tasks/create/sync 在任务结束后返回。

2.2 加载图数据

具体参数参考 Vermeer 参数列表文档。

vermeer提供三种加载方式:

  1. 从本地加载

可以预先获取数据集,例如 twitter-2010 数据集。获取方式:https://snap.stanford.edu/data/twitter-2010.html,第一个 twitter-2010.txt.gz 即可。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "load",
 "graph": "testdb",
 "params": {
  "load.parallel": "50",
  "load.type": "local",
  "load.vertex_files": "{\"localhost\":\"data/twitter-2010.v_[0,99]\"}",
  "load.edge_files": "{\"localhost\":\"data/twitter-2010.e_[0,99]\"}",
  "load.use_out_degree": "1",
  "load.use_outedge": "1"
 }
}
  1. 从hugegraph加载

request 示例:

⚠️ 安全警告:切勿在配置文件或代码中存储真实密码。请改用环境变量或安全的凭据管理系统。

POST http://localhost:6688/tasks/create
{
  "task_type": "load",
  "graph": "testdb",
  "params": {
    "load.parallel": "50",
    "load.type": "hugegraph",
    "load.hg_pd_peers": "[\"<your-hugegraph-ip>:8686\"]",
    "load.hugegraph_name": "DEFAULT/hugegraph2/g",
    "load.hugegraph_username": "admin",
    "load.hugegraph_password": "<your-password-here>",
    "load.use_out_degree": "1",
    "load.use_outedge": "1"
  }
}
  1. 从hdfs加载

request 示例:

POST http://localhost:6688/tasks/create
{
  "task_type": "load",
  "graph": "testdb",
  "params": {
    "load.parallel": "50",
    "load.type": "hdfs",
    "load.hdfs_namenode": "name_node1:9000",
    "load.hdfs_conf_path": "/path/to/conf",
    "load.krb_realm": "EXAMPLE.COM",
    "load.krb_name": "user@EXAMPLE.COM",
    "load.krb_keytab_path": "/path/to/keytab",
    "load.krb_conf_path": "/path/to/krb5.conf",
    "load.hdfs_use_krb": "1",
    "load.vertex_files": "/data/graph/vertices",
    "load.edge_files": "/data/graph/edges",
    "load.use_out_degree": "1",
    "load.use_outedge": "1"
  }
}

2.3 输出计算结果

所有的 vermeer 计算任务均支持多种结果输出方式,可自定义输出方式:local、hdfs、afs 或 hugegraph,在发送请求时的 params 参数下加入对应参数,即可生效。指定 output.need_statistics 为 1 时,支持计算结果统计信息输出,结果会写在接口任务信息内。统计模式算子目前支持 “count” 和 “modularity” 。但仅针对社区发现算法适用。

具体参数参考 Vermeer 参数列表文档。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "pagerank",
 "compute.parallel": "10",
 "compute.max_step": "10",
 "output.type": "local",
 "output.parallel": "1",
 "output.file_path": "result/pagerank"
  }
}

三、支持的算法

3.1 PageRank

PageRank 算法又称网页排名算法,是一种由搜索引擎根据网页(节点)之间相互的超链接进行计算的技

术,用来体现网页(节点)的相关性和重要性。

  • 如果一个网页被很多其他网页链接到,说明这个网页比较重要,也就是其 PageRank 值会相对较高。
  • 如果一个 PageRank 值很高的网页链接到其他网页,那么被链接到的网页的 PageRank 值会相应地提高。

PageRank 算法适用于网页排序、社交网络重点人物发掘等场景。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "pagerank",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/pagerank",
 "compute.max_step":"10"
 }
}

3.2 WCC(弱连通分量)

弱连通分量,计算无向图中所有联通的子图,输出各顶点所属的弱联通子图 id,表明各个点之间的连通性,区分不同的连通社区。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "wcc",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/wcc",
 "compute.max_step":"10"
 }
}

3.3 LPA(标签传播)

标签传递算法,是一种图聚类算法,常用在社交网络中,用于发现潜在的社区。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "lpa",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/lpa",
 "compute.max_step":"10"
 }
}

3.4 Degree Centrality(度中心性)

度中心性算法,算法用于计算图中每个节点的度中心性值,支持无向图和有向图。度中心性是衡量节点重要性的重要指标,节点与其它节点的边越多,则节点的度中心性值越大,节点在图中的重要性也就越高。在无向图中,度中心性的计算是基于边信息统计节点出现次数,得出节点的度中心性的值,在有向图中则基于边的方向进行筛选,基于输入边或输出边信息统计节点出现次数,得到节点的入度值或出度值。它表明各个点的重要性,一般越重要的点度数越高。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "degree",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/degree",
 "degree.direction":"both"
 }
}

3.5 Closeness Centrality(紧密中心性)

紧密中心性(Closeness Centrality)用于计算一个节点到所有其他可达节点的最短距离的倒数,进行累积后归一化的值。紧密中心度可以用来衡量信息从该节点传输到其他节点的时间长短。节点的“Closeness Centrality”越大,其在所在图中的位置越靠近中心,适用于社交网络中关键节点发掘等场景。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "closeness_centrality",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/closeness_centrality",
 "closeness_centrality.sample_rate":"0.01"
 }
}

3.6 Betweenness Centrality(中介中心性算法)

中介中心性算法(Betweeness Centrality)判断一个节点具有"桥梁"节点的值,值越大说明它作为图中两点间必经路径的可能性越大,典型的例子包括社交网络中的共同关注的人。适用于衡量社群围绕某个节点的聚集程度。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "betweenness_centrality",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/betweenness_centrality",
 "betweenness_centrality.sample_rate":"0.01"
 }
}

3.7 Triangle Count(三角形计数)

三角形计数算法,用于计算通过每个顶点的三角形个数,适用于计算用户之间的关系,关联性是不是成三角形。三角形越多,代表图中节点关联程度越高,组织关系越严密。社交网络中的三角形表示存在有凝聚力的社区,识别三角形有助于理解网络中个人或群体的聚类和相互联系。在金融网络或交易网络中,三角形的存在可能表示存在可疑或欺诈活动,三角形计数可以帮助识别可能需要进一步调查的交易模式。

输出的结果为 每个顶点对应一个 Triangle Count,即为每个顶点所在三角形的个数。

注:该算法为无向图算法,忽略边的方向。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "triangle_count",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/triangle_count"
 }
}

3.8 K-Core

K-Core 算法,标记所有度数为 K 的顶点,适用于图的剪枝,查找图的核心部分。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "kcore",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/kcore",
 "kcore.degree_k":"5"
 }
}

3.9 SSSP(单元最短路径)

单源最短路径算法,求一个点到其他所有点的最短距离。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "sssp",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/degree",
 "sssp.source":"tom"
 }
}

3.10 KOUT

以一个点为起点,获取这个点的 k 层的节点。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "kout",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/kout",
 "kout.source":"tom",
 "compute.max_step":"6"
 }
}

3.11 Louvain

Louvain 算法是一种基于模块度的社区发现算法。其基本思想是网络中节点尝试遍历所有邻居的社区标签,并选择最大化模块度增量的社区标签。在最大化模块度之后,每个社区看成一个新的节点,重复直到模块度不再增大。

Vermeer 上实现的分布式 Louvain 算法受节点顺序、并行计算等因素影响,并且由于 Louvain 算法由于其遍历顺序的随机导致社区压缩也具有一定的随机性,导致重复多次执行可能存在不同的结果。但整体趋势不会有大的变化。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "louvain",
 "compute.parallel":"10",
 "compute.max_step":"1000",
 "louvain.threshold":"0.0000001",
 "louvain.resolution":"1.0",
 "louvain.step":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/louvain"
  }
 }

3.12 Jaccard 相似度系数

Jaccard index , 又称为 Jaccard 相似系数(Jaccard similarity coefficient)用于比较有限样本集之间的相似性与差异性。Jaccard 系数值越大,样本相似度越高。用于计算一个给定的源点,与图中其他所有点的 Jaccard 相似系数。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "jaccard",
 "compute.parallel":"10",
 "compute.max_step":"2",
 "jaccard.source":"123",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/jaccard"
 }
}

3.13 Personalized PageRank

个性化的 pagerank 的目标是要计算所有节点相对于用户 u 的相关度。从用户 u 对应的节点开始游走,每到一个节点都以 1-d 的概率停止游走并从 u 重新开始,或者以 d 的概率继续游走,从当前节点指向的节点中按照均匀分布随机选择一个节点往下游走。用于给定一个起点,计算此起点开始游走的个性化 pagerank 得分。适用于社交推荐等场景。

由于计算需要使用出度,需要在读取图时需要设置 load.use_out_degree 为 1。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "ppr",
 "compute.parallel":"100",
 "compute.max_step":"10",
 "ppr.source":"123",
 "ppr.damping":"0.85",
 "ppr.diff_threshold":"0.00001",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/ppr"
 }
}

3.14 全图 Kout

计算图的所有节点的k度邻居(不包含自己以及1~k-1度的邻居),由于全图kout算法内存膨胀比较厉害,目前k限制在1和2,另外,全局kout算法支持过滤功能( 参数如:“compute.filter”:“risk_level==1”),在计算第k度的是时候进行过滤条件的判断,符合过滤条件的进入最终结果集,算法最终输出是符合条件的邻居个数。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "kout_all",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"10",
 "output.file_path":"result/kout",
 "compute.max_step":"2"
 "compute.filter":"risk_level==1"
 }
}

3.15 集聚系数 clustering coefficient

集聚系数表示一个图中节点聚集程度的系数。在现实的网络中,尤其是在特定的网络中,由于相对高密度连接点的关系,节点总是趋向于建立一组严密的组织关系。集聚系数算法(Cluster Coefficient)用于计算图中节点的聚集程度。本算法为局部集聚系数。局部集聚系数可以测量图中每一个结点附近的集聚程度。

request 示例:

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "clustering_coefficient",
 "compute.parallel":"100",
 "compute.max_step":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/cc"
 }
}

3.16 SCC(强连通分量)

在有向图的数学理论中,如果一个图的每一个顶点都可从该图其他任意一点到达,则称该图是强连通的。在任意有向图中能够实现强连通的部分我们称其为强连通分量。它表明各个点之间的连通性,区分不同的连通社区。

POST http://localhost:6688/tasks/create
{
 "task_type": "compute",
 "graph": "testdb",
 "params": {
 "compute.algorithm": "scc",
 "compute.parallel":"10",
 "output.type":"local",
 "output.parallel":"1",
 "output.file_path":"result/scc",
 "compute.max_step":"200"
 }
}

🚧, 后续随时更新完善,欢迎随时提出建议和意见。

4.2 - HugeGraph-Computer Quick Start

1 HugeGraph-Computer 概述

HugeGraph-Computer 是分布式图处理系统 (OLAP). 它是 Pregel的一个实现。它可以运行在 Kubernetes(K8s)/Yarn 上。(它侧重可支持百亿~千亿的图数据量下进行图计算, 会使用磁盘进行排序和加速, 这是它和 Vermeer 相对最大的区别之一)

特性

  • 支持分布式 MPP 图计算,集成 HugeGraph 作为图输入输出存储。
  • 算法基于 BSP(Bulk Synchronous Parallel) 模型,通过多次并行迭代进行计算,每一次迭代都是一次超步。
  • 自动内存管理。该框架永远不会出现 OOM(内存不足),因为如果它没有足够的内存来容纳所有数据,它会将一些数据拆分到磁盘。
  • 边的部分或超级节点的消息可以在内存中,所以你永远不会丢失它。
  • 您可以从 HDFS 或 HugeGraph 或任何其他系统加载数据。
  • 您可以将结果输出到 HDFS 或 HugeGraph,或任何其他系统。
  • 易于开发新算法。您只需要像在单个服务器中一样专注于仅顶点处理,而不必担心消息传输和内存存储管理。

2 依赖

2.1 安装 Java 11 (JDK 11)

必须在 ≥ Java 11 的环境上启动 Computer,然后自行配置。

在往下阅读之前务必执行 java -version 命令查看 jdk 版本

3 开始

3.1 在本地运行 PageRank 算法

要使用 HugeGraph-Computer 运行算法,必须装有 Java 11 或更高版本。

还需要首先部署 HugeGraph-Server 和 Etcd.

有两种方式可以获取 HugeGraph-Computer:

  • 下载已编译的压缩包
  • 克隆源码编译打包

3.1.1 下载已编译的压缩包

下载最新版本的 HugeGraph-Computer release 包:

wget https://downloads.apache.org/hugegraph/${version}/apache-hugegraph-computer-incubating-${version}.tar.gz
tar zxvf apache-hugegraph-computer-incubating-${version}.tar.gz -C hugegraph-computer

3.1.2 克隆源码编译打包

克隆最新版本的 HugeGraph-Computer 源码包:

$ git clone https://github.com/apache/hugegraph-computer.git

编译生成 tar 包:

cd hugegraph-computer
mvn clean package -DskipTests

3.1.3 启动 master 节点

您可以使用 -c 参数指定配置文件,更多 computer 配置请看:Computer 配置选项

cd hugegraph-computer
bin/start-computer.sh -d local -r master

3.1.4 启动 worker 节点

bin/start-computer.sh -d local -r worker

3.1.5 查询算法结果

2.5.1 为 server 启用 OLAP 索引查询

如果没有启用 OLAP 索引,则需要启用,更多参考:modify-graphs-read-mode

PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph_read_mode

"ALL"

3.1.5.2 查询 page_rank 属性值:

curl "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices?page&limit=3" | gunzip

3.2 在 Kubernetes 中运行 PageRank 算法

要使用 HugeGraph-Computer 运行算法,您需要先部署 HugeGraph-Server

3.2.1 安装 HugeGraph-Computer CRD

# Kubernetes version >= v1.16
kubectl apply -f https://raw.githubusercontent.com/apache/hugegraph-computer/master/computer-k8s-operator/manifest/hugegraph-computer-crd.v1.yaml

# Kubernetes version < v1.16
kubectl apply -f https://raw.githubusercontent.com/apache/hugegraph-computer/master/computer-k8s-operator/manifest/hugegraph-computer-crd.v1beta1.yaml

3.2.2 显示 CRD

kubectl get crd

NAME                                        CREATED AT
hugegraphcomputerjobs.hugegraph.apache.org   2021-09-16T08:01:08Z

3.2.3 安装 hugegraph-computer-operator&etcd-server

kubectl apply -f https://raw.githubusercontent.com/apache/hugegraph-computer/master/computer-k8s-operator/manifest/hugegraph-computer-operator.yaml

3.2.4 等待 hugegraph-computer-operator&etcd-server 部署完成

kubectl get pod -n hugegraph-computer-operator-system

NAME                                                              READY   STATUS    RESTARTS   AGE
hugegraph-computer-operator-controller-manager-58c5545949-jqvzl   1/1     Running   0          15h
hugegraph-computer-operator-etcd-28lm67jxk5                       1/1     Running   0          15h

3.2.5 提交作业

更多 computer crd spec 请看:Computer CRD

更多 Computer 配置请看:Computer 配置选项

cat <<EOF | kubectl apply --filename -
apiVersion: hugegraph.apache.org/v1
kind: HugeGraphComputerJob
metadata:
  namespace: hugegraph-computer-operator-system
  name: &jobName pagerank-sample
spec:
  jobId: *jobName
  algorithmName: page_rank
  image: hugegraph/hugegraph-computer:latest # algorithm image url
  jarFile: /hugegraph/hugegraph-computer/algorithm/builtin-algorithm.jar # algorithm jar path
  pullPolicy: Always
  workerCpu: "4"
  workerMemory: "4Gi"
  workerInstances: 5
  computerConf:
    job.partitions_count: "20"
    algorithm.params_class: org.apache.hugegraph.computer.algorithm.centrality.pagerank.PageRankParams
    hugegraph.url: http://${hugegraph-server-host}:${hugegraph-server-port} # hugegraph server url
    hugegraph.name: hugegraph # hugegraph graph name
EOF

3.2.6 显示作业

kubectl get hcjob/pagerank-sample -n hugegraph-computer-operator-system

NAME               JOBID              JOBSTATUS
pagerank-sample    pagerank-sample    RUNNING

3.2.7 显示节点日志

# Show the master log
kubectl logs -l component=pagerank-sample-master -n hugegraph-computer-operator-system

# Show the worker log
kubectl logs -l component=pagerank-sample-worker -n hugegraph-computer-operator-system

# Show diagnostic log of a job
# 注意: 诊断日志仅在作业失败时存在,并且只会保存一小时。
kubectl get event --field-selector reason=ComputerJobFailed --field-selector involvedObject.name=pagerank-sample -n hugegraph-computer-operator-system

3.2.8 显示作业的成功事件

NOTE: it will only be saved for one hour

kubectl get event --field-selector reason=ComputerJobSucceed --field-selector involvedObject.name=pagerank-sample -n hugegraph-computer-operator-system

3.2.9 查询算法结果

如果输出到 Hugegraph-Server 则与 Locally 模式一致,如果输出到 HDFS ,请检查 hugegraph-computerresults{jobId}目录下的结果文件。

4 内置算法文档

4.1 支持的算法列表:

中心性算法:

  • PageRank
  • BetweennessCentrality
  • ClosenessCentrality
  • DegreeCentrality

社区算法:

  • ClusteringCoefficient
  • Kcore
  • Lpa
  • TriangleCount
  • Wcc

路径算法:

  • RingsDetection
  • RingsDetectionWithFilter

更多算法请看:Built-In algorithms

4.2 算法描述

TODO

5 算法开发指南

TODO

6 注意事项

  • 如果 computer-k8s 模块下面的某些类不存在,你需要运行mvn compile来提前生成对应的类。

4.3 - HugeGraph-Computer 配置参考

Computer 配置选项

表格中的默认值来自 computer-api 模块的 ComputerOptions.java。分发包的 conf/computer.properties 显式覆盖某项时,表格以“代码默认值(打包:实际值)”标注;程序启动后以配置文件中的值为准。


1. 基础配置

HugeGraph-Computer 核心作业设置。

配置项默认值说明
hugegraph.urlhttp://127.0.0.1:8080HugeGraph 服务器 URL,用于加载数据和写回结果。
hugegraph.namehugegraph图名称,用于加载数据和写回结果。
hugegraph.username"" (空)HugeGraph 认证用户名(如果未启用认证则留空)。
hugegraph.password"" (空)HugeGraph 认证密码(如果未启用认证则留空)。
job.idlocal_0001 (打包: local_001)YARN 集群或 K8s 集群上的作业标识符。
job.namespace"" (空)作业命名空间,可以分隔不同的数据源。该项由运行系统管理。
job.workers_count1执行一个图算法作业的 Worker 数量。在 K8s 中由 Operator 设置。
job.partitions_count1执行一个图算法作业的分区数量。
job.partitions_thread_nums4分区并行计算的线程数量。

2. 算法配置

计算逻辑的算法特定配置。

配置项默认值说明
algorithm.params_classComputerOptions.Null 占位类必填。用于在算法运行前传递算法参数的类。
algorithm.result_classComputerOptions.Null 占位类顶点值的类,用于存储顶点的计算结果。
algorithm.message_classComputerOptions.Null 占位类计算顶点时传递的消息类。

3. 输入配置

从 HugeGraph 或其他数据源加载输入数据的配置。

3.1 输入源

配置项默认值说明
input.source_typehugegraph-server加载输入数据的源类型,允许值:[‘hugegraph-server’, ‘hugegraph-loader’]。‘hugegraph-loader’ 表示使用 hugegraph-loader 从 HDFS 或文件加载数据。如果使用 ‘hugegraph-loader’,请配置 ‘input.loader_struct_path’ 和 ‘input.loader_schema_path’。
input.loader_struct_path"" (空)Loader 输入的结构路径,仅在 input.source_type=hugegraph-loader 时生效。
input.loader_schema_path"" (空)Loader 输入的 Schema 路径,仅在 input.source_type=hugegraph-loader 时生效。

3.2 输入分片

配置项默认值说明
input.split_size1048576 (1 MB)输入分片大小(字节)。
input.split_max_splits10000000最大输入分片数量。
input.split_page_size500流式加载输入分片数据的页面大小。
input.split_fetch_timeout300获取输入分片的超时时间(秒)。

3.3 输入处理

配置项默认值说明
input.filter_classorg.apache.hugegraph.computer.core.input.filter.DefaultInputFilter创建输入过滤器对象的类。输入过滤器用于根据用户需求过滤顶点边。
input.edge_directionOUT要加载的边的方向,允许值:[OUT, IN, BOTH]。当值为 BOTH 时,将加载 OUT 和 IN 两个方向的边。
input.edge_freqMULTIPLE一对顶点之间可以存在的边的频率,允许值:[SINGLE, SINGLE_PER_LABEL, MULTIPLE]。SINGLE 表示一对顶点之间只能存在一条边(通过 sourceId + targetId 标识);SINGLE_PER_LABEL 表示每个边标签在一对顶点之间可以有一条边(通过 sourceId + edgeLabel + targetId 标识);MULTIPLE 表示一对顶点之间可以存在多条边(通过 sourceId + edgeLabel + sortValues + targetId 标识)。
input.max_edges_in_one_vertex200允许附加到一个顶点的最大邻接边数量。邻接边将作为一个批处理单元一起存储和传输。

3.4 输入性能

配置项默认值说明
input.send_thread_nums4并行发送顶点或边的线程数量。

4. 快照与存储配置

HugeGraph-Computer 支持快照功能,可将顶点/边分区保存到本地存储或 MinIO 对象存储,用于断点恢复或加速重复计算。

4.1 基础快照配置

配置项默认值说明
snapshot.writefalse是否写入输入顶点/边分区的快照。
snapshot.loadfalse是否从顶点/边分区的快照加载。
snapshot.name"" (空)用户自定义的快照名称,用于区分不同的快照。

4.2 MinIO 集成(可选)

MinIO 可用作 K8s 部署中快照的分布式对象存储后端。

配置项默认值说明
snapshot.minio_endpoint"" (空)MinIO 服务端点(例如 http://minio:9000)。使用 MinIO 时必填。
snapshot.minio_access_keyminioadminMinIO 认证访问密钥。
snapshot.minio_secret_keyminioadminMinIO 认证密钥。
snapshot.minio_bucket_name"" (空)用于存储快照数据的 MinIO 存储桶名称。

使用场景:

  • 断点恢复:作业失败后从快照恢复,避免重新加载数据
  • 重复计算:多次运行同一算法时从快照加载数据以加速启动
  • A/B 测试:保存同一数据集的多个快照版本,测试不同的算法参数

示例:本地快照(在 computer.properties 中):

snapshot.write=true
snapshot.name=pagerank-snapshot-20260201

示例:MinIO 快照(在 K8s CRD computerConf 中):

computerConf:
  snapshot.write: "true"
  snapshot.name: "pagerank-snapshot-v1"
  snapshot.minio_endpoint: "http://minio:9000"
  snapshot.minio_access_key: "my-access-key"
  snapshot.minio_secret_key: "my-secret-key"
  snapshot.minio_bucket_name: "hugegraph-snapshots"

5. Worker 与 Master 配置

Worker 和 Master 计算逻辑的配置。

5.1 Master 配置

配置项默认值说明
master.computation_classorg.apache.hugegraph.computer.core.master.DefaultMasterComputationMaster 计算是可以决定是否继续下一个超步的计算。它在每个超步结束时在 master 上运行。

5.2 Worker 计算

配置项默认值说明
worker.computation_classorg.apache.hugegraph.computer.core.config.Null创建 worker 计算对象的类。Worker 计算用于在每个超步中计算每个顶点。
worker.combiner_classorg.apache.hugegraph.computer.core.config.NullCombiner 可以将消息组合为一个顶点的一个值。例如,PageRank 算法可以将一个顶点的消息组合为一个求和值。
worker.partitionerorg.apache.hugegraph.computer.core.graph.partition.HashPartitioner分区器,决定顶点应该在哪个分区中,以及分区应该在哪个 worker 中。

5.3 Worker 组合器

配置项默认值说明
worker.vertex_properties_combiner_classorg.apache.hugegraph.computer.core.combiner.OverwritePropertiesCombiner组合器可以在输入步骤将同一顶点的多个属性组合为一个属性。
worker.edge_properties_combiner_classorg.apache.hugegraph.computer.core.combiner.OverwritePropertiesCombiner组合器可以在输入步骤将同一边的多个属性组合为一个属性。

5.4 Worker 缓冲区

配置项默认值说明
worker.received_buffers_bytes_limit104857600 (100 MB)接收数据缓冲区的限制字节数。所有缓冲区的总大小不能超过此限制。如果接收缓冲区达到此限制,它们将被合并到文件中(溢出到磁盘)。
worker.write_buffer_capacity52428800 (50 MB)用于存储顶点或消息的写缓冲区的初始大小。
worker.write_buffer_threshold52428800 (50 MB)写缓冲区的阈值。超过它将触发排序。写缓冲区用于存储顶点或消息。

5.5 Worker 数据与超时

配置项默认值说明
worker.data_dirs[jobs]用逗号分隔的目录,接收的顶点和消息可以持久化到其中。
worker.wait_sort_timeout600000 (10 分钟)消息处理程序等待排序线程对一批缓冲区进行排序的最大超时时间(毫秒)。
worker.wait_finish_messages_timeout86400000 (24 小时)消息处理程序等待所有 worker 完成消息的最大超时时间(毫秒)。

6. I/O 与输出配置

输出计算结果的配置。

6.1 输出类与结果

配置项默认值说明
output.output_classorg.apache.hugegraph.computer.core.output.LogOutput输出每个顶点计算结果的类。在迭代计算后调用。
output.result_namevalue该值由 WORKER_COMPUTATION_CLASS 创建的实例的 #name() 动态分配。
output.result_write_typeOLAP_COMMON输出到 HugeGraph 的结果写入类型,允许值:[OLAP_COMMON, OLAP_SECONDARY, OLAP_RANGE]。

6.2 输出行为

配置项默认值说明
output.with_adjacent_edgesfalse是否输出顶点的邻接边。
output.with_vertex_propertiesfalse是否输出顶点的属性。
output.with_edge_propertiesfalse是否输出边的属性。

6.3 批量输出

配置项默认值说明
output.batch_size500输出的批处理大小。
output.batch_threads1用于批量输出的线程数量。
output.single_threads1用于单个输出的线程数量。

6.4 HDFS 输出

配置项默认值说明
output.hdfs_urlhdfs://127.0.0.1:9000输出的 HDFS URL。
output.hdfs_userhadoop输出的 HDFS 用户。
output.hdfs_path_prefix/hugegraph-computer/resultsHDFS 输出结果的目录。
output.hdfs_delimiter, (逗号)HDFS 输出的分隔符。
output.hdfs_merge_partitionstrue是否合并多个分区的输出文件。
output.hdfs_replication3HDFS 的副本数。
output.hdfs_core_site_path"" (空)HDFS core site 路径。
output.hdfs_site_path"" (空)HDFS site 路径。
output.hdfs_kerberos_enablefalse是否为 HDFS 启用 Kerberos 认证。
output.hdfs_kerberos_principal"" (空)HDFS 的 Kerberos 认证 principal。
output.hdfs_kerberos_keytab"" (空)HDFS 的 Kerberos 认证 keytab 文件。
output.hdfs_krb5_conf/etc/krb5.confKerberos 配置文件路径。

6.5 重试与超时

配置项默认值说明
output.retry_times3输出失败时的重试次数。
output.retry_interval10输出失败时的重试间隔(秒)。
output.thread_pool_shutdown_timeout60输出线程池关闭的超时时间(秒)。

7. 网络与传输配置

Worker 和 Master 之间网络通信的配置。

7.1 服务器配置

配置项默认值说明
transport.server_host127.0.0.1监听传输数据的主机名或 IP,由运行系统管理。
transport.server_port0监听传输数据的端口;0 表示分配随机端口。该项由运行系统管理。
transport.server_threads4服务器传输线程的数量。

7.2 客户端配置

配置项默认值说明
transport.client_threads4客户端传输线程的数量。
transport.client_connect_timeout3000客户端连接到服务器的超时时间(毫秒)。

7.3 协议配置

配置项默认值说明
transport.provider_classorg.apache.hugegraph.computer.core.network.netty.NettyTransportProvider传输提供程序,目前仅支持 Netty。
transport.io_modeAUTO网络 IO 模式,允许值:[NIO, EPOLL, AUTO]。AUTO 表示自动选择适当的模式。
transport.tcp_keep_alivetrue是否启用 TCP keep-alive。
transport.transport_epoll_ltfalse是否启用 EPOLL 水平触发(仅在 io_mode=EPOLL 时有效)。

7.4 缓冲区配置

配置项默认值说明
transport.send_buffer_size0Socket 发送缓冲区大小(字节)。0 表示使用系统默认值。
transport.receive_buffer_size0Socket 接收缓冲区大小(字节)。0 表示使用系统默认值。
transport.write_buffer_high_mark67108864 (64 MB)写缓冲区的高水位标记(字节)。如果排队字节数 > write_buffer_high_mark,将触发发送不可用。
transport.write_buffer_low_mark33554432 (32 MB)写缓冲区的低水位标记(字节)。如果排队字节数 < write_buffer_low_mark,将触发发送可用。

7.5 流量控制

配置项默认值说明
transport.max_pending_requests8客户端未接收 ACK 的最大数量。如果未接收 ACK 的数量 >= max_pending_requests,将触发发送不可用。
transport.min_pending_requests6客户端未接收 ACK 的最小数量。如果未接收 ACK 的数量 < min_pending_requests,将触发发送可用。
transport.min_ack_interval200服务器回复 ACK 的最小间隔(毫秒)。

7.6 超时配置

配置项默认值说明
transport.close_timeout10000关闭服务器或关闭客户端的超时时间(毫秒)。
transport.sync_request_timeout10000发送同步请求后等待响应的超时时间(毫秒)。
transport.finish_session_timeout0完成会话的超时时间(毫秒)。0 表示使用 (transport.sync_request_timeout × transport.max_pending_requests)。
transport.write_socket_timeout3000将数据写入 socket 缓冲区的超时时间(毫秒)。
transport.server_idle_timeout360000 (6 分钟)服务器空闲的最大超时时间(毫秒)。

7.7 心跳配置

配置项默认值说明
transport.heartbeat_interval20000 (20 秒)客户端心跳之间的最小间隔(毫秒)。
transport.max_timeout_heartbeat_count120客户端超时心跳的最大次数。如果连续等待心跳响应超时的次数 > max_timeout_heartbeat_count,通道将从客户端关闭。

7.8 高级网络设置

配置项默认值说明
transport.max_syn_backlog511服务器端 SYN 队列的容量。0 表示使用系统默认值。
transport.recv_file_modetrue是否启用接收缓冲文件模式。如果启用,将使用零拷贝从 socket 接收缓冲区并写入文件。注意:需要操作系统支持零拷贝(例如 Linux sendfile/splice)。
transport.network_retries3网络通信不稳定时的重试次数。

8. 存储与持久化配置

HGKV(HugeGraph Key-Value)存储引擎和值文件的配置。

8.1 HGKV 配置

配置项默认值说明
hgkv.max_file_size2147483648 (2 GB)每个 HGKV 文件的最大字节数。
hgkv.max_data_block_size65536 (64 KB)HGKV 文件数据块的最大字节大小。
hgkv.max_merge_files10一次合并的最大文件数。
hgkv.temp_file_dir/tmp/hgkv此文件夹用于在文件合并过程中存储临时文件。

8.2 值文件配置

配置项默认值说明
valuefile.max_segment_size1073741824 (1 GB)值文件每个段的最大字节数。

9. BSP 与协调配置

批量同步并行(BSP)协议和 etcd 协调的配置。

配置项默认值说明
bsp.etcd_endpointshttp://localhost:2379etcd 端点;多个地址用逗号分隔。K8s 部署中由 Operator 设置。
bsp.max_super_step10 (打包: 2)算法的最大超步数。
bsp.register_timeout300000 (打包: 100000)等待 master 和 worker 注册的最大超时时间(毫秒)。
bsp.wait_workers_timeout86400000 (24 小时)等待 worker BSP 事件的最大超时时间(毫秒)。
bsp.wait_master_timeout86400000 (24 小时)等待 master BSP 事件的最大超时时间(毫秒)。
bsp.log_interval30000 (30 秒)等待 BSP 事件时打印日志的日志间隔(毫秒)。

10. 性能调优配置

性能优化的配置。

配置项默认值说明
allocator.max_vertices_per_thread10000每个内存分配器中每个线程处理的最大顶点数。
sort.thread_nums4执行内部排序的线程数量。

11. 系统管理配置

以下配置由运行系统管理,不应由作业配置覆盖。

以下配置项由 K8s Operator、Driver 或运行时系统自动管理。手动修改将导致集群通信失败或作业调度错误。

配置项管理者说明
bsp.etcd_endpointsK8s Operator自动设置为 operator 的 etcd 服务地址
transport.server_host运行时自动设置为 pod/容器主机名
transport.server_port运行时自动分配随机端口
job.namespaceK8s Operator自动设置为作业命名空间
job.idK8s Operator自动从 CRD 设置为作业 ID
job.workers_countK8s Operator自动从 CRD workerInstances 设置
rpc.server_host运行时RPC 服务器主机名(系统管理)
rpc.server_port运行时RPC 服务器端口(系统管理)
rpc.remote_url运行时RPC 远程 URL(系统管理)

为什么禁止修改:

  • BSP/RPC 配置:必须与实际部署的 etcd/RPC 服务匹配。手动覆盖会破坏协调。
  • 作业配置:必须与 K8s CRD 规范匹配。不匹配会导致 worker 数量错误。
  • 传输配置:必须使用实际的 pod 主机名/端口。手动值会阻止 worker 间通信。

K8s Operator 配置选项

注意:选项需要通过环境变量设置进行转换,例如 k8s.internal_etcd_url => INTERNAL_ETCD_URL

配置项默认值说明
k8s.auto_destroy_podtrue作业完成或失败时是否自动销毁所有 pod。
k8s.close_reconciler_timeout120关闭 reconciler 的最大超时时间(毫秒)。
k8s.internal_etcd_urlhttp://127.0.0.1:2379operator 系统的内部 etcd URL。
k8s.max_reconcile_retry3reconcile 的最大重试次数。
k8s.probe_backlog50服务健康探针的最大积压。
k8s.probe_port9892controller 绑定的用于服务健康探针的端口。
k8s.ready_check_internal1000检查就绪的时间间隔(毫秒)。
k8s.ready_timeout30000检查就绪的最大超时时间(毫秒)。
k8s.reconciler_count10reconciler 线程的最大数量。
k8s.resync_period600000被监视资源进行 reconcile 的最小频率。
k8s.timezoneAsia/Shanghaicomputer 作业和 operator 的时区。
k8s.watch_namespacehugegraph-computer-system监视自定义资源的命名空间。使用 ‘*’ 监视所有命名空间。

HugeGraph-Computer CRD

CRD: https://github.com/apache/hugegraph-computer/blob/master/computer/computer-k8s-operator/manifest/hugegraph-computer-crd.v1.yaml

字段默认值说明必填
algorithmName算法名称。true
jobId作业 ID。true
image算法镜像。true
computerConfcomputer 配置选项的映射。true
workerInstancesworker 实例数量,将覆盖 ‘job.workers_count’ 选项。true
pullPolicyAlways镜像拉取策略,详情请参考:https://kubernetes.io/docs/concepts/containers/images/#image-pull-policyfalse
pullSecrets镜像拉取密钥,详情请参考:https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-podfalse
masterCpumaster 的 CPU 限制,单位可以是 ’m’ 或无单位,详情请参考:https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-cpufalse
workerCpuworker 的 CPU 限制,单位可以是 ’m’ 或无单位,详情请参考:https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-cpufalse
masterMemorymaster 的内存限制,单位可以是 Ei、Pi、Ti、Gi、Mi、Ki 之一,详情请参考:https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-memoryfalse
workerMemoryworker 的内存限制,单位可以是 Ei、Pi、Ti、Gi、Mi、Ki 之一,详情请参考:https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-memoryfalse
log4jXmlcomputer 作业的 log4j.xml 内容。false
jarFilecomputer 算法的 jar 路径。false
remoteJarUricomputer 算法的远程 jar URI,将覆盖算法镜像。false
jvmOptionscomputer 作业的 Java 启动参数。false
envVars请参考:https://kubernetes.io/docs/tasks/inject-data-application/define-interdependent-environment-variables/false
envFrom请参考:https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/false
masterCommandbin/start-computer.shmaster 的运行命令,等同于 Docker 的 ‘Entrypoint’ 字段。false
masterArgs["-r master", “-d k8s”]master 的运行参数,等同于 Docker 的 ‘Cmd’ 字段。false
workerCommandbin/start-computer.shworker 的运行命令,等同于 Docker 的 ‘Entrypoint’ 字段。false
workerArgs["-r worker", “-d k8s”]worker 的运行参数,等同于 Docker 的 ‘Cmd’ 字段。false
volumes请参考:https://kubernetes.io/docs/concepts/storage/volumes/false
volumeMounts请参考:https://kubernetes.io/docs/concepts/storage/volumes/false
secretPathsk8s-secret 名称和挂载路径的映射。false
configMapPathsk8s-configmap 名称和挂载路径的映射。false
podTemplateSpec请参考:https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-template-v1/#PodTemplateSpecfalse
securityContext请参考:https://kubernetes.io/docs/tasks/configure-pod-container/security-context/false

KubeDriver 配置选项

配置项默认值说明
k8s.build_image_bash_path用于构建镜像的命令路径。
k8s.enable_internal_algorithmtrue是否启用内部算法。
k8s.framework_image_urlhugegraph/hugegraph-computer:latestcomputer 框架的镜像 URL。
k8s.image_repository_password登录镜像仓库的密码。
k8s.image_repository_registry登录镜像仓库的地址。
k8s.image_repository_urlhugegraph/hugegraph-computer镜像仓库的 URL。
k8s.image_repository_username登录镜像仓库的用户名。
k8s.internal_algorithm[pageRank]所有内部算法的名称列表。注意:算法名称在这里使用驼峰命名法(例如 pageRank),但算法实现返回下划线命名法(例如 page_rank)。
k8s.internal_algorithm_image_urlhugegraph/hugegraph-computer:latest内部算法的镜像 URL。
k8s.jar_file_dir/cache/jars/算法 jar 将上传到的目录。
k8s.kube_config~/.kube/configk8s 配置文件的路径。
k8s.log4j_xml_pathcomputer 作业的 log4j.xml 路径。
k8s.namespacehugegraph-computer-systemhugegraph-computer 系统的命名空间。
k8s.pull_secret_names[]拉取镜像的 pull-secret 名称。

5 - HugeGraph Client

Java 和 Go Client 位于 HugeGraph Toolchain 仓库,Python Client 位于 HugeGraph-AI 仓库。三者的安装方式和 API 不完全相同,请进入对应页面查看。

5.1 - HugeGraph-Java-Client

1 HugeGraph-Client 概述

HugeGraph Java Client 将 Java API 转换为 HugeGraph Server 的 REST 请求,支持管理 Schema 和图数据、执行 Gremlin 及调用 Traverser API。详细接口见 Client API,本文给出 Java 项目的接入示例。

其他语言可使用 Go Client 或 HugeGraph-AI 仓库中的 Python Client

2 环境要求

  • JDK 11(当前 CI 使用版本;源码目标版本为 Java 8)
  • Maven 3.6+

3 使用流程

使用 HugeGraph-Client 的基本步骤如下:

  • 新建Eclipse/ IDEA Maven 项目;
  • 在 pom 文件中添加 HugeGraph-Client 依赖;
  • 创建类,调用 HugeGraph-Client 接口;

详细使用过程见下节完整示例。

4 完整示例

4.1 新建 Maven 工程

可以选择 Eclipse 或者 Intellij Idea 创建工程:

4.2 添加 hugegraph-client 依赖

添加 hugegraph-client 依赖


<dependencies>
    <dependency>
        <groupId>org.apache.hugegraph</groupId>
        <artifactId>hugegraph-client</artifactId>
        <!-- 请按下载页选择已发布版本 -->
        <version>1.7.0</version>
    </dependency>
</dependencies>

Client 与 Server 的开发版本可能不同。升级前应按对应发布说明核对兼容性。

4.3 Example

4.3.1 SingleExample
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.apache.hugegraph.driver.GraphManager;
import org.apache.hugegraph.driver.GremlinManager;
import org.apache.hugegraph.driver.HugeClient;
import org.apache.hugegraph.driver.SchemaManager;
import org.apache.hugegraph.structure.constant.T;
import org.apache.hugegraph.structure.graph.Edge;
import org.apache.hugegraph.structure.graph.Path;
import org.apache.hugegraph.structure.graph.Vertex;
import org.apache.hugegraph.structure.gremlin.Result;
import org.apache.hugegraph.structure.gremlin.ResultSet;

public class SingleExample {

    public static void main(String[] args) throws IOException {
        // If connect failed will throw a exception.
        HugeClient hugeClient = HugeClient.builder("http://localhost:8080",
                                                   "DEFAULT",
                                                   "hugegraph")
                                          .configUser("username", "password")
                                          // 这是示例,生产环境需要使用安全的凭证
                                          .build();

        SchemaManager schema = hugeClient.schema();

        schema.propertyKey("name").asText().ifNotExist().create();
        schema.propertyKey("age").asInt().ifNotExist().create();
        schema.propertyKey("city").asText().ifNotExist().create();
        schema.propertyKey("weight").asDouble().ifNotExist().create();
        schema.propertyKey("lang").asText().ifNotExist().create();
        schema.propertyKey("date").asDate().ifNotExist().create();
        schema.propertyKey("price").asInt().ifNotExist().create();

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

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

        schema.indexLabel("personByCity")
              .onV("person")
              .by("city")
              .secondary()
              .ifNotExist()
              .create();

        schema.indexLabel("personByAgeAndCity")
              .onV("person")
              .by("age", "city")
              .secondary()
              .ifNotExist()
              .create();

        schema.indexLabel("softwareByPrice")
              .onV("software")
              .by("price")
              .range()
              .ifNotExist()
              .create();

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

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

        schema.indexLabel("createdByDate")
              .onE("created")
              .by("date")
              .secondary()
              .ifNotExist()
              .create();

        schema.indexLabel("createdByWeight")
              .onE("created")
              .by("weight")
              .range()
              .ifNotExist()
              .create();

        schema.indexLabel("knowsByWeight")
              .onE("knows")
              .by("weight")
              .range()
              .ifNotExist()
              .create();

        GraphManager graph = hugeClient.graph();
        Vertex marko = graph.addVertex(T.LABEL, "person", "name", "marko",
                                       "age", 29, "city", "Beijing");
        Vertex vadas = graph.addVertex(T.LABEL, "person", "name", "vadas",
                                       "age", 27, "city", "Hongkong");
        Vertex lop = graph.addVertex(T.LABEL, "software", "name", "lop",
                                     "lang", "java", "price", 328);
        Vertex josh = graph.addVertex(T.LABEL, "person", "name", "josh",
                                      "age", 32, "city", "Beijing");
        Vertex ripple = graph.addVertex(T.LABEL, "software", "name", "ripple",
                                        "lang", "java", "price", 199);
        Vertex peter = graph.addVertex(T.LABEL, "person", "name", "peter",
                                       "age", 35, "city", "Shanghai");

        marko.addEdge("knows", vadas, "date", "2016-01-10", "weight", 0.5);
        marko.addEdge("knows", josh, "date", "2013-02-20", "weight", 1.0);
        marko.addEdge("created", lop, "date", "2017-12-10", "weight", 0.4);
        josh.addEdge("created", lop, "date", "2009-11-11", "weight", 0.4);
        josh.addEdge("created", ripple, "date", "2017-12-10", "weight", 1.0);
        peter.addEdge("created", lop, "date", "2017-03-24", "weight", 0.2);

        GremlinManager gremlin = hugeClient.gremlin();
        System.out.println("==== Path ====");
        ResultSet resultSet = gremlin.gremlin("g.V().outE().path()").execute();
        Iterator<Result> results = resultSet.iterator();
        results.forEachRemaining(result -> {
            System.out.println(result.getObject().getClass());
            Object object = result.getObject();
            if (object instanceof Vertex) {
                System.out.println(((Vertex) object).id());
            } else if (object instanceof Edge) {
                System.out.println(((Edge) object).id());
            } else if (object instanceof Path) {
                List<Object> elements = ((Path) object).objects();
                elements.forEach(element -> {
                    System.out.println(element.getClass());
                    System.out.println(element);
                });
            } else {
                System.out.println(object);
            }
        });

        hugeClient.close();
    }
}
4.3.2 BatchExample
import java.util.ArrayList;
import java.util.List;

import org.apache.hugegraph.driver.GraphManager;
import org.apache.hugegraph.driver.HugeClient;
import org.apache.hugegraph.driver.SchemaManager;
import org.apache.hugegraph.structure.graph.Edge;
import org.apache.hugegraph.structure.graph.Vertex;

public class BatchExample {

    public static void main(String[] args) {
        // If connect failed will throw a exception.
        HugeClient hugeClient = HugeClient.builder("http://localhost:8080",
                                                "DEFAULT",
                                                "hugegraph")
                                          .configUser("username", "password")
                                          // 这是示例,生产环境需要使用安全的凭证
                                          .build();

        SchemaManager schema = hugeClient.schema();

        schema.propertyKey("name").asText().ifNotExist().create();
        schema.propertyKey("age").asInt().ifNotExist().create();
        schema.propertyKey("lang").asText().ifNotExist().create();
        schema.propertyKey("date").asDate().ifNotExist().create();
        schema.propertyKey("price").asInt().ifNotExist().create();

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

        schema.vertexLabel("person")
              .properties("price")
              .nullableKeys("price")
              .append();

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

        schema.indexLabel("softwareByPrice")
              .onV("software").by("price")
              .range()
              .ifNotExist()
              .create();

        schema.edgeLabel("knows")
              .link("person", "person")
              .properties("date")
              .ifNotExist()
              .create();

        schema.edgeLabel("created")
              .link("person", "software")
              .properties("date")
              .ifNotExist()
              .create();

        schema.indexLabel("createdByDate")
              .onE("created").by("date")
              .secondary()
              .ifNotExist()
              .create();

        // get schema object by name
        System.out.println(schema.getPropertyKey("name"));
        System.out.println(schema.getVertexLabel("person"));
        System.out.println(schema.getEdgeLabel("knows"));
        System.out.println(schema.getIndexLabel("createdByDate"));

        // list all schema objects
        System.out.println(schema.getPropertyKeys());
        System.out.println(schema.getVertexLabels());
        System.out.println(schema.getEdgeLabels());
        System.out.println(schema.getIndexLabels());

        GraphManager graph = hugeClient.graph();

        Vertex marko = new Vertex("person").property("name", "marko")
                                           .property("age", 29);
        Vertex vadas = new Vertex("person").property("name", "vadas")
                                           .property("age", 27);
        Vertex lop = new Vertex("software").property("name", "lop")
                                           .property("lang", "java")
                                           .property("price", 328);
        Vertex josh = new Vertex("person").property("name", "josh")
                                          .property("age", 32);
        Vertex ripple = new Vertex("software").property("name", "ripple")
                                              .property("lang", "java")
                                              .property("price", 199);
        Vertex peter = new Vertex("person").property("name", "peter")
                                           .property("age", 35);

        Edge markoKnowsVadas = new Edge("knows").source(marko).target(vadas)
                                                .property("date", "2016-01-10");
        Edge markoKnowsJosh = new Edge("knows").source(marko).target(josh)
                                               .property("date", "2013-02-20");
        Edge markoCreateLop = new Edge("created").source(marko).target(lop)
                                                 .property("date",
                                                           "2017-12-10");
        Edge joshCreateRipple = new Edge("created").source(josh).target(ripple)
                                                   .property("date",
                                                             "2017-12-10");
        Edge joshCreateLop = new Edge("created").source(josh).target(lop)
                                                .property("date", "2009-11-11");
        Edge peterCreateLop = new Edge("created").source(peter).target(lop)
                                                 .property("date",
                                                           "2017-03-24");

        List<Vertex> vertices = new ArrayList<>();
        vertices.add(marko);
        vertices.add(vadas);
        vertices.add(lop);
        vertices.add(josh);
        vertices.add(ripple);
        vertices.add(peter);

        List<Edge> edges = new ArrayList<>();
        edges.add(markoKnowsVadas);
        edges.add(markoKnowsJosh);
        edges.add(markoCreateLop);
        edges.add(joshCreateRipple);
        edges.add(joshCreateLop);
        edges.add(peterCreateLop);

        vertices = graph.addVertices(vertices);
        vertices.forEach(vertex -> System.out.println(vertex));

        edges = graph.addEdges(edges, false);
        edges.forEach(edge -> System.out.println(edge));

        hugeClient.close();
    }
}

4.4 运行 Example

运行 Example 之前需要启动 Server, 启动过程见HugeGraph-Server Quick Start

4.5 详细 API 说明

示例说明见HugeGraph-Client 基本 API 介绍

5.2 - HugeGraph Python 客户端快速入门

hugegraph-python-client 是 HugeGraph 的 Python SDK,可管理 Schema、读写图数据并执行 Gremlin 查询。HugeGraph-LLM 和 HugeGraph-ML 也使用这个客户端。

该模块位于 hugegraph-ai 仓库的 hugegraph-python-client/ 目录下,导入名为 pyhugegraph

环境要求

  • 客户端本身要求 Python 3.9 或更高版本。HugeGraph-AI workspace 要求 Python 3.10 或更高版本,CI 在 3.10 和 3.11 上运行客户端测试。
  • HugeGraph Server 1.5.0 或更高版本。客户端会拒绝连接更低版本的 Server,此类场景请改用 v1.3.x 客户端。
  • uv(推荐)或 pip

运行时依赖为 decoratorrequestssetuptoolsurllib3rich

安装

发布到 PyPI 的包名是 hugegraph-python

uv pip install hugegraph-python
# 也可以使用 pip install hugegraph-python

PyPI 上的发布版本落后于仓库代码。在源码中该发行包声明为 hugegraph-python-client,版本号与 HugeGraph-AI 其他模块保持一致,需要最新代码时请从源码安装。

如需使用仓库中的最新代码,请从 HugeGraph-AI 仓库根目录同步 workspace。hugegraph-python-client 是 workspace 成员,通过 python-client extra 暴露,因此仅执行 uv sync 不会安装它:

git clone https://github.com/apache/hugegraph-ai.git
cd hugegraph-ai
uv sync --extra python-client
source .venv/bin/activate

连接并写入数据

from pyhugegraph.client import PyHugeClient

client = PyHugeClient(
    url="http://127.0.0.1:8080",
    graph="hugegraph",
    user="admin",
    pwd="admin",
    graphspace=None,
)

schema = client.schema()
schema.propertyKey("name").asText().ifNotExist().create()
schema.propertyKey("birthDate").asText().ifNotExist().create()
schema.vertexLabel("Person").properties("name", "birthDate") \
      .usePrimaryKeyId().primaryKeys("name").ifNotExist().create()
schema.vertexLabel("Movie").properties("name") \
      .usePrimaryKeyId().primaryKeys("name").ifNotExist().create()
schema.edgeLabel("ActedIn").sourceLabel("Person").targetLabel("Movie") \
      .ifNotExist().create()

graph = client.graph()
person = graph.addVertex(
    "Person", {"name": "Al Pacino", "birthDate": "1940-04-25"}
)
movie = graph.addVertex("Movie", {"name": "The Godfather"})
edge = graph.addEdge("ActedIn", person.id, movie.id, {})

print(graph.getVertexById(person.id))
print(graph.getEdgeById(edge.id))
graph.close()

客户端参数

PyHugeClient(url, graph, user, pwd, graphspace=None, timeout=None)

参数类型默认值说明
urlstr必填HugeGraph Server 的基础 URL。若未带协议头,客户端会自动补上 http://,因此 127.0.0.1:8080 也可以使用。
graphstr必填图名称,是第二个位置参数。
userstr必填用户名,以 HTTP Basic Auth 发送。
pwdstr必填密码,以 HTTP Basic Auth 发送。
graphspacestrNoneNoneGraphSpace 名称,None 的解析规则见下文。
timeouttuple[float, float]NoneNone(连接, 读取) 超时时间,单位为秒。None 会取 (0.5, 15.0)

每个 HTTP 会话在收到 500、502、504 响应时会重试 3 次,退避因子为 0.1。

Server 版本与 GraphSpace

客户端在构造时解析 GraphSpace:

  • 传入非空的 graphspace 字符串时直接开启 GraphSpace 模式。
  • 否则客户端会请求 GET {url}/versions 并读取 versions.core
  • Server 版本低于 1.5.0 时抛出 RuntimeError,提示升级 Server 或改用 v1.3.x 客户端。
  • Server 版本高于 1.5.0 时会把 graphspace 设为 DEFAULT 并开启 GraphSpace 模式,同时在日志中打印警告。版本恰好为 1.5.0 时保持关闭。
  • 若因网络原因探测失败,GraphSpace 模式保持关闭。

该模式决定请求前缀:开启时为 /graphspaces/<graphspace>/graphs/<graph>/...,关闭时为 /graphs/<graph>/...

客户端提供的 Manager

每个访问器都会惰性创建对应的 Manager,并为其分配独立的 HTTP 会话。

访问器Manager覆盖范围
client.schema()SchemaManager属性、顶点标签、边标签、索引标签
client.graph()GraphManager顶点与边的增删改查、批量写入、分页
client.gremlin()GremlinManager执行 Gremlin
client.graphs()GraphsManager图列表、图信息、配置、清空数据
client.traverser()TraverserManager遍历与路径算法
client.variable()VariableManager图变量
client.task()TaskManager异步任务的查询、取消、删除
client.auth()AuthManager用户、用户组、资源、归属、权限
client.metrics()MetricsManagerServer 指标
client.version()VersionManagerServer 版本

pyhugegraph.api 中还提供了 RankManagerRebuildManagerServicesManager,但 PyHugeClient 暂未提供对应的访问器,需要时可自行传入 session 构造。

常用操作

构建 Schema

Schema 构建器采用链式调用,最后调用 create(),也可以用 append()eliminate()remove() 修改已有定义。

schema = client.schema()

# 属性类型:asText/asInt/asLong/asFloat/asDouble/asBool/asByte/asBlob/asDate/asObject
# 基数:valueSingle/valueList/valueSet
# 聚合:calcMax/calcMin/calcSum/calcOld
schema.propertyKey("age").asInt().valueSingle().ifNotExist().create()

# 顶点标签 ID 策略:useAutomaticId/useCustomizeStringId/useCustomizeNumberId/usePrimaryKeyId
schema.vertexLabel("person").properties("name", "age", "city") \
      .primaryKeys("name").nullableKeys("city").ifNotExist().create()

# 边标签:link() 等价于 sourceLabel() 加 targetLabel()
schema.edgeLabel("knows").link("person", "person").multiTimes() \
      .properties("date", "city").sortKeys("date").nullableKeys("city") \
      .ifNotExist().create()

# 索引标签:先 onV/onE,再选择 secondary/range/search/shard/unique
schema.indexLabel("personByCity").onV("person").by("city") \
      .secondary().ifNotExist().create()

查询 Schema

schema = client.schema()
print(schema.getSchema())            # 完整 Schema,format 默认为 json
print(schema.getPropertyKeys())
print(schema.getVertexLabels())
print(schema.getEdgeLabels())
print(schema.getIndexLabels())

# 查询单个定义
print(schema.getPropertyKey("name"))
print(schema.getVertexLabel("person"))
print(schema.getEdgeLabel("knows"))
print(schema.getIndexLabel("personByCity"))

# 边标签的连接关系,格式形如 Person--ActedIn-->Movie
print(schema.getRelations())

读取、更新和删除图数据

图接口直接接收属性字典,不支持链式的属性构建器:

graph = client.graph()
graph.appendVertex(person.id, {"birthDate": "1940-04-25"})    # 追加属性
graph.eliminateVertex(person.id, {"birthDate": "1940-04-25"}) # 删除属性
graph.appendEdge(edge.id, {"city": "Beijing"})
graph.eliminateEdge(edge.id, {"city": "Beijing"})
graph.removeEdgeById(edge.id)
graph.removeVertexById(person.id)
graph.close()

addVertex 返回 VertexData,包含 idlabeltypepropertiesaddEdge 返回 EdgeData,包含 idlabeltypeoutVoutVLabelinVinVLabelproperties

传给客户端的顶点 ID 可以是字符串、整数或 uuid.UUID。布尔值会被拒绝,整数必须落在 Java signed long 范围内。

批量写入

addVertices 接收 (label, properties) 二元组,addEdges 接收 (label, out_id, in_id, out_label, in_label, properties) 六元组。两者返回的对象只携带生成的 ID。

graph = client.graph()
vertices = graph.addVertices([
    ("person", {"name": "Alice", "age": 20}),
    ("person", {"name": "Bob", "age": 23}),
])
edges = graph.addEdges([
    ("knows", vertices[0].id, vertices[1].id, "person", "person", {"date": "2012-01-10"}),
])

分页与条件查询

graph = client.graph()

# 返回 (vertices, next_page),把 next_page 传回即可继续翻页
vertices, next_page = graph.getVertexByPage("person", limit=10)
vertices, next_page = graph.getVertexByPage("person", limit=10, page=next_page)

# 服务端属性条件
older = graph.getVertexByCondition("person", properties={"age": "P.gt(29)"})

# 边分页查询,传入 vertex_id 时必须同时传 direction
edges, next_page = graph.getEdgeByPage(label="knows", limit=10)
edges, next_page = graph.getEdgeByPage(vertex_id=person.id, direction="OUT", limit=10)

# 按 ID 批量查询
graph.getVerticesById([v1.id, v2.id])
graph.getEdgesById([e1.id, e2.id])

执行 Gremlin

gremlin = client.gremlin()
result = gremlin.exec("g.V().limit(5)")
print(result)

exec 会根据图名称和解析出的 GraphSpace 自动绑定 graphg 别名,并返回服务端响应中的 result 字段。响应缺少 requestIdstatusresult 时抛出 ResponseParseError

图遍历

TraverserManager 封装了 Server 的 traverser 接口,方法名使用蛇形命名。

traverser = client.traverser()

traverser.k_out(marko_id, 2)
traverser.k_neighbor(marko_id, 2)
traverser.same_neighbors(marko_id, josh_id)
traverser.jaccard_similarity(marko_id, josh_id)
traverser.shortest_path(marko_id, ripple_id, 3)
traverser.all_shortest_paths(marko_id, ripple_id, 3)
traverser.weighted_shortest_path(marko_id, ripple_id, "weight", 3)
traverser.single_source_shortest_path(marko_id, 2)
traverser.multi_node_shortest_path([marko_id, josh_id], max_depth=2)
traverser.paths(marko_id, josh_id, 2)
traverser.crosspoints(marko_id, josh_id, 2)
traverser.rings(marko_id, 3)
traverser.rays(marko_id, 2)
traverser.vertices(marko_id)
traverser.edges(edge_id)

基于 POST 的接口需要传入请求体:advanced_pathscustomized_pathstemplate_pathscustomized_crosspointsfusiform_similarity

图变量

variable = client.variable()
variable.set("owner", "mary")
print(variable.get("owner"))
print(variable.all())
variable.remove("owner")

异步任务

task = client.task()
print(task.list_tasks(status="success", limit=10))
print(task.get_task(task_id))
task.cancel_task(task_id)
task.delete_task(task_id)

Server 指标与图信息

metrics = client.metrics()
metrics.get_all_basic_metrics()
metrics.get_gauges_metrics()
metrics.get_counters_metrics()
metrics.get_histograms_metrics()
metrics.get_meters_metrics()
metrics.get_timers_metrics()
metrics.get_statistics_metrics()
metrics.get_system_metrics()
metrics.get_backend_metrics()

graphs = client.graphs()
graphs.get_all_graphs()
graphs.get_version()
graphs.get_graph_info()
graphs.get_graph_config()
graphs.clear_graph_all_data()   # 删除全部顶点、边和 Schema

print(client.version().version())

认证与授权

AuthManager 与 Server 的路由保持一致:用户、资源、归属和权限挂载在 /graphspaces/{graphspace}/auth/... 下,用户组仍在 Server 级别的 /auth/groups。在 HugeGraph 1.7.0 及以上版本必须能解析出 graphspace,否则这些调用会在发出请求前抛出 ValueError

auth = client.auth()

user = auth.create_user("test_user", "password")
auth.modify_user(user["id"], user_email="hugegraph@apache.org")
auth.get_user(user["id"])
auth.list_users(limit=10)
auth.delete_user(user["id"])

group = auth.create_group("test_group", "read only")
auth.modify_group(group["id"], group_description="updated")
auth.list_groups()
auth.delete_group(group["id"])

target = auth.create_target("target1", "hugegraph", "127.0.0.1:8080", [])
auth.update_target(target["id"], "target1", "hugegraph", "127.0.0.1:8080", [])
auth.list_targets()
auth.delete_target(target["id"])

belong = auth.create_belong(user["id"], group["id"])
auth.update_belong(belong["id"], "description")
auth.list_belongs()
auth.delete_belong(belong["id"])

access = auth.grant_accesses(group["id"], target["id"], "READ")
auth.modify_accesses(access["id"], "description")
auth.list_accesses()
auth.revoke_accesses(access["id"])

方法命名

Manager 中以驼峰命名的方法(例如 addVertexgetVertexById)会在构造时自动生成蛇形命名别名,graph.add_vertex(...)graph.addVertex(...) 指向同一个方法。驼峰写法已在 debug 日志中标记为废弃,新代码建议使用蛇形命名。

错误处理

异常定义在 pyhugegraph.utils.exceptions 中:

异常触发条件
NotAuthorizedErrorServer 返回 401
NotFoundErrorServer 返回 404,或缺少必填参数
ServerError其他非 2xx 响应,异常信息中附带服务端消息
ResponseParseError成功响应无法解析为预期结构
ServiceUnavailableErrorServer 返回 ServiceUnavailableException
InvalidParameterErrorCreateErrorRemoveErrorUpdateErrorDataFormatError由各构建器和数据结构抛出

请求体与响应体写入日志时,会对密码、token 和 secret 等字段做脱敏处理。

from pyhugegraph.utils.exceptions import NotFoundError

try:
    graph.getVertexById("no-such-id")
except NotFoundError:
    print("vertex missing")

接口参数会随 HugeGraph REST API 版本变化。遇到不兼容时,先核对当前 Server 的 REST API 文档与客户端测试用例。

开发检查

在 HugeGraph-AI 仓库根目录运行格式与静态检查:

./style/code_format_and_analysis.sh

按照 CI 的方式运行测试:

# 单元测试与契约测试,无需 Server
uv run pytest hugegraph-python-client/src/tests -m "unit or contract"

# 集成测试,需要可访问的 Server
HUGEGRAPH_URL=http://127.0.0.1:8080 \
HUGEGRAPH_GRAPH=hugegraph \
HUGEGRAPH_USER=admin \
HUGEGRAPH_PASSWORD=admin \
uv run pytest hugegraph-python-client/src/tests -m "integration and hugegraph"

CI 的集成测试作业使用 hugegraph/hugegraph:1.7.0 镜像。需要非默认空间时,还可以设置 HUGEGRAPH_GRAPHSPACE

源码与测试位于 hugegraph-python-client/src/pyhugegraph/hugegraph-python-client/src/tests/,可直接运行的示例在 hugegraph-python-client/src/pyhugegraph/example/hugegraph_example.py

5.3 - HugeGraph Go 客户端快速入门

HugeGraph Go Client 是 Toolchain 仓库中的 Go SDK,目前提供版本查询、Schema(PropertyKey、VertexLabel、EdgeLabel)、顶点和 Gremlin API。边数据 API 尚未实现。

该模块仍在开发中。接口范围以 hugegraph-client-go/api/v1 下的源码为准。

环境要求

  • Go 1.19 或更高版本
  • 可访问的 HugeGraph Server,默认示例地址为 http://127.0.0.1:8080

安装

在 Go module 项目中执行:

go get github.com/apache/hugegraph-toolchain/hugegraph-client-go

初始化客户端

NewCommonClient 要求 Host 是 IP 地址,Port 在 1 到 65535 之间;客户端始终使用明文 HTTP 连接。未启用认证时,用户名和密码留空;只有两者都设置时才会发送 Basic Auth。

GraphSpace 只在 Vertex API(此时请求路径为 /graphspaces/{space}/graphs/{graph}/...)和 Gremlin 默认 aliases 中生效(空值按 DEFAULT 处理)。Schema 相关入口和 Version() 始终请求 /graphs/{graph}/.../versions,与 GraphSpace 无关。默认图空间填写 DEFAULT;将 GraphSpace 留空时,Vertex API 会回退到旧版 Server 使用的 /graphs/{graph} 路径。

package main

import (
	"fmt"
	"log"

	hugegraph "github.com/apache/hugegraph-toolchain/hugegraph-client-go"
)

func main() {
	client, err := hugegraph.NewCommonClient(hugegraph.Config{
		Host:       "127.0.0.1",
		Port:       8080,
		GraphSpace: "DEFAULT",
		Graph:      "hugegraph",
		Username:   "",
		Password:   "",
	})
	if err != nil {
		log.Fatal(err)
	}

	response, err := client.Version()
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()

	fmt.Println(response.Versions.Version)
}

Version() 返回的 Versions 包含 HugeGraph Server、Core、Gremlin 和 REST API 版本。若使用源码提供的 NewDefaultCommonClient(),默认连接 127.0.0.1:8080 下的 hugegraph 图,使用 admin/pa 认证,并挂载一个打印全部请求和响应体的 ColorLogger;生产代码通常应显式传入配置。

配置项

hugegraph.Config 包含以下字段:

字段类型说明
HoststringHugeGraph Server 的 IP 地址,不支持主机名
PortintHugeGraph Server 的 REST 端口,取值 1 到 65535
GraphSpacestring图空间,仅 Vertex API 和 Gremlin 默认 aliases 使用;不需要时填空字符串
GraphstringServer 上配置的图名
UsernamestringServer 用户名,未启用认证时填空字符串
PasswordstringServer 密码,未启用认证时填空字符串
Transporthttp.RoundTripper自定义 HTTP transport,为 nil 时使用 http.DefaultTransport
Loggerhgtransport.Logger请求/响应日志,为 nil 时不记录日志

hgtransport 包提供四种 logger:TextLogger(纯文本)、ColorLogger(终端彩色)、CurlLogger(可执行的 curl 命令)和 JSONLogger(JSON 行)。它们的字段相同:Outputio.Writer)、EnableRequestBodyEnableResponseBody

import (
	"os"

	hugegraph "github.com/apache/hugegraph-toolchain/hugegraph-client-go"
	"github.com/apache/hugegraph-toolchain/hugegraph-client-go/hgtransport"
)

client, err := hugegraph.NewCommonClient(hugegraph.Config{
	Host:  "127.0.0.1",
	Port:  8080,
	Graph: "hugegraph",
	Logger: &hgtransport.ColorLogger{
		Output:             os.Stdout,
		EnableRequestBody:  true,
		EnableResponseBody: true,
	},
})

已实现的入口

CommonClient 当前公开以下入口:

入口用途
Version()查询服务端版本
Schema()查询完整 Schema
PropertykeyCreateGetAllGetByNameUpdateUserdataDeleteByName
VertexLabelCreateGetAllGetByNameUpdateUserdataDeleteByName
EdgeLabelCreateGetAllDeleteByName
VertexCreateBatchCreateUpdateProperties(通过 WithAction 指定 appendeliminate
GremlinGetPostPost 默认 languagegremlin-groovy,根据 GraphSpaceGraph 自动填充 graph/g aliases,并在 Data 中返回解析后的结果;Get 只返回状态码,并把原始响应打印到 stdout。

每个操作都通过挂在操作本身上的 With... 函数式选项传参,例如 client.Gremlin.Post.WithGremlin(...)client.Propertykey.GetByName.WithName(...)

resp, err := client.Gremlin.Post(
	client.Gremlin.Post.WithGremlin("g.V().limit(3)"),
)
if err != nil {
	log.Fatal(err)
}
fmt.Println(resp.StatusCode, resp.Data.Status.Code, resp.Data.Result.Data)

Vertex 相关操作的入参是 internal/model 包中的 model.Vertex[any]。Go 不允许从其他 module 导入 internal 包,因此目前 Vertex API 只能在客户端 module 内部调用;其测试文件也已全部注释。

完整调用方式可参考各 API 目录中的测试,例如 version_test.gogemlin_test.govertexlabel_test.go