跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

Documentation

Apache HugeGraph 文档

Apache HugeGraph 包含图数据库、图计算和图 AI 组件。HugeGraph 核心引擎负责属性图管理、事务处理与实时查询,Computer 和 Vermeer 运行图算法,HugeGraph-AI 提供 GraphRAG、图机器学习和 Python 客户端。

按场景快速导航

我想要…从这里开始
运行图查询 (OLTP)HugeGraph Server 快速上手
运行图算法 (OLAP)HugeGraph Computing
构建 Graph + AI 应用HugeGraph-AI
批量导入数据HugeGraph Loader、SeaTunnel
可视化管理图Hubble Web UI

生态系统一览

 1+-----------------------------------------------------------------+
 2|                   Apache HugeGraph Ecosystem                    |
 3+-----------------------------------------------------------------+
 4|  +-------------+  +-------------+  +-------------------------+  |
 5|  | HugeGraph   |  | Vermeer*    |  | HugeGraph-AI            |  |
 6|  | Core Engine |  | Computer    |  | (GraphRAG/ML/Python)    |  |
 7|  | (OLTP)      |  | (Java BSP)  |  |                         |  |
 8|  +------+------+  +------+------+  +------------+------------+  |
 9|         |                |                      |               |
10|  +------+----------------+----------------------+------------+  |
11|  | HugeGraph Toolchain                                       |  |
12|  | Hubble (UI) | Loader | Client (Java/Go/Py) | Tools        |  |
13|  +-----------------------------------------------------------+  |
14+-----------------------------------------------------------------+
  • Vermeer 为默认图计算入口;Computer 用于 Java BSP 作业。

核心组件

  • HugeGraph 核心引擎(OLTP):通过 HugeGraph Server 提供 REST API,并支持 Gremlin 和 Cypher 查询
  • HugeGraph Toolchain:包含 Java/Go Client、Loader、Hubble、Spark Connector 和 Tools;Python Client 位于 HugeGraph-AI,Rust Client 正在开发中
  • HugeGraph Computer:仓库内包含分布式 Computer 引擎和内存计算引擎 Vermeer
  • HugeGraph-AI:包含 GraphRAG、图机器学习、Python Client 和 Vermeer Python Client

部署模式

模式核心组件适用场景数据规模
单机模式Server + RocksDB开发、测试、Graph AI 和中小规模生产环境≤ 2 TB
分布式模式Server + PD + Store(HStore)生产环境、水平扩展和多副本部署≤ 1 PB

各组件的适用范围和启动方式见系统介绍及对应快速上手文档。

1 - Apache HugeGraph 介绍

什么是 Apache HugeGraph?

Apache HugeGraph 是一套易用、高效、通用的开源全栈图系统(GitHub),覆盖图数据库(OLTP 实时查询)、图计算(OLAP 大规模分析)与图 AI(GraphRAG / 图机器学习)三大领域。

HugeGraph 支持百亿以上的顶点和边的快速存储与查询,具备出色的 OLTP 性能。其图引擎兼容 Apache TinkerPop 3 框架,同时支持 Gremlin 和 Cypher(OpenCypher 标准)查询语言。

典型应用场景: 深度关系探索、关联分析、路径搜索、特征抽取、社区检测、知识图谱等。
适用领域: 网络安全、电信反欺诈、金融风控、广告推荐、社交网络、智能问答等。

生态系统全景

 1+----------------------------------------------------------------------+
 2|              Apache HugeGraph - Full-Stack Graph System              |
 3+------------------+--------------------+------------------------------+
 4| Graph DB (OLTP)  | Graph Compute      | Graph AI                     |
 5| HugeGraph        | Vermeer (Memory)   | HugeGraph-AI                 |
 6| Server           | Computer (Dist.)   | GraphRAG / GNN / Py          |
 7+------------------+--------------------+------------------------------+
 8|                         HugeGraph Toolchain                          |
 9| Hubble | Loader | Client (Java/Go/Python; Rust WIP) | Spark | Tools  |
10| SeaTunnel 3.0+: Source + Sink                                        |
11+----------------------------------------------------------------------+

HugeGraph Server(OLTP 图引擎)

HugeGraph Server 是图数据库的 OLTP 引擎和服务入口,负责属性图建模、事务处理、查询执行和 API 接入。图数据实际保存在配置的 RocksDB、HStore 或 HBase 后端中。

  • 属性图与 Schema:支持 VertexLabel、EdgeLabel、PropertyKey 和 IndexLabel 管理
  • 查询语言:支持 Gremlin(TinkerPop 3)和 Cypher(OpenCypher)
  • REST API:提供 Schema、图数据、查询、任务和运维接口
  • 索引与查询:支持精确查询、范围查询和复合条件查询
  • 存储后端:支持 RocksDB(单机推荐)、HStore(分布式推荐)和 HBase(Cassandra、MySQL、PostgreSQL 等历史后端已在 1.7.0 禁用并在 1.8.0 彻底移除)

主要模块包括 hugegraph-core、存储后端模块和 hugegraph-api。Core 实现图模型、事务和查询逻辑,后端模块负责连接具体存储系统,API 模块负责 HTTP 接入。当前 REST 资源路径包含图空间与图名称,例如:

1/graphspaces/{graphspace}/graphs/{graph}

单机部署通常使用 RocksDB。分布式部署使用 HStore,由 PD 管理集群元数据和分区调度,Store 保存图数据及其副本。HBase 可作为独立的后端存储。

HugeGraph Toolchain

HugeGraph Toolchain 提供客户端、数据导入、可视化管理、Spark 集成和命令行运维工具,覆盖图应用从接入数据到日常管理的主要环节。

模块用途
Client封装 Schema 管理、图数据读写、Gremlin 和 Traverser API;支持 Java、Python 和 Go,Rust 客户端正在开发中
Loader从本地文件、HDFS、JDBC、Kafka 或其他图读取数据,转换为顶点和边后批量导入 HugeGraph
Hubble提供图连接、Schema、数据导入、Gremlin 查询和图形化结果展示的 Web 管理界面
Spark Connector在 Spark 作业中批量读写 HugeGraph,适合大数据离线处理
SeaTunnel Sink通过 SeaTunnel 3.0+ 将数据导入 HugeGraph;导出与迁移请查看 Source 文档
Tools提供部署、图管理、备份恢复和 Gremlin 执行等命令行能力

图计算引擎(OLAP)

HugeGraph-Computer 仓库提供两种互补的 OLAP 图计算引擎。通用图算法任务默认建议从 Vermeer 开始;需要 Java BSP/Pregel 计算模型时,可使用 Computer:

  • Vermeer(默认入口):使用 Go 编写,采用 master-worker 架构,以内存计算为主,提供 REST API、gRPC 和 Web UI,适合快速执行中小规模图分析任务。
  • Computer:使用 Java 编写,实现 BSP/Pregel 分布式计算模型,可运行在 Kubernetes、YARN 或本地进程中。数据超过内存阈值时可以落盘,适合更大规模的图计算任务。

两者都可以读取 HugeGraph 数据,但运行架构、资源需求、配置和算法接口不同。

HugeGraph-AI(Graph + AI)

HugeGraph-AI 连接图技术与大语言模型、图机器学习框架。仓库使用 Python 3.10 或更高版本,并通过 uv 管理工作区,主要包含以下模块:

  • hugegraph-llm:提供 GraphRAG、知识图谱构建、自然语言查询和 Text2Gremlin
  • hugegraph-ml:提供节点分类、图分类、图嵌入、链接预测和欺诈检测等模型
  • hugegraph-python-client:通过 Python 管理 Schema、图数据和 Gremlin 查询
  • vermeer-python-client:通过 Python 调用 Vermeer 图计算服务

HugeGraph-AI 快速上手

部署模式

模式核心组件适用场景数据规模
单机模式(OLTP)Server + RocksDB开发、测试、Graph AI 和中小规模生产环境≤ 2 TB
分布式模式(OLTP)Server + PD + Store(HStore)生产环境、水平扩展和多副本部署≤ 1 PB

图计算属于 OLAP 任务,容量和资源需求取决于所选引擎、图结构与算法,不沿用上表的 OLTP 存储容量口径。

选择入口

需求文档
启动图数据库并执行查询Server 快速上手
批量导入数据Loader、SeaTunnel
使用 Web 界面管理图Hubble
运行图算法HugeGraph Computing
构建 GraphRAG 或图机器学习应用HugeGraph-AI

社区

微信公众号二维码

2 - 下载 Apache HugeGraph

指南:

  • 推荐使用已发布的软件包。Server 1.7.0 建议使用 Java 11,其他 JDK 的支持范围见 Server 启动指南;Toolchain、AI、Vermeer 等组件的运行环境请按各自版本的快速入门核对。
  • 验证下载版本, 请使用相应的哈希 (SHA512)、签名和 项目签名验证 KEYS
  • 检查哈希 (SHA512)、签名的说明在 版本验证 页面, 也可参考 ASF 验证说明
  • 注: HugeGraph 所有组件版本号已保持一致, client/loader/hubble/common 等 maven 仓库版本号同理, 依赖引用可参考 maven 示例
  • 兼容说明: HugeGraph 于 2026 年 1 月毕业后,下载路径已从 /incubator/hugegraph 迁移到 /hugegraph。历史版本的发布文件名可能仍包含 -incubating-。
  • 从源码构建请参考 编译构建说明

文件名中的 src 表示源码包,需要按对应组件的指南编译,不能直接按二进制包的目录执行启动脚本。源码主线可能包含尚未发布的配置和接口;使用下表中的发布包或指定版本的容器镜像时,应核对文档里的适用版本说明。

最新版本

源码归档是 Apache 软件基金会的正式发布物;二进制软件包是基于源码构建的便利用品。所有文件均通过 ASF 镜像分发,签名与校验和托管在 downloads.apache.org。GitHub 自动生成的源码归档不是 ASF 正式发布版本。


归档版本

注:

  1. 请大家尽早迁移到最新 Release 版本上, 社区将不再维护 1.0.0 前的旧版本 (非 ASF 版本)
  2. 1.3.0 是最后一个兼容 Java8 的主版本, 请尽早使用/迁移运行时为 Java11 (低版本 Java 有潜在更多的 SEC 风险和性能影响)
  3. 从版本 1.5.0 开始,需要 Java11 运行时环境

1.5.0

1.3.0

1.2.0

1.0.0

3 - 快速上手

根据需要选择 Server、Toolchain、图计算或 HugeGraph-AI 的快速上手文档。各组件独立发布,安装前请核对对应仓库的运行环境和版本。

3.1 - HugeGraph (OLTP)

本目录包含 HugeGraph Server 单机快速上手,以及分布式部署所需的 PD 和 Store 入门文档。

DeepWiki 项目概览;涉及安装、配置和运行行为时,请以对应版本的 HugeGraph 文档及代码为准。

首次使用可从 Server 单机快速上手 开始。该页将 ASF 已发布的 1.7.0 下载包与 master 源码构建分开说明。若使用 HStore 分布式存储,还需配置 PD 和 Store。

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

3.1.1 - HugeGraph Server 快速上手

1 HugeGraph Server 概述

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

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

警告

版本说明:本文区分已发布版本与开发主线。已发布的官方包请使用对应版本的正式安装包(如 1.7.0 或即将发布的 1.8.0);源码构建、配置默认值和启动行为以 apache/hugegraph 的 master 分支(当前对应 1.8.0 开发版本)为准。主线源码构建出的包不是 ASF 发布包,即使包内版本号与发布版本一致也不代表属于官方发布包。存储后端支持 RocksDB、HStore 和 HBase;已废弃的旧后端请参考 HugeGraph 1.5.x 文档。

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

flowchart TD
    A{选择安装来源}
    A -->|已发布版本| R["HugeGraph 1.7.0 tar 包"]
    R --> V[SHA-512 校验]
    V --> X[解压并使用随包配置]
    A -->|开发主线| M["master 源码"]
    M --> B["mvn package -DskipTests"]
    B --> C[确认 conf/graphs 中的 RocksDB 配置]
    C --> I[bin/init-store.sh]
    I --> S["bin/start-hugegraph.sh -p true"]
    S --> Q["请求 /versions 和图顶点接口"]

主仓库模块概览使用短名称;server、core、api、dist、pd 和 store 对应带 hugegraph- 前缀的模块。上方保留功能说明,dist 负责发行打包。

---
markmap:
  spacingHorizontal: 40
---
# HugeGraph
## server
- core
- api
- dist
## pd
## store

2 依赖

2.1 安装 Java 17 (JDK 17)

从 HugeGraph 1.8.0 开始使用 Java 17;1.7.0 是最后一个支持 Java 11 的版本。 所有模块的源码构建要求 JDK 17 和 Maven 3.6.3 或更高版本,Server、PD 和 Store 的运行环境统一使用 JDK 17。 Server 安全检查(-s true)要求 Java 17 到 23 以及可读的 conf/java-security.properties;在 Java 24 或更高版本上,需以 -s false 启动 Server(JDK 24 通过 JEP 486 移除了 Security Manager)。

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

说明

TinkerPop 3.8.1 兼容性与核心变更

HugeGraph 1.8.0 升级至 TinkerPop 3.8.1 与 Groovy 4.0.25。请使用 Server 随包提供的 Gremlin 配置文件。

  • 序列化器包路径变更:Driver 序列化器类从 org.apache.tinkerpop.gremlin.driver.ser 移至 org.apache.tinkerpop.gremlin.util.ser,需保留配置中的 HugeGraph registries。
  • Graph.Features 调整:supportsUniformListValues() 现返回 false;按 Schema 定义的 valueList()/LIST 属性仍正常支持,无需重写既有列表数据。
  • 遍历倍数语义:遍历中途扫描保留上游输入数量(如 3 个顶点执行 g.V().V().count() 返回 9L)。
  • 日期时间类型:DATE 属性支持写入及索引等值/范围查询中的 OffsetDateTime(按 instant 毫秒归一化)。
  • 过滤与优化:P.typeOf() 作为本地过滤执行;Count 过滤仅在谓词分支可证明截断安全时应用优化。
GraphBinary (推荐/默认)
1# 随包 Driver 与 Console 默认采用 GraphBinary V1
2# - Schema 结果为标准 Map
3# - Blob 值以二进制格式传输(包含在返回图元素内的 Blob)
4serializer:
5  className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1
6  config:
7    builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder
8    ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
GraphSON (HTTP/兼容)
1# 默认 HTTP JSON 采用 untyped GraphSON V1
2# - 保留 Tree 的旧 key/value 数组结构
3# - Typed GraphSON V1 因安全原因已禁用(typed V2/V3 仅适用于受支持的简单标量与 ID)
4# - graph.schema() 返回包含各类 label 的 Map
提示

完整的 Gremlin 语法改写、兼容性要求与速查表请参阅 1.8 Gremlin 与 TinkerPop 迁移指南。更多运行时细节见 Server 运行时文档。

3 部署

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

警告

生产环境必须启用鉴权并限制网络访问

HugeGraph 默认不启用用户认证。生产环境必须启用认证与授权、启用并维护 IP 白名单,并按最小权限为用户授权;不得将 Gremlin、Cypher 等查询接口直接暴露到公网。必须保留并限制读取 Server 标准配置生成的 audit-*.log。auth.audit_log_rate 只限制每用户日志输出速率,不是审计日志的启停开关。部署安全要求见安全指南。

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

完整容器部署指引请参考 Docker 部署方式。

快速启动使用 RocksDB 单机后端的 Server 容器:

快速启动 (默认)
1docker run -itd --name=server -p 8080:8080 hugegraph/hugegraph:1.7.0
附带内置样例图
1# 启动时自动预加载内置样例图(marko / lop 等数据)
2docker run -itd --name=server -p 8080:8080 -e PRELOAD="true" hugegraph/hugegraph:1.7.0
开启用户鉴权
1# 开启鉴权模式并设置内置 admin 初始密码
2docker run -itd --name=server -p 8080:8080 -e PASSWORD="replace-with-your-password" hugegraph/hugegraph:1.7.0

常用容器操作:

  • 进入容器终端:docker exec -it server bash
  • 查看启动日志:docker logs -f server
  • 验证服务可用性:curl -fsS http://127.0.0.1:8080/versions

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

Docker Desktop 中 HugeGraph 容器的运行设置
说明

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

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

拓扑compose 文件服务
单机(推荐从这里开始)docker-compose.yml1 个 RocksDB Server + 1 个 Hubble
最小 HStore(当前主线)docker-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 一起使用)
1cd hugegraph/docker
2# 注意版本号请随时保持更新 → 1.x.0
3HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose.yml up -d --wait

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

单机 docker-compose.yml 示例使用 HugeGraph 1.7.0 版本镜像 hugegraph/hugegraph:1.7.0;该文件引用的 docker/conf/hubble/standalone.properties 已随源码提供。Compose 文件从 HUGEGRAPH_ADMIN_PASSWORD 读取管理员密码,从 HUGEGRAPH_AUTH_TOKEN_SECRET 读取 JWT 密钥,通常放在 docker/.env 文件中。HUGEGRAPH_ADMIN_PASSWORD 非空即开启鉴权,Hubble 会自动识别该模式。若直接使用 docker run,则改为传入 -e PASSWORD=xxx。HStore Compose 文件属于当前主线,不能与 1.7.0 的 PD/Store/Server 发布镜像混用,见下文。

JWT 密钥的版本差异:当前主线构建的 Server 镜像会把 HUGEGRAPH_AUTH_TOKEN_SECRET 映射到 HG_SERVER_AUTH_TOKEN_SECRET,并写入 Server 启动配置;跨重建时应在 .env 中保留同一密钥。1.7.0 镜像的 Docker 入口脚本只处理 PASSWORD 等旧变量,不会读取 HG_SERVER_AUTH_TOKEN_SECRET。如需在 1.7.0 中固定 JWT 密钥,须将 auth.token_secret 持久写入该版本的 conf/graphs/hugegraph.properties;若保留默认随机密钥,不应假定已有 JWT 在 Server 重启后仍有效。

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

使用 PD 的 Server 服务标识

对于使用 PD 的 Server,Helm chart 提供 server.serviceId 和 server.graphSpace 配置项。 二者默认为 DEFAULT,此时保留 conf/rest-server.properties 中已有的 server.service_id 和 server.graphspace。 非默认值会向 Server 容器注入 HG_SERVER_SERVICE_ID 或 HG_SERVER_GRAPHSPACE。 注意:这些服务身份相关的 Chart 配置项(server.serviceId、server.graphSpace 和 server.testGraphAlias)适用于开发中的 1.8.0+ 版本镜像与 Chart; 目前尚无已发布的 Chart 或镜像支持这些选项。不要将本示例与未支持该特性的旧版本搭配使用。 通过 HG_SERVER_SERVICE_ID、SERVICE_ID 或 server.serviceId 传入的非空服务 ID 仅支持可打印 ASCII,包含空格和反斜杠; 部署校验会拒绝非 ASCII 和控制字符。此限制仅针对这些配置入口,不改变 Core Service 名称协议和已有的手工 properties 配置。 Helm 会将 server.serviceId 中的美元符号(包括 $(POD_IP))按字面量保留,不展开 Kubernetes 环境变量引用。 重读服务元数据或清理图空间时,会保留完整的服务 ID,包括其中的 / 和 -。 使用上述 chart values 设置身份;Server 的 extraEnv 会保留对应的新旧身份变量名,禁止重复覆盖。 HG_SERVER_GRAPHSPACE、生效的旧变量 GRAPH_SPACE 和 server.graphSpace 遵循同一规则: 接受 DEFAULT,或以小写字母开头、最多 48 位的小写字母、数字和下划线组成的已有空间名称:

1helm upgrade --install hg ./helm/hugegraph \
2  --set-string server.serviceId=analytics \
3  --set-string server.graphSpace=team_a

部署分配到 team_a 的 Server 前,先通过现有 DEFAULT 空间的 Server,用具有创建图空间权限的账号创建该空间。 chart 和这些环境变量不会自动创建图空间;同一个 Server Deployment 的所有副本使用相同服务标识。

用 helm test 检查该空间中的图前,先创建目标图,再将 --set-string server.testGraphAlias=team_a-demo 设置为它实际的 Gremlin 绑定。 创建图空间不会自动创建 hugegraph 图。

容器部署中的 HG_SERVER_SERVICE_ID 和 HG_SERVER_GRAPHSPACE 写入上述两个配置项。 旧名称 SERVICE_ID 和 GRAPH_SPACE 仍可使用;非空的新变量优先于对应旧变量。 同一配置项的新旧变量均未设置或为空时,保留已有值。Compose 不会自动传入宿主机上的这些变量, 需要在 Compose override 的 Server environment: 中显式添加。详见 Helm chart 配置说明。

这些设置选择 Server 在 PD 中的服务元数据,不会搬迁已有图,也不会修改未指定图空间的 REST 路径所用的 server.path_graphspace。 请求使用 /graphspaces/team_a/... 路径,并在 Hubble 中选择匹配的图空间和服务;开启鉴权时,显式指定路径仍须获得授权。

server.testGraphAlias 默认为 DEFAULT-hugegraph。hook 会逐个 Server Pod 检查这一已有本地图绑定,不会从 server.graphSpace 自动派生别名。 别名的大小写须与实际绑定一致:本地 Demo.properties 可以绑定为 DEFAULT-Demo;通过 REST 创建的图使用小写名称。 本地图绑定可以独立于 Server 在 PD 中分配的图空间存在,因此默认 hook 成功不能证明 team_a 中的图可查询。 出现 Could not rebind 时,先确认目标图存在且别名正确;重启 Pod 不能创建缺失的图或纠正别名。

配置渲染和入口脚本检查不能单独证明 Linux 上的非默认服务发现、鉴权或跨图空间隔离已通过验收。

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

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

3.2 下载已发布的 tar 包

以下示例针对 HugeGraph 1.7.0。使用其他版本时,请先在 ASF 下载目录 确认该版本及对应文件名;不要把 master 源码构建包当作已发布的二进制包。

1cd /path/to/downloads
2wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz
3wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz.sha512
4sha512sum -c apache-hugegraph-incubating-1.7.0.tar.gz.sha512
5tar zxf apache-hugegraph-incubating-1.7.0.tar.gz

SHA-512 校验通过后再解压。也可按 Apache 发布流程验证 PGP 签名:

1wget https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz.asc
2wget https://downloads.apache.org/hugegraph/KEYS
3gpg --import KEYS
4gpg --verify apache-hugegraph-incubating-1.7.0.tar.gz.asc apache-hugegraph-incubating-1.7.0.tar.gz

只应信任通过 Apache 项目渠道核实的发布者密钥;签名验证可与 SHA-512 校验一起使用。

3.3 从 master 源码构建

下面的命令构建的是开发主线,不是 1.7.0 发布包。

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

下载 HugeGraph 源代码

1git clone --branch master https://github.com/apache/hugegraph.git

编译打包生成 tar 包

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

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

1[INFO] BUILD SUCCESS

执行成功后,根目录 target/ 下会生成主线聚合包(当前仓库版本属性为 1.8.0):

1target/apache-hugegraph-1.8.0.tar.gz

该文件名中的版本号来自源码的 revision 属性;它不会把主线构建变成 ASF 发布物料。构建过程还会在仓库根目录生成 apache-hugegraph-1.8.0/ 聚合目录,其中的 Server 子目录名由 Server 模块的 final.name 决定,例如当前为 apache-hugegraph-server-1.8.0。若只保留了 tar 包,则先执行 tar zxf target/apache-hugegraph-1.8.0.tar.gz 再进入该目录。

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

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

3.4 使用 tools 工具部署 (Outdated)

已过时 仅指此一键部署入口。

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

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

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

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

1bin/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 配置

Server 的 tar 包随包提供 conf/rest-server.properties、conf/gremlin-server.yaml 和 conf/graphs/hugegraph.properties;源码构建包从 hugegraph-server/hugegraph-dist/src/assembly/static/conf/ 装配这些文件。解压后在 Server 安装目录内编辑配置,无需另行生成。发行包版本之间可能有默认值差异,下面涉及的默认值和启动行为按 master 主线说明。

单机 RocksDB 快速上手只需确认 conf/graphs/hugegraph.properties 使用 backend=rocksdb、serializer=binary。正常 Server 初始化会扫描 conf/graphs/ 并加载本地图配置,无需额外设置 graph.load_from_local_config=true。该选项默认 false,控制构造阶段的提前加载。图配置变化通过重启 Server 应用,不使用热重载进行维护。

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

5 启动

5.1 使用启动脚本启动

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

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

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

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

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

警告

生产环境启动 Server 前必须完成鉴权配置

按照 Server 鉴权配置 启用认证与授权并设置非默认强管理员密码;同时启用 IP 白名单,为业务用户配置最小权限。

5.1.1 分布式存储 (HStore)

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

警告

umask 077 保护新建的 .env,但 set-hubble-pd-password.sh 会将生成的 .local.properties 权限设为 0644,本机其他用户也能读取其中的 PD 密钥。下面示例仅适用于本机用户均可信的环境;共享主机必须先按 Hubble 运行用户设置文件属主与读取权限,确保 Hubble 可读且其他非授权用户不可读。不提交文件不能替代文件权限保护。

分布式存储配置及启动方法

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

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

  1. 修改 Server 服务的 hugegraph.properties 配置:
1backend=hstore
2serializer=binary
3
4# PD 服务地址,多个 PD 地址用逗号分割,配置 PD 的 RPC 端口
5pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
6pd.cluster=hg
 1# 简单示例(带鉴权)
 2gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy
 3
 4# 指定存储 hstore(必须)
 5backend=hstore
 6serializer=binary
 7store=hugegraph
 8
 9# pd config
10pd.peers=127.0.0.1:8686
11pd.cluster=hg

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

此例的 rest-server.properties 使用 cluster=hg,图配置使用 pd.cluster=hg,与下方主线 Compose 拓扑选用同一集群名。它们位于不同配置文件,分别供 Server 进程和图配置使用;按部署实际选择集群名,不要把两个键当成同一个配置项。类似地,两个文件中的 pd.peers 也属于各自的配置范围;本例都填写同一组 PD RPC 地址。

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

  1. 修改 Server 服务的 rest-server.properties 配置:
1usePD=true
2# 本例与图配置的 pd.cluster 共用集群名 hg
3cluster=hg
4# 配置 Server 进程连接的 PD 地址;替换为实际 PD RPC 地址
5pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688
6
7# 本地测试可按需启用;生产环境必须启用鉴权
8# auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator

以下地址示例适用于在同一台主机运行多个 Server 进程;127.0.0.1 仅用于本机场景。跨主机部署时,将 restserver.url、gremlinserver.url、pd.peers、Gremlin host 和 rpc.server_host 替换为各节点可路由的 IP 或 DNS;rpc.server_host 公布的地址和端口必须能被其他节点互达。

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

节点 1(主节点):

 1usePD=true
 2restserver.url=http://127.0.0.1:8081
 3gremlinserver.url=http://127.0.0.1:8181
 4pd.peers=127.0.0.1:8686
 5
 6rpc.server_host=127.0.0.1
 7rpc.server_port=8091
 8
 9server.id=server-1
10server.role=master

节点 2(工作节点):

 1usePD=true
 2restserver.url=http://127.0.0.1:8082
 3gremlinserver.url=http://127.0.0.1:8182
 4pd.peers=127.0.0.1:8686
 5
 6rpc.server_host=127.0.0.1
 7rpc.server_port=8092
 8
 9server.id=server-2
10server.role=worker

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

节点 1:

1host: 127.0.0.1
2port: 8181

节点 2:

1host: 127.0.0.1
2port: 8182

启动 Server:

1bin/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 拓扑即采用这种方式。

验证服务是否正常启动:

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

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

  1. 停止 Server 服务
  2. 停止 HugeGraph-Store
  3. 停止 HugeGraph-PD
1bin/stop-hugegraph.sh
Docker HStore 高可用集群(当前主线)

docker-compose-3pd-3store-3server.yml 使用当前主线的 HG_PD_*、HG_STORE_* 和 HG_SERVER_* 环境变量;1.7.0 发布镜像不支持这套配置。先从同一份主线源码构建 PD、Store 和 Server 镜像,并使用相同的本地 local 标签:

1# 在 hugegraph 仓库根目录执行
2docker build -f hugegraph-pd/Dockerfile -t hugegraph/pd:local .
3docker build -f hugegraph-store/Dockerfile -t hugegraph/store:local .
4docker build -f hugegraph-server/Dockerfile-hstore -t hugegraph/server:local .
5
6cd docker

先在 docker/ 目录创建认证环境并生成 HStore Hubble 配置。用自己设置的管理员密码替换示例文本;因 .env 使用单引号包裹,密码不能含单引号或换行。脚本生成 JWT 与 PD 随机密钥,并将 PD 密钥写入两个 HStore Compose 会挂载的未跟踪 .local.properties 文件:

 1(
 2  set -eu
 3  command -v openssl >/dev/null
 4  jwt_secret="$(openssl rand -hex 32)"
 5  pd_secret="$(openssl rand -hex 24)"
 6  umask 077
 7  test ! -e .env || {
 8    echo ".env already exists; edit it instead of overwriting it" >&2
 9    exit 1
10  }
11  printf "HUGEGRAPH_ADMIN_PASSWORD='%s'\nHUGEGRAPH_AUTH_TOKEN_SECRET='%s'\nHG_PD_AUTH_SECRET_KEY='%s'\n" \
12    'replace-with-your-password' "${jwt_secret}" "${pd_secret}" > .env
13  HG_PD_AUTH_SECRET_KEY="${pd_secret}" ./set-hubble-pd-password.sh hstore
14  HG_PD_AUTH_SECRET_KEY="${pd_secret}" ./set-hubble-pd-password.sh hstore-ha
15)

然后在 docker/ 目录启动 HA 拓扑。HUGEGRAPH_VERSION=local 令 PD、Store 和 Server 使用刚构建的本地镜像;该 Compose 文件的 pull_policy: missing 会优先使用已存在的本地标签。Hubble 仍由 HUBBLE_IMAGE 独立选择:

1set -a
2. ./.env
3set +a
4HUGEGRAPH_VERSION=local docker compose \
5  -f docker-compose-3pd-3store-3server.yml \
6  up -d --wait pd0 pd1 pd2 store0 store1 store2 server0 server1 server2 hubble

HG_PD_AUTH_SECRET_KEY 应只为新数据目录生成一次;重启或复用已有数据目录时,继续使用原值。不要提交 .env 或生成的 conf/hubble/*.local.properties。服务通过 hg-net 桥接网络上的容器主机名通信。Server 拓扑要求共享 JWT 密钥;不要只设置管理员密码而遗漏 HUGEGRAPH_AUTH_TOKEN_SECRET。完整的环境变量说明见 Docker 集群指南 和仓库 docker/README.md。

验证集群:

1curl -fsS http://localhost:8080/versions
2curl -fsS -u "hg:${HG_PD_AUTH_SECRET_KEY:?请先加载 .env}" \
3  http://localhost:8620/v1/stores

当前主线的 PD /v1/stores REST 接口需要 HTTP Basic 认证;此处用生成后已加载的 HG_PD_AUTH_SECRET_KEY 作为 hg 用户密码。

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

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

5.1.2 RocksDB / ToplingDB

从 master 构建的单机最小流程如下。此例启用内置样例数据,以便后续请求能验证图数据读写路径。

  1. 检查 Java 环境,确认满足主线构建要求。
  2. 构建 master 源码;下方命令使用该构建包中的 Server 子目录。
  3. 确认 RocksDB 配置,再进入构建产物中的 Server 子目录。
  4. 初始化存储,然后启动服务并加载样例图,命令见下方。
  5. 请求 /versions 和样例图顶点接口,检查实际返回内容。
说明

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

主线包内的 conf/graphs/hugegraph.properties 默认已设置 backend=rocksdb 和 serializer=binary。使用默认数据目录时无需修改;若改过后端或数据路径,先确认配置,再初始化存储。

初始化数据库(首次启动,或在 conf/graphs/ 下添加了新图配置后):

1# 进入解压或构建出的 Server 根目录
2cd apache-hugegraph-*/apache-hugegraph-server-*
3bin/init-store.sh

启动 Server 并加载内置样例图:

1bin/start-hugegraph.sh -p true

启动脚本会按 rest-server.properties 中的 restserver.url 轮询 /graphs,超时或进程失败时以非零状态退出。随后先检查服务版本,再读取样例顶点:

1curl -fsS http://127.0.0.1:8080/versions
2curl --compressed -fsS \
3  http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices

第一条请求应返回包含 versions 的 JSON;第二条应返回包含 vertices 的 JSON,且样例数据中可见 marko、lop 等顶点。仅检查进程存在或 HTTP 状态码,不足以证明图后端和业务请求正常。

ToplingDB (Beta): 作为 RocksDB 的高性能替代方案,配置方式请参考: ToplingDB 快速上手

5.1.3 HBase

说明

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

HBase 配置及启动方法

修改 hugegraph.properties

 1backend=hbase
 2serializer=hbase
 3
 4# hbase backend config
 5hbase.hosts=localhost
 6hbase.port=2181
 7# Note: recommend to modify the HBase partition number by the actual/env data amount & RS amount before init store
 8# it may influence the loading speed a lot
 9#hbase.enable_partition=true
10#hbase.vertex_partitions=10
11#hbase.edge_partitions=30

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

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

启动 server

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

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

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

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

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

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

1> curl "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices" | gunzip
2
3{"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。

参数取值默认值作用
-dtrue、falsetrue守护进程模式。-d false 时脚本留在前台,并把 SIGTERM/SIGINT 转发给服务进程
-gg1、G1、zgc、ZGCJVM 默认值选择垃圾回收器(g1/G1 设置 -XX:+UseG1GC;zgc/ZGC 设置 -XX:+UseZGC)。不填则使用 JVM 默认收集器配置
-mtrue、falsefalse安装基于 crontab 的监控任务(bin/start-monitor.sh),仅用于虚拟机和物理机部署
-ptrue、falsefalse预加载示例图,见 5.1.4
-strue、falsetrue开启安全检查(HugeSecurityManager),要求 Java 17 到 23 以及 conf/java-security.properties 可读。在 Java 24+ 上需传 -s false
-jJVM 参数空追加到服务命令行的额外 JVM 参数
-t秒30判定启动失败前等待服务响应的时长
-ytrue、falsefalse开启 OpenTelemetry agent 上报链路追踪

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

bin/hugegraph-server.sh 会把 -XX:+HeapDumpOnOutOfMemoryError、-XX:HeapDumpPath 和 -XX:ErrorFile 放在 JAVA_TOOL_OPTIONS 的最前面。因此无论是否设置了 JAVA_OPTIONS(下文所述的例外情况除外),内存溢出时的堆转储(heapdump_<主机名>_<启动时间>/java_pid<pid>.hprof)和 JVM 崩溃日志(hs_err_pid<pid>_<主机名>_<启动时间>.log)都会写入 logs/,其中 <启动时间> 为本地时间,格式是 YYYYMMDD-HHMMSS。每次启动都有自己的 heapdump_* 目录,因此服务及其启动的 JVM(例如 computer 任务)会分别写入各自的转储(HotSpot 按 JVM 的 PID 命名转储文件和崩溃日志,因此同一次启动中复用了先前 PID 的 JVM 无法写入它的转储,它的崩溃日志也会覆盖先前那个 JVM 的)。主机名可避免共用同一日志目录的多个服务选到相同的名字;如果同一主机在同一秒内已经用过该名字,会再加上计数(<启动时间>-1、-2……)。如果无法创建该目录(例如磁盘已满),服务仍会启动,堆转储改为尽力写入 logs/ 本身;磁盘已满时可能也没有空间写入转储。堆转储可能和堆一样大。启动脚本从不删除转储或 heapdump_* 目录:每次启动到 Java 阶段都会留下一个目录,除非发生内存溢出否则为空;启动脚本保留它,是因为 computer 任务的 JVM 可能在服务退出后仍在使用它。在该次启动的 HugeGraph JVM 都已退出后,可以移走或删除旧目录,但不要动正在运行的服务最新的那个目录;没有它,下一次转储会被写成一个同名文件。JVM 会在这些默认值之后读取你自己的 JAVA_TOOL_OPTIONS、JDK_JAVA_OPTIONS(包括 @argfile)、命令行(JAVA_OPTIONS;未设置或为空时为 -j)和 _JAVA_OPTIONS,因此在其中任意一处为上述参数指定的值都会覆盖默认值。只有环境变量会传给服务启动的 JVM:要对所有 JVM 关闭堆转储,请设置 JAVA_TOOL_OPTIONS=-XX:-HeapDumpOnOutOfMemoryError;通过 -j 或 JAVA_OPTIONS 关闭只对服务自身的 JVM 生效。无论哪种方式,每次启动到 Java 阶段仍会创建空的 heapdump_* 目录,除非创建失败而改为写入 logs/。如果日志路径中包含双引号或 %,启动脚本会给出警告,堆转储直接写入 logs/,不使用每次启动的目录,也不设置崩溃日志的默认值;通过 JAVA_TOOL_OPTIONS 关闭堆转储的方式仍然有效。同时包含两种引号的路径则完全不设置堆转储默认值。由于设置了这些默认值,JVM 启动时会在 stderr 输出 Picked up JAVA_TOOL_OPTIONS: ...。

版本范围:以上行为适用于当前开发分支/master 分支。1.7.0 只在未设置 JAVA_OPTIONS 时添加堆转储参数,堆转储直接写入 logs/java_pid<pid>.hprof,JVM 崩溃日志写入安装目录。

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 脚本改变预加载的数据。

     1version: '3'
     2services:
     3  server:
     4    image: hugegraph/hugegraph:1.7.0
     5    container_name: server
     6    environment:
     7      - PRELOAD=true
     8      - PASSWORD=xxx
     9    volumes:
    10      - /path/to/yourscript:/hugegraph-server/scripts/example.groovy
    11    ports:
    12      - 8080:8080

    基于当前 master 构建的 Server 镜像以非 root 的 UID 10001 运行,挂载的脚本必须对该用户可读。

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

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

1> curl "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices" | gunzip
2
3{"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 查看服务进程

1jps
26475 HugeGraphServer

curl 请求 RESTful API

1curl -fsS http://127.0.0.1:8080/versions

返回包含 versions 的 JSON(HTTP 2xx)可确认 REST API 已响应。jps 中出现 HugeGraphServer 只表示进程存在;要确认图后端可用,请按单机流程加载样例图后请求顶点接口。

6.2 请求 Server

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

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

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

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

说明

  1. 对于顶点、边等列表请求,Server 可以压缩响应。使用 curl --compressed 可自动解压:

    1curl --compressed -fsS "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices"
  2. 默认监听地址为 127.0.0.1,其他机器无法直接访问。

警告

调整 Server 监听地址

若将地址调整为 0.0.0.0,Server 将监听所有网卡。生产环境必须启用认证与授权、IP 白名单及最小权限授权,并保留和保护审计日志;不得将 Gremlin、Cypher 等接口直接暴露到公网。

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

响应体如下:

 1{
 2    "vertices": [
 3        {
 4            "id": "2lop",
 5            "label": "software",
 6            "type": "vertex",
 7            "properties": {
 8                "price": [
 9                    {
10                        "id": "price",
11                        "value": 328
12                    }
13                ],
14                "name": [
15                    {
16                        "id": "name",
17                        "value": "lop"
18                    }
19                ],
20                "lang": [
21                    {
22                        "id": "lang",
23                        "value": "java"
24                    }
25                ]
26            }
27        },
28        {
29            "id": "1josh",
30            "label": "person",
31            "type": "vertex",
32            "properties": {
33                "name": [
34                    {
35                        "id": "name",
36                        "value": "josh"
37                    }
38                ],
39                "age": [
40                    {
41                        "id": "age",
42                        "value": 32
43                    }
44                ]
45            }
46        },
47        ...
48    ]
49}

详细的 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

1# 在 Server 根目录下执行
2bin/stop-hugegraph.sh

8 使用 IntelliJ IDEA 调试 Server

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

3.1.2 - HugeGraph-PD 快速上手

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 版本:HugeGraph 1.8.0+ 使用 Java 17(Maven 源码构建仅接受 JDK 17;启动脚本拒绝低于 17 的运行时;1.7.0 是最后一个支持 Java 11 的版本)
  • Maven 版本:≥ 3.6.3(从源码编译时)

3 部署

HugeGraph-PD 组件主要支持以下部署与运行方式:

  • 下载发布包 — 下载并解压官方发布的完整二进制安装包。
  • 源码编译 — 基于 master 主线代码使用 Maven 与 Java 17 编译 PD 模块。
  • Docker 部署 — 使用容器快速体验或搭建分布式集群。

3.1 下载 tar 包

Apache 下载页目前提供 1.7.0 的完整二进制包,其中包含 PD、Store 和 Server;没有单独列出 PD 二进制包。下载前请在 官方 Apache HugeGraph 下载页核对版本、签名和 SHA512。1.7.0 是孵化期发布的历史版本,归档文件和解压目录仍带 incubating:

1# 1.7.0 是项目孵化期发布的历史版本,因此文件名和目录名仍带 incubating
2curl -fLO --connect-timeout 10 --max-time 1800 https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz
3tar zxf apache-hugegraph-incubating-1.7.0.tar.gz
4cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-pd-incubating-1.7.0

3.2 源码编译

  1. 克隆源代码仓库:

    1git clone https://github.com/apache/hugegraph.git
    2cd hugegraph
  2. 编译 PD 模块:

    1# 仅编译 PD 发行包及其依赖模块
    2mvn clean package -pl hugegraph-pd/hg-pd-dist -am -DskipTests
  3. 检查编译产物:

    1cd hugegraph-pd/apache-hugegraph-pd-*/
    2ls -la bin conf lib

解压后的发布目录只包含三个子目录:bin(启停脚本)、conf(application.yml、application.yml.template、log4j2.xml、verify-license.json)和 lib(hg-pd-service jar 包)。

3.3 Docker 部署

HG_PD_* 环境变量和 /v1/ready 是当前主线源码提供的功能;server 的 1.7.0 发布源码标签尚无这些 Docker 环境变量映射或 readiness API。本文下面的 Docker 示例仅适用于从当前主线源码构建并标记为 local 的镜像;使用 1.7.0 发布资产时,应以该版本随包配置和说明为准:

1# 在 hugegraph 仓库根目录执行
2docker build -f hugegraph-pd/Dockerfile -t hugegraph/pd:local .

单独运行当前主线构建的 PD 时,先设置部署专用密钥,并把示例地址替换为容器可达的真实地址:

下面的 mkdir -p 和非递归 chown 仅适用于新建空目录。复用旧 root 镜像写入的数据时,先停止 PD, 执行一次 sudo chown -R 10001:10001 /path/to/data,再启动 UID 10001 镜像。

 1export HG_PD_AUTH_SECRET_KEY="$(openssl rand -hex 24)"
 2# master 构建的镜像以 UID 10001 运行,宿主机数据目录必须对该用户可写
 3mkdir -p /path/to/data && sudo chown 10001:10001 /path/to/data
 4docker run -d \
 5  -p 8620:8620 -p 8686:8686 -p 8610:8610 \
 6  -e HG_PD_GRPC_HOST=192.168.1.10 \
 7  -e HG_PD_RAFT_ADDRESS=192.168.1.10:8610 \
 8  -e HG_PD_RAFT_PEERS_LIST=192.168.1.10:8610 \
 9  -e HG_PD_INITIAL_STORE_LIST=192.168.1.20:8500 \
10  -e HG_PD_AUTH_SECRET_KEY="$HG_PD_AUTH_SECRET_KEY" \
11  -v /path/to/data:/hugegraph-pd/pd_data \
12  --name hugegraph-pd \
13  hugegraph/pd:local
变量必填默认值对应配置项描述
HG_PD_GRPC_HOST是无grpc.host本节点对外公布的 gRPC 主机名/IP;容器网络中应使用容器主机名。
HG_PD_RAFT_ADDRESS是无raft.address本节点 Raft 地址。
HG_PD_RAFT_PEERS_LIST是无raft.peers-list所有 PD 节点的 Raft 地址,含本节点。
HG_PD_INITIAL_STORE_LIST是无pd.initial-store-list预期的 Store gRPC 地址。
HG_PD_AUTH_SECRET_KEY是无auth.secret-keyREST Basic 密码;所有 PD REST 客户端都必须使用同一密钥。
HG_PD_GRPC_PORT否8686grpc.portgRPC 服务端口。
HG_PD_REST_PORT否8620server.portREST API 端口。
HG_PD_DATA_PATH否/hugegraph-pd/pd_datapd.data-path元数据存储路径。
HG_PD_INITIAL_STORE_COUNT否1pd.initial-store-count集群可用所需的最小 Store 数量。
HG_PD_ACTUATOR_EXPOSURE否health,metrics,prometheusmanagement.endpoints.web.exposure.include公开的 Actuator 端点白名单;不允许设置为 *。

当前主线 entrypoint 要求以上五个必填变量,生成 SPRING_APPLICATION_JSON 覆盖项后再启动 PD;其他配置继续从镜像内的 conf/application.yml 读取。JAVA_OPTS 会透传给 JVM。旧变量 GRPC_HOST、RAFT_ADDRESS、RAFT_PEERS、PD_INITIAL_STORE_LIST 仍可用,但会输出弃用警告。

PD 镜像的 Docker HEALTHCHECK 每 15 秒检查 /v1/health,它只表示 REST 监听器有响应,不代表 Raft 已形成多数派。Compose 示例中的健康检查也使用这个存活接口;需要在启动 Store 前另行检查 /v1/ready。容器以前台方式运行,Java 退出会让容器退出;只有配置了 Docker 重启策略时容器才会自动重启。Docker 日志可通过 docker logs <container-name> 查看。

当前主线 Compose 的完整启动和最小拓扑见 Store 页面及 docker/README.md。Compose 文件的服务配置来自主线源码;若启动包含 Hubble 的完整拓扑,先按 docker/README.md 生成未跟踪的 Hubble 配置文件。

4 配置

PD 启动脚本读取安装目录中的 conf/application.yml。请使用与安装包版本相同的源文件,不要把发布版和主线配置混用: 1.7.0 发布标签配置;当前主线配置。主线 application.yml 将 auth.secret-key 留空,REST 受保护接口在未设置密钥时会拒绝请求;application.yml.template 不由 PD 启动脚本读取。

4.1 配置项参考

以下表格列出主线配置及代码默认值,Raft 超时设置可参阅 PDConfig 实现。1.7.0 二进制包请使用对应标签的原始配置;主线源码构建包则以 主线配置文件 为准。下文会单独说明与 1.7.0 的差异。

gRPC 与 REST

配置项主线目录值内置默认值描述
grpc.host127.0.0.1无,必填本 PD 对外公布的 gRPC 地址。Store 和 Server 会连到这个地址,因此分布式部署时必须填可访问的 IPv4 地址或主机名,不能用 127.0.0.1 或 0.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未设置10000PD 节点之间 Raft RPC 的超时时间(毫秒)。PD 读取 id 计数器前等待 ReadIndex 的时限也是这个值,超过时限则 id 分配失败。
raft.rpc-connect-timeout未设置1000与 peer 建立 Raft 连接时 Ping 的超时时间(毫秒)。候选节点逐个连接 peer,某个 peer 接受了 TCP 连接却不应答时,选举会为它等待这么久。已建立连接上的请求使用 raft.rpc-timeout。
raft.rpc-install-snapshot-timeout未设置0向落后于日志的 follower 发送快照的超时时间(毫秒)。0 表示使用 raft.rpc-timeout。快照较大而超时时可调大。

raft.rpc-connect-timeout 和 raft.rpc-install-snapshot-timeout 仅在 1.7.0 之后的版本中提供。1.7.0 中 raft.rpc-timeout 同时也是连接超时和安装快照超时,id 分配也不等待 ReadIndex。

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.min-store-count未设置0Store 排空/下线容量校验所需的最小活跃 Store 数量。若下线后剩余活跃 Store 低于该值,拒绝转入 Exiting 状态。
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采样间隔,格式为 <数字> <单位>,单位为 second、minute、hour、day、month、year 之一;省略数字时按 1 计。
store.monitor_data_retention1 day1 day监控数据保留时长,格式同上。

分区

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

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

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

服务发现、License 与监控

配置项主线目录值内置默认值描述
discovery.heartbeat-try-count未设置3客户端注册后连续丢失多少次心跳就删除其注册信息。
license.verify-path./conf/verify-license.json无,配置键必填PD 发行目录随包提供该 JSON 文件;当前主线代码没有读取此配置项的运行时位置。
license.license-path./conf/hugegraph.license无,配置键必填目标路径不会随包带入 license 文件;内部 gRPC putLicense 会把上传内容写到此处。当前主线的 REST GET /v1/license 返回空对象,不因文件缺失而阻止 PD 启动。
auth.secret-key空空当前主线的 PD REST Basic 密码;合法用户名为 hg、store、hubble、vermeer。Docker 镜像要求设置;裸机 PD 可在密钥为空时启动,但受保护 REST 请求都会被拒绝。
management.metrics.export.prometheus.enabledtrueSpring Boot 默认值是否暴露 /actuator/prometheus。
management.endpoints.web.exposure.includehealth,metrics,prometheusSpring Boot 默认只暴露 healthActuator 暴露白名单;这些端点不经过 PD REST Basic 拦截器。
logging.configfile:./conf/log4j2.xml无Log4j2 配置文件,会写出 logs/hugegraph-pd.log、logs/hugegraph-pd_raft.log 和 logs/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 为基础,只需按节点改写 gRPC/Raft 地址和数据路径,并设置 auth.secret-key。以下值仅适用于开发测试;单节点 PD 不提供多数派容错,partition.default-shard-count: 1 表示每个分区只有一个副本。

 1grpc:
 2  host: 127.0.0.1
 3  port: 8686
 4server:
 5  port: 8620
 6raft:
 7  address: 127.0.0.1:8610
 8  peers-list: 127.0.0.1:8610
 9pd:
10  data-path: ./pd_data
11  initial-store-count: 1
12  initial-store-list: 127.0.0.1:8500
13partition:
14  default-shard-count: 1
15auth:
16  secret-key: 替换为部署专用密钥

可以用 openssl rand -hex 24 生成部署密钥;使用 Docker 时通过 HG_PD_AUTH_SECRET_KEY 传入。1.7.0 发布标签的认证行为不同,详见“REST API 认证”。

4.3 三节点集群配置

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

节点 1(192.168.1.10):

 1grpc:
 2  host: 192.168.1.10
 3  port: 8686
 4server:
 5  port: 8620
 6raft:
 7  address: 192.168.1.10:8610
 8  peers-list: 192.168.1.10:8610,192.168.1.11:8610,192.168.1.12:8610
 9pd:
10  data-path: /data/pd
11  initial-store-count: 3
12  initial-store-list: 192.168.1.20:8500,192.168.1.21:8500,192.168.1.22:8500
13partition:
14  default-shard-count: 3

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

 1# 节点 2
 2grpc:
 3  host: 192.168.1.11
 4raft:
 5  address: 192.168.1.11:8610
 6  peers-list: 192.168.1.10:8610,192.168.1.11:8610,192.168.1.12:8610
 7
 8# 节点 3
 9grpc:
10  host: 192.168.1.12
11raft:
12  address: 192.168.1.12:8610
13  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 地址:

 1# 所有 PD 节点共用同一个密钥,实际部署从私密环境变量注入
 2HG_PD_AUTH_SECRET_KEY: ${HG_PD_AUTH_SECRET_KEY:?set HG_PD_AUTH_SECRET_KEY}
 3
 4# pd0
 5HG_PD_GRPC_HOST: pd0
 6HG_PD_RAFT_ADDRESS: pd0:8610
 7HG_PD_RAFT_PEERS_LIST: pd0:8610,pd1:8610,pd2:8610
 8HG_PD_INITIAL_STORE_LIST: store0:8500,store1:8500,store2:8500
 9HG_PD_INITIAL_STORE_COUNT: 3
10
11# pd1
12HG_PD_GRPC_HOST: pd1
13HG_PD_RAFT_ADDRESS: pd1:8610
14HG_PD_RAFT_PEERS_LIST: pd0:8610,pd1:8610,pd2:8610
15
16# pd2
17HG_PD_GRPC_HOST: pd2
18HG_PD_RAFT_ADDRESS: pd2:8610
19HG_PD_RAFT_PEERS_LIST: pd0:8610,pd1:8610,pd2:8610

5 启动与停止

5.1 启动 PD

在 PD 安装目录下执行:

1./bin/start-hugegraph-pd.sh

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

下文的生命周期说明适用于当前主线构建;上文下载的 1.7.0 启动脚本不包含这些修复。 支持的参数如下,GC 的版本限制见下文:

参数取值默认值描述
-dtrue、falsetrue守护进程模式,详见下文。
-g见下文版本限制不设置选择垃圾回收器;不支持的参数会中止启动。
-jJVM 参数空额外的 JVM 参数,例如 -j "-Xmx8g -Xms8g"。
-ytrue、falsefalse挂载 OpenTelemetry Java agent。首次使用时会把 agent 下载到 plugins/ 并校验 MD5,trace 通过 gRPC 上报到 http://127.0.0.1:4317。

master 构建接受 g1、G1、zgc 和 ZGC。 上文下载的 1.7.0 启动脚本仅接受显式指定 zgc 或 ZGC;-g g1、-g G1 和其他参数会中止启动。 默认路径请省略 -g;参数被拒绝时,查看 logs/hugegraph-pd-stdout.log。

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

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

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

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

1YYYY-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 安装目录下执行:

1./bin/stop-hugegraph-pd.sh

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

6 分布式集群的启动顺序

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

  1. 全部 PD 节点。它们组成 Raft 组并选出 leader。对每个节点检查 GET /v1/ready;仅当 HTTP 状态为 200 且响应中的 ready 为 true 时,再启动 Store。GET /v1/health 只检查 REST 监听器是否存活。
  2. 全部 Store 节点。每个 Store 通过 gRPC 向 PD 注册,PD 会自动激活 pd.initial-store-list 中列出的 Store。等到 GET /v1/stores 中每个 Store 的 state 都是 Up 再继续。
  3. 全部 Server 节点。Server 读取 pd.peers,并依赖 PD 报告至少有一个存活的 Store 才能完成分区分配。
sequenceDiagram
    participant 运维者
    participant PD
    participant Store
    participant Server
    运维者->>PD: GET /v1/ready(逐个检查 PD)
    PD-->>运维者: 200 且 ready=true
    运维者->>Store: 启动 Store
    Store->>PD: gRPC 注册与心跳
    运维者->>PD: GET /v1/stores(Basic 认证)
    PD-->>运维者: 每个目标 Store 状态为 Up
    运维者->>Server: 启动 Server
    Server->>PD: gRPC 查询分区与服务发现
    Server->>Store: gRPC 访问图数据

主线 Compose 中 Store 的 depends_on: condition: service_healthy 只等待 PD /v1/health 存活检查,Server 同样只等待 Store REST 存活检查;Server entrypoint 还会轮询 PD /v1/stores,直到有 Store 报告 Up 才启动 HugeGraph。docker compose up --wait 因而不能替代 PD Raft 就绪与 Store 注册状态检查。

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

7 验证

7.1 REST API 认证

当前主线除 /actuator/*、/v1/health、/v1/ready 和 /v1/prom/targets/* 之外,所有 PD REST 路径都要求 HTTP Basic Authorization。用户名必须是内部服务名 hg、store、hubble、vermeer 之一,密码必须等于 auth.secret-key;无密钥或密码不匹配时会返回 HTTP 401。用启动 PD 时的同一密钥检查 Store 列表:

1{"status": -1, "error": "Unauthorized"}
1curl -u "store:${HG_PD_AUTH_SECRET_KEY:?请先设置 PD 部署密钥}" \
2  http://localhost:8620/v1/stores

bin/wait-storage.sh 通过 PD_AUTH_USER、PD_AUTH_PASSWORD 配置同一凭据。1.7.0 发布标签的认证实现只检查用户名是否属于内部服务名,不比较密码;不要把该旧版行为套用到当前主线源码构建包。

警告

生产环境分别保护 Server 与 PD 端口

生产环境的 Server 图 API 必须按 Server 认证与授权配置启用 Auth、IP 白名单和最小权限授权,并保留、保护 Server audit-*.log。这些设置不保护 PD:当前主线 PD REST 使用 auth.secret-key;1.7.0 的认证实现仅检查用户名是否属于内部服务名,不比较密码。Raft 端口应保持 raft.ip-whitelist.enabled 并只允许配置的 peer,PD REST 与 gRPC 端口也必须限制在受信网络内。PD 的 /v1/health、/v1/ready 和 Actuator 探针无需 Basic 认证,须由网络策略限制可达范围;主线默认日志配置生成的 logs/audit-hugegraph-pd.log 也须纳入日志保护。

7.2 健康检查

GET /v1/health 不需要凭据,返回 200 且响应体为空,只表示 PD REST 监听器已启动:

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

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

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

/actuator/health 的 {"status":"UP"} 也不代表 PD Raft 集群已有可用 leader。主线新增的 GET /v1/ready 会在 PD Raft 节点已激活并能看到 leader 时返回 HTTP 200 和 ready:true;尚未就绪时返回 HTTP 503 和 ready:false:

1curl -i http://localhost:8620/v1/ready

7.3 集群与成员状态

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

1curl -u "store:${HG_PD_AUTH_SECRET_KEY:?请先设置 PD 部署密钥}" \
2  http://localhost:8620/v1/members

响应中包含 pdList、选出的 pdLeader、numOfService、numOfNormalService 和 stateCountMap。健康的 3 节点 PD 集群中,numOfService 和 numOfNormalService 都应为 3,且恰好有一个成员的 role 为 Leader。

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

7.4 Store 状态

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

1curl -u "store:${HG_PD_AUTH_SECRET_KEY:?请先设置 PD 部署密钥}" \
2  http://localhost:8620/v1/stores

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

 1{
 2  "message": "OK",
 3  "data": {
 4    "stores": [
 5      {
 6        "storeId": 8319292642220586694,
 7        "address": "127.0.0.1:8500",
 8        "raftAddress": "127.0.0.1:8510",
 9        "version": "",
10        "state": "Up",
11        "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",
12        "dataPath": "./storage",
13        "startTimeStamp": 1754027127969,
14        "registedTimeStamp": 1754027127969,
15        "lastHeartBeat": 1754027909444,
16        "capacity": 494384795648,
17        "available": 346535829504,
18        "partitionCount": 0,
19        "graphSize": 0,
20        "keyCount": 0,
21        "leaderCount": 0,
22        "serviceName": "127.0.0.1:8500-store",
23        "serviceVersion": "",
24        "serviceCreatedTimeStamp": 1754027127000,
25        "partitions": []
26      }
27    ],
28    "stateCountMap": {
29      "Up": 1
30    },
31    "numOfService": 1,
32    "numOfNormalService": 1
33  },
34  "status": 0
35}

7.5 其他 REST 接口

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

方法与路径描述
GET /集群简要统计:leader、状态、成员数、Store 数、图数量、分区数
GET /v1/health存活检查;HTTP 200 不代表 Raft 就绪,无需认证
GET /v1/readyRaft readiness;HTTP 200 且 ready:true 表示本节点已激活并看到 leader,无需认证(当前主线)
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/license旧接口,当前主线返回空对象
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:ss 和 yyyy-MM-dd 都是可接受的格式。

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

同时暴露用于监控 Raft 法定人数(Quorum)状态及告警的成员指标:

  • hg_raft_leader:当前 PD 节点若为选出的 Raft Leader 则为 1,Follower 节点为 0。
  • hg_raft_has_leader:当前 PD 节点若能看到活跃的 Raft Leader(即属于法定多数 Quorum 一部分)则为 1,失去 Quorum 时为 0。
  • hg_raft_alive_peers:Leader 节点在租约超时时间内收到心跳的活跃 Raft 节点总数(包含自身);非 Leader 节点上返回 NaN。
说明

Quorum 丢失告警规则:当集群所有成员上 sum(hg_raft_leader) == 0 或 hg_raft_has_leader == 0 时,表明集群已失去 Quorum。告警规则的 for: 持续时间应长于 Raft 选举超时时间(例如 for: 30s),以避免正常重新选举期间误报。若需监控活跃副本数,可使用表达式 hg_raft_alive_peers and on(instance) (hg_raft_leader == 1)。

在 1.7.0 之后的版本中,PD 还会为每个已注册的 Store 导出 hg_store_state{store="<id>",state="<state>"}:Store 当前状态(Unknown、Pending、Up、Offline、Exiting 或 Tombstone)对应的序列为 1,其余为 0;以及 hg_store_leader_count{store="<id>"},即 leader 位于该 Store 上的分片组数量。重建后的 Store 在 leader 迁回之前会报告 0。所有 PD 成员读取的是同一份复制的元数据,因此聚合这些序列前请先只选取一个实例。

7.6 Store 下线与排空生命周期

下线或下架 Store 节点遵循严谨的状态机流转,以确保在不中断业务的前提下安全排空分片副本:

  1. 状态机流转过程:

    • Up:Store 在线且健康,正常参与副本分配和 leader 选举。
    • Exiting:Store 处于排空状态。处于 Exiting 时,该节点继续正常续租心跳,但 PD 会将其排除在新的副本分配和迁移目标之外。
    • 分区迁移:PD 自动调度后台迁移任务,将该节点上的所有分片副本逐步迁至其他健康的活跃 Store 上。
    • Tombstone:Store 永久下线退出。一旦标记为 Tombstone,管理接口不再允许将其恢复为活跃状态。
  2. 发起排空操作: 通过管理接口将目标 Store 状态置为 Exiting:

    1curl -X POST http://<pd-host>:8620/v1/store/{storeId} \
    2  -H "Authorization: Basic <credentials>" \
    3  -H "Content-Type: application/json" \
    4  -d '{"storeState": "Exiting"}'
  3. 容量约束与下线检查:

    • 容量校验:排空会校验集群剩余可用 Store 节点数是否满足 minStoreCount(pd.min-store-count)。若剩余容量不足, PD 将直接拦截并在状态持久化前拒绝请求;此时需扩容足够的活跃 Store 后重新发起下线请求。
    • 退出完成判定:PD 会持续保持 Exiting 状态,直到 Store 最新心跳上报本地分区引擎数为 0 且 PD 元数据中无任何分片组引用该 Store ID。
    • 销毁前核验:在删除 Store Pod 或持久化存储卷前,运维人员必须确认其余分片组已具备完整的 Raft 成员、全额副本以及最新的健康心跳。
    • 重新注册意图保留:处于 Exiting 状态的 Store 重启重新注册时,即使其地址在 pd.initial-store-list 中,PD 仍会保留其 Exiting 排空意图。

3.1.3 - HugeGraph-Store 快速上手

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 版本:HugeGraph 1.8.0+ 使用 Java 17(Maven 源码构建仅接受 JDK 17;启动脚本拒绝低于 17 的运行时;1.7.0 是最后一个支持 Java 11 的版本)
  • Maven 版本:≥ 3.6.3(从源码编译时)
  • 如需进行多节点部署,请先部署 HugeGraph-PD

3 部署

3 部署

HugeGraph-Store 组件主要支持以下部署与运行方式:

  • 下载发布包 — 下载并解压官方发布的完整二进制安装包。
  • 源码编译 — 基于 master 主线代码使用 Maven 与 Java 17 编译 Store 模块。
  • Docker 部署 — 使用容器运行 Store 节点并组建分布式集群。

3.1 下载 tar 包

Apache 下载页目前提供 1.7.0 的完整二进制包,其中包含 PD、Store 和 Server;没有单独列出 Store 二进制包。下载前请在 官方 Apache HugeGraph 下载页核对版本、签名和 SHA512。1.7.0 是孵化期发布的历史版本,归档文件和解压目录仍带 incubating:

1# 1.7.0 是项目孵化期发布的历史版本,因此文件名和目录名仍带 incubating
2curl -fLO --connect-timeout 10 --max-time 1800 https://downloads.apache.org/hugegraph/1.7.0/apache-hugegraph-incubating-1.7.0.tar.gz
3tar zxf apache-hugegraph-incubating-1.7.0.tar.gz
4cd apache-hugegraph-incubating-1.7.0/apache-hugegraph-store-incubating-1.7.0

3.2 源码编译

  1. 克隆源代码仓库:

    1git clone https://github.com/apache/hugegraph.git
    2cd hugegraph
  2. 编译依赖及 Store 模块:

    1# 单独编译 Store 前需先编译其依赖的 hugegraph-struct 模块
    2mvn install -pl hugegraph-struct -am -DskipTests
    3mvn clean package -pl hugegraph-store/hg-store-dist -am -DskipTests
  3. 检查编译产物:

    1cd hugegraph-store/apache-hugegraph-store-*
    2ls -la bin conf lib

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

3.3 Docker 部署

HG_STORE_* 环境变量映射是当前主线源码提供的功能;server 的 1.7.0 发布源码标签尚无这些映射。本文下面的 Docker 示例仅适用于从当前主线源码构建并使用同一个本地标签的 PD、Store 和 HStore Server 镜像:

1# 在 hugegraph 仓库根目录执行
2docker build -f hugegraph-pd/Dockerfile -t hugegraph/pd:local .
3docker build -f hugegraph-store/Dockerfile -t hugegraph/store:local .
4docker build -f hugegraph-server/Dockerfile-hstore -t hugegraph/server:local .

首次启动前,按 docker/README.md 的认证环境步骤 在 docker/ 创建 .env。 该步骤使用 umask 077 并拒绝覆盖已有文件;若 .env 已存在,应保留原文件并编辑补全缺少的项。不要为已初始化的数据目录重新生成 HG_PD_AUTH_SECRET_KEY。此文件由仓库 .gitignore 忽略,仍不要提交。 每次在新 shell 执行 Compose 或 PD REST 命令前,都从 docker/ 目录加载同一文件:

1# 在 hugegraph 仓库根目录执行
2cd docker
3set -a; . ./.env; set +a
4: "${HG_PD_AUTH_SECRET_KEY:?请在 .env 中设置 HG_PD_AUTH_SECRET_KEY}"
5# 只启动 PD、Store、Server,不启动可选 Hubble 服务
6HUGEGRAPH_VERSION=local HUGEGRAPH_PULL_POLICY=never \
7  docker compose -f docker-compose-hstore.yml \
8  up -d --wait pd store server

后续重启或调用 PD REST 时,先按上面的方式加载同一个密钥;不要为已初始化的数据目录重新生成新值。HUGEGRAPH_VERSION=local 和 HUGEGRAPH_PULL_POLICY=never 是此 Compose 命令的参数,每次运行 Compose 生命周期命令时都要显式带上。

若要启动 Compose 文件中的 Hubble 服务,需使用拓扑对应的未跟踪配置文件。最小拓扑 docker-compose-hstore.yml 使用 conf/hubble/hstore.local.properties; HA 拓扑 docker-compose-3pd-3store-3server.yml 使用 conf/hubble/hstore-ha.local.properties。 上述 README 初始化步骤会用共享 PD 密钥生成两份文件。若文件缺失或需更新,先从 docker/ 目录载入已有 .env,再执行对应命令:

1set -a; . ./.env; set +a
2./set-hubble-pd-password.sh hstore      # 最小拓扑
3./set-hubble-pd-password.sh hstore-ha  # HA 拓扑

多节点拓扑中的服务名是 pd0–pd2、store0–store2 和 server0–server2。该主线 Compose 文件也应使用上述本地构建的同标签镜像,不能将 HUGEGRAPH_VERSION=1.7.0 发布镜像与主线 Compose 文件混用。

单独运行当前主线构建的 Store 时,将示例地址换成 Store 与 PD 均可路由的实际地址:

下面的 mkdir -p 和非递归 chown 仅适用于新建空目录。复用旧 root 镜像写入的数据时,先停止 Store, 执行一次 sudo chown -R 10001:10001 /path/to/storage,再启动 UID 10001 镜像。

 1# master 构建的镜像以 UID 10001 运行,宿主机数据目录必须对该用户可写
 2mkdir -p /path/to/storage && sudo chown 10001:10001 /path/to/storage
 3docker run -d \
 4  -p 8520:8520 -p 8500:8500 -p 8510:8510 \
 5  -e HG_STORE_PD_ADDRESS=192.168.1.10:8686 \
 6  -e HG_STORE_GRPC_HOST=192.168.1.20 \
 7  -e HG_STORE_RAFT_ADDRESS=192.168.1.20:8510 \
 8  -v /path/to/storage:/hugegraph-store/storage \
 9  --name hugegraph-store \
10  hugegraph/store:local

当前主线 Docker 环境变量:

变量必填默认值对应配置项描述
HG_STORE_PD_ADDRESS是无pdserver.addressPD gRPC 地址,多个地址用逗号分隔。
HG_STORE_GRPC_HOST是无grpc.host本节点对外公布的 gRPC 主机名/IP;容器网络中应使用容器主机名。
HG_STORE_RAFT_ADDRESS是无raft.address本节点的 Raft 地址。
HG_STORE_GRPC_PORT否8500grpc.portgRPC 服务端口。
HG_STORE_REST_PORT否8520server.portREST API 端口。
HG_STORE_DATA_PATH否/hugegraph-store/storageapp.data-path数据存储路径。
HG_STORE_ROCKSDB_TOTAL_MEMORY_SIZE否无rocksdb.total_memory_sizeRocksDB 内存预算:auto 或字节数。空值视为未设置;其他值会使入口脚本以退出码 2 退出。未设置时使用 application-pd.yml 中的值或自动计算。

当前主线 entrypoint 将这些变量写入 SPRING_APPLICATION_JSON,覆盖镜像内 conf/application.yml;其余配置仍从该文件和 application-pd.yml 读取,然后以前台方式启动 Java。旧变量 PD_ADDRESS、GRPC_HOST、RAFT_ADDRESS 仍可用,但会输出弃用警告。

PD 和 Store 的 Docker HEALTHCHECK 都检查 /v1/health,只说明本地 REST 监听器有响应。Compose 的 depends_on 也以此作为启动门槛,因此还需单独检查 PD /v1/ready 与 PD /v1/stores 中的 Store Up 状态。Store 镜像默认设置 STDOUT_MODE=true;其 Dockerfile 只声明 EXPOSE 8520,从 Docker 网络外访问 gRPC 8500 或 Raft 8510 时需另行发布端口。

4 配置

Store 从 conf/ 读取两个配置文件。1.7.0 发布标签的源文件见 application.yml 和 application-pd.yml;当前主线文件见 application.yml 和 application-pd.yml。主线默认配置把 spring.profiles.include: pd 加载的 RocksDB 设置放在第二个文件中;启动脚本指定 application.yml。

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

4.1 application.yml

以下配置参考表核对的是 Server 主线提交的发行目录值和 Java 默认注入值;1.7.0 发布包请使用其版本标签对应的配置文件,不要跨版本覆盖。

4.2 application-pd.yml

此文件只保存 rocksdb 参数和 Actuator 暴露设置。

警告

生产环境分别保护 Server 与 Store 端口

生产环境的 Server 图 API 必须按 Server 认证与授权配置启用 Auth、IP 白名单和最小权限授权,并保留、保护 Server audit-*.log。这些设置不保护 Store:主线默认配置暴露所有 Actuator 端点,且没有 PD 式 Basic 认证保护;必须将 Store REST、gRPC 和 Raft 端口限制在集群与受信运维网络内。

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 数(至少为 1)取最接近的 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_sizeauto自动计算,见说明本节点所有 RocksDB 实例共享的堆外内存预算(取值为 auto 或具体字节数)。详细自动推导规则见下方说明。
rocksdb.write_buffer_size32000000自动推导,见说明memtable 大小,单位字节。缺失或为 0 时取 total_memory_size / 1000,最小为 1048576(1 MiB)。
rocksdb.min_write_buffer_number_to_merge1616落盘前合并的 memtable 数量。
rocksdb.write_buffer_ratio未设置0.66total_memory_size 中分配给写缓存的比例,其余作为 block cache。

RocksDB 内存预算自动计算规则

说明

当 rocksdb.total_memory_size 设置为 auto(或未设置、为 0)时,系统自动计算堆外 RocksDB 缓存预算:

  • 推导公式:以物理内存(容器环境下优先取可见的 cgroup 限制)减去 JVM 最大堆(-Xmx)、直接内存(MaxDirectMemorySize)和 1.5 GiB 系统预留后,取剩余量的一半,范围钳制在 256 MiB 至 32 GB(32000000000 字节)之间。
  • 写缓存与 Block Cache:根据 rocksdb.write_buffer_ratio(默认 0.66)切分。该预算为软目标容量;大量并发写入时可将 rocksdb.write_buffer_allow_stall 设为 true,以增加写入延迟为代价把写缓存限制在其份额内。Block cache 并非严格上限,本地内存仍可能超出预算,容器仍可能被 OOM 终止。
  • 升级与覆盖:历史配置若保留了旧固定值 32000000000,可通过设置环境变量 HG_STORE_ROCKSDB_TOTAL_MEMORY_SIZE=auto 或启动参数 -Drocksdb.total_memory_size=auto 启用自动推导。

org/apache/hugegraph/rocksdb/access/RocksDBOptions.java 中定义的其他选项都可以加在同一个 rocksdb: 块下,例如 rocksdb.max_background_jobs、rocksdb.level0_file_num_compaction_trigger 或 rocksdb.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扫描任务队列容量。

gRPC 回调队列(1.8.0)

Store 使用无界队列处理 gRPC 回调,避免队列满时丢弃取消或完成通知,导致请求无法正常结束。thread.pool.grpc.queue 仍可写在配置中,但不再限制这个队列的容量。

thread.pool.grpc.core 和 thread.pool.grpc.max 仍用于配置线程池。由于回调可以继续排队,积压通常不会触发线程数从 core 增长到 max;只增大 max 无法提高回调处理能力。

持续过载仍会使队列积压并增加内存占用。应限制客户端并发,并根据节点资源调整扫描和查询工作线程池;不要依赖 thread.pool.grpc.queue 限流。1.7.0 仍使用配置的 gRPC 队列容量。

查询下推

配置项代码默认值说明
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每个分区的副本数。

诊断

自 HugeGraph 1.8.0 起,Store 的 HTTP 激活接口 GET /v1/arthasstart 已禁用(直接返回 403),旧 Arthas 配置字段仅为兼容保留。 推荐直接以服务进程属主身份运行发行包内置的脚本诊断正在运行的 JVM (官方容器镜像内置 JDK 17,可直接使用 docker exec 执行):

1bin/arthas.sh

同机多进程时可指定 --pid <PID> --telnet-port 3659。 更多参数、认证配置及安全实践参见 Arthas 诊断代理。

4.4 各节点需要区分的配置

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

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

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

5 启动与停止

5.1 启动 Store

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

1./bin/start-hugegraph-store.sh

下文的生命周期与下载时限说明适用于包含启动脚本修复的 master 构建;上文下载的 1.7.0 启动脚本不包含这些修复。 启动脚本支持四个参数,GC 的版本限制见下文:

参数取值默认值说明
-dtrue、falsetrue守护进程模式,见下文。
-g见下文版本限制未设置选择垃圾回收器;不支持的参数会中止启动。
-jJVM 参数字符串空附加的 JVM 参数,例如 -j "-Xmx16g -Xms8g"。
-ytrue、falsefalse挂载 OpenTelemetry Java agent(首次使用时下载到 plugins/),并将 trace 导出到 127.0.0.1:4317。

master 构建接受 g1、G1、zgc 和 ZGC。 上文下载的 1.7.0 启动脚本仅接受显式指定 zgc 或 ZGC;-g g1、-g G1 和其他参数会中止启动。 默认路径请省略 -g;参数被拒绝时,查看 logs/hugegraph-store-server.log。

守护进程模式:

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

JVM 内存方面,如果没有自行设置 JAVA_OPTIONS:-Xms512m,-Xmx 取空闲内存的一半并限制在 512 MB 到 2048 MB 之间。 脚本还会加上与该堆大小相同的 -XX:MaxDirectMemorySize、-XX:MetaspaceSize=256M、OOM 时把堆转储写入 logs/,以及滚动的 GC 日志 logs/gc.log。 生产节点通常需要大得多的堆,请显式指定,并同时设置直接内存上限,例如 -j "-Xmx32g -Xms32g -XX:MaxDirectMemorySize=2g"。 不设上限时,JVM 允许的直接内存与 32 GB 的堆相同,RocksDB 预算会把它计算在内,在内存不足约 66 GB 的主机上会降到 256 MiB 的下限。

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

主线构建中,每次可选 jemalloc 下载的连接时限为 5 秒,总时限为 30 秒。 1.7.0 的下载 helper 没有连接或总时限。超时或校验失败时沿用已有回退路径,不预加载下载库并继续启动。 校验有效的缓存库仍可复用,失败下载的临时文件会被清理。

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

1YYYY-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 安装目录下执行:

1./bin/stop-hugegraph-store.sh

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

5.3 重启 Store

1./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,分区分配也就无法完成。当前主线应先对每个 PD 检查 /v1/ready 返回 HTTP 200 且 ready:true;/v1/health 只是存活检查。
  2. 再启动 Store。Store 早于 PD 启动并不致命:心跳线程会持续重试注册,并在 PD 可用之前打印 store heartbeat error: PD UNREACHABLE。
  3. 最后启动 HugeGraph-Server,此时所有 Store 节点都应上报 state: "Up"。Server 需要分区就绪之后才能初始化或打开图。

主线 Compose 用 depends_on: condition: service_healthy 等待本地健康检查,但 PD 和 Store 的 Docker 健康检查都只访问 /v1/health,不能证明 Raft 多数派或 Store 注册已就绪。Server entrypoint 会等待 PD 至少报告一个 Up 的 Store;运维时仍应检查 PD /v1/ready 和 /v1/stores。

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:

1grpc:
2  port: 8500
3raft:
4  address: 127.0.0.1:8510
5server:
6  port: 8520
7app:
8  data-path: ./storage-a

节点 B:

1grpc:
2  port: 8501
3raft:
4  address: 127.0.0.1:8511
5server:
6  port: 8521
7app:
8  data-path: ./storage-b

节点 C:

1grpc:
2  port: 8502
3raft:
4  address: 127.0.0.1:8512
5server:
6  port: 8522
7app:
8  data-path: ./storage-c

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

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

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

1pd:
2  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 节点拥有独立的主机名和环境变量:

 1# store0,宿主机端口 8500(gRPC)、8510(Raft)、8520(REST)
 2HG_STORE_PD_ADDRESS: pd0:8686,pd1:8686,pd2:8686
 3HG_STORE_GRPC_HOST: store0
 4HG_STORE_GRPC_PORT: "8500"
 5HG_STORE_REST_PORT: "8520"
 6HG_STORE_RAFT_ADDRESS: store0:8510
 7HG_STORE_DATA_PATH: /hugegraph-store/storage
 8
 9# store1,宿主机端口 8501、8511、8521
10HG_STORE_GRPC_HOST: store1
11HG_STORE_RAFT_ADDRESS: store1:8510
12
13# store2,宿主机端口 8502、8512、8522
14HG_STORE_GRPC_HOST: store2
15HG_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 服务是否正常运行:

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

如果返回 {"status":"UP"},表示 Store 本地应用健康检查通过;它本身不证明已在 PD 注册为 Up。

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

1curl -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/节点概览,包含 leaderCount 和 partitionCount
GET/-/state运维设置的节点状态标志,取值为 STARTING、ONLINE、STOPPING;此标志不表示 PD 注册状态
GET/-/lifecycle进程生命周期状态(1.8.0+ 提供)
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

GET /-/lifecycle 返回 JSON 格式的进程生命周期状态,形如 {"status":0,"text":"STARTED"}。其中 text 包含四种状态:

  • STARTING:Spring 上下文或 gRPC 服务仍在启动中;
  • STARTED:Spring 应用已就绪(ApplicationReadyEvent)且 gRPC 服务已启动运行;
  • STOPPING:进程已进入关闭流程(ContextClosedEvent,优先级最高);
  • UNAVAILABLE:gRPC 服务已提前停止或已终止。
警告

进程生命周期不等于存储或集群就绪: STARTED 仅代表本地 JVM 与 gRPC 进程状态,不代表节点可对外提供数据读写服务。它无法证明节点已成功向 PD 注册、数据分片已恢复完成或 Raft 副本已追平日志。

  • 在执行滚动重启或下线替换节点前,必须通过 PD 端点 GET /v1/stores 确认节点处于 Up 状态,并通过 GET /v1/partitions 确认本节点所有 Raft 分区状态健康,切勿仅凭 STARTED 作为滚动更新放行条件。
  • 1.8.0 之前的旧版本 Store 未提供此接口,调用将返回 HTTP 404;不能将 404 视为已启动或可替换状态。

主线发行目录的 Store 配置将 management.endpoints.web.exposure.include 设为 "*",并启用 Prometheus;Actuator 端点没有 PD REST Basic 认证保护,请限制 Store REST 端口的网络可达范围。

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

7.2 通过 PD 检查注册结果

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

1curl -u "store:${HG_PD_AUTH_SECRET_KEY:?请先设置 PD 部署密钥}" \
2  http://localhost:8620/v1/stores

对于当前主线源码构建包,PD REST 用户名必须是 hg、store、hubble、vermeer 之一,密码必须与 PD 的 auth.secret-key 相同;HG_PD_AUTH_SECRET_KEY 会同时配置 Compose 中的 PD 和 Server。/v1/health、/v1/ready、/actuator/* 和 /v1/prom/targets/* 不需要认证。1.7.0 发布标签的实现只校验用户名,不比较密码;不要把这一旧行为用于主线源码构建包。

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

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

 1{
 2  "message": "OK",
 3  "data": {
 4    "stores": [
 5      {
 6        "storeId": 8319292642220586694,
 7        "address": "127.0.0.1:8500",
 8        "raftAddress": "127.0.0.1:8510",
 9        "version": "",
10        "state": "Up",
11        "deployPath": "/Users/{your_user_name}/hugegraph/hugegraph-store/apache-hugegraph-store-{version}/lib/hg-store-node-{version}.jar",
12        "dataPath": "./storage",
13        "startTimeStamp": 1754027127969,
14        "registedTimeStamp": 1754027127969,
15        "lastHeartBeat": 1754027909444,
16        "capacity": 494384795648,
17        "available": 346535829504,
18        "partitionCount": 0,
19        "graphSize": 0,
20        "keyCount": 0,
21        "leaderCount": 0,
22        "serviceName": "127.0.0.1:8500-store",
23        "serviceVersion": "",
24        "serviceCreatedTimeStamp": 1754027127000,
25        "partitions": []
26      }
27    ],
28    "stateCountMap": {
29      "Up": 1
30    },
31    "numOfService": 1,
32    "numOfNormalService": 1
33  },
34  "status": 0
35}

7.3 最小图读写验证

确认 Store 已在 PD 中显示为 Up 后,再启动配置为 HStore 后端、连接同一 PD 集群的 Server。Server 配置步骤见 Server 快速上手。确认 GET /versions 可访问且默认图 hugegraph 已加载后,可以创建一个属性键、顶点标签和顶点,再读取该顶点:

 1SERVER_URL=http://localhost:8080
 2GRAPH_URL="$SERVER_URL/graphspaces/DEFAULT/graphs/hugegraph"
 3
 4# 这些名称在当前图空间中必须唯一;已存在时换一组名称再执行
 5curl -fsS -X POST "$GRAPH_URL/schema/propertykeys" \
 6  -H 'Content-Type: application/json' \
 7  -d '{"name":"pd_store_demo_name","data_type":"TEXT","cardinality":"SINGLE","properties":[]}'
 8
 9curl -fsS -X POST "$GRAPH_URL/schema/vertexlabels" \
10  -H 'Content-Type: application/json' \
11  -d '{"name":"pd_store_demo_vertex","id_strategy":"CUSTOMIZE_STRING","properties":["pd_store_demo_name"],"primary_keys":[],"nullable_keys":[]}'
12
13curl -fsS -X POST "$GRAPH_URL/graph/vertices" \
14  -H 'Content-Type: application/json' \
15  -d '{"id":"pd-store-demo-1","label":"pd_store_demo_vertex","properties":{"pd_store_demo_name":"stored in HStore"}}'
16
17curl -fsS "$GRAPH_URL/graph/vertices/%22pd-store-demo-1%22"

最后一个响应应包含顶点 ID pd-store-demo-1 和属性 pd_store_demo_name。若 Server 开启了认证,以上请求还需按其认证配置增加凭据。

3.1.4 - 使用 Helm 部署 HugeGraph

本文适用于 HugeGraph 1.8.0 及以后版本,需要支持 OCI 的 Helm 3.10+ 和 Kubernetes (K8s) 1.23+。 可从 GHCR 或 Docker Hub 安装 hugegraph-helm。Chart 与 HugeGraph 服务分别维护版本,例如 0.4.x 的 Chart 可以部署 1.8.x 的服务。

警告

当前开发 Chart 的 HugeGraph 基础组件使用 latest 镜像,适合测试。 可选 Vermeer 已固定为经过验证的已发布镜像及 digest,见可选引擎。 对应 HugeGraph 服务正式发布后,生产环境请选择稳定 Chart,并检查其中的镜像版本。 镜像标签可能变化;需要固定镜像内容时,请配置各组件的 image.digest。

Artifact Hub 方便查找 Chart、查看版本和安装说明,实际安装包仍从 GHCR 或 Docker Hub 下载。 参数和源码开发方式见 chart README, 生命周期操作见 运维参考。

在 Artifact Hub 选择版本,从 GHCR 或 Docker Hub 下载 Chart,再使用 Helm 安装到 Kubernetes

1 安装

说明

默认部署规格与存储要求

  • 拓扑组成:默认部署 3 PD + 3 Store + 3 Server 与 1 Hubble,默认开启鉴权与持久化存储。
  • 存储依赖:需要集群具备默认动态 StorageClass 或预先匹配的静态 local PV,共需 7 个持久卷(3 个 10 GiB PD 卷、3 个 50 GiB Store 卷、1 个 1 GiB Hubble 卷)。
  • 内存考量:保留镜像内 JVM 内存自动推导;按需调整 resource requests/limits,确保宿主机给 9 个图服务 JVM 与 Hubble 提供足够内存。

选择一个下载源即可,公共 CI 推荐 GHCR。本地轻量测试可直接使用单节点预设。

提示

--devel 按版本号选择最新 Chart,包含开发版和稳定版,不限于某个版本系列。 生产部署或需要复现时,将 --devel 换成 --version <已发布版本>,固定你选定的版本。

GHCR(推荐)
1CHART=oci://ghcr.io/hugegraph/hugegraph-helm
2kubectl config current-context
3kubectl get nodes
4kubectl get storageclass
5helm install hugegraph "$CHART" --devel -n hugegraph \
6  --create-namespace --wait --timeout 15m
Docker Hub
1CHART=oci://registry-1.docker.io/hugegraph/hugegraph-helm
2kubectl config current-context
3kubectl get nodes
4kubectl get storageclass
5helm install hugegraph "$CHART" --devel -n hugegraph \
6  --create-namespace --wait --timeout 15m
单节点试用
1# 适合本地 Minikube/Kind 等轻量测试;直接安装本次下载的 Chart
2CHART=oci://ghcr.io/hugegraph/hugegraph-helm
3helm pull "$CHART" --devel --untar
4helm install hugegraph ./hugegraph-helm -n hugegraph \
5  -f ./hugegraph-helm/values-single.yaml \
6  --create-namespace --wait --timeout 10m

单节点试用预设使用 HStore 的 1 PD + 1 Store + 1 Server 与 Hubble,放宽调度限制,适合资源受限环境。 SeaTunnel 和 Vermeer 仍保持关闭。

2 模式和访问入口

解压后目录为 hugegraph-helm/,源码目录仍为 helm/hugegraph/。

HugeGraph Helm 核心文件与结构

  • hugegraph-helm/
    • Chart.yamlChart 元数据与版本定义
    • values.yaml默认配置(easy 模式:3 PD + 3 Store + 3 Server + 1 Hubble,NodePort 入口)
    • values-single.yaml单节点预设(本地 Minikube/Kind 测试,1 副本且关闭反亲和与 PDB)
    • values-cluster.yaml生产集群预设(跨节点反亲和调度,Store 采用 OnDelete 逐个滚动升级)
    • values-strict.yaml安全加固预设(strict 模式:全部 ClusterIP,强制启用 NetworkPolicy 隔离)
    • values.schema.jsonvalues 配置参数校验规范
    • templates/Kubernetes 资源编排模板
      • pd-statefulset.yamlPD 服务有状态副本集(元数据与调度中心)
      • store-statefulset.yamlStore 存储节点有状态副本集(分布式存储引擎)
      • server-deployment.yamlServer 引擎无状态 Deployment(注入 serviceId / graphSpace)
      • hubble-deployment.yaml可视化控制台 Deployment
      • tests/冒烟验证测试钩子(helm test,支持自定义 testGraphAlias)
    • examples/部署示例(local PV、GitOps 凭据、可选引擎、Ingress 等)
    • docs/operations.md生命周期进阶运维与故障恢复手册

默认 mode: easy,Server 和 Hubble 自动分配 NodePort,PD 保持 ClusterIP。可以直接使用 HTTP,无需域名、证书或额外确认参数。 mode: strict 默认将 Server/Hubble 设为 ClusterIP,并开启完整 NetworkPolicy 隔离。 SeaTunnel 和 Vermeer 启用后的原生 HTTP/UI 在 easy 模式下默认使用 NodePort,strict 模式下默认使用 ClusterIP,两种模式均需登录。 内部 RPC、Worker HTTP 与 SeaTunnel 成员端口仍保持私有。两个模式都保留鉴权和持久化。 优先级是组件显式参数高于全局参数,全局参数高于模式默认值,显式 false 也会生效。 全局参数包括 persistence.enabled 和 global.imageRegistry,严格预设为 values-strict.yaml。

入口访问方式前提
NodePorthttp://<可达节点IP>:<分配的NodePort>节点网络可达且防火墙放行,无需额外控制器
ClusterIP集群内虚拟 Service IP/DNS,如 hugegraph-server.hugegraph.svc:8080集群外通过 port-forward 或已有网关访问
LoadBalancer基础设施分配的地址集群有对应负载均衡控制器
Ingress通过控制器路由 HTTP 请求已安装 Ingress 控制器,域名和 TLS 都可选
1kubectl -n hugegraph get svc hugegraph-server hugegraph-hubble
2kubectl get nodes -o wide
3kubectl -n hugegraph get secret hugegraph-admin \
4  -o jsonpath='{.data.password}' | base64 --decode

使用 Hubble 的 NodePort 打开页面,以 admin 和查出的密码登录。 默认 externalTrafficPolicy: Cluster 下,访问的节点不必运行目标 Pod。ClusterIP 是集群内部的虚拟服务地址,不是节点 IP,普通笔记本通常不能直接访问。 也可以运行 kubectl -n hugegraph port-forward svc/hugegraph-hubble 8088:8088,在本机打开 http://127.0.0.1:8088。

基础 PD/Server/Hubble 三类客户端 Service 支持 externalTrafficPolicy、loadBalancerClass、loadBalancerIP、loadBalancerSourceRanges、externalIPs 和 allocateLoadBalancerNodePorts,具体行为取决于集群及负载均衡实现。LoadBalancer 专用字段应配合对应类型使用。 NodePort 省略或设为 0 时自动分配,固定端口由 Kubernetes 根据集群配置的范围校验,chart 不再强制 30000–32767。 原 HTTP 暴露确认参数保留兼容,但不再阻止渲染。

可选引擎:默认关闭

Chart 默认仅部署核心图服务(PD + Store + Server + Hubble)。针对数据集成与超大规模内存图计算场景,Chart 提供了 SeaTunnel 与 Vermeer 两款原生可选引擎,默认均保持关闭:

可选引擎默认状态核心用途运行模式 (*.mode)访问控制
Hubble开启 (true)图数据可视化、多图空间与任务监控单副本 Deployment跟随全局 mode(NodePort 或 ClusterIP)
SeaTunnel关闭 (false)异构数据源批流导入与跨图整库迁移standalone / clustereasy 为 NodePort,strict 为 ClusterIP;HTTP Basic 鉴权
Vermeer关闭 (false)内存优先的高性能分布式图计算算法standalone / clustereasy 为 NodePort,strict 为 ClusterIP;Token 鉴权,Hubble 自动集成

在 values 中将对应引擎的 enabled 设为 true 即可启用,管理密码与 Server 独立生成。 seatunnel.service.type 和 vermeer.service.type 为 null 时继承模式默认值:easy 为 NodePort,strict 为 ClusterIP。 显式 ClusterIP 保持私有;显式 NodePort(包括 strict 模式)开放需要登录的 HTTP/UI。 旧配置显式指定了 ClusterIP 时,需改回 null 才会继承 easy 默认值;省略 service.nodePort 或设为 null 时由 Kubernetes 分配端口。 引擎的 standalone / cluster 拓扑独立于上述访问设置。

SeaTunnel:按需开启原生数据导入、导出与迁移
1helm install hugegraph ./hugegraph-helm -n hugegraph --create-namespace \
2  -f ./hugegraph-helm/values-single.yaml \
3  --set seatunnel.enabled=true --set seatunnel.mode=standalone \
4  --wait --timeout 30m
  • 运行模式:standalone 启动 1 个 Hybrid 节点(轻量测试);cluster 模式启动多个同构节点(高并发批处理)。

  • 访问与凭据:easy 模式通过分配的 HTTP NodePort 打开 http://<可达节点IP>:<NodePort>/#/overview:

    1kubectl -n hugegraph get svc hugegraph-seatunnel \
    2  -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}{"\n"}'
    3kubectl get nodes -o wide

    使用 HTTP Basic 用户名 admin 和 hugegraph-seatunnel-auth Secret 中的密码登录。 strict 默认 ClusterIP,可用 kubectl -n hugegraph port-forward svc/hugegraph-seatunnel 8081:8080 在本机访问;5801 仍仅供内部通信。

  • 完整作业配置、内置示例验证及跨图迁移流程见 SeaTunnel 部署章节 或 SeaTunnel 部署指南。

Vermeer:按需开启内存图计算,自动接入 Hubble
1helm install hugegraph ./hugegraph-helm -n hugegraph --create-namespace \
2  -f ./hugegraph-helm/values-single.yaml \
3  --set vermeer.enabled=true --set vermeer.mode=standalone \
4  --wait --timeout 20m
1hugegraph-helm/
2  examples/
3    values-vermeer-standalone.yaml # 单机预设(单个 Pod 同时包含 Master 与 Worker)
4    values-vermeer-cluster.yaml    # 集群预设(1 个 Master Pod + 3 个 Worker Pods)
5  docs/
6    vermeer.md                     # Vermeer 算法调用、参数映射与进阶运维手册
  • 运行模式:standalone 单机模式在同一个 Pod 中运行 Master 协调与 Worker 计算容器;cluster 模式提供独立的 Master Pod 与可水平扩展的 Worker Pod 集群(默认 3 副本)。

  • Hubble 一键集成:Hubble 会自动注入 Master 内部 Service 地址与访问令牌。管理员在 Hubble 控制台即可直接触发 15+ 种图算法,计算结果保留在内存副本中,不污染原图属性。

  • 原生控制台直连:easy 模式通过 <release>-vermeer-master 分配的 HTTP NodePort 打开 http://<可达节点IP>:<NodePort>/:

    1kubectl -n hugegraph get svc hugegraph-vermeer-master \
    2  -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}{"\n"}'
    3kubectl get nodes -o wide

    并在 Admin credential 输入框中填入 <release>-vermeer-admin Secret 的 password(无需用户名)登录。 strict 模式默认 ClusterIP,可用 kubectl -n hugegraph port-forward svc/hugegraph-vermeer-master 6688:6688 转发访问;内部 Master/Worker RPC 与 Worker HTTP 保持私有。

  • 镜像固定策略与进阶凭据管理见 Vermeer 部署指南。

PD 元数据命名空间

顶层参数 metadataCluster(默认 hg-test)定义了 PD 中元数据的集群前缀。Chart 会将该值同步注入 Server 的 HG_SERVER_CLUSTER 与 Store 的 PD_CLUSTER,使得 Store 在接收 Vermeer 扫描请求时能准确定位 Server 写入的 Schema。

重要

metadataCluster 是元数据存储的前缀空间,而非 Raft 分组名。修改该值不会自动迁移已有图数据。开启 Vermeer 时必须保留原有集群的前缀值;若加载图时遇到 Schema missing 或 no such vertex label,请优先检查各组件的元数据前缀是否一致。自定义前缀的核验流程请参考 元数据命名空间运维指引。

服务身份与图空间

默认 server.serviceId 与 server.graphSpace 均为 DEFAULT。如需将 Server 注册到指定的业务服务名或图空间,可通过 values 指定:

仅修改已有部署的配置时,保留当前 Chart 版本和 values。用 helm list 查看版本,替换下面的版本占位符:

1helm list -n hugegraph
2CHART=oci://ghcr.io/hugegraph/hugegraph-helm
3CHART_VERSION='<已安装的Chart版本>'
4helm upgrade hugegraph "$CHART" --version "$CHART_VERSION" -n hugegraph --reuse-values \
5  --set-string server.serviceId=analytics \
6  --set-string server.graphSpace=team_a \
7  --set-string server.testGraphAlias=team_a-demo

注意:非默认图空间必须在启动 Server 前先调用 PD API 创建;server.testGraphAlias 用于指定 helm test 验证的 Gremlin 图别名(区分大小写), 不会从 graphSpace 自动推导。请勿在 server.extraEnv 中重复声明服务 ID 或图空间。

3 内网镜像和存储

完整例子包含内网镜像、动态存储、七个 local PV、 GitOps 凭据、仅 API 部署以及无域名的 HTTP Ingress。

global.imageRegistry 为未指定 registry 的镜像仓库加前缀,组件指定完整 registry 地址时优先采用组件配置。 默认只需镜像仓库中的 hugegraph/pd、hugegraph/store、hugegraph/server 和 hugegraph/hubble 四个镜像,标签或 digest 按实际配置选取。 等待 PD 的 init container 复用 Store 镜像,Helm test 复用 Server 镜像。这两个镜像已包含 curl,无需额外 curl 镜像或启动时安装软件。 自定义镜像可以继续使用显式 store.waitImage 和 server.waitImage 覆盖。

启用 SeaTunnel 时还需同步其配置的 apache/seatunnel 镜像,启用 Vermeer 时使用上文固定的已发布构建。 Vermeer 的 Master、Worker 和服务令牌初始化复用同一镜像;所有已启用镜像及显式 helper 覆盖都应同步。 使用自定义 Vermeer 镜像时,还需更新 vermeer.image.digest,或在按标签选择时显式清空;非空 digest 优先于标签。

存储配置

storageClassName 为空时继承集群默认 StorageClass,"-" 表示显式不使用 StorageClass。 local PV 需要预建宿主机目录、匹配容量、nodeAffinity 和 kubernetes.io/no-provisioner StorageClass。 WaitForFirstConsumer 根据 Pod 调度约束绑定,创建资源前请查看七个卷的完整例子。 新建临时实例可以设置 persistence.enabled=false 使用 emptyDir,组件存储开关优先。 PVC 失败不会自动降级为临时存储,已经初始化的 PD/Store 切换存储模式会被拒绝。

Vermeer 的 Master 和 Worker 使用独立数据卷,单 Pod 模式也不共享 Pebble 目录。 单机模式增加 2 个卷;集群模式为 1 个 Master 卷加每 Worker 1 个卷,默认增加 4 个。 因此默认基础拓扑加 Vermeer 单机/集群分别需要 9/11 个卷,轻量 HugeGraph 预设加 Vermeer 单机需要 5 个。 七卷 local PV 示例仅覆盖基础安装;SeaTunnel checkpoint 仍使用临时本地文件。

离线安装和私库

先选择最新版本,再按该版本下载 Chart,将 .tgz 搬入内网。可以直接安装,也可以接入已有的 OCI 或 HTTP 私库。 内网安装需通过 --set global.imageRegistry=... 覆盖镜像私库, 参见 values-internal-registry.yaml。

1CHART=oci://ghcr.io/hugegraph/hugegraph-helm
2CHART_VERSION=$(helm show chart "$CHART" --devel | sed -n 's/^version: //p')
3helm pull "$CHART" --version "$CHART_VERSION"
直接安装
1# 内网环境需覆盖镜像私库(或使用 -f values-internal-registry.yaml)
2helm install hugegraph "./hugegraph-helm-${CHART_VERSION}.tgz" -n hugegraph \
3  --set global.imageRegistry=registry.example.com \
4  --create-namespace --wait --timeout 15m
OCI 私库
1helm registry login registry.example.com
2helm push "./hugegraph-helm-${CHART_VERSION}.tgz" oci://registry.example.com/charts
3helm install hugegraph oci://registry.example.com/charts/hugegraph-helm \
4  --version "$CHART_VERSION" -n hugegraph \
5  --set global.imageRegistry=registry.example.com \
6  --create-namespace --wait --timeout 15m
HTTP 私库
1# 按私库的上传方式接收同一个 .tgz,并更新 index.yaml。
2# 自建静态 HTTP 源可用 helm repo index 生成索引;helm push 只适用于 OCI。
3helm repo add hugegraph-internal https://charts.example.com
4helm repo update hugegraph-internal
5helm install hugegraph hugegraph-internal/hugegraph-helm \
6  --version "$CHART_VERSION" -n hugegraph \
7  --set global.imageRegistry=registry.example.com \
8  --create-namespace --wait --timeout 15m

私库地址请替换为实际地址。Chart 包不包含容器镜像;完整离线部署还需搬运配置引用的所有容器镜像,并覆盖镜像地址。

4 鉴权和 Secret

普通 Helm 安装自动生成、复用三份凭据,分别为 <release>-admin 的 password、<release>-auth-token 的 token_secret 以及 <release>-pd-auth 的 secret-key。PD REST 使用共享的 PD Secret,通过 HG_PD_AUTH_SECRET_KEY 注入 PD 容器, Server 等待存储和 Hubble 使用同一份凭据,不需要用户为每个 PD Pod 单独发明密码。

GitOps 使用加密的固定值,或预先创建 Secret 并配置 pd.auth.existingSecret、server.auth.admin.existingSecret 和 server.auth.token.existingSecret。existingSecret 高于内联值,chart 不管理这类外部 Secret。 管理员密码需要可打印 ASCII,不能包含空格、冒号、反斜杠;PD 密码需要可打印 ASCII,不能包含首尾空白和反斜杠;JWT key 至少 32 字节。 离线渲染器不能通过 lookup 读取在线已生成 Secret,因此不能依赖每次渲染随机生成凭据。

管理员 Secret 是初始凭据,更新 Secret 不会修改已经创建的账户密码。 先使用旧密码调用 PUT /graphspaces/DEFAULT/auth/users/admin,请求体为 {"user_password":"<新密码>"}, 再把 Secret 和源配置同步为新密码,最后重启 Server Deployment 清理所有副本的鉴权缓存。

Hubble 默认开启,当前镜像的登录仍依赖 Server 鉴权。只使用 API 可以设置 hubble.enabled=false, 如需关闭 API 鉴权,再设置 server.auth.enabled=false。未使用的凭据配置可以留在 values 中。

可选引擎的原生入口始终需要登录,easy 模式也不例外。新生成的独立管理员密码在 easy 模式下为 6 位随机字母数字,strict 模式下为 16 位。 SeaTunnel 使用 HTTP Basic,Vermeer 使用 <release>-vermeer-admin Secret 与 Admin credential 登录。 升级保留既有密码,切换模式也不会自动轮换。 Vermeer 管理密码可通过 vermeer.auth.admin.password 或 vermeer.auth.admin.existingSecret/key 配置,仅 Master 读取。 原生管理按最终 Service 类型访问:NodePort 直接通过节点 IP 和分配端口访问,ClusterIP 使用 port-forward 转发,Hubble 的服务凭据自动配置。

高级:Vermeer 部署凭据与 GitOps

GitOps 需保留稳定的管理员凭据和独立的内部服务身份。 服务签名因子通过 vermeer.auth.value 或 vermeer.auth.existingSecret/key 配置,Hubble 自动生成服务令牌; 日常 Hubble 使用和原生密码登录都不需要手工获取该令牌。 更改外部管理密码 Secret 只需重启 Master;服务签名因子轮换需重启 Master 与 Hubble,无需重启 Worker。 Worker Schema 读取默认复用部署管理员,也可通过 vermeer.hugegraphCredentials.existingSecret/key 指向现有用户的受保护用户名密码 JSON。 该用户需具备目标图的 Schema 权限,Chart 不会自动创建账户。

5 升级和验证

使用 Helm 原生值复用保留已有部署的 UI、入口、存储和凭据设置。

1helm get values hugegraph -n hugegraph --all
2# 测试环境继续跟随最新版本;生产升级请改用 --version 指定已审阅的稳定版本。
3helm upgrade hugegraph "$CHART" --devel -n hugegraph \
4  --reuse-values --wait --timeout 15m
5helm test hugegraph -n hugegraph --logs --timeout 5m

已有配置中的显式 helper 镜像也会保留。添加 --set-string store.waitImage= --set-string server.waitImage= 可清空覆盖并复用组件镜像。 要采用新的默认值,先审阅已有配置,再使用 --reset-values 和保留镜像、凭据、存储、拓扑设置的配置文件。 PD 成员、持久存储和共享凭据变更需要按生命周期说明协调处理。

基于当前 master 构建的 PD、Store 和 Server 镜像以 UID/GID 10001 运行。除非 podSecurityContext 已设置 fsGroup,Chart 会为 PD 和 Store Pod 设置 fsGroup: 10001(以及 fsGroupChangePolicy: OnRootMismatch),即使 --reuse-values 保留了旧 Release 的空值也是如此,使其能写入旧镜像(以 root 运行)创建的 PVC。

请在首次应用 fsGroup 的同一次滚动更新中,将 PD 和 Store 切换到基于此版本构建的镜像,使 kubelet 在 10001 镜像启动前修改卷的属主。不要先用仍以 root 运行的镜像(例如尚未更新到此版本的 latest)运行此 Chart:这些镜像创建的文件归 root 所有,而 OnRootMismatch 只检查卷的根目录,之后不会再修正它们。 请将 pd.image 和 store.image 固定为基于此版本构建的镜像,而不要依赖 latest。非空的 image.digest 优先于 image.tag,且 --reuse-values 会保留已有的 digest,因此按 digest 固定镜像的 Release 必须修改 digest,而不能只修改标签。

如果 Release 已在设置了 fsGroup 的情况下运行过 root 镜像,请在首次滚动更新到 10001 镜像的同时执行一次递归属主变更。请在同一条命令中设置镜像, 使递归变更作用于 10001 镜像,而不是已固定的 root 镜像。示例清空了保留下来的 digest,使标签生效;按 digest 固定镜像的 Release 应改为将 pd.image.digest 和 store.image.digest 设为此版本镜像的 digest:

1helm upgrade hugegraph "$CHART" --devel -n hugegraph --reuse-values \
2  --set pd.image.tag=<this-version> \
3  --set store.image.tag=<this-version> \
4  --set-string pd.image.digest= \
5  --set-string store.image.digest= \
6  --set pd.podSecurityContext.fsGroupChangePolicy=Always \
7  --set store.podSecurityContext.fsGroupChangePolicy=Always \
8  --wait --timeout 15m

改回原策略前,请确认每个 PD 和 Store Pod 运行的都是你设置的 10001 镜像,而不是旧的 root 镜像:

1kubectl get pods -n hugegraph \
2  -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'

--reuse-values 会保留 Always,而它会在每次 Pod 启动时遍历整个卷,因此请在这些 Pod 运行后改回原策略:

1helm upgrade hugegraph "$CHART" --devel -n hugegraph --reuse-values \
2  --set pd.podSecurityContext.fsGroupChangePolicy=OnRootMismatch \
3  --set store.podSecurityContext.fsGroupChangePolicy=OnRootMismatch \
4  --wait --timeout 15m

CSI 驱动忽略 fsGroup 的卷(例如许多 NFS 驱动)和 hostPath 卷需要改为执行一次 chown -R 10001:10001。

server.storageWaitTimeoutSeconds 默认 300,通过 WAIT_STORAGE_TIMEOUT_S 传给启动脚本。 未指定的启动探针阈值按存储等待加 150 秒推导;显式探针不会被改写,但预算必须覆盖存储等待和至少 120 秒 Server 启动时间。 矛盾预算会在渲染时报出对应参数。这个等待超时不是 JVM 内存配置。

默认 helm test hook 检查连接和读取。安装或恢复后,还应重新登录 UI,并验证应用实际使用的读写查询。 调度、NetworkPolicy、滚动升级和恢复见 Kubernetes 运维。

6 部署与使用 SeaTunnel(可选引擎)

SeaTunnel 是 HugeGraph 支持的可选数据集成引擎,默认关闭。启用后,Helm 会在集群内拉起常驻的 SeaTunnel Zeta 引擎及任务 Web 前端。 官方 apache/seatunnel:3.0.0 镜像已内置 HugeGraph 连接器(Source 与 Sink),无需额外构建镜像或安装插件。

 1helm/hugegraph/
 2  examples/
 3    values-seatunnel-standalone.yaml # 单机预设(单个 Hybrid 节点,适合本地与轻量测试)
 4    values-seatunnel-cluster.yaml    # 集群预设(多个 Hybrid 节点,支持分布式并行执行)
 5    seatunnel/
 6      hugegraph-sink.conf            # 写入示例:向 HugeGraph 批量导入测试顶点
 7      hugegraph-source.conf          # 读取示例:从 HugeGraph 读取图数据并输出至日志
 8      clone/                         # 跨图整库迁移配置集
 9        copy-schema.py               # 自动化 Schema 同步脚本
10        person.conf / knows.conf     # 分标签顶点与边迁移作业配置
flowchart TB
    A["外部数据源 / 远端源图"] --> ST
    subgraph Release["同一个 Helm Release"]
        ST["SeaTunnel Zeta<br/>Hybrid 混合节点"] -->|读写| HG["HugeGraph<br/>Server + PD + Store"]
    end
    U["管理人员"] -->|Web UI / REST (HTTP Basic)| ST

6.1 选择单机或集群模式

SeaTunnel 采用 Hybrid 节点架构,单个节点同时负责作业协调调度与任务执行:

  • 单机模式(Standalone):启动 1 个常驻节点,内存占用小,适合开发测试与小规模数据处理。
  • 集群模式(Cluster):启动多个同构节点组成集群,支持分布式高可用和更大吞吐。

SeaTunnel 的副本规模与 HugeGraph 拓扑完全独立解耦。在解压包目录(或源码根目录)下,可通过组合 values 快速安装:

SeaTunnel 单机
1helm install hugegraph ./hugegraph-helm -n hugegraph --create-namespace \
2  -f ./hugegraph-helm/values-single.yaml \
3  -f ./hugegraph-helm/examples/values-seatunnel-standalone.yaml \
4  --wait --timeout 30m
SeaTunnel 集群
1helm install hugegraph ./hugegraph-helm -n hugegraph --create-namespace \
2  -f ./hugegraph-helm/values-single.yaml \
3  -f ./hugegraph-helm/examples/values-seatunnel-cluster.yaml \
4  --wait --timeout 30m
提示

若为已有 HugeGraph 集群追加 SeaTunnel,只需在现有 values 中加入 seatunnel.enabled: true 及相应模式配置,执行 helm upgrade 即可,无需重建已有图服务。SeaTunnel 镜像体积较大,建议在离线环境提前同步至私有镜像仓库。

6.2 访问 Web 控制台与鉴权

seatunnel.service.type: null 时继承全局 mode:easy 默认 NodePort,strict 默认 ClusterIP。 显式 ClusterIP 保持私有;显式 NodePort(包括 strict 模式)开放 HTTP/UI,仍需正常登录。 旧配置显式指定 ClusterIP 时,需改回 null 才会继承 easy;省略 seatunnel.service.nodePort 或设为 null 时自动分配端口。 standalone / cluster 拓扑不改变上述访问选择:

NodePort 入口(easy 模式)
1kubectl -n hugegraph get svc hugegraph-seatunnel \
2  -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}{"\n"}'
3kubectl get nodes -o wide
4# 访问浏览器:http://<节点 IP>:<NodePort>/#/overview
端口转发(通用)
1kubectl -n hugegraph port-forward svc/hugegraph-seatunnel 8081:8080
2# 访问本地:http://127.0.0.1:8081/#/overview

SeaTunnel 前端及 REST API 在两种模式下均需独立的 HTTP Basic 认证,与 HugeGraph 账户体系相互独立。 用户名为 admin;新生成密码在 easy 下为 6 位随机字母数字,strict 下为 16 位,升级与模式切换保留既有密码。 从 release 的 Secret 读取密码:

1kubectl -n hugegraph get secret hugegraph-seatunnel-auth \
2  -o jsonpath='{.data.password}' | base64 --decode
警告

端口 5801 为 Zeta 内部通信与 CLI 命令通道,不经过 HTTP Basic 鉴权,继续保持私有。 对外仅通过分配的 NodePort 访问需要登录的 HTTP Service,应用仍监听 8080。

6.3 运行内置示例作业

Chart 在 SeaTunnel Pod 内预置了连接 HugeGraph 的示例作业,并通过环境变量自动注入了当前 Release 内的 Server 地址、图空间及认证凭据:

  1. 准备图实例:在 Hubble 控制台或通过 REST API 创建空的测试图(默认为 DEFAULT/graph_a)。

  2. 执行导入作业:向图中的 seatunnel_demo_person 标签批量写入 10 条数据:

    1kubectl -n hugegraph exec sts/hugegraph-seatunnel -- \
    2  /opt/seatunnel/bin/seatunnel.sh --master cluster \
    3  --config /opt/seatunnel/config/hugegraph-sink.conf
  3. 执行读取验证:运行 Source 示例读取同一批顶点,并在控制台日志中查看输出:

    1kubectl -n hugegraph exec sts/hugegraph-seatunnel -- \
    2  /opt/seatunnel/bin/seatunnel.sh --master cluster \
    3  --config /opt/seatunnel/config/hugegraph-source.conf

作业执行状态可进入 Web 控制台实时查看 DAG 拓扑与指标统计。如需修改目标图或连接凭据,可在 values 的 seatunnel.env 中覆盖环境变量,或在 seatunnel.config 中挂载自定义的 .conf 配置文件。

6.4 跨图迁移与模式切换

  • 拓扑切换:单机与集群模式切换时直接修改 values 并执行 helm upgrade。切换会重置引擎进程,建议在所有批处理任务完成后再执行。
  • 跨图整库迁移:建议遵循 Schema 元数据 → 顶点数据 → 边数据 的标准顺序。可参考 examples/seatunnel/clone/ 下的自动化脚本与配置模板。迁移含有 DATE 类型字段时,务必在 Sink 配置中显式指定与源端 Server 相同的时区(如 timeZone = "UTC"),避免跨时区解析偏差。详细配置可参阅 SeaTunnel 导出与迁移文档。

3.1.5 - HugeGraph Kubernetes 运维

本文配合 Helm 部署使用。生命周期检查和恢复说明见 运维参考,所有参数说明见 chart 的 values.yaml。 命令假设 release 和 namespace 都是 hugegraph,覆盖名称时请替换实际工作负载名。

1 存储和内网镜像

基础安装需要七个持久卷。动态存储需要正常的 provisioner,静态 local 存储需要预建目录和绑定节点的匹配 PV。 完整例子包含七个 local PV、WaitForFirstConsumer、镜像仓库和 GitOps Secret。 WaitForFirstConsumer 的 PVC 初期 Pending 可以是正常等待;持续 Pending 应检查 PVC/Pod 事件和 PV 匹配。 PVC 已绑定但目录不存在或权限不匹配时可能挂载失败,不能把故障 PVC 静默替换成临时目录。

1kubectl -n hugegraph get pvc,pods
2kubectl -n hugegraph describe pvc <claim-name>
3kubectl -n hugegraph describe pod <pod-name>
4kubectl get pv,storageclass

出现 ImagePullBackOff 时检查 Pod 事件、仓库连通性和拉取凭据。默认只需四个组件镜像,等待 Store/Helm test 复用已包含 curl 的组件镜像。 如显式覆盖 helper 镜像,该镜像也需要同步到内网仓库。 启用 SeaTunnel 还需配置的 apache/seatunnel 镜像;启用 Vermeer 使用按 digest 固定的 hugegraph/vermeer:helm-30b67d93e7d0, Master、Worker 和令牌初始化共用它。官方发布运行记录源码与镜像 digest, 详见 Vermeer 部署指南。 自定义镜像覆盖还需同步更新 vermeer.image.digest,或显式清空以按标签选择;非空 digest 优先。 基础 local PV 示例不包含 Vermeer 卷:单机增加两个,集群增加一个 Master 卷及每 Worker 一个卷,默认增加四个。

2 端口和健康检查

PD 端口为 REST 8620、gRPC 8686、Raft 8610;Store 为 REST 8520、gRPC 8500、Raft 8510;Server HTTP 为 8080;Hubble HTTP 为 8088。 客户端 Service 隐藏 Pod 地址,NodePort 是节点上另外分配的端口,与应用监听端口不同。 PD /v1/ready 需要 Raft leader,/v1/health 只说明监听器已启动,Store 等待多数 PD peer ready 后启动。 Server 等待存储的默认上限为 300 秒,可以用 server.storageWaitTimeoutSeconds 调整。 本地模板渲染不能验证集群连通性、卷挂载或 JVM 运行容量。

保留元数据命名空间

metadataCluster: hg-test 用于声明 Server 和 Store 访问 PD 时的元数据前缀(注入至 Server 的 HG_SERVER_CLUSTER 与 Store 的 PD_CLUSTER)。 它并非 Raft 分组名,修改该值不会自动迁移历史元数据。切勿为了启用 Vermeer 将已有集群的前缀随意变更。若遇到 Server 查询正常但 Vermeer 扫描 Store 报 Schema missing 或 no such vertex label,应优先核查各组件的元数据前缀是否完全一致。

若历史自建环境使用了非默认前缀,升级前需在 Server Deployment 显式标注确认:

1kubectl -n hugegraph annotate deployment hugegraph-server \
2  hugegraph.apache.org/metadata-cluster='<已核准的历史前缀>'

并在 values 中将 metadataCluster 设为同一值。对于采用 store.updateStrategy.type=OnDelete 策略的 Store 节点,需按受控滚动升级流程逐个重建 Pod,新配置方可生效。

可选引擎运维:探针、凭据与拓扑切换
  • 端口与健康状态:SeaTunnel HTTP/UI 端口为 8080;Vermeer Master HTTP/gRPC 为 6688/6689,Worker 为 6788/6789。 原生 HTTP/UI 在 easy 下默认 NodePort,strict 下默认 ClusterIP,两者均需登录;内部 RPC、Worker HTTP 与 SeaTunnel 5801 保持私有。 service.type: null 继承模式默认值,显式 ClusterIP 保持私有,显式 NodePort 则开放需要登录的 HTTP/UI。 使用 hugegraph-seatunnel 或 hugegraph-vermeer-master Service 分配的 HTTP NodePort 与可达节点 IP 访问。 查询命令见原生入口说明;ClusterIP 可使用 port-forward。
  • 密码与会话:初次部署生成的管理密码在 easy 模式下为 6 位字符,strict 模式下为 16 位;后续升级与模式切换均自动保留既有凭据。 Vermeer 原生控制台直接在 Admin credential 填入 <release>-vermeer-admin Secret 的 password 即可登录;Hubble 内部服务凭据已自动注入。
  • 拓扑与副本切换:修改 seatunnel.mode 或 vermeer.mode 前,请确保所有计算与导入批任务已结束并卸载内存图副本。单机与集群使用独立的数据卷声明,拓扑切换不会自动迁移本地文件。
  • 完整恢复指引与进阶参数详见 Vermeer 部署指南 与 SeaTunnel 部署指南。

Helm test 检查范围

helm test 逐 Server Pod 检查图绑定(默认检查 DEFAULT-hugegraph,可通过 server.testGraphAlias 指定图别名),并要求当前可见关联索引处于 CREATED 状态。 请在索引创建/重建任务结束后执行,检查期间不要并发修改 schema。 在 HStore 上,读取尚未完成的索引可能将临时状态缓存到其他 Pod;重试不会刷新该状态。 即使任务随后成功,这些 Pod 的索引查询也可能继续失败;应在任务结束后再替换受影响的 Server Pod。 hook 不修复跨 Server 的 schema 缓存一致性。内部 150 秒重试窗口用于等待短暂选举等状态恢复, Helm 的 --timeout 不会修改这个窗口。 它按 ID 读取索引,不刷新全量索引缓存;不证明索引查询结果或完整 schema 一致性。 对已有数据,可在 Helm 升级时用 --set-file server.testGremlin=assertions.groovy 添加逐 Pod 的只读业务断言。 脚本必须用 assert 或抛异常表示结果不符,仅返回 false 不会让请求失败。 业务查询断言 给出了示例与检查边界。未配置脚本时明确显示业务断言已跳过,默认 hook 不创建 schema 或数据。 自定义脚本使用 hook 的 Server 凭据执行(开启鉴权时为 admin),不强制只读;请提供可信的只读断言。

Server API 根据 Accept-Encoding 协商响应压缩。支持 gzip 的客户端可请求 gzip 或使用 curl --compressed; identity 或未请求压缩时返回未压缩内容。需从更新后的源码重新构建 Server 镜像才能包含该行为,仅更新 chart 不会改变现有镜像。

PD REST 鉴权

PD REST 使用 HTTP Basic 鉴权,hg、store、hubble 和 vermeer 共用 PD REST Secret 密码。 Server 的 admin 不是 PD REST 账户,使用它会返回 401。默认 release/Secret 的查询示例,地址应为可达的 PD REST 地址:

1PD_SECRET=$(kubectl -n hugegraph get secret hugegraph-pd-auth \
2  -o jsonpath='{.data.secret-key}' | base64 --decode)
3curl --user "hg:${PD_SECRET}" "http://<pd-rest-address>:8620/v1/stores"

以上 HTTP 示例适用于可信内网。其他访问路径可使用 HTTPS 网关,或按需执行 kubectl -n hugegraph port-forward service/hugegraph-pd-client 8620:8620,再访问 http://127.0.0.1:8620。

使用 pd.auth.existingSecret 或自定义 pd.auth.key 时读取实际 Secret 和 key,不使用 Server 管理员密码。 变量式示例避免将密码字面值写入 shell 历史,但展开后的凭据可能短暂出现在进程参数中。 共享终端可选用 curl --user hg 提示输入密码,或权限为 600 的私有 curl 配置文件; 凭据操作说明 也包含改密请求体的处理方式。不要记录或提交凭据文件。

3 调度

默认 preferred 反亲和允许节点少于副本数时调度;values-cluster.yaml 对 PD/Store 设置 required 反亲和,因此需要至少三个可调度节点。 显式 affinity 优先于预设。local PV 节点亲和必须匹配工作负载位置约束,PV 容量声明不等于文件系统配额。 持久化 PD/Store 的 Raft 主机名和端口会记录为成员身份,不能作为普通配置随意变更。

4 分区副本

首次初始化时,Store 至少三个则默认每个分区三副本,否则一副本。 PD 会持久化分区设置,初始化后修改 chart 值不会覆盖已有元数据,应使用 PD 配置 API 并协调分区巡检。 显式 shard 数必须为奇数且不超过 Store 数,操作在线集群前先核对 拓扑约束;chart 不负责迁移已有 shard 元数据。

5 NetworkPolicy

基础服务的完整隔离在 easy 和普通集群预设下默认关闭,strict 下开启。 SeaTunnel 和 Vermeer 始终需要登录。原生策略仅在最终 Service 类型为 NodePort 时允许外部 HTTP, 内部 RPC、Worker HTTP 与 SeaTunnel 成员端口仍限制为相应 release 调用方,networkPolicy.enabled=false 也不例外。 集群网络插件必须支持策略执行,才有实际隔离效果。 生成策略允许组件间通信和 DNS,基础服务的外部客户端、Ingress 控制器需要适当的 networkPolicy.<component>.extraIngress, 外部发现地址可能还需要 extraEgress。基础服务规则的空列表合法但可能阻止外部访问,并支持 Kubernetes 原生规则,包括允许全部的 {}。 按实际来源地址或 selector 配置,并考虑 NodePort SNAT 和控制器行为。

 1networkPolicy:
 2  enabled: true
 3  server:
 4    extraIngress:
 5      - from:
 6          - ipBlock:
 7              cidr: 10.20.0.0/16
 8        ports:
 9          - protocol: TCP
10            port: 8080
11  hubble:
12    extraIngress:
13      - from:
14          - ipBlock:
15              cidr: 10.20.0.0/16
16        ports:
17          - protocol: TCP
18            port: 8088

原生引擎的 extraIngress 只接受显式内部 Pod/namespace selector,拒绝 IP block 和通配规则。 NodePort HTTP 访问已由生成的策略直接放行,无需额外的 extraIngress 规则。 上面的基础服务示例用于 Server。外部数据源可按需配置引擎 extraEgress,strict 进一步限制出站流量。

6 逐个升级 Store

集群预设使用 store.updateStrategy.type=OnDelete 便于维护时控制逐个替换。 每次只删除一个 Store Pod,下一次删除前确认上一个 Pod Ready、Store 心跳新鲜,并从 PD leader 查询每个 shard group 都有完整成员及唯一 leader。 PD 的 Up 状态本身不证明 shard 恢复完成。PDB 限制主动驱逐,不限制 StatefulSet 控制器更新。 发现缺成员或无 leader 时停止继续替换。 运维参考说明这些升级条件, 但不提供完整的逐组诊断或丢盘恢复步骤。

即使副本完整,替换单个 Store 时,Raft leader 和客户端路由收敛期间仍可能出现请求失败或超时,不保证零错误。 继续维护前同时观察应用错误和 shard 恢复状态,不要盲目重试写请求。

PD 巡检和 leader 均衡

分区巡检修复 shard 成员关系;leader 均衡是单独的手动任务,不会自动定时执行。 执行前通过鉴权的 /v1/members 查询 data.pdLeader.restUrl,并确认该 PD 的 /v1/ready 返回 isLeader: true。 GET 任务 /v1/task/patrolPartitions 和 /v1/task/balanceLeaders 会改变集群状态,应携带 PD REST 凭据请求已确认的 leader。 成员恢复和 split/move 任务完成后才能执行 leader 均衡;Store 心跳需新鲜,各组成员需完整、健康。 忙碌任务返回 body status: 1001。follower 可能返回空成功,leader 转移是异步的,HTTP 200 或转移计划不代表执行完成。 继续维护前重新检查 /v1/partitions、/v1/stores 和应用错误。 任务操作步骤 说明巡检和均衡的独立操作;维护忙碌时不要循环请求任务。

7 灾难恢复

保留原卷、claim 身份和 PD 成员关系,不通过删除 RocksDB lock 文件恢复,也不把持久化成员配置替换为全新的节点。 Store 丢盘后,新建空 PVC 并不能恢复原有数据。 local 磁盘不能在节点故障时自动迁移文件。备份应放在这些 PV 之外,并单独验证恢复;chart 不提供自动备份和自动恢复。 恢复说明列出恢复约束,不是完整的恢复操作顺序。 破坏性变更前,应结合部署版本、剩余副本或备份制定并验证恢复方案。

8 扩缩容

Server 副本可以常规变更,HPA 还需要 CPU requests。Store 扩容需要协调存储和 shard。 PD 扩缩容及 Store 缩容不能仅修改副本数,需要先更新持久化 Raft/shard 成员关系。 chart 对已初始化 StatefulSet 检查不支持的身份和成员变更,首次安装不执行升级专用查询。 按生命周期流程扩缩容,避免直接 kubectl scale 使 Hubble 的 Store metrics 配置过期。

9 集群外的 Hubble

direct 模式只需要可达的 Server URL;PD discovery 还需要集群外可达的 PD gRPC,PD 注册的 Server 地址也必须可达。 必要时用 server.advertiseUrl 注册共享 Server 地址,这会影响所有 discovery 客户端,包括集群内 Hubble。 chart 内置 Hubble 已配置内部服务发现,不需要公开 PD 入口。 HTTP 可以直接使用,TLS 终止可选。Hubble 仍是单副本,当前登录依赖 Server 鉴权。

10 Gremlin 报 Could not rebind

PD 滚动更新期间,Server 可能 Ready、能响应 REST,但 Gremlin binding 失败。 执行 helm test hugegraph -n hugegraph --logs --timeout 5m 检查每个 Server Pod 的鉴权图查询;PD 稳定后替换失败 Pod 并再次验证。 只查询 /versions 不证明图绑定成功,还应检查 Hubble 新登录和图查询。

出现 ERROR: missing required env 'HG_PD_AUTH_SECRET_KEY' 时,检查 PD Pod 的 Secret 引用和对应 key,不要把 Secret 值输出到日志。 chart 正常情况下自动注入共享 PD REST 凭据,自定义容器或 manifest 必须向 PD 和客户端提供同一值。 GitOps 先创建外部 Secret 再调谐工作负载,普通 Helm 保留自动创建的 release Secret。

3.2 - HugeGraph ToolChain

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

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

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

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

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

源码仓库: apache/hugegraph-toolchain

3.2.1 - 使用 Hubble 实现图可视化:单机快速上手

用 Docker 启动 RocksDB Server 与 Hubble,从示例图开始建模、导入 CSV,并用 Gremlin、Cypher 或 Text2GQL 查询图数据。

Hubble 是 HugeGraph 的 Web 管理与图可视化界面。你可以在同一个工作台中管理图的 Schema、导入数据、执行查询, 并在图、表格和 JSON 视图之间自由切换。本文以 单机 RocksDB Server + Hubble 为例走通完整操作,无需预先部署 PD 或 Store。

如需搭配 HStore 分布式集群使用,可先了解本文的基础操作,再参考 HStore 分布式补充。 文档内容以 Toolchain 与 Server 的 master 分支(当前均以 1.8 为基线,尚未正式发布)为准;Docker latest 为动态标签,生产环境建议使用已发布的固定版本。

本文截图基于 HugeGraph Hubble 界面,中英文界面功能与操作一致。

警告

请勿将未配置防护的 Hubble 或 Server 直接暴露在公网上。生产环境请务必开启 HTTPS、容器网络隔离、 认证与授权及访问白名单。

可按需快速跳转到对应操作;首次使用建议从启动单机环境开始:

启动单机组合

直接使用主仓库提供的 docker/docker-compose.yml 即可, 无需自行编写 Compose 配置文件。该文件已内置编排了 RocksDB Server 与 Hubble,并配置好网络、健康检查及持久化数据卷; 完整部署说明见同目录的 README。

  1. 准备官方 Compose 配置。

    1git clone --branch master --single-branch --depth 1 https://github.com/apache/hugegraph.git
    2cd hugegraph/docker

    若本地已有主仓库,直接进入其 docker/ 目录即可。Compose 会自动挂载该目录下的 conf/hubble/standalone.properties, 已预设 pd.enabled=false 与 server.direct_url=http://server:8080。两项服务处于同一 Docker 网络中通信, 无需为每个图单独配置 Server 地址。请直接在 docker/ 目录下启动,以确保相对配置路径有效。

    Hubble 默认只在宿主机回环地址开放 8088(由 HUBBLE_PUBLISH_HOST 环境变量控制,默认为 127.0.0.1); Server 默认对外发布 8080。若仅供本机试用,可将 Compose 中 Server 的 ports 改为 127.0.0.1:8080:8080,避免匿名端口暴露到外部网络。

  2. 启动并检查服务。

    为本次试用指定一个独立的项目名,后续命令在同一终端中沿用这些环境变量;另起终端时请重新设置。

    1export HUGEGRAPH_VERSION=latest
    2export HUBBLE_IMAGE=hugegraph/hubble:latest
    3export HUBBLE_DEMO_PROJECT="hubble-demo-$(date +%Y%m%d-%H%M%S)"
    4docker compose ls
    5docker compose -p "$HUBBLE_DEMO_PROJECT" -f docker-compose.yml pull
    6docker compose -p "$HUBBLE_DEMO_PROJECT" -f docker-compose.yml up -d --wait
    7docker compose -p "$HUBBLE_DEMO_PROJECT" -f docker-compose.yml ps
    8curl -fsS http://127.0.0.1:8080/versions
  3. 打开 Hubble。

    服务启动完成后,在浏览器访问 http://127.0.0.1:8088。若未在 .env 中配置 HUGEGRAPH_ADMIN_PASSWORD,Server 默认允许匿名访问, Hubble 会直接进入首页。若已启用认证,请根据 Docker README 在 .env 中配置管理员密码与 JWT 密钥,并使用 Server 账号登录(Hubble 无独立用户库)。 个人中心与账号管理入口仅在开启认证且具备相应权限时展示。

latest 镜像便于快速体验最新功能,生产环境建议指定发布版本号或镜像 digest。正式发布包可前往 下载页 获取。

核实部署版本

文档截图用于定位界面元素,实际版本以部署镜像的 digest 及构建信息为准。

Compose 中的 server-data 与 hubble-data 卷分别持久化保存图数据与 Hubble 元数据;更多生产配置参见 Server 部署指南。

首页与任务入口

首页按“图概览 → 图导入 → 图查询”组织核心工作流。左侧导航栏可随时切换各功能模块; 顶部的图选择器用于切换当前操作的目标图,所有查询、Schema 操作和异步任务均作用于当前选中的图。 单机模式下仅包含默认的 DEFAULT 图空间,无需配置 PD。

栏目主要用途
图概览与图详情选择图、加载示例、查看数据规模,再进入建模或查询
Schema / 元数据配置定义属性、顶点类型、边类型及索引
GQL 图遍历编写查询,在图、表格和 JSON 中探索结果
内置图算法用参数表单探索邻居、路径和相似关系
异步任务跟踪后台查询、Schema 和索引操作
数据源管理上传文件或配置外部数据的读取方式
数据导入将源端字段映射到图模型,执行或调度导入
个人中心与账号管理查看个人资料、修改密码,按权限管理账号及空间成员
系统运维查看 Server 节点;PD 模式还提供集群概览和 Store / PD 节点

界面速览

图概览、Schema 和查询工作区如下,点击任一截图可查看原图。

认识图概览与图详情

在【图概览】中选择默认图 hugegraph。点击图卡片或详情,可查看该图的 Schema 结构与数据统计,并快速跳转到建模、数据导入或查询页面。

在图卡片的【更多操作】菜单中点击【加载人物与软件 Demo 图】。该示例会自动创建预设 Schema 并导入示例数据(不会清空已有数据)。 初次体验建议在空图上加载,避免与已有同名 Schema 冲突。后续章节均基于该示例图演示。

若需新建图,可在页面点击新建按钮,填写图名称、可选别名并选择 Schema 模板或示例数据。连接信息由 Hubble 后端统一配置, 无需重复填写 Server 主机与账号。用户自定义 Schema 模板属于 PD 模式功能,详见 分布式补充。

Hubble 概览使用有界扫描。响应包含 approximate:true 与 scan_limit:100000 时,即使实际有数千万条数据, 顶点或边计数也可能停在 100000。这些值是扫描观测值,不能当作精确总量。 字段名依接口而定,例如 gremlin-query 返回 vertexcount / edgecount。精确计数应读取已完成的异步计数任务结果。

定义 Schema

Schema 规定了图中允许存储的属性、顶点与边类型,并决定顶点 ID 的生成策略与索引规则。 在【元数据配置】中,可以通过列表视图维护定义,或通过图关系视图直观查看顶点与边的拓扑结构。

定义建模时关注什么
属性数据类型、单值或多值,避免把数值读成文本
顶点类型属性、可空属性、ID 策略与主键
边类型起点和终点类型、属性、边的频次及排序键
顶点索引 / 边索引索引类型与字段,匹配实际过滤和范围查询

在人物与软件示例中,person 以 name 为主键生成 ID,age 与 city 允许为空; software 采用自定义数值 ID;边类型 created 连接人物与软件。模型定义与 Loader 示例 保持一致。

自主建模时,建议遵循 属性 → 顶点类型 → 边类型 → 索引 的顺序依次创建。 删除类型或创建/重建索引操作通常会提交为后台异步任务,操作提交后可在【异步任务】中查看最终执行结果。

在 GQL 工作台查询人物关系

进入【GQL 图遍历】,确认当前图为 hugegraph。工作台将查询编辑器与图展示区集成在一起, 支持即时执行与异步执行、常用语句收藏,并可随时从执行历史中重载语句(语法参考见 图查询语言)。先在 Gremlin 编辑器中查询人物属性。

1g.V().hasLabel('person').valueMap()

这条查询适合在表格或 JSON 视图核对属性。也可以查询人物与软件的关系。

1g.V().hasLabel('person').outE('created').inV().path()

图结果支持 2D / 3D 展示。点击顶点或边查看 ID、类型和属性,双击顶点展开邻居; 布局、样式和筛选工具帮助突出重点,导出功能便于分享结果。【新增】用于创建元素,有权限时也可以编辑已有数据。 调整布局、颜色或显示范围仅影响前端画布;通过界面新增、编辑元素或执行 Gremlin 写入语句才会真正修改 Server 中的图数据。

快捷键 Ctrl / Command + Enter 可快速执行查询。普通即时执行适合小规模交互探索;大数据量或耗时查询建议提交为后台异步任务。 Cypher 查询仅在 Server 后端支持时提供。快捷键会作用于当前获得焦点的输入框(在自然语言框中生成查询,在语句框中执行已有语句)。

Text2GQL 自然语言查询

在【自然语言】输入框中用自然语言描述查询需求,Text2GQL 会结合当前图的 Schema 自动生成只读 Gremlin 或 Cypher 语句并执行查询。 生成的语句支持二次编辑(执行前同样会进行只读安全校验)。切换至【异步】模式时,生成的查询与手写查询均可提交为后台异步任务。 输入框会自动恢复当前图最近一次的查询输入(不会自动触发执行),执行记录中也会完整保留原始自然语言问题。

配图中的模型尚未配置,图结果来自手写 Gremlin;自然语言生成功能需要先连接可用模型。

模型来源配置与保存方式
使用内置模型在【系统与运维 → 模型设置】统一配置,Key 加密存入 H2,不回传浏览器
使用临时模型在查询页填写 API 类别、Base URL、模型名称和临时 API Key;Key 只保留在前端内存中,刷新后清除

使用 OpenAI、DeepSeek、GLM 等模型时选择【OpenAI 兼容接口】;使用本地运行的 Ollama 时选择【Ollama(本地)】(无认证时 Key 可留空)。 Base URL 必须能被 Hubble 后端服务正常访问(若 Hubble 运行在容器中,localhost 指向容器本身而非宿主机)。公网端点必须使用 HTTPS,HTTP 仅允许用于 本地回环或私网模型;在【模型设置】中修改 Base URL 时,必须重新填写 Key 或清空已保存的 Key。 全局内置模型由具备模型设置管理权限的管理员统一配置;未开启 Server 认证时,任何访问者均可配置。

在模型设置页面右上角打开 Text2GQL Prompt,可分别定制 Gremlin 与 Cypher 的生成规则及 Few-shot 示例。 点击【应用】后需保存模型设置,模板将持久化存入 H2 数据库供内置模型与临时模型共享,生成时会自动附加当前图的 Schema。

API Key 存储与隐私说明

备份 Hubble H2 数据库时,请一并备份主密钥文件(默认路径 data/text2gql-master.key),该文件丢失将导致无法解密已保存的 Key。 生成查询时仅向模型接口发送用户问题、当前 Schema 及纠错提示,绝不会发送图数据查询结果。 浏览器可选择记住常用的 Base URL 与模型名称,但临时 API Key 仅保留在前端内存中,刷新页面即自动清除。

页脚分别显示模型生成耗时与查询请求耗时;异步提交耗时仅代表任务入队耗时,不代表后台任务实际运行时间。

使用内置图算法

Hubble 将图算法清晰划分为两个独立工作流:OLTP 在线探索与 OLAP 批量分析计算。

OLTP 在线探索算法

不想从头编写遍历语句时,可以进入【内置图算法】,使用参数表单完成实时图查询:

  • 邻居探索:用于回答“这个顶点附近有什么”(如 K-neighbor、K-hop 等)。
  • 路径分析:用于寻找两个顶点间的连通关系(如最短路径、全路径)。
  • 相似度与排序:在局部子图内对顶点进行相似度比对或排序。

算法表单提供参数说明及文档入口;常用参数可以在页面间往返时恢复。 表单聚焦时可用 Ctrl / Command + Enter 快捷运行当前算法。

例如选择 K-neighbor(GET),设置 source=1:marko、max_depth=1、limit=20, 参数校验通过后点击卡片右侧运行按钮,或在参数表单内使用快捷键,即可观察一跳邻居。

内置邻居算法的参数与图结果

原生 Vermeer OLAP 分析集成

针对全图级别的大规模复杂分析计算,Hubble 原生集成了高性能图计算引擎 Vermeer。 Hubble 默认优先选用 Vermeer 承担 OLAP 计算任务,同时保留 Computer 作为可选引擎。

hugegraph-hubble.properties 配置项

在 conf/hugegraph-hubble.properties 中开启 Vermeer 直连通信:

1# Vermeer Master 直连 HTTP 服务地址
2vermeer.url=http://vermeer-master:6688
3# 存放 Vermeer 服务 Bearer Token 的安全凭据文件路径
4vermeer.token_file=/path/to/vermeer-service.token
说明

当 vermeer.url 为空时,Hubble 保持原有的 Server 代理转发路径。Vermeer 直连模式需要 PD/Store 分布式集群模式支持,单机模式下自动禁用。

支持的 OLAP 算法与执行生命周期

Vermeer 在内存分布式分区上执行批处理图算法:

  • 支持算法:PageRank、Personalized PageRank(个性化 PageRank)、Weakly Connected Components(WCC 弱连通分量)、 Label Propagation Algorithm(LPA 标签传播)、Betweenness Centrality(介数中心度)、Closeness Centrality(紧密中心度)、 Degree Centrality(度中心度)、Triangle Count(三角形计数)、K-Core 以及 Single-Source Shortest Path(SSSP 单源最短路径)。
  • 内存图加载:计算流程首先将图数据从 PD/Store 加载或重新加载至 Vermeer Worker 内存。每个图在加载确认后保持任务 ID,入队任务维持在 Loading 状态直至加载完毕。
  • 任务监控与取消:原生任务在后台异步运行,可按状态(RUNNING、SUCCESS、FAILED)筛选监控,并支持在需要时主动取消任务。
  • 游标分页结果:计算产出的分析指标(如顶点得分、社区编号)通过游标机制进行分页流式拉取。分页跨页数据完整一致,并在最后一页精准停止。

查看异步任务的最终结果

【异步任务】集中显示当前图的后台任务,包括异步查询及部分 Schema、索引操作。 可以按任务类型和状态筛选,查看任务 ID、创建时间与执行状态;成功查询可打开结果,失败任务可展开错误信息。 已结束的任务可按界面提供的操作删除记录,任务列表与导入任务的执行历史是两个不同入口。

例如把 g.V().count() 以异步方式提交后,先在列表确认成功,再查看返回的数量。 “提交成功”只表示请求被接受,不表示计算或索引已完成。排查失败时,结合任务错误和 Server 日志定位原因。

准备数据源

数据源负责“从哪里读、怎样解析”,可以被导入任务引用。Hubble 支持 FILE、HDFS、JDBC 和 Kafka; 不同来源需要对应的路径、连接或订阅配置。首次体验可选择 FILE。上传文件后,配置格式、分隔符、编码和表头, 检查读取的列名,再进入映射。上传限制和允许的扩展名由 Hubble 配置决定。

为人物示例保存一个 UTF-8 文件 people.csv。

1name,age,city
2docs_alice,28,Beijing
3docs_bob,32,Shanghai

创建 FILE 数据源并上传它,选择 CSV(逗号分隔、默认 UTF-8),列名为 name,age,city。 表头、分隔符和编码属于数据源配置,不在后面的映射步骤设置;源字段应与文件内容一致。

映射字段并导入数据

【数据导入】把数据源中的行转换为顶点和边。任务创建采用四段配置,先明确目标,再选择字段和映射,最后决定执行时机。 沿用上面的数据源,在 DEFAULT / hugegraph 中创建人物导入任务。

  1. 基础信息 选择目标图与刚创建的数据源,填写任务名。
  2. 源端字段 选择 name、age、city,移到已选字段列表。
  3. 映射字段 添加 person 顶点映射,用【自动匹配】关联同名属性后核对类型。
  4. 调度信息 选择执行一次,确认后提交任务。

person 使用 PRIMARY_KEY,不设置独立 ID 列。自定义 ID 策略需要指定 ID 列; AUTOMATIC 由 Server 生成 ID,PRIMARY_KEY 根据映射的主键属性生成 ID。边映射还需指定起点、终点字段并匹配对应顶点的 ID 规则。

任务列表用于管理配置和执行入口,详情中的执行历史用于查看每次实例的状态、导入量与错误。 Hubble 还提供周期调度和 Kafka 实时执行,调度方式需与数据源类型匹配。 完成后返回 GQL 工作台查询新导入的数据。

1g.V().hasLabel('person').has('name', within('docs_alice', 'docs_bob')).valueMap()

结果应包含两条新人物记录。导入量统计不应直接当作新增顶点数;重跑可能更新已有元素,表头处理也会影响读取统计。 失败时先检查源字段、数值类型、可空属性及目标 Schema。Hubble 导入适合小规模体验, 大批量正式导入请使用 HugeGraph Loader。

个人中心与账号权限

Hubble 使用 Server 的认证和账号,没有独立用户库。匿名访问时不显示【个人中心】与【账号管理】; 开启认证后,个人中心展示当前账号资料与权限信息,可修改自己的密码。昵称等资料编辑依赖 Server 对个人资料接口的支持。 修改密码后会退出当前会话,需要重新登录。

单机账号管理

单机模式由管理员管理账号,可创建、查看、编辑或删除账号,并支持批量创建。 通过 Hubble 新建的普通单机账号会获得覆盖所有图的读、写、删除和执行权限,不能把它当作只读账号或单图隔离账号。 需要更细的资源权限时,应按 Server 认证与授权配置,而不是依赖空间预设。

PD 模式的空间权限

连接支持默认角色接口的 Server 后,账号与空间访问可以分别管理。管理员管理全局账号, 空间管理员只管理已授权空间的成员;普通成员不会获得账号管理或运维入口。 以下四种预设属于 PD 模式,不表示旧版本或单机 Server 都提供同样的权限编辑能力。

预设范围与用途
SUPER_ADMIN全局管理账号、图空间和运维;可授予或撤销超级管理员
GS_ADMIN管理已授权图空间及其成员,不授予其他空间或全局超级管理员权限
GS_READ_WRITE在已授权空间执行图数据读写操作,不管理全局账号
GS_READ_ONLY在已授权空间读取图数据,不进行写入

同一账号在不同空间可以有不同权限。成员管理先选择空间,再添加已有账号或调整权限; 把已有自定义权限替换为预设前,先核对需要保留的授权,避免把复杂权限误认为单一预设。 权限变更后刷新权限上下文或重新登录,确认菜单和目标空间已更新;最终请求仍由 Server 校验。 旧 Server 未提供相应接口时,页面按能力隐藏或禁用操作,不应只凭按钮是否可见推断资源权限。 更完整的空间管理见 分布式补充。

认证模式下的账号列表(单机模式示例)

Hubble HTTP API 接口

Hubble 开放了一组用于自动化与集成的 HTTP REST 接口,监听地址默认为 http://localhost:8088。

登录与会话

鉴权模式下,登录字段使用 snake_case,并保存会话 cookie:

1curl -c hubble.cookies -X POST 'http://localhost:8088/api/v1.3/auth/login' \
2  -H 'Content-Type: application/json' \
3  -d '{"user_name":"<username>","user_password":"<password>"}'

userName 与 userPassword 不会填入该登录模型。连续失败可能返回 HTTP 429,请修正字段与凭据后再重试。 匿名模式不使用登录接口。

集成 Gremlin 与 Cypher 查询

集成用 Gremlin 接口当前除登录会话外,还要求请求体中的 username 与 password:

1curl -b hubble.cookies -X POST \
2  'http://localhost:8088/api/v1.3/graphspaces/DEFAULT/graphs/hugegraph/gremlin' \
3  -H 'Content-Type: application/json' \
4  -d '{"query":"g.V().count()","username":"<username>","password":"<password>"}'

可信本地网络以外应使用 HTTPS;JSON 本身不会加密口令。这里的 query 不同于 Server 的 gremlin 字段, 也不同于 Hubble 工作区 gremlin-query 请求格式。调用者身份由会话确定,请求体凭据不能替代登录 cookie。

Hubble Cypher 使用工作区查询模型,不使用集成 Gremlin 的请求模型:

1curl -b hubble.cookies -X POST \
2  'http://localhost:8088/api/v1.3/graphspaces/DEFAULT/graphs/hugegraph/cypher' \
3  -H 'Content-Type: application/json' \
4  -d '{"content":"MATCH (n) RETURN count(n)","preview":false}'

查询字段是 content,query 或嵌套的 gremlin-query 对象不会填入该字段;鉴权来自登录会话。 Server 必须声明支持 Cypher。/asyncTasks 等路径是 UI 导航路由,任务 API 使用 /api/v1.3/graphspaces/{space}/graphs/{graph}/async-tasks 前缀。

Schema 默认值

Hubble 在 1.8.0 及以上版本中支持以下可选字段默认值。若使用未包含该特性的旧版本,请在请求体中显式提供 "open_label_index":true,"style":{"display_fields":["~id"]}:

1curl -b hubble.cookies -X POST \
2  'http://localhost:8088/api/v1.3/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels' \
3  -H 'Content-Type: application/json' \
4  -d '{"name":"http_demo_person","id_strategy":"AUTOMATIC","properties":[]}'

缺少或为 null 的 style 使用标准样式并显示 ~id; 缺少或为 null 的 open_label_index 默认为 true,显式 false 保持不变。 样式字段使用 snake_case(display_fields、join_symbols),不能写成 displayFields。 PRIMARY_KEY 类型还需要 properties 和 primary_keys;创建标签前应先创建属性。 Server schema 使用不同的请求模型,不要求 Hubble 的视觉样式字段。

通过 Hubble 导入图元素

POST /api/v1.3/graphspaces/{space}/graphs/{graph}/import 接收 multipart 字段 file,内容是图元素 JSON。 上传内容不是 CSV,也不是 Loader 作业规格;请先创建所引用的 schema。 例如,已有使用 CUSTOMIZE_STRING ID、带 name 属性的 person 顶点类型,以及连接两个 person 的 knows 边类型时, 将以下内容保存为 graph.json:

1{
2  "vertices": [
3    {"id": "alice", "label": "person", "properties": {"name": "Alice"}},
4    {"id": "bob", "label": "person", "properties": {"name": "Bob"}}
5  ],
6  "edges": [
7    {"label": "knows", "source": "alice", "target": "bob", "properties": {}}
8  ]
9}
1curl -b hubble.cookies -X POST \
2  'http://localhost:8088/api/v1.3/graphspaces/DEFAULT/graphs/hugegraph/import' \
3  -F 'file=@graph.json;type=application/json'

两个数组都必须存在;空数组只执行空导入。请提供 schema 要求的所有非空属性,顶点 ID 必须匹配对应 ID 策略。 边端点使用 source 与 target;顶点条目中的 file 键不是数据源定义。该接口返回图视图,CSV 请使用独立的数据源/Loader 流程。

使用图空间权限预设

Server 禁用自定义图空间角色分配时,旧图空间用户 POST 会被策略拒绝。该接口为已有账号分配角色,不是注册账号。 请使用 Hubble 提供的权限预设,不要自行构造角色 ID 或关闭 Server 策略。 对于已有账号,具备授权权限的图空间管理者可这样设置预设:

1curl -b hubble.cookies -X PUT \
2  'http://localhost:8088/api/v1.3/graphspaces/DEFAULT/auth/users/<user_id>/preset' \
3  -H 'Content-Type: application/json' \
4  -d '{"user_id":"<user_id>","username":"<username>","permission_preset":"GS_READ_ONLY"}'

支持 GS_READ_ONLY、GS_READ_WRITE 与 GS_ADMIN,具体授权仍受调用者权限约束。 路径与请求体中的账号身份必须匹配;匿名模式不提供账号管理能力。

检查单机 Server

单机模式的【系统运维】提供【节点信息】,只显示 Server,不显示 PD / Store 节点或集群概览。 节点列表可搜索、筛选健康状态并进入详情;详情用于查看可用的版本、系统、JVM、Server 后端等指标。 指标缺失或标记过期时,应结合采集状态与最近成功时间判断,不能把空值当作零或健康。

匿名模式可以查看运维信息;开启认证后,运维入口仅对有运维权限的管理员显示。 此处用于观测和排查,不是启动、停止或扩缩容控制台。PD 模式的集群概览与节点层级见分布式补充。

Vermeer 计算集群健康观测

在部署了 Vermeer 计算服务时,Hubble 在【系统运维】中提供独立的 Vermeer 计算集群健康监控视图:

  • 在 conf/hugegraph-hubble.properties 中配置运维指标收集:
    1operations.vermeer.enabled=true
    2operations.vermeer.address=http://vermeer-master:6688
    3operations.vermeer.token_file=/path/to/vermeer-service.token
  • 就绪状态与节点拓扑:监控 Vermeer Master 服务的就绪情况、注册的 Worker 节点健康状态与集群拓扑。
  • 资源利用率:直观展示正在运行的计算作业、各 Worker 节点的 CPU 利用率以及进程物理内存(RSS)占用。
  • 故障隔离与保真:服务凭据仅在后端安全读取。若采集超时或 Worker 离线,界面将明确区分陈旧数据与零负载,避免误判健康状态。

快捷键与画布操作

顶部的快捷键帮助入口随时可查看按键说明。以下快捷键有不同的作用范围,输入框中不会触发全局 ? 帮助。

操作按键或动作生效位置
打开 / 关闭快捷键说明?输入框和编辑器之外
执行查询Ctrl 加 Enter / Command 加 Enter查询编辑器
运行当前算法Ctrl 加 Enter / Command 加 Enter算法参数表单
切换图全屏F先点击聚焦图画布;不是全局按键
查看元素详情单击顶点或边图结果
展开相邻关系双击顶点图结果

排查连接与结果问题

现象先检查
Hubble 页面打不开检查容器状态及 docker compose -p "$HUBBLE_DEMO_PROJECT" -f docker-compose.yml logs hubble
页面打开但无法访问图Server 是否健康,server.direct_url 是否能从 Hubble 容器访问,两个容器是否在同一网络
出现登录页或没有写操作入口Server 的认证模式和当前账号权限;Hubble 不单独开启认证
查询没有预期数据顶部当前图、示例是否加载成功、标签和属性是否一致;区分画布展示与 Server 数据
没有集群概览本例没有 PD;集群功能见分布式补充

查询显示规模受配置影响。gremlin.suffix_limit 默认 250,用于对适用的 Gremlin 查询追加 .limit(N), 不是所有查询的硬上限;gremlin.vertex_degree_limit(100)与 gremlin.edges_total_limit(500)限制展开规模。 FILE 上传默认允许 csv,txt,单文件 1 GB、总量 10 GB;需要覆盖时修改 upload_file.* 配置。

停止试用环境或从源码构建

清理测试环境时,在 docker/ 目录下执行以下命令:

1docker compose -p "${HUBBLE_DEMO_PROJECT:?}" -f docker-compose.yml down --volumes

这会删除该项目的容器、网络、命名卷与匿名卷,示例图和 Hubble 导入任务也会丢失。 若想保留数据,下线时省略 --volumes,以后用同一项目名启动。

从当前 master 构建时,需要 JDK 17、Maven 3.9+、Python 3.9+、稳定版 Node.js 24(至少 24.22.0), 并通过 Corepack 使用仓库锁定的 pnpm 12.14.0。Maven 不再自动安装 Node/Yarn。

  1. 按 Java 17 构建说明 编译并安装 Server SDK 到独立 Maven 仓库。

  2. 按 Hubble 源码构建步骤 安装 Python 依赖,再使用同一 Maven 仓库构建 Client、Loader 和 Hubble(跳过测试)。

  3. 进入构建生成的 hugegraph-hubble/apache-hugegraph-hubble-* 目录,配置 conf/hugegraph-hubble.properties 中的 Server 连接信息后启动:

    1bin/start-hubble.sh -d

当前 master 使用新的 H2 元数据库。升级时保留旧 Hubble 包及其数据,新版使用独立的数据目录;旧元数据不支持自动迁移,不能直接复用。

打包配置默认绑定本机 localhost:8088。bin/stop-hubble.sh 会先请求正常停机,超时后才强制终止。 需要开发与测试说明时,参考 Toolchain 本地测试指南。

3.2.2 - 图可视化

Hubble 为 HugeGraph 提供图数据、Schema、查询和导入的 Web 界面。先从不依赖 PD 的单机组合入手, 再按需要了解分布式集群的差异。

3.2.2.1 - 使用 Hubble 管理 HStore 分布式集群

连接 HStore 与 PD,理解 Hubble 的图空间、Schema 模板、集群拓扑和节点指标。

本篇重点介绍 HStore + PD 分布式部署与单机 RocksDB 的核心差异。图建模、数据导入和图遍历等通用操作请参考 Hubble 基础与单机指南。 内容以 Toolchain、Server、PD 与 Store 的 master 分支(当前版本均为 1.8.0)为准。

主仓库的 docker/docker-compose-hstore.yml 已提供完整的 PD、Store、Server 与 Hubble 服务编排。请直接参考同目录 Docker README 配置 .env 并生成 Hubble 本地配置文件,然后在 docker/ 目录下启动,无需自行维护部署文件。 下文重点说明连接与运维配置要点,部署前请确保满足 README 中的 PD 凭据与前置依赖要求。 Docker latest 为动态标签,配图用于定位界面,实际版本以部署镜像的 digest 及构建信息为准。 不同版本可提供的指标和权限接口有所区别。

本文截图基于 HugeGraph Hubble 界面,中英文界面功能与操作一致。

连接分布式集群

Hubble 仍通过 Server 的图 API 管理数据。区别在于,分布式模式通过 PD 发现 Server, 同时从 PD 和 Store 获取集群信息;Hubble 不直接读写 Store 中的图数据。

flowchart LR
    H[Hubble] -->|图 API| S[Server]
    S -->|读写图数据| T[Store]
    H -.->|服务发现与集群信息| P[PD]
    H -.->|节点指标| T
  1. 生成 Hubble 配置。 按 Docker README 在主仓库的 docker/ 目录准备 .env。

    1set -a
    2. ./.env
    3set +a
    4./set-hubble-pd-password.sh hstore

    脚本会读取 .env 中的 HG_PD_AUTH_SECRET_KEY,将其值作为 operations.pd.password 写入生成文件 docker/conf/hubble/hstore.local.properties。 若需调整连接地址或运维参数,直接编辑该文件即可(请勿覆盖 Git 跟踪的 .example 模板文件),并确保 operations.pd.password 与 PD 所用密钥一致。Compose 会将该文件只读挂载到容器内部,无需进入容器修改。 该生成文件与 .env 均属于敏感配置,请勿提交到版本库;重新运行脚本会覆盖该文件,届时需重新补齐自定义参数。

  2. 启动服务。 在同一 docker/ 目录启动组合,确认 Server 已注册、Store 已就绪。

    1docker compose -f docker-compose-hstore.yml up -d --wait

若分别部署服务,参照 PD 部署指南 和 HStore 部署指南;源码或二进制包启动的 Hubble 则编辑其 conf/hugegraph-hubble.properties。以下连接项与官方最小拓扑一致,其他部署请使用 Hubble 后端实际可达的地址。

1pd.enabled=true
2cluster=hg
3pd.peers=pd:8686
4pd.server=pd:8620
配置用途随包配置值
pd.enabled显式启用 PD 模式;此时不使用 server.direct_url。false
cluster用于 Server 服务发现的集群名称,应与注册信息一致。hg
pd.peersPD gRPC 地址;多个地址用逗号分隔。127.0.0.1:8686
pd.server集群运维使用的 PD REST 地址,不是 gRPC peer 列表。127.0.0.1:8620

请区分两个端口。8686 为 gRPC 端口,8620 为 REST 端口,切勿混用;跨容器通信时请使用容器服务名或网络可达 IP,避免使用 127.0.0.1。 发行包默认配置中显式设为 pd.enabled=false;若未配置该项,代码默认值为 true,因此单机与分布式部署均建议显式声明该配置。 修改配置后,源码或二进制部署需重启 Hubble 服务;Docker Compose 部署则在 docker/ 目录下重新创建 Hubble 容器以重新加载挂载配置 (沿用启动时的项目名及所有 -f 参数)。

1docker compose -f docker-compose-hstore.yml up -d --force-recreate hubble

在 Hubble 界面中无需为每个图单独配置 Server 主机与端口。

用图空间组织图与权限

GraphSpace(图空间)将图、Schema 模板和访问权限组织在同一个范围内。例如,分别为业务团队创建 sales 与 research, 让各团队只看到并操作自己的图。进入图空间后,图的建模、导入和查询仍沿用基础指南的流程。

创建与调整图空间

开启 Server 认证时,创建、编辑和删除图空间要求超级管理员权限。创建时先填写全局唯一的 GraphSpace 名称、 可选的显示别名及最大图数;例如用 research 作 API 标识,用“研究图谱”作显示名。GraphSpace 名称创建后不可修改, 别名和描述可随后调整,别名不参与 URL 或权限匹配。图空间管理员从已有账号中选择。

“高级部署与资源限制”包含图查询/写入服务、异步计算任务的 CPU 与内存上限,以及存储容量限制。 这些部署配额不会显示实时资源用量,也不会自动扩容现有容器。

高级部署的默认值

默认最大图数为 100;图服务与计算任务分别为 64 核、128 GB,存储上限为 1000000 GB。 普通容器试用可保留默认值。Kubernetes 命名空间、Operator 和算法镜像仅在对应场景中填写。

选择图空间后,再进入其中的图。切换空间时应重新确认当前图,尤其是不同空间中存在同名图时。 列表只显示账号可访问的空间;看不到预期空间时,先检查成员权限,不要反复新建图。

图空间创建表单与高级资源限制入口

复用 Schema 模板

用户 Schema 模板仅适用于 PD 模式,按图空间持久化保存 Groovy Schema。 当一组业务图需要同样的顶点类型、边类型和索引时,可以先保存模板,再在创建图时选择它,减少重复建模。 例如 research 中的用户模板用于该空间后续创建的图;切换到另一个空间后,应重新选择该空间的模板。

主篇的内置示例模板用于快速体验预设模型。用户模板用于保存自己的模型并长期复用。 模板本身不等于导入数据;是否加载示例数据是创建图时的另一个选择。 开启 Server 认证时,创建用户模板需要所在空间的写权限,更新或删除还要求模板所有者或相应管理权限。 匿名模式不进行按用户的权限与模板所有者检查。 单机模式不提供用户模板管理。

给用户分配图空间权限

账号创建、登录和个人资料管理见基础指南; 分布式模式额外提供“管理 GraphSpace 成员”,在已有账号与指定空间之间分配权限。 支持权限预设的 Server 提供以下常用选择。

预设适用对象作用范围
GraphSpace 只读查看、查询图数据的使用者所选空间。
GraphSpace 读写建模、导入和维护图数据的使用者所选空间。
GraphSpace 管理员管理该空间的成员与图资源的负责人所选空间,不因此获得创建/编辑图空间或集群运维权限。
超级管理员管理账号、图空间及集群的运维人员全局,应按实际职责分配。

同一账号可在不同空间拥有不同权限,例如对 research 读写、对 sales 只读。 账号与空间成员分开管理,移除成员不会删除全局账号。创建账号后可以立即继续分配空间权限;调整已有成员时,确认当前空间及预设,保留其他空间仍需要的权限。 仅启用 pd.enabled 不会授予权限,旧 Server 的自定义角色也不能直接当作这些预设处理。 认证配置见 Server 认证与授权。

GraphSpace 成员与权限预设

从集群概览定位异常

集群概览用一张拓扑展示 Server → PD → Store,可切换节点列表按类型、状态或名称筛选。 概览中的 PD Leader、在线 Store 数、图数、分区数、副本数和数据量,帮助判断当前连接的规模及哪些节点需要关注。 分区和副本描述数据分布;数据量是采集到的用量,不是图空间配置的存储上限。

先看集群和来源状态,再进入异常节点。UP 表示本次采集的来源正常;DEGRADED 表示集群或部分来源异常; DOWN 表示相应探测未成功。拓扑可用而指标部分缺失时,仍可能正常查询图。 页面会区分不支持、不可用、数据过期和采集失败,并显示采集时间;空值不是零,历史值也不等于当前状态。

节点详情读什么

节点主要关注信息如何使用
Server节点可用性、JVM/CPU/内存及后端指标判断查询与写入入口是否可达,并检查资源压力。
PDLeader/Follower 角色、状态及上游可提供的运行指标确认元数据与调度入口;Leader 信息缺失时不推断角色。
Store分区数、Leader 分区数、系统/磁盘指标,以及 Raft 组数和启用组数检查存储节点及副本服务,结合其他节点比较分布。

PD Leader 与 Store 的 Leader 分区分别负责不同的工作。前者协调集群元数据,后者负责相应数据分区的 Raft 组。 Hubble 展示上游提供的观测值,不代替完整的 Raft 副本一致性检查;各版本可用的指标不同。

开启 Server 认证时,集群运维读取要求超级管理员(ADMIN 级别),空间管理员和普通成员不会因此获得集群读取权限。 部署时使用容器隔离、可信 HTTPS 入口、Server 认证与网络白名单,避免直接公开 Hubble 和组件端口。

配置运维访问

PD/Store 的运维凭据由 Hubble 后端使用,与浏览器登录 Server 的账号分开。 Compose 部署修改上文生成的宿主机 docker/conf/hubble/hstore.local.properties;其他部署修改 Hubble 包内配置文件。 其中 PD 密码由脚本生成并与 .env 中的密钥保持一致,Store 启用认证时再配置对应服务账号。不要把密码写进文档、截图或提交的配置。

配置随包默认值设置方式
operations.pd.username / operations.pd.password用户名 hubble,密码为空与 PD 运维 REST 认证匹配。
operations.store.username / operations.store.password用户名 hubble,密码为空上游 Store REST 启用认证时配置对应服务账号。
operations.store.allowed_targets[http://127.0.0.1:8520,http://[::1]:8520]列出信任的 Store 指标来源。

例如容器中的 Store 上报 store:8520,将白名单配置为以下内容。

1operations.store.allowed_targets=[http://store:8520]

多节点集群中需列出所有允许访问的目标地址。每项必须是包含显式端口的 http 或 https 源地址(Origin),不可包含路径、凭据或通配符, 且需与 PD 返回的 Store 指标目标完全一致。仅在白名单中添加地址不会自动建立节点发现。

若集群拓扑可见但节点指标不完整,请依次检查 Hubble 后端到 PD REST 的网络连通性与认证凭据、PD 返回的 Store REST 与指标地址, 以及目标地址是否已加入上述白名单。概览中的部分可用状态仅表示特定来源指标采集受阻,并不代表图 API 服务不可用。

3.2.3 - HugeGraph-Loader 快速上手

本文以 Toolchain master 分支(以 1.8 为基线,尚未正式发布)为准。发布版和 Docker latest 可能存在部分差异,使用未发布功能前请先核对版本。

快速上手:本地文件导入

下面通过一个最简示例体验 Loader 的基本导入流程:导入两个人和一条关系,并在 Hubble 中查询验证。 请先安装 Loader 并启动 HugeGraph Server。 以下命令均在 Loader 安装目录下执行,连接本地默认图 hugegraph。若 Server 已启用鉴权,在命令中追加 --username 与 --password(或 --token)。

  1. 创建数据文件

    两份 CSV 均不含表头,列名由下一步的映射文件指定。

    1mkdir -p demo-loader
    2cat > demo-loader/people.csv <<'EOF'
    3docs-smoke-alice,29
    4docs-smoke-bob,31
    5EOF
    6cat > demo-loader/knows.csv <<'EOF'
    7docs-smoke-alice,docs-smoke-bob
    8EOF
  2. 创建 Schema 和映射文件

    本例使用独立的 docs_* 名称,避免与内置的 person 数据冲突。 映射文件中的路径相对于运行 Loader 时的工作目录。

     1cat > demo-loader/schema.groovy <<'EOF'
     2schema.propertyKey("docs_name").asText().ifNotExist().create()
     3schema.propertyKey("docs_age").asInt().ifNotExist().create()
     4schema.vertexLabel("docs_smoke_person").properties("docs_name", "docs_age")
     5      .primaryKeys("docs_name").ifNotExist().create()
     6schema.edgeLabel("docs_smoke_knows").sourceLabel("docs_smoke_person")
     7      .targetLabel("docs_smoke_person").ifNotExist().create()
     8EOF
     9cat > demo-loader/struct.json <<'EOF'
    10{
    11  "version": "2.0",
    12  "structs": [
    13    {
    14      "id": "people",
    15      "input": {
    16        "type": "FILE",
    17        "path": "demo-loader/people.csv",
    18        "format": "CSV",
    19        "header": ["docs_name", "docs_age"]
    20      },
    21      "vertices": [{"label": "docs_smoke_person"}]
    22    },
    23    {
    24      "id": "knows",
    25      "input": {
    26        "type": "FILE",
    27        "path": "demo-loader/knows.csv",
    28        "format": "CSV",
    29        "header": ["source_name", "target_name"]
    30      },
    31      "edges": [{
    32        "label": "docs_smoke_knows",
    33        "source": ["source_name"],
    34        "target": ["target_name"],
    35        "field_mapping": {"source_name": "docs_name", "target_name": "docs_name"}
    36      }]
    37    }
    38  ]
    39}
    40EOF
  3. 执行导入

    保持在同一工作目录。Server 运行在其他地址时,修改主机和端口。

    1bin/hugegraph-loader.sh \
    2  --graphspace DEFAULT --graph hugegraph \
    3  --file demo-loader/struct.json --schema demo-loader/schema.groovy \
    4  --host 127.0.0.1 --port 8080

    首次成功导入后,统计应显示两个顶点、一条边。检查汇总中的成功数和失败数。

  4. 在 Hubble 中查询结果

    将 Hubble 连接到同一个 Server 和图,在 Gremlin 工作台分别执行以下查询。

    1g.V().hasLabel('docs_smoke_person').valueMap('docs_name', 'docs_age')
    2g.V().has('docs_smoke_person', 'docs_name', 'docs-smoke-alice')
    3 .out('docs_smoke_knows').values('docs_name')

    第一条查询返回 Alice 的年龄 29、Bob 的年龄 31,第二条返回 docs-smoke-bob。

导入其他数据源时,继续阅读映射文件参考。 内置完整示例还包含软件顶点和边属性。

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 快速上手

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

并发导入保护:Toolchain master 分支的 Loader 已支持针对同一 Server 实例的 LOADING owner 保护。当配套 Server 的 GET .../mode/owners 返回 protocol: 1 时会自动生效;若 Server 无此接口,则保持原有导入行为。

2 获取 HugeGraph-Loader

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

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

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

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

以下组合用于本地匿名试用,Server API 只发布到本机。

 1version: '3'
 2
 3services:
 4  server:
 5    image: hugegraph/hugegraph:latest
 6    container_name: server
 7    ports:
 8      - 127.0.0.1:8080:8080
 9
10  loader:
11    image: hugegraph/loader:latest
12    container_name: loader
13    # mount your own data here
14    # volumes:
15      # - /path/to/data/file:/loader/file

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

注意:

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

  2. 生产环境应固定已发布的版本标签或镜像 digest。latest 是可变标签,不能据此判断其与 master 一致。

2.2 下载已编译的压缩包

从 下载页面 选择已发布的 Toolchain 压缩包并解压。 发布包不一定包含 master 的全部功能;需要本文对应实现时,使用下一节的源码构建方式。

2.3 克隆源码编译安装

从 master 分支编译 Loader 需要 Java 17、Maven 3.6.3+ 与 Python 3.9+。直接克隆仓库并编译:

1git clone --branch master --single-branch https://github.com/apache/hugegraph-toolchain.git
2cd hugegraph-toolchain
3mvn package -pl hugegraph-client,hugegraph-loader -am -DskipTests -ntp
4cd hugegraph-loader/apache-hugegraph-loader-*

如需搭配开发阶段的 Server master SDK 编译,可参阅 Java 17 迁移指引。

如需读取 Oracle 数据,按所用 Oracle/JDK 版本准备兼容的 JDBC 驱动 JAR,并放入解压后 Loader 的 lib/ 目录。 启动脚本会加载该目录中的 JAR;仅将驱动安装到 Maven 本地仓库并不会让运行中的 Loader 找到它。

3 使用流程

导入数据到 HugeGraph 遵循以下四个标准操作阶段:

  1. 编写图模型 (Schema) — 使用 Groovy 脚本定义属性键、顶点标签与边标签。
  2. 准备数据源文件 — 准备待导入的文本、表格或数据库连接配置。
  3. 编写数据源映射配置 — 建立源字段与图模型的映射关系规则。
  4. 执行命令导入 — 运行 hugegraph-loader.sh 脚本执行批量数据导入。

3.1 编写图模型

先确定数据对应的顶点类型、边类型和属性,再编写 Schema。

以下示例包含 person 和 software 两类顶点,以及 knows 和 created 两类边。 人有姓名、年龄和城市,软件有名称和价格,两类边都记录日期。

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

示例图模型

将 Schema 定义保存到 schema.groovy。

 1// 创建一些属性
 2schema.propertyKey("name").asText().ifNotExist().create();
 3schema.propertyKey("age").asInt().ifNotExist().create();
 4schema.propertyKey("city").asText().ifNotExist().create();
 5schema.propertyKey("date").asText().ifNotExist().create();
 6schema.propertyKey("price").asDouble().ifNotExist().create();
 7
 8// 创建 person 顶点类型,其拥有三个属性:name, age, city,主键是 name
 9schema.vertexLabel("person").properties("name", "age", "city").primaryKeys("name").ifNotExist().create();
10// 创建 software 顶点类型,其拥有两个属性:name, price,主键是 name
11schema.vertexLabel("software").properties("name", "price").primaryKeys("name").ifNotExist().create();
12
13// 创建 knows 边类型,这类边是从 person 指向 person 的
14schema.edgeLabel("knows").sourceLabel("person").targetLabel("person").properties("date").ifNotExist().create();
15// 创建 created 边类型,这类边是从 person 指向 software 的
16schema.edgeLabel("created").sourceLabel("person").targetLabel("software").ifNotExist().create();

关于 schema 的详细说明请参考 HugeGraph Java 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 或属性;

示例如下:

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

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

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

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

1{"source_name": "marko", "target_name": "vadas", "date": "20160110", "weight": 0.5}
2{"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。

Loader 解析一行数据时,不会根据外键再查询其他表。输入行必须直接提供构造图元素所需的值。 需要关联数据时,先在数据源侧准备好查询结果。

以下以 person、software、created 三张表为例。

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

若 person 和 software 使用 PRIMARY_KEY 策略,以 name 为主键,导入边时就需要两个端点的 name。 created 表只有 p_id 和 s_id,Loader 不会用它们回查名称。可以改用以下两种 ID 设计。

  1. 保留 PRIMARY_KEY 策略,将两张顶点表的 id 列作为主键属性。Loader 可用 p_id、s_id 和顶点标签生成端点 ID。
  2. 使用自定义 ID 策略,将两张顶点表的 id 列直接作为顶点 ID,导入边时直接使用 p_id 和 s_id。

这两种设计都让边数据直接提供端点 ID,省去回查。

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

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

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

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

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

3.3 编写数据源映射文件

3.3.1 映射文件概述

映射文件使用 JSON 格式。每个 structs 映射块包含一个 input,以及该输入对应的 vertices 和 edges 映射。

input 描述数据位置、格式和分隔符。顶点和边映射指定标签、ID、属性及字段转换。

Loader 0.11.0 起使用 2.0 映射格式,此前的格式称为 1.0。下文未特别说明时,均使用 2.0 格式。

点击展开/折叠 2.0 版本的映射文件的框架
 1{
 2  "version": "2.0",
 3  "structs": [
 4    {
 5      "id": "1",
 6      "input": {
 7      },
 8      "vertices": [
 9        {},
10        {}
11      ],
12      "edges": [
13        {},
14        {}
15      ]
16    }
17  ]
18}

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

点击展开/折叠 2.0 版本的映射文件
  1{
  2  "version": "2.0",
  3  "structs": [
  4    {
  5      "id": "1",
  6      "skip": false,
  7      "input": {
  8        "type": "FILE",
  9        "path": "vertex_person.csv",
 10        "file_filter": {
 11          "extensions": [
 12            "*"
 13          ]
 14        },
 15        "format": "CSV",
 16        "delimiter": ",",
 17        "date_format": "yyyy-MM-dd HH:mm:ss",
 18        "time_zone": "GMT+8",
 19        "skipped_line": {
 20          "regex": "(^#|^//).*|"
 21        },
 22        "compression": "NONE",
 23        "header": [
 24          "name",
 25          "age",
 26          "city"
 27        ],
 28        "charset": "UTF-8",
 29        "list_format": {
 30          "start_symbol": "[",
 31          "elem_delimiter": "|",
 32          "end_symbol": "]"
 33        }
 34      },
 35      "vertices": [
 36        {
 37          "label": "person",
 38          "skip": false,
 39          "id": null,
 40          "unfold": false,
 41          "field_mapping": {},
 42          "value_mapping": {},
 43          "selected": [],
 44          "ignored": [],
 45          "null_values": [
 46            ""
 47          ],
 48          "update_strategies": {}
 49        }
 50      ],
 51      "edges": []
 52    },
 53    {
 54      "id": "2",
 55      "skip": false,
 56      "input": {
 57        "type": "FILE",
 58        "path": "vertex_software.csv",
 59        "file_filter": {
 60          "extensions": [
 61            "*"
 62          ]
 63        },
 64        "format": "CSV",
 65        "delimiter": ",",
 66        "date_format": "yyyy-MM-dd HH:mm:ss",
 67        "time_zone": "GMT+8",
 68        "skipped_line": {
 69          "regex": "(^#|^//).*|"
 70        },
 71        "compression": "NONE",
 72        "header": null,
 73        "charset": "UTF-8",
 74        "list_format": {
 75          "start_symbol": "",
 76          "elem_delimiter": ",",
 77          "end_symbol": ""
 78        }
 79      },
 80      "vertices": [
 81        {
 82          "label": "software",
 83          "skip": false,
 84          "id": null,
 85          "unfold": false,
 86          "field_mapping": {},
 87          "value_mapping": {},
 88          "selected": [],
 89          "ignored": [],
 90          "null_values": [
 91            ""
 92          ],
 93          "update_strategies": {}
 94        }
 95      ],
 96      "edges": []
 97    },
 98    {
 99      "id": "3",
100      "skip": false,
101      "input": {
102        "type": "FILE",
103        "path": "edge_knows.json",
104        "file_filter": {
105          "extensions": [
106            "*"
107          ]
108        },
109        "format": "JSON",
110        "delimiter": null,
111        "date_format": "yyyy-MM-dd HH:mm:ss",
112        "time_zone": "GMT+8",
113        "skipped_line": {
114          "regex": "(^#|^//).*|"
115        },
116        "compression": "NONE",
117        "header": null,
118        "charset": "UTF-8",
119        "list_format": null
120      },
121      "vertices": [],
122      "edges": [
123        {
124          "label": "knows",
125          "skip": false,
126          "source": [
127            "source_name"
128          ],
129          "unfold_source": false,
130          "target": [
131            "target_name"
132          ],
133          "unfold_target": false,
134          "field_mapping": {
135            "source_name": "name",
136            "target_name": "name"
137          },
138          "value_mapping": {},
139          "selected": [],
140          "ignored": [],
141          "null_values": [
142            ""
143          ],
144          "update_strategies": {}
145        }
146      ]
147    },
148    {
149      "id": "4",
150      "skip": false,
151      "input": {
152        "type": "FILE",
153        "path": "edge_created.json",
154        "file_filter": {
155          "extensions": [
156            "*"
157          ]
158        },
159        "format": "JSON",
160        "delimiter": null,
161        "date_format": "yyyy-MM-dd HH:mm:ss",
162        "time_zone": "GMT+8",
163        "skipped_line": {
164          "regex": "(^#|^//).*|"
165        },
166        "compression": "NONE",
167        "header": null,
168        "charset": "UTF-8",
169        "list_format": null
170      },
171      "vertices": [],
172      "edges": [
173        {
174          "label": "created",
175          "skip": false,
176          "source": [
177            "source_name"
178          ],
179          "unfold_source": false,
180          "target": [
181            "target_name"
182          ],
183          "unfold_target": false,
184          "field_mapping": {
185            "source_name": "name",
186            "target_name": "name"
187          },
188          "value_mapping": {},
189          "selected": [],
190          "ignored": [],
191          "null_values": [
192            ""
193          ],
194          "update_strategies": {}
195        }
196      ]
197    }
198  ]
199}

点击展开/折叠 1.0 版本的映射文件
 1{
 2  "vertices": [
 3    {
 4      "label": "person",
 5      "input": {
 6        "type": "file",
 7        "path": "vertex_person.csv",
 8        "format": "CSV",
 9        "header": ["name", "age", "city"],
10        "charset": "UTF-8"
11      }
12    },
13    {
14      "label": "software",
15      "input": {
16        "type": "file",
17        "path": "vertex_software.csv",
18        "format": "CSV"
19      }
20    }
21  ],
22  "edges": [
23    {
24      "label": "knows",
25      "source": ["source_name"],
26      "target": ["target_name"],
27      "input": {
28        "type": "file",
29        "path": "edge_knows.json",
30        "format": "JSON"
31      },
32      "field_mapping": {
33        "source_name": "name",
34        "target_name": "name"
35      }
36    },
37    {
38      "label": "created",
39      "source": ["source_name"],
40      "target": ["target_name"],
41      "input": {
42        "type": "file",
43        "path": "edge_created.json",
44        "format": "JSON"
45      },
46      "field_mapping": {
47        "source_name": "name",
48        "target_name": "name"
49      }
50    }
51  ]
52}

映射文件 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 版本的,使用方式如下:

1bin/mapping-convert.sh struct.json

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

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

1bin/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: 本地文件或目录的路径,绝对路径或相对于 Loader 进程当前工作目录的相对路径,必填;为避免工作目录不同导致找不到文件,建议使用绝对路径;
    • file_filter: 从path中筛选复合条件的文件,复合结构,目前只支持配置扩展名,用子节点extensions表示,默认为"*",表示保留所有文件;
    • format: 本地文件的格式,可选值为 CSV、TEXT 及 JSON,必须大写,默认为 CSV,选填;
    • header: 文件各列的列名,如不指定则以数据文件第一行作为 header;显式指定时,首行若与 header 完全相同,默认仍会跳过,详见 has_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_sql 和 table 参数必须填其中一个;
  • custom_sql: 自定义 SQL 语句,custom_sql 和 table 参数必须填其中一个;
  • 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:输入源类型,必须填 kafka 或 KAFKA,必填;
  • bootstrap_server:kafka bootstrap server 列表,必填;
  • topic:订阅的 topic,必填;
  • group:Kafka 消费者组,必填;
  • from_beginning:设置 Kafka 的 auto.offset.reset;true 对应 earliest,false 对应 latest,默认为 false。该策略仅在消费组没有已提交 offset,或已提交 offset 不再有效时生效;已有有效 offset 时会从该 offset 继续读取;
  • 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:当前 master 的 KafkaReader 未实现该过滤,配置此字段不会跳过 Kafka 消息;每条消息仍会直接交给所选格式的解析器,空行或注释行可能因此触发解析错误。需要过滤时请在写入 Kafka 前或消费侧预处理;
  • 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:输入源类型,必须填 graph 或 GRAPH,必填;
  • 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,Beijing,2,18,Beijing和3,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

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

 1// JSON 文件中以如下方式指定更新策略
 2{
 3  "vertices": [
 4    {
 5      "label": "person",
 6      "update_strategies": {
 7        "age": "SMALLER",
 8        "set": "UNION"
 9      },
10      "input": {
11        "type": "file",
12        "path": "vertex_person.txt",
13        "format": "TEXT",
14        "header": ["name", "age", "set"]
15      }
16    }
17  ]
18}
19
20// 1.写入一行带 OVERRIDE 更新策略的数据 (这里 null 代表空)
21'a b null null'
22
23// 2.再写一行
24'null null c d'
25
26// 3.最后可以得到
27'a b c d'   
28
29// 如果没有更新策略,则会得到
30'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当前 master 未启用 Store 直连,仍经 Server API 导入;保留默认值
--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-typetrue仅 spark-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批量插入失败时是否回退至单条插入模式

映射文件选项 --file(-f)是必填项,其他选项使用默认值。有效的最简调用为:

1bin/hugegraph-loader.sh --file struct.json

启动脚本也支持 JCommander 原生的 @file 语法。在 loader.args 中把每个选项及其值分别写在单独一行:

1--file
2struct.json
1bin/hugegraph-loader.sh @loader.args

这与上面的最简调用等价。参数中的相对路径以 Loader 进程的工作目录为基准。 若参数文件包含凭据,使用 chmod 0600 loader.args 把权限限制为 0600;@file 调用让这些值不出现在进程参数中。 Loader 必须能够创建并写入以映射文件前缀命名的进度目录。 从只读 Kubernetes ConfigMap 挂载映射文件时,先把映射复制到可写卷中再运行 Loader。

3.4.2 断点续导模式

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

设置 --incremental-mode 为 true 即可从进度文件续导。Loader 在导入成功或正常停止后关闭时写入进度;意外失败可能阻止该写入。 进度文件位于 ${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 或 --print-progress 是否打开无关。 意外失败导致导入中止时,可能不会写入进度文件。

如果数据文件格式都是合法的,是用户自己停止(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 并传入参数

1bin/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 配置。

3.4.5 最小本地文件导入示例

按本页开头的本地文件导入步骤操作。

3.4.6 并发导入与 LOADING owner

在 master 分支中,Loader 为普通导入实现了 LOADING 所有权管理协议,与 Server 的 /mode/owners 接口协同工作。 若部署的 Server 提供该接口并返回 protocol: 1,Loader 会自动启用所有权保护;已发布的 Server 1.7.0 及更早版本则继续使用原有模式切换流程。

graph TD
    A["图模式 NONE"] -->|首个 Loader 申请所有权| B["进入 LOADING 模式 (分配 token)"]
    B -->|其他并发 Loader 加入| B
    B -->|部分 Loader 导入完成释放| B
    B -->|最后一个 Loader 释放| C["自动恢复 NONE 模式"]
    B -.->|"异常/进程中断 (Token 残留)"| D["管理员恢复 / 释放 / 重启图实例"]
    D -.->|"最后一个 owner 释放,或 recover/重启"| A
    D -.->|"仍有其他 owner 活跃"| B
  1. 探测与获取:Loader 启动后探测 /mode/owners。首个 Loader 获取所有权句柄(instance/epoch/token),图模式由 NONE 转为 LOADING;并发 Loader 可申请加入该模式。
  2. 数据导入:持有有效句柄的 Loader 并行执行数据导入。
  3. 安全释放:导入完成后停止 worker 并释放对应句柄。当最后一个 owner 释放时,图模式自动恢复为 NONE。
  4. 异常恢复:若因异常中断(如 kill -9)导致句柄残留,请先停止并排空所有相关的导入任务与图写操作, 然后通过 RESTful API 管理员恢复接口 执行恢复,或重启 Server。 直接调用 release 仅适用于仍持有 Token 的调用方(如直接调用 REST API 的客户端)。
说明

兼容性与运维说明

  • 旧版本兼容:普通导入时仅在接口返回不支持该路由的 404 响应时回退至旧版 LOADING/NONE 枚举流程(支持 1.7 等旧版 Server,但不提供并发隔离)。 权限、网络、图不存在或无效响应错误不会触发回退。
  • 恢复与图源导入:保留 RESTORING 模式,不探测 owner 且不自动重置。恢复导入完成后须手动将图模式设回 NONE,否则后续普通导入无法获取首个所有权。 在活跃 owner 存在期间,请勿运行恢复导入、图源导入、Spark connector 或旧版 Loader 导入。
  • 作用范围与生命周期:所有权属于直连 Server 实例,不跨节点同步;owner 无自动租期过期机制。 对于嵌入式程序集成,调用方必须调用 HugeGraphLoader.shutdown() 执行单次句柄释放;若释放失败,不会自动重试; 该 owner 可能会在 Server 端保持活跃,此时可能需要通过上述管理员恢复流程处理。

4 完整示例

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

4.1 准备数据

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

1marko,29,Beijing
2vadas,27,Hongkong
3josh,32,Beijing
4peter,35,Shanghai
5"li,nary",26,"Wu,han"
6tom,null,NULL

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

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

边文件:example/file/edge_knows.json

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

边文件:example/file/edge_created.json

1{"source_name": "marko", "target_id": 1, "date": "2017-12-10", "weight": 0.4}
2{"source_name": "josh", "target_id": 1, "date": "2009-11-11", "weight": 0.4}
3{"source_name": "josh", "target_id": 2, "date": "2017-12-10", "weight": 1.0}
4{"source_name": "peter", "target_id": 1, "date": "2017-03-24", "weight": 0.2}

4.2 编写 schema

点击展开/折叠 schema 文件:example/file/schema.groovy
 1schema.propertyKey("name").asText().ifNotExist().create();
 2schema.propertyKey("age").asInt().ifNotExist().create();
 3schema.propertyKey("city").asText().ifNotExist().create();
 4schema.propertyKey("weight").asDouble().ifNotExist().create();
 5schema.propertyKey("lang").asText().ifNotExist().create();
 6schema.propertyKey("date").asText().ifNotExist().create();
 7schema.propertyKey("price").asDouble().ifNotExist().create();
 8
 9schema.vertexLabel("person").properties("name", "age", "city").primaryKeys("name").nullableKeys("age", "city").ifNotExist().create();
10schema.vertexLabel("software").useCustomizeNumberId().properties("name", "lang", "price").ifNotExist().create();
11
12schema.indexLabel("personByAge").onV("person").by("age").range().ifNotExist().create();
13schema.indexLabel("personByCity").onV("person").by("city").secondary().ifNotExist().create();
14schema.indexLabel("personByAgeAndCity").onV("person").by("age", "city").secondary().ifNotExist().create();
15schema.indexLabel("softwareByPrice").onV("software").by("price").range().ifNotExist().create();
16
17schema.edgeLabel("knows").sourceLabel("person").targetLabel("person").properties("date", "weight").ifNotExist().create();
18schema.edgeLabel("created").sourceLabel("person").targetLabel("software").properties("date", "weight").ifNotExist().create();
19
20schema.indexLabel("createdByDate").onE("created").by("date").secondary().ifNotExist().create();
21schema.indexLabel("createdByWeight").onE("created").by("weight").range().ifNotExist().create();
22schema.indexLabel("knowsByWeight").onE("knows").by("weight").range().ifNotExist().create();

person 使用 name 作为主键;Tom 的 age 和 city 会被 null_values 去掉,因此这两个属性必须允许为空。 software 使用自定义数值 ID,映射中的 id 和 created.target_id 分别对应顶点 ID 及边的目标 ID。 请在未包含同名 Schema 的空图中执行,避免 ifNotExist() 保留已有的不兼容定义。

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

点击展开/折叠 源映射文件 example/file/struct.json
 1{
 2  "vertices": [
 3    {
 4      "label": "person",
 5      "input": {
 6        "type": "file",
 7        "path": "example/file/vertex_person.csv",
 8        "format": "CSV",
 9        "header": ["name", "age", "city"],
10        "charset": "UTF-8",
11        "skipped_line": {
12          "regex": "(^#|^//).*"
13        }
14      },
15      "null_values": ["NULL", "null", ""]
16    },
17    {
18      "label": "software",
19      "input": {
20        "type": "file",
21        "path": "example/file/vertex_software.txt",
22        "format": "TEXT",
23        "delimiter": "|",
24        "charset": "GBK"
25      },
26      "id": "id",
27      "ignored": ["ISBN"]
28    }
29  ],
30  "edges": [
31    {
32      "label": "knows",
33      "source": ["source_name"],
34      "target": ["target_name"],
35      "input": {
36        "type": "file",
37        "path": "example/file/edge_knows.json",
38        "format": "JSON",
39        "date_format": "yyyyMMdd"
40      },
41      "field_mapping": {
42        "source_name": "name",
43        "target_name": "name"
44      }
45    },
46    {
47      "label": "created",
48      "source": ["source_name"],
49      "target": ["target_id"],
50      "input": {
51        "type": "file",
52        "path": "example/file/edge_created.json",
53        "format": "JSON",
54        "date_format": "yyyy-MM-dd"
55      },
56      "field_mapping": {
57        "source_name": "name"
58      }
59    }
60  ]
61}

4.4 执行命令导入

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

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

 1vertices/edges has been loaded this time : 8/6
 2--------------------------------------------------
 3count metrics
 4     input read success            : 14
 5     input read failure            : 0
 6     vertex parse success          : 8
 7     vertex parse failure          : 0
 8     vertex insert success         : 8
 9     vertex insert failure         : 0
10     edge parse success            : 6
11     edge parse failure            : 0
12     edge insert success           : 6
13     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 文件夹下,文件结构如下:

1tree -f hugegraph-dataset/
2
3hugegraph-dataset
4├── hugegraph-dataset/edge_created.json
5├── hugegraph-dataset/edge_knows.json
6├── hugegraph-dataset/schema.groovy
7├── hugegraph-dataset/struct.json
8├── hugegraph-dataset/vertex_person.csv
9└── hugegraph-dataset/vertex_software.txt

将文件复制到容器内部

1docker cp hugegraph-dataset loader:/loader/dataset
2docker exec -it loader ls /loader/dataset
3
4edge_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 参数说明

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

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

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

自定义数据集的 struct.json 还需将每个 input.path 改为容器内实际路径,例如 /loader/dataset/vertex_person.csv。 只修改 -f 和 -s 不会改变数据文件的解析路径。

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

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

 1HugeGraphLoader worked in NORMAL MODE
 2vertices/edges loaded this time : 8/6
 3--------------------------------------------------
 4count metrics
 5    input read success            : 14                  
 6    input read failure            : 0                   
 7    vertex parse success          : 8                   
 8    vertex parse failure          : 0                   
 9    vertex insert success         : 8                   
10    vertex insert failure         : 0                   
11    edge parse success            : 6                   
12    edge parse failure            : 0                   
13    edge insert success           : 6                   
14    edge insert failure           : 0                   
15--------------------------------------------------
16meter metrics
17    total time                    : 0.199s              
18    read time                     : 0.046s              
19    load time                     : 0.153s              
20    vertex load time              : 0.077s              
21    vertex load rate(vertices/s)  : 103                 
22    edge load time                : 0.112s              
23    edge load rate(edges/s)       : 53   

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

以下使用支持 GraphSpace 的 Server API;旧版 Server 的路径需去掉 /graphspaces/DEFAULT。

1curl --compressed "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices"
2{"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 --compressed "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges"

4.5.2 进入 docker 容器进行导入

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

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

1sh 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 导入

当前 master 分支的 API 写入路径使用 Spark 3.5.8、Scala 2.12,driver 和 executor 均需 Java 17。 POM 中的 Spark 3.2.2 只提供编译期 API,不是运行引擎。设置 SPARK_HOME 和 JAVA_HOME, 再使用发行目录中的启动脚本和 shaded Loader JAR。

先创建 Schema,确保 executor 可以读取数据文件。CSV、TEXT 数据须使用 UTF-8、去掉表头行,并在映射中显式指定 header。 其他字符集和 has_header: true 会被拒绝。边依赖已有顶点时,先导入顶点。将以下路径替换为准备好的顶点映射文件。

1bin/hugegraph-spark-loader.sh \
2  --master 'local[2]' --driver-memory 1g \
3  --file /path/to/vertex-mapping.json \
4  --host 127.0.0.1 --port 8080 --graph hugegraph --sink-type true

启动脚本可同时接收 --master、--conf、--jars 等 Spark 参数和 Loader 参数。 额外的 JDBC 驱动需通过 --jars 传入,仅放在 lib/ 中不会分发到 executor。 导入后查询目标图,核对数量和属性;API 写入路径的插入计数器不统计分布式写入。

该路径拒绝 --incremental-mode true 和 --failure-mode true。Standalone Spark 仅支持 client 部署模式。 Spark 3.5.8 / Java 17 不支持 HBase bulkload(--sink-type false)。已有 bulkload 部署建议继续沿用原环境验证通过的 Loader 发布包及其相关依赖。更多细节见 Spark 迁移说明。

当前 master 分支适配 Flink 2.2.1、MySQL CDC 3.6.0-2.2 和 Java 17。 此前使用 Flink 1.13.5、CDC 2.2.1 的示例属于旧实现。 设置 FLINK_HOME,确保提交进程、JobManager 和 TaskManager 都使用 Java 17。 保留 Flink 的模块访问参数,发行目录的 lib/ 中须恰好有一个 shaded Loader JAR。

每个映射都需使用 MySQL JDBC 输入,包含 url、database、table、username 和 password。 MySQL 须配置 binlog_row_image=FULL。UPDATE 事件需要显式指定非空的 update_strategies,且图元素标识保持不变。 顶点 ID、边端点或排序键变化时,任务会拒绝更新。CDC 也会拒绝 --dry-run true 和 --use-prefilter true。

不带分隔符时,所有参数均交给 Loader。需要设置 Flink 参数时,将其放在 -- 之前,Loader 参数放在之后。 准备好 mysql-cdc.json 映射后,使用单个 sink writer 提交任务。

1bin/hugegraph-flinkcdc-loader.sh -p 1 -- \
2  --file ./mysql-cdc.json --host 127.0.0.1 --port 8080 \
3  --graph hugegraph --cdc-sink-parallelism 1

每个映射使用一个 source reader 和一个 sink writer。--cdc-sink-parallelism 默认为 1,其他取值会被拒绝。 -- 之后的 Loader 参数 -p 表示 Server 端口。Checkpoint 刷新不提供图写入事务,也不保证 exactly-once。 在生产环境部署边 CDC 或更复杂的多表映射前,建议先在真实环境中充分验证。 支持范围和恢复流程见 Flink CDC 说明。

3.2.4 - 图导入

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

3.2.4.1 - 使用 SeaTunnel Sink 导入图数据

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

版本要求:本文面向 SeaTunnel 3.0+。 所有示例使用 SeaTunnel 3.0+ 提供的 mappings 配置。

通过 HugeGraph Helm 部署时,可直接启用内置 SeaTunnel。 Chart 已预置 HugeGraph 连接器、运行环境及同 Release 的连接凭据;本页重点介绍接入外部数据源时的作业配置。

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+ 中都支持 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+

使用 JDK 11 并设置 JAVA_HOME;官方部署文档 列出的前置要求为 Java 8 或 11。从官方下载页[4] 选择 3.0+ 二进制发行包,并使用页面提供的校验文件或签名验证下载包。 下面以 3.0.0 为例,请将 SEATUNNEL_VERSION 改为实际下载的发行版本。

1export SEATUNNEL_VERSION=3.0.0
2tar -xzf "apache-seatunnel-${SEATUNNEL_VERSION}-bin.tar.gz"
3cd "apache-seatunnel-${SEATUNNEL_VERSION}"

二进制发行包不包含连接器插件。在 config/plugin_config 中选择示例需要的连接器:

1--seatunnel-connectors--
2connector-hugegraph
3connector-jdbc
4connector-kafka
5--end--

按官方插件安装说明[5] 安装同版本的已发布插件:

1sh bin/install-plugin.sh "${SEATUNNEL_VERSION}"

后续命令均在该安装目录执行,引擎和连接器插件保持相同版本。 本文使用自带的 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 中填写 username、password。

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

图元素名称与属性
属性name 为 Text,age 和 since 为 Int
顶点person,主键为 name,属性为 name、age
边knows,从 person 指向 person,属性为 since

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

3 从关系库导入(sql2graph)

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

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

3.1 导入顶点

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

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

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

 1env {
 2  job.mode = "BATCH"
 3}
 4
 5source {
 6  Jdbc {
 7    url = "jdbc:mysql://mysql:3306/demo?useSSL=false&serverTimezone=UTC"
 8    driver = "com.mysql.cj.jdbc.Driver"
 9    username = "seatunnel"
10    password = "change_me"
11    query = "SELECT name, age FROM person ORDER BY name"
12  }
13}
14
15sink {
16  HugeGraph {
17    host = "hugegraph"
18    port = 8080
19    graph_name = "hugegraph"
20    graph_space = "DEFAULT"
21    batch_failure_fallback = false
22    mappings = [
23      {
24        type = "VERTEX"
25        label = "person"
26        idStrategy = "PRIMARY_KEY"
27        idFields = ["name"]
28        properties = ["name", "age"]
29      }
30    ]
31  }
32}
1./bin/seatunnel.sh --config ./config/sql2graph-person.conf -m local

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

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

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

3.2 导入边

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

1CREATE TABLE knows (
2  source_name VARCHAR(64) NOT NULL,
3  target_name VARCHAR(64) NOT NULL,
4  since INT NOT NULL
5);
6INSERT INTO knows VALUES ('marko', 'vadas', 2010);
展开配置,保存为 config/sql2graph-knows.conf
 1env {
 2  job.mode = "BATCH"
 3}
 4
 5source {
 6  Jdbc {
 7    url = "jdbc:mysql://mysql:3306/demo?useSSL=false&serverTimezone=UTC"
 8    driver = "com.mysql.cj.jdbc.Driver"
 9    username = "seatunnel"
10    password = "change_me"
11    query = "SELECT source_name, target_name, since FROM knows ORDER BY source_name, target_name"
12  }
13}
14
15sink {
16  HugeGraph {
17    host = "hugegraph"
18    port = 8080
19    graph_name = "hugegraph"
20    graph_space = "DEFAULT"
21    batch_failure_fallback = false
22    check_vertex = true
23    mappings = [
24      {
25        type = "EDGE"
26        label = "knows"
27        sourceConfig = {
28          label = "person"
29          idFields = ["source_name"]
30        }
31        targetConfig = {
32          label = "person"
33          idFields = ["target_name"]
34        }
35        fieldMapping = {
36          source_name = "name"
37          target_name = "name"
38        }
39        properties = ["since"]
40      }
41    ]
42  }
43}

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

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

下面的查询应返回 marko 到 vadas 的 knows 边,属性 since 为 2010:

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

sourceConfig 和 targetConfig 指定端点字段,fieldMapping 将它们对应到顶点主键 name,properties = ["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 顶点:

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

保存为 config/kafka2graph.conf:

 1env {
 2  job.mode = "STREAMING"
 3  checkpoint.interval = 10000
 4  sink.flush.interval = 5000
 5}
 6
 7source {
 8  Kafka {
 9    bootstrap.servers = "kafka:9092"
10    topic = "user-events"
11    consumer.group = "hugegraph-import"
12    start_mode = "earliest"
13    format = "json"
14    schema = {
15      fields = {
16        name = "string"
17        age = "int"
18      }
19    }
20  }
21}
22
23sink {
24  HugeGraph {
25    host = "hugegraph"
26    port = 8080
27    graph_name = "hugegraph"
28    graph_space = "DEFAULT"
29    batch_failure_fallback = false
30    mappings = [
31      {
32        type = "VERTEX"
33        label = "person"
34        idStrategy = "PRIMARY_KEY"
35        idFields = ["name"]
36        properties = ["name", "age"]
37      }
38    ]
39  }
40}
1./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+ 版本:

配置用途
host、port分别指定 HugeGraph 主机和端口
graph_name、graph_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+ 正式版下载
[5] 连接器插件安装说明
[6] SeaTunnel 本地部署

执行引擎

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

数据源连接器

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

3.2.5 - Tools 快速上手

1 HugeGraph-Tools概述

HugeGraph-Tools 提供图与任务管理、备份和恢复命令,也保留旧版 Server/Studio 的部署命令。

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

2 获取 HugeGraph-Tools

HugeGraph-Tools 包含在 Toolchain 发布包中,可以通过以下途径获取与构建:

2.1 下载二进制tar包

以下以已发布的 HugeGraph-Toolchain 1.7.0 为例。其他发布版本见下载页。

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

2.2 下载源码编译安装

任选一种方式构建发布版 1.7.0 Tools,开始前先安装 Maven 和 JDK 11。源码包方式还需要 wget。 两段命令均包含编译和进入生成目录,最后用 bin/hugegraph help 查看可用命令。

Git 标签
1git clone --branch 1.7.0 --single-branch https://github.com/apache/hugegraph-toolchain.git
2cd hugegraph-toolchain
3mvn package -pl hugegraph-tools -am -DskipTests -ntp
4cd hugegraph-tools/apache-hugegraph-tools-incubating-1.7.0
5bin/hugegraph help
源码包
1export VERSION=1.7.0
2export ARCHIVE="apache-hugegraph-toolchain-incubating-${VERSION}"
3wget "https://downloads.apache.org/hugegraph/${VERSION}/${ARCHIVE}-src.tar.gz"
4tar zxf "${ARCHIVE}-src.tar.gz"
5cd "${ARCHIVE}-src"
6mvn package -pl hugegraph-tools -am -DskipTests -ntp
7cd "hugegraph-tools/apache-hugegraph-tools-incubating-${VERSION}"
8bin/hugegraph help

编译还会在源码根目录下生成 hugegraph-tools/target/apache-hugegraph-tools-incubating-1.7.0.tar.gz。

2.3 构建当前源码

若需要使用 master 分支未发布的新特性,可按以下步骤从源码构建 Tools(当前 master 以 1.8 为基线,需 JDK 17、Maven 3.6.3+ 与 Python 3.9+):

  1. 获取 Toolchain 源码

    1git clone --branch master --single-branch https://github.com/apache/hugegraph-toolchain.git
    2cd hugegraph-toolchain
  2. 构建配套 Server SDK

    执行以下脚本下载 Server 源码并将配套 SDK 安装到独立 Maven 仓库:

    1java -version
    2mvn -version
    3candidate_dir=$(mktemp -d)
    4mkdir -p "$candidate_dir/m2"
    5bash hugegraph-client/assembly/travis/install-candidate-sdk.sh \
    6  master "$candidate_dir/server" "$candidate_dir/m2"

    详细说明见 Java 17 迁移指引。

  3. 打包 Tools

    1mvn -Dmaven.repo.local="$candidate_dir/m2" \
    2  -Dsdk.validation.mode=candidate \
    3  package -pl hugegraph-tools -am -DskipTests -Dmaven.javadoc.skip=true -ntp
    4cd hugegraph-tools/apache-hugegraph-tools-*
    5bin/hugegraph help

使用这份源码构建时保留 SDK 仓库。master 分支生成目录名不含 incubating。

3 使用

3.1 功能概览

进入解压或编译生成的 Tools 目录,用 bin/hugegraph help 查看命令列表, 用 bin/hugegraph help <子命令> 查看单个命令的用法。可用命令分为以下几类。

  • 图管理类,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
  • 旧版 Server/Studio 部署,deploy、clear、start-all 和 stop-all
1Usage: hugegraph [options] [command] [command options]
3.2 [options]-全局变量

以下全局选项可以通过命令行或环境变量设置。

  • --graph 指定要操作的图,默认为 hugegraph。
  • --url 指定 Server 地址,默认为 http://127.0.0.1:8080。
  • --user 在 Server 启用认证时提供用户名。
  • --password 提供该用户的密码。
  • --timeout 设置连接超时时间,默认为 30 秒。
  • --trust-store-file 指定 HTTPS truststore,留空时使用内置的 conf/hugegraph.truststore。
  • --trust-store-password 提供其密码,留空时使用内置 truststore 的密码。
  • --throw-mode 默认为 false,出错时打印错误并退出。设为 true 时抛出异常,主要用于测试。

--url 的 scheme 决定连接协议。使用 https://... 连接 HTTPS 时,才可设置 truststore 选项。 --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

下面两种写法查询同一个图的顶点总数,可按使用习惯任选一种。示例使用未启用鉴权的本地 Server;已启用鉴权时还需提供上述用户名和密码。

命令行参数
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph gremlin-execute --script 'g.V().count()'
环境变量
1export HUGEGRAPH_URL=http://127.0.0.1:8080
2export HUGEGRAPH_GRAPH=hugegraph
3./bin/hugegraph gremlin-execute --script 'g.V().count()'

也可以在 bin/hugegraph 脚本中设置这些变量。

 1#!/bin/bash
 2
 3# Set environment here if needed
 4#export HUGEGRAPH_URL=
 5#export HUGEGRAPH_GRAPH=
 6#export HUGEGRAPH_USERNAME=
 7#export HUGEGRAPH_PASSWORD=
 8#export HUGEGRAPH_TIMEOUT=
 9#export HUGEGRAPH_TRUST_STORE_FILE=
10#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,即默认迁移图结束后不保留产生的源图备份
    警告

    备份与迁移快速失败与分片诊断:若在重试达到上限后仍有顶点或边数据页拉取失败,备份流程会立即报错中止,且 migrate 不会启动向目标图的恢复操作。 系统会保留已下载的分块文件以及分片诊断日志(以 *_shards 结尾,如 vertex_failed_shards、edge_timeout_shards),便于定位超时或超限原因。 数据备份目录(--directory)与日志目录(--log,默认为 ./logs)相互独立。注意重新执行任务时会自动清空日志目录下的历史 *_shards 文件。 在重新执行前,请先备份诊断日志,或同时指定全新的 --log 目录与干净的 --directory 备份目录(或清理残留的局部数据)。

  • 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 安装部署类

注意:此处的安装部署命令仅适用于早期历史版本(Server 0.6.10.10.4 与 Studio 0.6.10.10.0),不支持当前版本的 HugeGraph Server 或 Hubble。 新部署请参考 Server 快速上手 与 Hubble 快速上手, 以下说明仅供维护旧环境参考。

  • 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.sh、bin/start-all.sh、bin/clear.sh 和 bin/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 具体命令参数

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

  1Usage: hugegraph [options] [command] [command options]
  2  Options:
  3    --graph
  4      Name of graph
  5      Default: hugegraph
  6    --password
  7      Password of user
  8    --throw-mode
  9      Whether the hugegraph-tools work to throw an exception
 10      Default: false
 11    --timeout
 12      Connection timeout
 13      Default: 30
 14    --trust-store-file
 15      The path of client truststore file used when https protocol is enabled
 16    --trust-store-password
 17      The password of the client truststore file used when the https protocol 
 18      is enabled
 19    --url
 20      The URL of HugeGraph-Server
 21      Default: http://127.0.0.1:8080
 22    --user
 23      Name of user
 24  Commands:
 25    graph-create      Create graph with config
 26      Usage: graph-create [options]
 27        Options:
 28          --file, -f
 29            Creating graph config file
 30          --name, -n
 31            The name of new created graph, default is g
 32            Default: g
 33
 34    graph-clone      Clone graph
 35      Usage: graph-clone [options]
 36        Options:
 37          --clone-graph-name
 38            The name of cloned graph, default is hugegraph
 39            Default: hugegraph
 40          --name, -n
 41            The name of new created graph, default is g
 42            Default: g
 43
 44    graph-list      List all graphs
 45      Usage: graph-list
 46
 47    graph-get      Get graph info
 48      Usage: graph-get
 49
 50    graph-clear      Clear graph schema and data
 51      Usage: graph-clear [options]
 52        Options:
 53        * --confirm-message, -c
 54            Confirm message of graph clear is "I'm sure to delete all data". 
 55            (Note: include "")
 56
 57    graph-drop      Drop graph
 58      Usage: graph-drop [options]
 59        Options:
 60        * --confirm-message, -c
 61            Confirm message of graph clear is "I'm sure to drop the graph". 
 62            (Note: include "")
 63
 64    graph-mode-set      Set graph mode
 65      Usage: graph-mode-set [options]
 66        Options:
 67        * --graph-mode, -m
 68            Graph mode, include: [NONE, RESTORING, MERGING]
 69            Possible Values: [NONE, RESTORING, MERGING, LOADING]
 70
 71    graph-mode-get      Get graph mode
 72      Usage: graph-mode-get
 73
 74    task-list      List tasks
 75      Usage: task-list [options]
 76        Options:
 77          --limit
 78            Limit number, no limit if not provided
 79            Default: -1
 80          --status
 81            Status of task
 82
 83    task-get      Get task info
 84      Usage: task-get [options]
 85        Options:
 86        * --task-id
 87            Task id
 88            Default: 0
 89
 90    task-delete      Delete task
 91      Usage: task-delete [options]
 92        Options:
 93        * --task-id
 94            Task id
 95            Default: 0
 96
 97    task-cancel      Cancel task
 98      Usage: task-cancel [options]
 99        Options:
100        * --task-id
101            Task id
102            Default: 0
103
104    task-clear      Clear completed tasks
105      Usage: task-clear [options]
106        Options:
107          --force
108            Force to clear all tasks, cancel all uncompleted tasks firstly, 
109            and delete all completed tasks
110            Default: false
111
112    gremlin-execute      Execute Gremlin statements
113      Usage: gremlin-execute [options]
114        Options:
115          --aliases, -a
116            Gremlin aliases, valid format is: 'key1=value1,key2=value2...'
117            Default: {}
118          --bindings, -b
119            Gremlin bindings, valid format is: 'key1=value1,key2=value2...'
120            Default: {}
121          --file, -f
122            Gremlin Script file to be executed, UTF-8 encoded, exclusive to 
123            --script 
124          --language, -l
125            Gremlin script language
126            Default: gremlin-groovy
127          --script, -s
128            Gremlin script to be executed, exclusive to --file
129
130    gremlin-schedule      Execute Gremlin statements as asynchronous job
131      Usage: gremlin-schedule [options]
132        Options:
133          --bindings, -b
134            Gremlin bindings, valid format is: 'key1=value1,key2=value2...'
135            Default: {}
136          --file, -f
137            Gremlin Script file to be executed, UTF-8 encoded, exclusive to 
138            --script 
139          --language, -l
140            Gremlin script language
141            Default: gremlin-groovy
142          --script, -s
143            Gremlin script to be executed, exclusive to --file
144
145    backup      Backup graph schema/data. If directory is on HDFS, use -D to 
146            set HDFS params. For example: 
147            -Dfs.default.name=hdfs://localhost:9000 
148      Usage: backup [options]
149        Options:
150          --all-properties
151            All properties to be backup flag
152            Default: false
153          --compress
154            compress flag
155            Default: true
156          --directory, -d
157            Directory of graph schema/data, default is './{graphname}' in 
158            local file system or '{fs.default.name}/{graphname}' in HDFS
159          --format
160            File format, valid is [json, text]
161            Default: json
162          --huge-types, -t
163            Type of schema/data. Concat with ',' if more than one. Other types 
164            include 'all' and 'schema'. 'all' means all vertices, edges and 
165            schema. In other words, 'all' equals with 'vertex, edge, 
166            vertex_label, edge_label, property_key, index_label'. 'schema' 
167            equals with 'vertex_label, edge_label, property_key, index_label'.
168            Default: [PROPERTY_KEY, VERTEX_LABEL, EDGE_LABEL, INDEX_LABEL, VERTEX, EDGE]
169          --label
170            Vertex label or edge label, only valid when type is vertex or edge
171          --log, -l
172            Directory of log
173            Default: ./logs
174          --properties
175            Vertex or edge properties to backup, only valid when type is 
176            vertex or edge
177            Default: []
178          --retry
179            Retry times, default is 3
180            Default: 3
181          --split-size, -s
182            Split size of shard
183            Default: 1048576
184          --thread-num, -T
185            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
186            2)) 
187            Default: 0
188          -D
189            HDFS config parameters
190            Syntax: -Dkey=value
191            Default: {}
192
193    schedule-backup      Schedule backup task
194      Usage: schedule-backup [options]
195        Options:
196          --backup-num
197            The number of latest backups to keep
198            Default: 3
199        * --directory, -d
200            The directory of backups stored
201          --interval
202            The interval of backup, format is: "a b c d e". 'a' means minute 
203            (0 - 59), 'b' means hour (0 - 23), 'c' means day of month (1 - 
204            31), 'd' means month (1 - 12), 'e' means day of week (0 - 6) 
205            (Sunday=0), "*" means all
206            Default: "0 0 * * *"
207
208    dump      Dump graph to files
209      Usage: dump [options]
210        Options:
211          --directory, -d
212            Directory of graph schema/data, default is './{graphname}' in 
213            local file system or '{fs.default.name}/{graphname}' in HDFS
214          --formatter, -f
215            Formatter to customize format of vertex/edge
216            Default: JsonFormatter
217          --log, -l
218            Directory of log
219            Default: ./logs
220          --retry
221            Retry times, default is 3
222            Default: 3
223          --split-size, -s
224            Split size of shard
225            Default: 1048576
226          --thread-num, -T
227            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
228            2)) 
229            Default: 0
230          -D
231            HDFS config parameters
232            Syntax: -Dkey=value
233            Default: {}
234
235    restore      Restore graph schema/data. If directory is on HDFS, use -D to 
236            set HDFS params if needed. For 
237            example:-Dfs.default.name=hdfs://localhost:9000 
238      Usage: restore [options]
239        Options:
240          --clean
241            Whether to remove the directory of graph data after restored
242            Default: false
243          --directory, -d
244            Directory of graph schema/data, default is './{graphname}' in 
245            local file system or '{fs.default.name}/{graphname}' in HDFS
246          --huge-types, -t
247            Type of schema/data. Concat with ',' if more than one. Other types 
248            include 'all' and 'schema'. 'all' means all vertices, edges and 
249            schema. In other words, 'all' equals with 'vertex, edge, 
250            vertex_label, edge_label, property_key, index_label'. 'schema' 
251            equals with 'vertex_label, edge_label, property_key, index_label'.
252            Default: [PROPERTY_KEY, VERTEX_LABEL, EDGE_LABEL, INDEX_LABEL, VERTEX, EDGE]
253          --log, -l
254            Directory of log
255            Default: ./logs
256          --retry
257            Retry times, default is 3
258            Default: 3
259          --thread-num, -T
260            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
261            2)) 
262            Default: 0
263          -D
264            HDFS config parameters
265            Syntax: -Dkey=value
266            Default: {}
267
268    migrate      Migrate graph
269      Usage: migrate [options]
270        Options:
271          --directory, -d
272            Directory of graph schema/data, default is './{graphname}' in 
273            local file system or '{fs.default.name}/{graphname}' in HDFS
274          --graph-mode, -m
275            Mode used when migrating to target graph, include: [RESTORING, 
276            MERGING] 
277            Default: RESTORING
278            Possible Values: [NONE, RESTORING, MERGING, LOADING]
279          --huge-types, -t
280            Type of schema/data. Concat with ',' if more than one. Other types 
281            include 'all' and 'schema'. 'all' means all vertices, edges and 
282            schema. In other words, 'all' equals with 'vertex, edge, 
283            vertex_label, edge_label, property_key, index_label'. 'schema' 
284            equals with 'vertex_label, edge_label, property_key, index_label'.
285            Default: [PROPERTY_KEY, VERTEX_LABEL, EDGE_LABEL, INDEX_LABEL, VERTEX, EDGE]
286          --keep-local-data
287            Whether to keep the local directory of graph data after restored
288            Default: false
289          --log, -l
290            Directory of log
291            Default: ./logs
292          --retry
293            Retry times, default is 3
294            Default: 3
295          --split-size, -s
296            Split size of shard
297            Default: 1048576
298          --target-graph
299            The name of target graph to migrate
300            Default: hugegraph
301          --target-password
302            The password of target graph to migrate
303          --target-timeout
304            The timeout to connect target graph to migrate
305            Default: 0
306          --target-trust-store-file
307            The trust store file of target graph to migrate
308          --target-trust-store-password
309            The trust store password of target graph to migrate
310          --target-url
311            The url of target graph to migrate
312            Default: http://127.0.0.1:8081
313          --target-user
314            The username of target graph to migrate
315          --thread-num, -T
316            Threads number to use, default is Math.min(10, Math.max(4, CPUs / 
317            2)) 
318            Default: 0
319          -D
320            HDFS config parameters
321            Syntax: -Dkey=value
322            Default: {}
323
324    deploy      Install HugeGraph-Server and HugeGraph-Studio
325      Usage: deploy [options]
326        Options:
327        * -p
328            Install path of HugeGraph-Server and HugeGraph-Studio
329          -u
330            Download url prefix path of HugeGraph-Server and HugeGraph-Studio
331        * -v
332            Version of HugeGraph-Server and HugeGraph-Studio
333
334    start-all      Start HugeGraph-Server and HugeGraph-Studio
335      Usage: start-all [options]
336        Options:
337        * -p
338            Install path of HugeGraph-Server and HugeGraph-Studio
339        * -v
340            Version of HugeGraph-Server and HugeGraph-Studio
341
342    clear      Clear HugeGraph-Server and HugeGraph-Studio
343      Usage: clear [options]
344        Options:
345        * -p
346            Install path of HugeGraph-Server and HugeGraph-Studio
347
348    stop-all      Stop HugeGraph-Server and HugeGraph-Studio
349      Usage: stop-all
350
351    auth-backup      null
352      Usage: auth-backup [options]
353        Options:
354          --directory
355            Directory of auth information, default is 
356            './{auth-backup-restore}' in local file system or 
357            '{fs.default.name}/{auth-backup-restore}' in HDFS
358          --retry
359            Retry times, default is 3
360            Default: 3
361          --types, -t
362            Type of auth data to restore and backup, concat with ',' if more 
363            than one. 'all' means all auth information. In other words, 'all' 
364            equals with 'user, group, target, belong, access'. In addition, 
365            'belong' or 'access' can not backup or restore alone, if type 
366            contains 'belong' then should contains 'user' and 'group'. If type 
367            contains 'access' then should contains 'group' and 'target'.
368            Default: [TARGET, GROUP, USER, ACCESS, BELONG]
369          -D
370            HDFS config parameters
371            Syntax: -Dkey=value
372            Default: {}
373
374    auth-restore      null
375      Usage: auth-restore [options]
376        Options:
377          --directory
378            Directory of auth information, default is 
379            './{auth-backup-restore}' in local file system or 
380            '{fs.default.name}/{auth-backup-restore}' in HDFS
381          --init-password
382            Init user password, if restore type include 'user', please specify 
383            the init-password of users.
384            Default: <empty string>
385          --retry
386            Retry times, default is 3
387            Default: 3
388          --strategy
389            The strategy needs to be chosen in the event of a conflict when 
390            restoring. Valid strategies include 'stop' and 'ignore', default 
391            is 'stop'. 'stop' means if there a conflict, stop restore. 
392            'ignore' means if there a conflict, ignore and continue to 
393            restore. 
394            Default: STOP
395            Possible Values: [STOP, IGNORE]
396          --types, -t
397            Type of auth data to restore and backup, concat with ',' if more 
398            than one. 'all' means all auth information. In other words, 'all' 
399            equals with 'user, group, target, belong, access'. In addition, 
400            'belong' or 'access' can not backup or restore alone, if type 
401            contains 'belong' then should contains 'user' and 'group'. If type 
402            contains 'access' then should contains 'group' and 'target'.
403            Default: [TARGET, GROUP, USER, ACCESS, BELONG]
404          -D
405            HDFS config parameters
406            Syntax: -Dkey=value
407            Default: {}
408
409    help      Print usage
410      Usage: help
3.10 具体命令示例
1. gremlin语句
1# 同步执行gremlin
2./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph gremlin-execute --script 'g.V().count()'
3
4# 异步执行gremlin
5./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph gremlin-schedule --script 'g.V().count()'
2. 查看task情况
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph task-list
2
3./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph task-list --limit 5
4
5./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph task-list --status success
3. 图模式查看和设置
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-set -m RESTORING
2
3./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-get
4
5./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-list
4. 清理图
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-clear -c "I'm sure to delete all data"
5. 图备份
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph backup -t all --directory ./backup-test
6. 周期性的备份
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph schedule-backup -d ./backup --interval "*/2 * * * *"
7. 图恢复
1# 设置图模式
2./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-set -m RESTORING
3
4# 恢复图
5./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph restore -t all --directory ./backup-test
6
7# 恢复图模式
8./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph graph-mode-set -m NONE
8. 图迁移
1./bin/hugegraph --url http://127.0.0.1:8080 --graph hugegraph migrate --target-url http://127.0.0.1:8090 --target-graph hugegraph
说明

若在迁移的源图备份阶段发生数据页拉取失败,migrate 会立即中止退出且不会对目标图做任何变更写入。请检查 ./logs/ 下的分片诊断文件(*_shards),并确保重试时使用干净的目录。

3.2.6 - 图导出/迁移

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

3.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+

SeaTunnel 3.0+ 提供 HugeGraph Source,支持图模型自动发现和多标签读取。 并行扫描的后端要求和配置限制见官方 Source 文档。

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

使用 HugeGraph Helm 时,可按 Helm 中的 SeaTunnel 部署说明启动常驻单机或集群, 直接运行挂载的测试作业。跨环境迁移源图的连接地址与认证凭据需按实际环境配置。

1 迁移 HugeGraph 图(graph2graph)

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

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

需要保留普通边标签的 Schema ID 和索引定义时,可参考 Helm Chart 中的 Schema 复制及分标签示例。 其中的脚本遇到继承边 PARENT/SUB 会在访问目标图前退出,不会自动迁移继承关系。

跨图迁移示例目录结构

  • helm/hugegraph/examples/seatunnel/clone/
    • copy-schema.py读取源图并写入目标图 Schema(保留 Schema ID 与普通索引)
    • person.conf顶点数据迁移任务配置(CUSTOMIZE_STRING 保留原 ID)
    • knows.conf边数据迁移任务配置(依赖顶点 ID 一致性)
警告

含 DATE 属性时,先确认源 Server 的时区。 SeaTunnel 3.0.0 读取的 REST 日期字符串不带时区, 应在每个 Sink mappings 条目内设置与源 Server 一致的 timeZone,例如 timeZone = "UTC";不要依赖 worker 的默认时区。 Source 的 time_zone 不能修正这些字符串。Chart 的复制示例按源 Server 为 UTC 配置,非 UTC 源需要相应修改,并核对原始时间戳。

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

1.1 先迁移顶点

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

展开配置,保存为 config/graph2graph-person.conf
 1env {
 2  job.mode = "BATCH"
 3}
 4
 5source {
 6  HugeGraph {
 7    host = "source-hugegraph"
 8    port = 8080
 9    graph_name = "hugegraph"
10    graph_space = "DEFAULT"
11    label = "person"
12    label_type = "VERTEX"
13    schema = {
14      fields = {
15        name = "string"
16        age = "int"
17      }
18    }
19  }
20}
21
22sink {
23  HugeGraph {
24    host = "target-hugegraph"
25    port = 8080
26    graph_name = "hugegraph"
27    graph_space = "DEFAULT"
28    batch_failure_fallback = false
29    mappings = [
30      {
31        type = "VERTEX"
32        label = "person"
33        idStrategy = "CUSTOMIZE_STRING"
34        idFields = ["~id"]
35        properties = ["name", "age"]
36      }
37    ]
38  }
39}
1./bin/seatunnel.sh --config ./config/graph2graph-person.conf -m local

1.2 再迁移边

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

展开配置,保存为 config/graph2graph-knows.conf
 1env {
 2  job.mode = "BATCH"
 3}
 4
 5source {
 6  HugeGraph {
 7    host = "source-hugegraph"
 8    port = 8080
 9    graph_name = "hugegraph"
10    graph_space = "DEFAULT"
11    label = "knows"
12    label_type = "EDGE"
13    schema = {
14      fields = {
15        since = "int"
16      }
17    }
18  }
19}
20
21sink {
22  HugeGraph {
23    host = "target-hugegraph"
24    port = 8080
25    graph_name = "hugegraph"
26    graph_space = "DEFAULT"
27    check_vertex = true
28    batch_failure_fallback = false
29    mappings = [
30      {
31        type = "EDGE"
32        label = "knows"
33        sourceConfig = {
34          label = "person"
35          idFields = ["~source_id"]
36        }
37        targetConfig = {
38          label = "person"
39          idFields = ["~target_id"]
40        }
41        properties = ["since"]
42      }
43    ]
44  }
45}
1./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] 及其配置即可。

 1env {
 2  job.mode = "BATCH"
 3}
 4
 5source {
 6  HugeGraph {
 7    host = "hugegraph"
 8    port = 8080
 9    graph_name = "hugegraph"
10    graph_space = "DEFAULT"
11    label = "person"
12    label_type = "VERTEX"
13    schema = {
14      fields = {
15        name = "string"
16        age = "int"
17      }
18    }
19  }
20}
21
22sink {
23  LocalFile {
24    path = "/tmp/hugegraph-export/${table_name}"
25    file_format_type = "json"
26  }
27}

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

1./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 图导入文档

3.2.7 - HugeGraph-Spark-Connector 快速上手

1 HugeGraph-Spark-Connector 概述

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

目前尚未实现从 HugeGraph 读取数据:表只实现了 SupportsWrite,因此不支持 spark.read.format(...)。连接器支持 CUSTOMIZE 和 PRIMARY_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 不执行测试的编译

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

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

3.2 执行默认测试的编译

1mvn 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} 换成实际使用的发布版本:

1<dependency>
2    <groupId>org.apache.hugegraph</groupId>
3    <artifactId>hugegraph-spark-connector</artifactId>
4    <version>${revision}</version>
5</dependency>

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

4.1 Schema 定义示例

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

 1schema.propertyKey("name").asText().ifNotExist().create()
 2schema.propertyKey("age").asInt().ifNotExist().create()
 3schema.propertyKey("city").asText().ifNotExist().create()
 4schema.propertyKey("weight").asDouble().ifNotExist().create()
 5schema.propertyKey("lang").asText().ifNotExist().create()
 6schema.propertyKey("date").asText().ifNotExist().create()
 7schema.propertyKey("price").asDouble().ifNotExist().create()
 8
 9schema.vertexLabel("person")
10        .properties("name", "age", "city")
11        .useCustomizeStringId()
12        .nullableKeys("age", "city")
13        .ifNotExist()
14        .create()
15
16schema.vertexLabel("software")
17        .properties("name", "lang", "price")
18        .primaryKeys("name")
19        .ifNotExist()
20        .create()
21
22schema.edgeLabel("knows")
23        .sourceLabel("person")
24        .targetLabel("person")
25        .properties("date", "weight")
26        .ifNotExist()
27        .create()
28
29schema.edgeLabel("created")
30        .sourceLabel("person")
31        .targetLabel("software")
32        .properties("date", "weight")
33        .ifNotExist()
34        .create()

4.2 写入顶点数据(Scala)

 1val df = sparkSession.createDataFrame(Seq(
 2  Tuple3("marko", 29, "Beijing"),
 3  Tuple3("vadas", 27, "HongKong"),
 4  Tuple3("Josh", 32, "Beijing"),
 5  Tuple3("peter", 35, "ShangHai"),
 6  Tuple3("li,nary", 26, "Wu,han"),
 7  Tuple3("Bob", 18, "HangZhou"),
 8)) toDF("name", "age", "city")
 9
10df.show()
11
12df.write
13  .format("org.apache.hugegraph.spark.connector.DataSource")
14  .option("host", "127.0.0.1")
15  .option("port", "8080")
16  .option("graph", "hugegraph")
17  .option("data-type", "vertex")
18  .option("label", "person")
19  .option("id", "name")
20  .option("batch-size", 2)
21  .mode(SaveMode.Overwrite)
22  .save()

4.3 写入边数据(Scala)

 1val df = sparkSession.createDataFrame(Seq(
 2  Tuple4("marko", "vadas", "20160110", 0.5),
 3  Tuple4("peter", "Josh", "20230801", 1.0),
 4  Tuple4("peter", "li,nary", "20130220", 2.0)
 5)).toDF("source", "target", "date", "weight")
 6
 7df.show()
 8
 9df.write
10  .format("org.apache.hugegraph.spark.connector.DataSource")
11  .option("host", "127.0.0.1")
12  .option("port", "8080")
13  .option("graph", "hugegraph")
14  .option("data-type", "edge")
15  .option("label", "knows")
16  .option("source-name", "source")
17  .option("target-name", "target")
18  .option("batch-size", 2)
19  .mode(SaveMode.Overwrite)
20  .save()

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

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

 1val df = sparkSession.createDataFrame(Seq(
 2  Tuple4("lop", "java", 328L, "ISBN978-7-107-18618-5"),
 3  Tuple4("ripple", "python", 199L, "ISBN978-7-100-13678-5"),
 4)).toDF("name", "lang", "price", "ISBN")
 5
 6df.write
 7  .format("org.apache.hugegraph.spark.connector.DataSource")
 8  .option("host", "127.0.0.1")
 9  .option("port", "8080")
10  .option("graph", "hugegraph")
11  .option("data-type", "vertex")
12  .option("label", "software")
13  .option("ignored-fields", "ISBN")
14  .option("batch-size", 2)
15  .mode(SaveMode.Overwrite)
16  .save()

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

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

 1val df = sparkSession.createDataFrame(Seq(
 2  Tuple4("marko", "lop", "20171210", 0.5),
 3  Tuple4("Josh", "lop", "20091111", 0.4),
 4  Tuple4("peter", "ripple", "20171210", 1.0),
 5  Tuple4("vadas", "lop", "20171210", 0.2)
 6)).toDF("source", "name", "date", "weight")
 7
 8df.write
 9  .format("org.apache.hugegraph.spark.connector.DataSource")
10  .option("host", "127.0.0.1")
11  .option("port", "8080")
12  .option("graph", "hugegraph")
13  .option("data-type", "edge")
14  .option("label", "created")
15  .option("source-name", "source") // 自定义 id
16  .option("target-name", "name")   // 主键
17  .option("batch-size", 2)
18  .mode(SaveMode.Overwrite)
19  .save()

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

5 配置参数

选项名匹配时不区分大小写并会去掉首尾空格。data-type 和 label 必填;当 data-type 为 edge 时 source-name 和 target-name 必填;其余选项都有默认值。

5.1 客户端配置

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

参数默认值说明
hostlocalhostHugeGraphServer 的地址,可以是主机名或 IP,也可以带 http:// / https:// 前缀
port8080HugeGraphServer 的端口
graphhugegraph图名称
protocolhttp向服务器发送请求的协议,可选 http 或 https
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必填。图数据类型,必须是 vertex 或 edge
label必填。要导入的顶点/边数据所属的标签
id指定某一列作为顶点的 id 列。当顶点 id 策略为 CUSTOMIZE 时,必填;当 id 策略为 PRIMARY_KEY 时,必须为空。不支持 AUTOMATIC id 策略
source-name当 data-type 为 edge 时必填。选择输入源的某些列作为源顶点的 id 列。当源顶点的 id 策略为 CUSTOMIZE 时,必须指定某一列作为顶点的 id 列;当源顶点的 id 策略为 PRIMARY_KEY 时,必须指定一列或多列用于拼接生成顶点的 id,即无论使用哪种 id 策略,此项都是必填的。多列之间用 , 分隔(delimiter 选项对此项不生效)
target-name当 data-type 为 edge 时必填。指定某些列作为目标顶点的 id 列,与 source-name 类似
selected-fields选择某些列进行插入,其他未选择的列不插入,不能与 ignored-fields 同时存在
ignored-fields忽略某些列使其不参与插入,不能与 selected-fields 同时存在
batch-size500导入数据时每批数据的条目数。按 Spark task 生效:每个分区的写入器在缓冲区累积到该数量的顶点/边时向服务端提交一次,commit 时再提交剩余部分

5.3 通用配置

通用配置包含一些常用的配置项。

参数默认值说明
delimiter,selected-fields 和 ignored-fields 的分隔符。source-name 和 target-name 始终按 , 拆分

6 注意事项与限制

  • 每个 Spark 写入 task 会创建自己的 HugeClient,写入前把图切换到 LOADING 模式,commit 或 abort 时恢复为 NONE 模式。
  • 顶点 id 长度限制为 128 字节(UTF-8),对自定义字符串 id 和由主键拼接出的 id 都生效。
  • 不支持 AUTOMATIC 顶点 id 策略,创建写入器时会抛出 IllegalArgumentException,写入失败。
  • 暂不支持 SET 或 LIST 基数的属性,只会转换 SINGLE 基数的值。
  • 日期属性:字符串值必须使用 yyyy-MM-dd HH:mm:ss 格式,按 GMT+8 时区解析;数值会被当作毫秒时间戳。
  • 以字符串形式给出的布尔属性接受 true、1、yes、y 和 false、0、no、n(不区分大小写)。
  • 自定义字符串 id 或任一主键值为空字符串的行会被跳过;为 null 时则会报错。

7 许可证

与 HugeGraph 一样,hugegraph-spark-connector 也采用 Apache 2.0 许可证。

3.3 - HugeGraph-AI

hugegraph-ai 提供 HugeGraph 的 Python 客户端、图机器学习工具,以及面向知识图谱构建和 GraphRAG 的 LLM 工具。

Apache License 2.0 · Ask DeepWiki

模块

  • hugegraph-llm-sdk:提供 Schema 设计、结构校验与属性图抽取审阅的独立 Python SDK。
  • hugegraph-mcp:通过 MCP 向 AI 客户端提供图查询、Schema 和受控写入工具。
  • hugegraph-llm:知识图谱构建、GraphRAG 和自然语言图查询。
  • hugegraph-ml:从 HugeGraph 读取图数据并运行图学习模型。
  • hugegraph-python-client:管理 Schema、图数据和 Gremlin 查询的 Python SDK。
  • vermeer-python-client:调用 Vermeer 图计算服务的 Python SDK。

仓库使用 uv workspace,其成员是 hugegraph-llm-sdk、hugegraph-llm 和 hugegraph-python-client。hugegraph-ml 和 vermeer-python-client 是可编辑的路径依赖,不在 workspace members 中。当前仓库版本为 1.8.0。客户端源码目录叫 hugegraph-python-client,但发行包名是 hugegraph-python。

环境要求

  • HugeGraph-AI 根目录 workspace:Python >= 3.12(支持 Python 3.12–3.14)
  • HugeGraph-LLM 与 HugeGraph-LLM-SDK:Python >= 3.12(支持 Python 3.12–3.14)
  • HugeGraph-ML:Python 3.10 或更高版本
  • PyPI 上的 hugegraph-python 1.5.0:Python 3.9 或更高版本;当前仓库源码随 workspace 使用 Python >= 3.12
  • Vermeer Python 客户端:当前源码要求 Python 3.10 或更高版本;发行元数据仍声明 >=3.9,详见客户端页
  • uv 0.7 或更高版本
  • HugeGraph Server 1.5.0 或更高版本;当前 workspace 的 Python 客户端会拒绝可探测到的更低版本

可选依赖组

根项目为每个模块声明一个 extra,另有几个组合项:

Extra安装内容
llmhugegraph-llm
mlhugegraph-ml
python-clienthugegraph-python(源码目录 hugegraph-python-client)
vermeervermeer-python-client
devpytest、pytest-cov、coverage、pylint、ruff、mypy、ty、pre-commit
nk-llmhugegraph-llm、hugegraph-python-client,以及编译镜像所需的 Nuitka
all四个模块包

hugegraph-llm 自身还声明了 vectordb extra,用于安装 pymilvus 和 qdrant-client。

Docker Compose 部署

仓库提供同时启动 HugeGraph Server 和 RAG 服务的 Compose 文件:

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3cp docker/env.template docker/.env
4# 编辑 docker/.env,将 PROJECT_PATH 改为当前仓库的绝对路径
5touch hugegraph-llm/.env
6# 在 hugegraph-llm/.env 中设置 GRAPH_URL=server:8080,并填写匹配 Server 的账号
7cd docker
8docker compose -f docker-compose-network.yml up -d

默认地址:

  • HugeGraph Server:http://localhost:8080
  • RAG 服务和 Web 界面:http://localhost:8001

从源码启动 RAG 服务

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3uv sync --extra llm
4source .venv/bin/activate
5cd hugegraph-llm
6python -m hugegraph_llm.demo.rag_demo.app

uv sync 会在仓库根目录创建 .venv。从根目录安装可让 uv 一起解析 workspace 成员和路径依赖。当前仓库不跟踪 uv.lock;uv sync 会按 pyproject.toml 中的依赖声明和版本约束解析依赖。

安装 ML 依赖

1cd hugegraph-ai
2uv sync --extra ml
3source .venv/bin/activate
4cd hugegraph-ml/src

示例脚本位于 hugegraph-ml/src/hugegraph_ml/examples/。

后续阅读

3.3.1 - HugeGraph-LLM

HugeGraph-LLM 用于知识图谱构建、GraphRAG 和自然语言图查询。演示服务把 Gradio 页面和 FastAPI 接口挂在同一个进程上,直接从源码启动时默认只监听本机 127.0.0.1:8001,可用 http://localhost:8001 访问。若显式启动源码入口且只需本机访问,可指定 --host 127.0.0.1;源码 Docker 镜像的 Dockerfile.llm 会覆盖默认值并监听 0.0.0.0:8001,不要在容器内改为 loopback,否则容器外无法通过映射端口访问。

警告

生产环境必须为 HugeGraph-LLM 启用自身的登录认证(ENABLE_LOGIN=True,并替换 USER_TOKEN、ADMIN_TOKEN),同时在防火墙或网络入口设置来源 IP 白名单。HugeGraph Server 还必须单独开启认证与授权(见认证与授权说明)并保留 Server 审计日志(标准日志文件为 audit-*.log),为 GRAPH_USER 配置只具备该服务所需权限的账号。AI 服务 token 只认证 LLM 页面和 API,不能替代 HugeGraph Server 认证。

环境要求

AI 总结项目文档:Ask DeepWiki

  • Python >= 3.12(支持 Python 3.12–3.14)
  • uv 0.7 或更高版本
  • HugeGraph Server 1.5.0 或更高版本;当前 workspace 中的 Python 客户端会拒绝可探测到的更低版本

支持以下部署与运行方式:

Docker Compose 部署

在 HugeGraph-AI 仓库根目录准备环境文件:

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3cp docker/env.template docker/.env
4# 编辑 docker/.env,将 PROJECT_PATH 改为当前仓库的绝对路径
5touch hugegraph-llm/.env
6# 编辑 hugegraph-llm/.env:GRAPH_URL=server:8080,并设置与 Server 相符的 GRAPH_USER、GRAPH_PWD
7cd docker
8docker compose -f docker-compose-network.yml up -d
9docker 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 也可以用同样方式挂载,该挂载默认被注释掉。

应用读取 GRAPH_URL,Compose 注入的 HUGEGRAPH_HOST 和 HUGEGRAPH_PORT 不会覆盖它;因此容器内要将 GRAPH_URL 设为 server:8080,并在 .env 中配置匹配 HugeGraph Server 的用户名和密码。

容器镜像

镜像构建文件内容
docker/Dockerfile.llm源码运行镜像构建配方,入口是 python -m hugegraph_llm.demo.rag_demo.app --host 0.0.0.0 --port 8001
docker/Dockerfile.nk基于 nk-llm extra 用 Nuitka 编译的二进制镜像构建配方,入口是 ./app.dist/app.bin

Compose 文件引用未指定标签的 hugegraph/rag,Docker 会使用默认的 latest 标签。scripts/build_llm_image.sh 则以 docker/Dockerfile.llm 在本地构建 hugegraph/graphrag:1.7.0。Compose 引用的 hugegraph/rag:latest 与本地构建的 hugegraph/graphrag:1.7.0 是不同镜像;本地构建不会自动替换 Compose 所用镜像。要在 Compose 中运行本地构建结果,需将 Compose 的 image 改为 hugegraph/graphrag:1.7.0。该脚本只构建镜像,不会推送。两个 Dockerfile 都声明 8001 端口、以非 root 用户 work 运行,并用 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 只部署 RAG 服务,不会部署 HugeGraph Server。挂载的 .env 中要把 GRAPH_URL 设为 Pod 可访问的 HugeGraph 地址,并配置匹配的用户名和密码。

chart 中 image.tag 仍默认为 v0.0.1。当前构建脚本生成的标签是本地 hugegraph/graphrag:1.7.0;部署前须确保同名镜像已推送到集群可访问的仓库,或已加载到集群节点,并将 chart 的标签和拉取策略设为匹配的值。

chart 的 values.yaml 中,.env 和提示词 YAML 的挂载默认被注释掉。提示词 YAML 可用 ConfigMap;.env 可能含有密钥和密码,应使用 Secret,并把 volumes 中 env-config 的 configMap 改为 secret。Secret 和提示词 ConfigMap 可分别创建:

1kubectl create secret generic hugegraph-llm-env --from-file=.env=/path/to/.env
2kubectl create configmap hugegraph-llm-prompt-config --from-file=/path/to/config_prompt.yaml

随后取消 volumeMounts 段落的注释,并按需要启用提示词 ConfigMap 的 volumes 和挂载。Helm 模板会直接渲染 values.yaml 中的卷定义。

从源码启动

  1. 克隆源代码仓库:

    1git clone https://github.com/apache/hugegraph-ai.git
    2cd hugegraph-ai
  2. 安装依赖并激活虚拟环境:

    1uv sync --extra llm
    2source .venv/bin/activate
  3. 启动 Web 应用服务:

    1cd hugegraph-llm
    2python -m hugegraph_llm.demo.rag_demo.app

自定义监听地址和端口:

1python -m hugegraph_llm.demo.rag_demo.app \
2  --host 127.0.0.1 \
3  --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 下拉框可在抽取前选择 document、paragraph 或 sentence 粒度。

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 可选 Faiss、Milvus 或 Qdrant,Web 页面的 5. Set up the vector engine. 面板提供同样的选择。Milvus 和 Qdrant 需要安装可选依赖:

1cd hugegraph-ai
2uv sync --package hugegraph-llm --extra vectordb

页面操作流程见使用流程,完整环境变量见配置参考,HTTP 请求格式见REST API。

程序化调用

原有的 RAGPipeline 和 KgBuilder 类已被流水线调度器取代。通过 SchedulerSingleton 按名称调用流程:

 1from hugegraph_llm.flows.scheduler import SchedulerSingleton
 2
 3scheduler = SchedulerSingleton.get_instance()
 4res = scheduler.schedule_flow(
 5    "rag_graph_only",
 6    query="Tell me about Al Pacino.",
 7    graph_only_answer=True,
 8    vector_only_answer=False,
 9    raw_answer=False,
10    gremlin_tmpl_num=-1,
11    gremlin_prompt=None,
12)
13print(res.get("graph_only_answer"))

已注册的流程名包括 rag_raw、rag_vector_only、rag_graph_only、rag_graph_vector、text2gremlin、build_examples_index、build_vector_index、graph_extract、import_graph_data、update_vid_embeddings、get_graph_index_info、build_schema 和 prompt_generate。schedule_stream_flow 是对应的异步流式版本。

开发检查

先在仓库根目录安装模块和开发工具,再运行与 CI 一致的检查:

 1cd hugegraph-ai
 2uv sync --extra llm --extra dev
 3uv run ruff format --check .
 4uv run ruff check .
 5
 6cd hugegraph-llm
 7SKIP_EXTERNAL_SERVICES=true uv run pytest src/tests/config/ src/tests/document/ src/tests/middleware/ \
 8  src/tests/operators/ src/tests/models/ src/tests/indices/ src/tests/test_utils.py -v --tb=short
 9SKIP_EXTERNAL_SERVICES=true uv run pytest src/tests/integration/test_graph_rag_pipeline.py \
10  src/tests/integration/test_kg_construction.py src/tests/integration/test_rag_pipeline.py -v --tb=short

Git hook 通过 pre-commit 启用:

1cd hugegraph-ai
2pre-commit install
3pre-commit run --all-files

3.3.2 - HugeGraph-ML

HugeGraph-ML 从 HugeGraph 读取图数据并转换为 DGL 图,供节点嵌入、节点分类、图分类、链接预测和欺诈检测等任务使用。模型实现位于 hugegraph-ml/src/hugegraph_ml/models/。

环境要求

  • Python 3.10 或更高版本
  • HugeGraph Server 1.5.0 或更高版本;当前 workspace 中的 Python 客户端会拒绝可探测到的更低版本
  • 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 或 CUDA 构建。支持 gpu 参数的任务默认值 -1 表示使用 CPU;使用 GPU 时,需要安装彼此兼容的 CUDA 版 torch 和 dgl。

安装

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3uv sync --extra ml
4source .venv/bin/activate
5cd hugegraph-ml/src

HugeGraph-ML 是根项目的路径依赖,但不属于 uv workspace members。应在仓库根目录选择 ml extra,让 uv 按 workspace 配置安装它及其本地客户端依赖。

已实现模型

下列模块均位于 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.pyMLP、CorrectAndSmooth、LabelPropagation对基础预测结果做校正与平滑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.pyDGCNN、SEALData链接预测1802.09691

GIN 的 pooling 参数可取 sum(默认)、mean、max、global_attention 和 set2set。

读取图数据

hugegraph-ml/src/hugegraph_ml/data/hugegraph2dgl.py 中的 HugeGraph2DGL 会创建 PyHugeClient,并把查询结果转换为 DGL 对象:

1from hugegraph_ml.data.hugegraph2dgl import HugeGraph2DGL
2
3hg2d = HugeGraph2DGL(
4    url="http://127.0.0.1:8080",
5    graph="hugegraph",
6    user="",
7    pwd="",
8    graphspace=None,
9)
方法返回值说明
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_graphs、max_n_nodes、n_feat_dim、n_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 只要求 feat;NodeClassify、NodeClassifyWithEdge 和 NodeClassifyWithSample 要求 feat、label、train_mask、val_mask 和 test_mask,缺少任意一项都会抛出 ValueError。

导入示例数据集

hugegraph_ml.utils.dgl2hugegraph_utils 负责把 DGL、OGB 和 NetworkX 数据集写入 HugeGraph,供转换层读取。这些函数都接受与 HugeGraph2DGL 相同的 url、graph、user、pwd 和 graphspace 参数,并且多数会先把数据集名转为大写再匹配。

函数支持的数据集创建的标签
import_graph_from_dglCORA、CITESEER、PUBMED<NAME>_vertex、<NAME>_edge
import_graphs_from_dglMUTAG、COLLAB、NCI1、PROTEINS、PTC、ENZYMES、DD<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_featCORA、CITESEER、PUBMED<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 先调用它,再导入 CORA、MUTAG 和 ACM,结束时再次调用。

AMAZONGATNE 和 AVAZU 不会自动下载,压缩包地址写在 import_hetero_graph_from_dgl_no_feat 和 import_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.py先 train(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 可以监控 loss 或 accuracy,保存最优权重并在训练结束时恢复。

可运行示例

脚本位于 hugegraph-ml/src/hugegraph_ml/examples/。在 hugegraph-ml/src 目录下执行:

1python ./hugegraph_ml/examples/dgi_example.py

每个脚本同时提供同名函数,可以导入后用较小的 epoch 数调用。

脚本模型任务读取的标签
agnn_example.pyAGNNNodeClassifyCORA_vertex、CORA_edge
appnp_example.pyAPPNPNodeClassifyCORA_vertex、CORA_edge
arma_example.pyARMA4NCNodeClassifyCORA_vertex、CORA_edge
bgnn_example.pyBGNNPredictor模型自带的 fit()AVAZU__N_v、AVAZU__E_e
bgrl_example.pyBGRLNodeEmbed、NodeClassifyCORA_vertex、CORA_edge
care_gnn_example.pyCAREGNNDetectorCaregnnAMAZON_user_v 以及 AMAZON_net_upu_e、AMAZON_net_usu_e、AMAZON_net_uvu_e
cluster_gcn_example.pySAGENodeClassifyWithSampleCORA_vertex、CORA_edge
correct_and_smooth_example.pycorrect_and_smooth 中的 MLPNodeClassifyCORA_vertex、CORA_edge
dagnn_example.pyDAGNNNodeClassifyCORA_vertex、CORA_edge
deepergcn_example.pyDeeperGCNNodeClassifyWithEdge通过 convert_graph_with_edge_feat 读取 CORA_vertex、CORA_edge
dgi_example.pyDGINodeEmbed、NodeClassifyCORA_vertex、CORA_edge
diffpool_example.pyDiffPoolGraphClassifyMUTAG_graph_vertex、MUTAG_vertex、MUTAG_edge
gatne_example.pyDGLGATNEHeteroSampleEmbedGATNEAMAZONGATNE__N_v、AMAZONGATNE_1_e、AMAZONGATNE_2_e
gin_example.pyGINGraphClassifyMUTAG_graph_vertex、MUTAG_vertex、MUTAG_edge
grace_example.pyGRACENodeEmbed、NodeClassifyCORA_vertex、CORA_edge
grand_example.pyGRANDNodeClassifyCORA_vertex、CORA_edge
jknet_example.pyJKNetNodeClassifyCORA_vertex、CORA_edge
pgnn_example.pyPGNNLinkPredictionPGNNCAVEMAN_vertex、CAVEMAN_edge
seal_example.pyDGCNNLinkPredictionSealogbl-collab_vertex、ogbl-collab_edge、ogbl-collab_split_edge

DGI 节点嵌入示例

先把 DGL 的 Cora 数据集导入 HugeGraph。数据集名会先转为大写,因此 cora 和 CORA 都会生成 CORA_vertex 和 CORA_edge 标签:

1from hugegraph_ml.utils.dgl2hugegraph_utils import import_graph_from_dgl
2
3import_graph_from_dgl("cora")

读取图并训练 DGI:

 1from hugegraph_ml.data.hugegraph2dgl import HugeGraph2DGL
 2from hugegraph_ml.models.dgi import DGI
 3from hugegraph_ml.models.mlp import MLPClassifier
 4from hugegraph_ml.tasks.node_classify import NodeClassify
 5from hugegraph_ml.tasks.node_embed import NodeEmbed
 6
 7hg2d = HugeGraph2DGL()
 8graph = hg2d.convert_graph(
 9    vertex_label="CORA_vertex",
10    edge_label="CORA_edge",
11)
12
13embed_model = DGI(n_in_feats=graph.ndata["feat"].shape[1])
14embed_task = NodeEmbed(graph=graph, model=embed_model)
15embedded_graph = embed_task.train_and_embed(
16    add_self_loop=True,
17    n_epochs=300,
18    patience=30,
19)
20
21classifier = MLPClassifier(
22    n_in_feat=embedded_graph.ndata["feat"].shape[1],
23    n_out_feat=embedded_graph.ndata["label"].unique().shape[0],
24)
25classify_task = NodeClassify(graph=embedded_graph, model=classifier)
26classify_task.train(lr=1e-3, n_epochs=400, patience=40)
27print(classify_task.evaluate())

evaluate() 返回类似 {'accuracy': 0.82, 'loss': 0.5714246034622192} 的字典。完整脚本是 hugegraph-ml/src/hugegraph_ml/examples/dgi_example.py。

GRAND 节点分类示例

 1from hugegraph_ml.data.hugegraph2dgl import HugeGraph2DGL
 2from hugegraph_ml.models.grand import GRAND
 3from hugegraph_ml.tasks.node_classify import NodeClassify
 4
 5hg2d = HugeGraph2DGL()
 6graph = hg2d.convert_graph(
 7    vertex_label="CORA_vertex",
 8    edge_label="CORA_edge",
 9)
10model = GRAND(
11    n_in_feats=graph.ndata["feat"].shape[1],
12    n_out_feats=graph.ndata["label"].unique().shape[0],
13)
14task = NodeClassify(graph, model)
15task.train(lr=1e-2, weight_decay=5e-4, n_epochs=2000, patience=100)
16print(task.evaluate())

GRAND 每次增强采样都会返回一组 logits,NodeClassify 会对列表中的每个元素分别应用掩码后再计算损失。完整脚本是 hugegraph-ml/src/hugegraph_ml/examples/grand_example.py。

排查问题

  • 连接失败:检查 HugeGraph Server 地址、端口和认证信息。
  • Schema 不匹配:示例默认使用 CORA_vertex 和 CORA_edge,自有数据需要传入实际标签。
  • ValueError: Graph is missing required node attribute ...:节点分类任务需要 ndata 中包含 feat、label、train_mask、val_mask 和 test_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.3 - HugeGraph-LLM 使用流程

本页按 Web 页面的操作顺序,说明如何建立索引、查询文档和生成 Gremlin。服务启动方式见 HugeGraph-LLM。

先准备可连接的 HugeGraph Server、生成模型和 Embedding 模型。查看配置或在 Graph Tools 手写 Gremlin 不需要模型; 文档向量化需要 Embedding,图数据抽取和答案生成还需要 LLM。Reranker 可选,初次运行可用本地 bleu。

想做什么页面入口需要准备什么
从文档建立索引1. Build RAG Index文档、Embedding;抽取图数据还需 Schema 和 LLM
根据文档或图回答问题2. (Graph)RAG & User Functions对应索引和 LLM
把问题转成 Gremlin3. Text2gremlin图 Schema、LLM;引用示例还需 Embedding 和示例索引
直接验证图数据4. Graph ToolsHugeGraph 连接和手写 Gremlin

本文截图基于 HugeGraph-LLM Web 界面,示例包含中英文提示词模式(通过环境变量 LANGUAGE 切换内置提示词语言,界面控件保持英文)。

源码启动时缺少批量问题模板

若启动时报 FileNotFoundError,且缺少的文件为 questions_template.xlsx,在已安装依赖的仓库根目录创建输入模板后重启。 已有文件会保留。模板包含完整的 6 列,只填写测试问题和预期答案,4 个模型回答列留空。

 1uv run --extra llm python - <<'PYTHON'
 2from pathlib import Path
 3from openpyxl import Workbook
 4
 5path = Path("hugegraph-llm/src/hugegraph_llm/resources/demo/questions_template.xlsx")
 6if not path.exists():
 7    workbook = Workbook()
 8    sheet = workbook.active
 9    sheet.append([
10        "Question", "Expected Answer", "Basic LLM Answer",
11        "Vector-only Answer", "Graph-only Answer", "Graph-Vector Answer",
12    ])
13    sheet.append(["Who is Sarah?", "Sarah is a 30-year-old attorney.", None, None, None, None])
14    workbook.save(path)
15PYTHON

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。页面顶部还会显示当前提示词语言。

在 LLM 配置的 chat、mini_tasks、text2gql 子页分别设置回答、抽取和查询生成模型。 截图使用本地 Ollama 的 qwen2.5:3b 和 mxbai-embed-large,向量引擎为 Faiss。 更换 Embedding 模型后需重建索引,避免新旧向量维数或含义不同。

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,可一次选择多个文件。

首次尝试可以使用下面的短文,填入 Input Doc(s)。请先选择专用测试图,避免将示例写入业务图。

1Sarah is a 30-year-old attorney. James is a journalist. Sarah has been James's roommate since 2010.

将下面的 JSON 填入 Graph Schema,保留默认抽取提示词。它只允许抽取人物及室友关系,年龄和职业可为空。

 1{
 2  "vertexlabels": [
 3    {"id": 1, "name": "person", "id_strategy": "PRIMARY_KEY",
 4     "primary_keys": ["name"], "properties": ["name", "age", "occupation"],
 5     "nullable_keys": ["age", "occupation"]}
 6  ],
 7  "edgelabels": [
 8    {"name": "roommate", "source_label": "person", "target_label": "person", "properties": ["date"]}
 9  ],
10  "propertykeys": [
11    {"name": "name", "data_type": "TEXT", "cardinality": "SINGLE"},
12    {"name": "age", "data_type": "INT", "cardinality": "SINGLE"},
13    {"name": "occupation", "data_type": "TEXT", "cardinality": "SINGLE"},
14    {"name": "date", "data_type": "TEXT", "cardinality": "SINGLE"}
15  ]
16}

页面包含文档、Schema、抽取提示词和结果区域。按下面的顺序建立图索引。只用向量检索时,完成第 1 步即可。

  1. 点击 Import into Vector,切分文档并建立 chunk 向量索引。
  2. 在 Graph Schema 填入 Schema JSON 或已有图名,再点击 Extract Graph Data (1)。检查 Output Info 中的顶点、边和属性。
  3. 确认抽取结果后点击 Load into GraphDB (2),写入 HugeGraph 并更新顶点向量。
  4. 打开 Graph Tools,执行 g.V().count() 和 g.E().count(),再查具体属性,确认数据已写入。

本例应得到 2 个顶点和 1 条边,Sarah 的年龄为 30,职业为 attorney。 图里已经有数据时,可以单独点击 Update Vid Embedding 更新顶点索引。

这些按钮旁的 Graph Extraction Split Type 下拉框可选 document、paragraph 或 sentence。document 把输入整体作为一个单元,另外两种会在抽取前先切分长文档。

页面还可以查看或清除 chunk 索引、顶点索引和图数据。清除操作会删除已有数据,执行前先确认当前图和索引是否仍被其他查询使用。

主控件下方还有两个折叠的辅助工具。

  • Graph Schema Generator 根据查询示例和少样本示例生成 Schema,填入 Graph Schema 字段。
  • Graph Extraction Prompt Generator 根据期望场景(例如社交关系、金融知识图谱)和选定的参考示例生成 Graph Extract Prompt Header。

2. GraphRAG 查询

第二个标签页提供四种回答范围,按需要选择对应索引。

控件回答依据
Basic LLM Answer直接调用 LLM,不查询文档或图
Vector-only Answerchunk 向量检索结果
Graph-only Answer图检索结果
Graph-Vector Answer图与 chunk 向量检索结果

推荐优先使用 Graph-Vector Answer,同时结合图数据检索与文档向量索引以获得更完整的事实支撑。其他范围的控件含义见上表。

截图使用下面的简短提示词。分别填入 Query Prompt 和 Keywords Extraction Prompt,其中占位符会由服务替换。 关键词输出需使用代码块中的英文前缀和冒号,姓名的大小写应与图数据一致。

1只根据检索到的上下文,用中文简洁回答问题,保留原文中的姓名。上下文不足时说明缺少信息。
2上下文: {context_str}
3问题: {query_str}
1从问题中提取人名,保留姓名原有的大小写,最多输出 {max_keywords} 个。
2只返回一行,严格使用英文冒号,格式为 KEYWORDS:姓名:1.0
3问题: {question}
  1. 输入 Who is Sarah?,将 Graph-only Answer 设为 False,Graph-Vector Answer 设为 True。
  2. 初次验证时保留 Template Num=-1 和 Rerank method=bleu,点击 Answer Question。
  3. 查看 Graph-Vector Answer,将答案中的职业、年龄等事实与原文和图数据核对。
flowchart TD
    Q[问题] --> V[查询 chunk 向量索引]
    Q --> K[抽取关键词]
    K --> M[匹配图顶点]
    M --> D{启用 Text2Gremlin}
    D -->|是| T[生成并执行 Gremlin]
    D -->|否| B[BFS 图遍历]
    T -->|失败| B
    T --> R[整理图结果]
    B --> R
    V --> S[合并与重排序]
    R --> S
    S --> A[生成答案]

图召回先用关键词精确匹配 HugeGraph 顶点,找不到时再用顶点向量做近似匹配。匹配结果会进入 Text2Gremlin;生成或执行失败时,流程可以回退到预定义的图遍历。

Template Num 控制 Text2Gremlin 在图召回中的参与方式。

  • 小于 0 时,完全跳过 Text2Gremlin,图召回直接使用预定义的图遍历。
  • 等于 0 时,不检索参考示例,使用基础生成结果。
  • 大于 0 时,从示例索引中取相应数量的相近示例,并采用带模板的生成结果。示例数量会被限制在 0 到 10 之间。

该标签页的其他控件还有 Rerank method(bleu 或 reranker)、Graph Ratio、Near neighbor first 和 Query related information,以及可编辑的 Query Prompt 和 Keywords Extraction Prompt。

单条问答面板下方是批量回归测试面板。上传 .xlsx 或 .csv 问题文件,设置 Max Lines To Show,点击 Generate Answer (Batch)。答案会显示在预览表格中,并可下载为文件。上传控件旁提供模板文件下载。

3. Text2Gremlin

第三个标签页将自然语言转换为 Gremlin,并执行生成的查询。上半部分用 .json 或 .csv 的问题与 Gremlin 对建立示例向量索引; 未上传文件时使用内置的 resources/demo/text2gremlin.csv。示例中的标签和属性应与当前图一致。

提示

若上传 CSV 构建示例向量索引后未自动召回示例模板,可直接在下面的 Prompt 模板中手动提供 Few-shot 参考示例。

复现 Sarah 查询时,使用以下输入。

  1. 将下面的 CSV 保存为 sarah-gremlin.csv,上传后点击 Build Example Vector Index,并把 Number of refer examples 设为 1。
  2. 在 Schema 填入下方的简化 Schema,只保留查询所需的类型与属性。
  3. 在 Prompt 填入下方的提示词,输入问题 Who is Sarah?,再点击 Text2Gremlin。
  4. 检查生成语句及两组 Query ... Output。本例返回 Sarah 的 age=30 和 occupation=attorney。
1query,gremlin
2Who is Sarah?,"g.V().has('person', 'name', 'Sarah').valueMap()"
1{"vertexlabels":[{"name":"person","properties":["name","age","occupation"]}],"edgelabels":[]}
 1把问题转换为 HugeGraph 的只读 Gremlin 查询。
 2按人物姓名查询时,使用 g.V().has('person', 'name', '<问题中的姓名>').valueMap()。
 3保留姓名的大小写,按姓名查询,不使用顶点 ID。
 4问题示例: Who is Peter?
 5Gremlin 示例: g.V().has('person', 'name', 'Peter').valueMap()
 6图 Schema: {schema}
 7其他示例: {example}
 8已知顶点: {vertices}
 9问题: {query}
10只返回一个 ```gremlin``` 代码块。

小模型可能生成错误 ID、大小写不符的姓名或不满足索引条件的过滤语句。应查看执行结果中的具体数据,再判断查询是否成功。 Web 页面会直接执行生成的语句,请使用专用测试图。需要只生成语句时,在 REST API 中选择相应输出类型。

自定义提示词必须保留 {query}、{schema}、{example} 和 {vertices}。缺少任一占位符时,REST API 会拒绝请求。

4. 图工具与管理工具

Graph Tools 标签页可直接对当前图执行 Gremlin 查询、手动触发图备份,并通过 beta 操作初始化 HugeGraph 演示数据。后台还有两个任务,每天凌晨 1 点自动备份图数据,以及在进程运行期间持续更新顶点 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。

警告

生产环境必须启用 HugeGraph-LLM 自身的登录认证,并替换 USER_TOKEN 和 ADMIN_TOKEN,同时在防火墙或网络入口设置来源 IP 白名单。HugeGraph Server 还必须单独开启认证与授权(见认证与授权说明)并保留 Server 审计日志(标准日志文件为 audit-*.log),为 GRAPH_USER 配置最小必要权限。AI 服务 token 不会替代 HugeGraph Server 认证。

5. 提示词语言

在 hugegraph-llm/.env 中选择一种提示词语言。

1# 英文提示词
2LANGUAGE=EN
3
4# 中文提示词
5LANGUAGE=CN

修改后重启服务。该配置选择内置提示词语言,不会自动翻译输入文档,也不属于 /rag 请求体字段。

6. REST 调用

Web 页面和 REST API 使用同一套流程。需要程序集成时使用 /rag、/rag/graph、/graph/extract 和 /text2gremlin;请求结构见 REST API。

3.3.4 - 配置参考

HugeGraph-LLM 从 .env 读取运行配置,提示词单独保存在 config_prompt.yaml。两者使用不同的路径解析规则;不要把提示词文件当作 .env 的一部分。

.env 路径按以下顺序解析:

  1. 若设置了环境变量 HUGEGRAPH_LLM_ENV_PATH,则使用该路径,开头的 ~ 会被展开。
  2. 从源码运行时,使用 hugegraph-llm/.env。
  3. 以已安装的包运行时,使用当前工作目录下的 .env。

该路径在导入配置模块时确定。设置 HUGEGRAPH_LLM_ENV_PATH 时,需在启动 Python 进程前设置;不能只把它写进将要读取的 .env 文件。覆盖路径使用相对路径时,以进程当前工作目录为基准。

提示词 YAML 路径按以下顺序解析:

  1. 若进程环境中设置了 HUGEGRAPH_LLM_PROMPT_CONFIG_PATH,使用该路径,并展开开头的 ~。
  2. 从源码运行时,使用 hugegraph-llm/src/hugegraph_llm/resources/demo/config_prompt.yaml。
  3. 以已安装的包运行时,使用 ${XDG_CONFIG_HOME:-~/.config}/hugegraph-llm/config_prompt.yaml。

覆盖路径的环境变量也要在进程启动前设置。相对路径以进程当前工作目录为基准。源码 Docker 镜像通过 PYTHONPATH 指向源码目录,因此默认提示词路径仍位于 hugegraph-llm/src/hugegraph_llm/resources/demo/。

运行以下命令可按配置类的默认值创建或更新文件:

1cd hugegraph-ai/hugegraph-llm
2python -m hugegraph_llm.config.generate --update

--update 默认开启,因此不带参数运行效果相同。配置模块首次导入时会为缺失的 .env 和提示词 YAML 按默认值创建文件;文件已存在时,生成器会交互询问是否覆盖。该命令会处理 HugeGraph、管理员、LLM、索引配置及提示词 YAML,不会在无确认的情况下覆盖已有文件。

.env 包含密钥和密码,不要提交到版本库。

基础选项

配置项默认值说明
LANGUAGEEN提示词语言,可选 EN、CN
CHAT_LLM_TYPEopenai回答模型,可选 openai、litellm、ollama/local
EXTRACT_LLM_TYPEopenai信息抽取模型,取值同上
TEXT2GQL_LLM_TYPEopenaiText2Gremlin 模型,取值同上
EMBEDDING_TYPEopenai嵌入模型,取值同上,也可以留空
RERANKER_TYPE空可选 cohere、siliconflow
KEYWORD_EXTRACT_TYPEllm可选 llm、textrank、hybrid
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_URL 和 OPENAI_API_KEY 可作为通用回退值。嵌入模型另有 OPENAI_EMBEDDING_BASE_URL 和 OPENAI_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_KEY空Cohere 或 SiliconFlow 密钥
RERANKER_MODEL空服务端支持的模型名

HugeGraph 连接与召回限制

配置项默认值说明
GRAPH_URL127.0.0.1:8080HugeGraph 地址,不拆分为 IP 和端口
GRAPH_NAMEhugegraph图名
GRAPH_USERadmin用户名
GRAPH_PWDxxx密码
GRAPH_SPACE空GraphSpace 名称
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当前使用的向量库:Faiss、Milvus 或 Qdrant
QDRANT_HOST空
QDRANT_PORT6333
QDRANT_API_KEY空
MILVUS_HOST空
MILVUS_PORT19530
MILVUS_USER空
MILVUS_PASSWORD空

FAISS 在本地运行,无需额外依赖。未安装可选依赖就选择 Milvus 或 Qdrant 时,会报错并指出缺少的包,因此需要先安装:

1cd hugegraph-ai
2uv 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。

警告

生产环境必须设置 ENABLE_LOGIN=True,替换 USER_TOKEN 和 ADMIN_TOKEN,并通过防火墙或网络入口设置来源 IP 白名单。这只保护 HugeGraph-LLM;HugeGraph Server 还必须单独开启认证与授权(见认证与授权说明)并保留 Server 审计日志(标准日志文件为 audit-*.log),为 GRAPH_USER 设置最小必要权限。两端使用不同的认证凭据。

最小 OpenAI 配置

 1LANGUAGE=CN
 2CHAT_LLM_TYPE=openai
 3EXTRACT_LLM_TYPE=openai
 4TEXT2GQL_LLM_TYPE=openai
 5EMBEDDING_TYPE=openai
 6
 7OPENAI_API_KEY=your-api-key
 8OPENAI_BASE_URL=https://api.openai.com/v1
 9OPENAI_CHAT_LANGUAGE_MODEL=gpt-4.1-mini
10OPENAI_EXTRACT_LANGUAGE_MODEL=gpt-4.1-mini
11OPENAI_TEXT2GQL_LANGUAGE_MODEL=gpt-4.1-mini
12OPENAI_EMBEDDING_MODEL=text-embedding-3-small
13
14GRAPH_URL=127.0.0.1:8080
15GRAPH_NAME=hugegraph
16GRAPH_USER=admin
17GRAPH_PWD=your-password

配置加载

配置类先提供代码默认值。当前实现会在初始化时把所选 .env 中的值写入进程环境,再初始化配置对象;若 shell 中已经有同名变量,文件中的值会覆盖它。缺少的键使用配置类默认值,空值会被忽略,未知键会被忽略。Web 页面和配置 API 可以在运行时更新当前设置,并把受支持的字段同步回 .env。手工改动 .env 后应重启服务;提示词 YAML 会在服务启动或页面加载时读取。

键名匹配不区分大小写。

配置定义位于:

  • 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.3.5 - HugeGraph-LLM REST API

HugeGraph-LLM 演示进程同时提供 Web 页面和 REST API。默认地址是 http://localhost:8001:

1cd hugegraph-ai/hugegraph-llm
2python -m hugegraph_llm.demo.rag_demo.app \
3  --host 127.0.0.1 \
4  --port 8001

所有接口都使用 POST:

路径成功状态码用途
/rag200按所选召回方式回答问题
/rag/graph200只做图召回,不生成最终答案
/graph/extract200从文本抽取顶点和边
/text2gremlin200由自然语言生成 Gremlin
/config/graph201更新 HugeGraph 连接
/config/llm201更新语言模型
/config/embedding201更新嵌入模型
/config/rerank201更新重排序模型
/logs200流式返回服务日志

认证

在 .env 中启用登录:

1ENABLE_LOGIN=True
2USER_TOKEN=replace-with-a-secret

启用后,请求需要 Bearer token:

1Authorization: Bearer replace-with-a-secret

同一开关也会给 Gradio 页面加上基础认证,用户名固定为 rag,密码是 USER_TOKEN。token 不正确时返回 401,并带上 WWW-Authenticate: Bearer 响应头。ENABLE_LOGIN 保持 False 时所有接口都不做鉴权。

警告

生产环境必须启用 HugeGraph-LLM 自身的登录认证,并在防火墙或网络入口设置来源 IP 白名单。该认证只保护 HugeGraph-LLM 的页面和 REST API;HugeGraph Server 还必须单独开启认证与授权(见认证与授权说明)并保留 Server 审计日志(标准日志文件为 audit-*.log),为 GRAPH_USER 配置最小必要权限。USER_TOKEN 不会替代 Server 认证。

RAG

POST /rag

根据开关返回一种或多种回答。未显式指定时只启用 graph_only。

 1curl -X POST http://localhost:8001/rag \
 2  -H 'Content-Type: application/json' \
 3  -d '{
 4    "query": "Al Pacino 出演过哪些电影?",
 5    "raw_answer": false,
 6    "vector_only": false,
 7    "graph_only": true,
 8    "graph_vector_answer": false,
 9    "max_graph_items": 30,
10    "topk_return_results": 20,
11    "vector_dis_threshold": 0.9,
12    "topk_per_keyword": 1,
13    "gremlin_tmpl_num": 1,
14    "client_config": {
15      "url": "127.0.0.1:8080",
16      "graph": "hugegraph",
17      "user": "admin",
18      "pwd": "admin",
19      "gs": "DEFAULT"
20    }
21  }'

响应只包含已启用的回答字段:

1{
2  "query": "Al Pacino 出演过哪些电影?",
3  "graph_only": "..."
4}

其他可选参数包括 graph_ratio(默认 0.5)、rerank_method(bleu 或 reranker,默认 bleu)、near_neighbor_first(默认 false)、custom_priority_info,以及三个自定义提示词字段 answer_prompt、keywords_extract_prompt 和 gremlin_prompt。省略提示词字段时使用 config_prompt.yaml 中的值。

gremlin_tmpl_num 决定图召回阶段 Text2Gremlin 的执行方式:小于 0 表示跳过 Text2Gremlin,直接使用预定义的图遍历;等于 0 表示不带示例生成 Gremlin;大于 0 表示从示例索引中取相应数量的示例。

query 为空或只有空白字符时返回 400。

POST /rag/graph

只执行图召回,不生成最终自然语言答案:

1curl -X POST http://localhost:8001/rag/graph \
2  -H 'Content-Type: application/json' \
3  -d '{
4    "query": "Al Pacino 出演过哪些电影?",
5    "get_vertex_only": false,
6    "gremlin_tmpl_num": 1,
7    "rerank_method": "bleu"
8  }'

响应的 graph_recall 可能包含 query、keywords、match_vids、graph_result_flag、gremlin、graph_result 和 vertex_degree_list。设置 get_vertex_only=true 可在顶点匹配后提前返回,此时接口会把 match_vids 替换为完整的顶点详情。

query 为空返回 400,请求类型错误返回 400,其他失败返回 500。

图抽取

POST /graph/extract

使用内联 Schema 时不会连接 HugeGraph:

 1curl -X POST http://localhost:8001/graph/extract \
 2  -H 'Content-Type: application/json' \
 3  -d '{
 4    "texts": ["Alice 在 Acme 工作。"],
 5    "schema": {
 6      "vertexlabels": [
 7        {"name": "person", "properties": ["name"]},
 8        {"name": "company", "properties": ["name"]}
 9      ],
10      "edgelabels": [
11        {
12          "name": "works_at",
13          "source_label": "person",
14          "target_label": "company",
15          "properties": []
16        }
17      ]
18    },
19    "language": "zh",
20    "split_type": "sentence",
21    "include_meta": true
22  }'

请求字段:

字段默认值说明
texts必填字符串或字符串数组;空白项会被丢弃,全部为空时报错
schema必填内联 JSON 对象或字符串,或现有图名
example_prompt提示词 YAML 中的值抽取提示词头部
extract_typeproperty_graph目前仅接受该值
languagezhzh 或 en,用于文本切分
split_typedocumentdocument、paragraph 或 sentence
include_metafalse在 meta 中加入 vertex_count、edge_count 和 text_count
review_options无(禁用)可选 JSON 对象,启用多轮模型审阅与有限修复:max_reviews、max_fixes、max_workers
client_config无仅在 schema 为图名时允许传入

内联 Schema 必须是包含 vertexlabels 和 edgelabels 两个列表的对象。每个顶点标签需要非空的 name 和非空的 properties 列表;每条边标签需要非空的 name、source_label 和 target_label。propertykeys 可选,若存在必须是列表。

若 schema 传现有图名,必须同时传入 client_config,且 client_config.graph 必须和图名相同。这里的 client_config 只接受 graph、user、pwd 和 gs,未知字段会被拒绝,且没有 url 字段:

 1{
 2  "texts": "Alice 在 Acme 工作。",
 3  "schema": "hugegraph",
 4  "client_config": {
 5    "graph": "hugegraph",
 6    "user": "admin",
 7    "pwd": "admin",
 8    "gs": "DEFAULT"
 9  }
10}

模型审阅与修复(review_options)

传入 review_options 可为每个切分后的文本块启用迭代式模型审阅与有限 Schema 自动修复:

1{
2  "texts": ["Alice 在 Acme 集团工作。", "Bob 在 Beta 公司工作。"],
3  "schema": {...},
4  "review_options": {
5    "max_reviews": 2,
6    "max_fixes": 1,
7    "max_workers": 4
8  }
9}
  • max_reviews(默认 2,范围 0–5):每个文本块允许的最大模型审阅轮数。
  • max_fixes(默认 1,范围 0–3):每个文本块允许的最大自动修复尝试次数。
  • max_workers(默认 4,范围 1–8):并发处理文本块的工作线程数。
  • 传入 {} 使用上述默认值;省略 review_options 或设为 null 则保持旧版直接抽取且不审阅。

响应格式说明

省略 review_options 时,HTTP 200 响应中的 status 始终为 succeeded。开启 review_options 后:

  • 全局 status 综合各分块状态计算:succeeded(所有分块达成 final)、partial(部分分块达成 final)或 failed(没有任何分块达成 final)。
  • 仅达成 final 状态的分块会被汇总合并到顶层 result.vertices 与 result.edges。
  • 响应体包含 chunk_results 列表,记录每个文本块的具体执行结果:
    • index:文本块在输入序列中的 0 起始索引。
    • status:final(通过结构校验与模型审阅)、candidate(通过校验但审阅配额耗尽)、blocked(Schema 约束无法修复或被审阅拦截)或 failed(调用异常或截断)。
    • graph:当前抽取的子图数据对象(vertices 与 edges),失败时为 null。
    • issues:校验或审阅中发现的问题列表,包含 path、message 及可选的原文 evidence。
    • reason 与 stage:失败原因与发生阶段(prepare、extract、validate、review 或 repair)。
    • reviews_used、fixes_used 与 llm_calls:记录该文本块消耗的大模型调用计数。

Text2Gremlin

POST /text2gremlin

1curl -X POST http://localhost:8001/text2gremlin \
2  -H 'Content-Type: application/json' \
3  -d '{
4    "query": "查找所有 person 顶点",
5    "example_num": 1,
6    "output_types": ["template_gremlin", "template_execution_result"]
7  }'

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

1{
2  "url": "127.0.0.1:8080",
3  "graph": "hugegraph",
4  "user": "admin",
5  "pwd": "admin",
6  "gs": "DEFAULT"
7}

user 和 pwd 默认是空字符串,gs 可选。

POST /config/llm 与 POST /config/embedding

两个端点使用同一个请求模型。/config/llm 会把 chat_llm_type、extract_llm_type 和 text2gql_llm_type 一起设为相同的值;要分别设置各任务的类型,只能通过 .env 或 Web 页面。OpenAI 或 LiteLLM 示例:

1{
2  "llm_type": "openai",
3  "api_key": "your-key",
4  "api_base": "https://api.openai.com/v1",
5  "language_model": "gpt-4.1-mini",
6  "max_tokens": "4096"
7}

Ollama 请求仍要提供公共字段;api_key 和 api_base 可传空字符串:

1{
2  "llm_type": "ollama/local",
3  "api_key": "",
4  "api_base": "",
5  "language_model": "qwen2.5:7b",
6  "host": "127.0.0.1",
7  "port": "11434"
8}

POST /config/rerank

1{
2  "reranker_type": "siliconflow",
3  "reranker_model": "BAAI/bge-reranker-v2-m3",
4  "api_key": "your-key"
5}

reranker_type 可选 cohere、siliconflow。Cohere 还可以传 cohere_base_url。

四个配置端点成功时都返回 201。它们会改动进程当前配置,并可能同步到 .env。/config/llm、/config/embedding 和 /config/rerank 在应用过程中抛出异常时会回滚到原有取值,/config/graph 不会。

/rag、/rag/graph 和 /text2gremlin 的 client_config 只在单次请求期间覆盖 HugeGraph 连接,且仅应用请求中实际出现的字段。当前实现仍会临时改动进程全局设置,不适合用不同连接并发发起长请求。

日志

POST /logs

该接口要求 .env 中的 ADMIN_TOKEN 已改成安全值。请求体示例:

1{
2  "admin_token": "replace-with-an-admin-secret",
3  "log_file": "llm-server.log"
4}

log_file 默认是 llm-server.log,只能是 logs/ 目录下的文件名,不能是绝对路径、不能包含路径分隔符,也不能解析为 . 或 ..。非法文件名返回 400。

ADMIN_TOKEN 未设置或仍是占位值时,在比对 token 之前就返回 403;token 不匹配时返回内容为 Invalid admin_token 的 403 响应。

成功时返回 text/plain 流:先回放文件末尾 125 行,然后像 tail -f 一样持续输出新内容。

3.3.6 - Vermeer Python 客户端

vermeer-python-client 是 Vermeer 的 Python SDK。Vermeer 是使用 Go 编写、以内存计算为主的图计算引擎。该 SDK 封装了 Vermeer master 的 REST API,可以在 Python 中列出图、提交加载和计算任务、读取任务状态。导入时使用的包名是 pyvermeer。

模块没有固定 Vermeer 服务端版本,它通过 HTTP 访问 Vermeer master,调用的接口见 API 概览。

环境要求

  • 当前源码实际要求 Python 3.10 或更高版本;虽然该模块打包元数据声明 >=3.9,代码中的类型标注使用了 Python 3.10 语法
  • 一个可通过 HTTP 访问的 Vermeer master。默认 HTTP 端口为 6688;Docker 部署需发布 6688:6688,见 Vermeer 快速上手。
  • uv(推荐)或 pip

运行时依赖:requests、urllib3、python-dateutil、decorator、rich 和 setuptools。

安装

打包元数据中的发行包名是 vermeer-python-client,其版本号独立于仓库版本号管理。该包尚未发布到 PyPI,请从源码安装。

在 HugeGraph-AI 仓库根目录,使用 vermeer extra 把它安装到共用的虚拟环境中:

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3uv sync --extra vermeer
4source .venv/bin/activate

vermeer-python-client 是以可编辑路径依赖的方式接入的,并不是 uv workspace member,因此在仓库根目录直接执行 uv sync 不会安装它,必须显式指定该 extra(或使用 --all-extras)。

单独安装该模块:

1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai/vermeer-python-client
3uv sync
4source .venv/bin/activate

连接 Vermeer master

1from pyvermeer.client.client import PyVermeerClient
2
3client = PyVermeerClient(
4    ip="127.0.0.1",
5    port=6688,
6    token="",
7    timeout=(0.5, 15.0),
8    log_level="INFO",
9)

构造函数参数:

参数类型默认值说明
ipstr必填Vermeer master 的主机名或 IP 地址
portint必填Vermeer master 的 REST 端口
tokenstr必填原样作为 Authorization 请求头发送
timeout(float, float) 或 NoneNone连接超时和读取超时,单位为秒
log_levelstr"INFO"应用到共享 VermeerClient 日志器的级别

如果 Python 客户端运行在宿主机,ip 填宿主机可访问的 master 地址;如果运行在容器中,则填容器网络内的 master 地址。客户端只连接 master 的 HTTP API,HugeGraph PD/Store 地址则必须能由执行加载任务的 Vermeer 节点访问。

连接前需要了解的行为:

  • 当 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 的退避系数;状态码重试遵循 urllib3 默认允许的方法,POST 不在其中,因此不能依赖它自动重试任务提交。
  • log_level 设置的是名为 VermeerClient 的共享日志器的级别。它的控制台 handler 固定为 INFO,因此目前 DEBUG 级别的记录不会打印到控制台。

端到端示例

模块自带一个可运行的示例:vermeer-python-client/src/pyvermeer/demo/task_demo.py。下面的版本在其基础上增加了有截止时间的任务轮询,先等待加载成功、再读取图并提交 PageRank 计算;PD 地址和 HugeGraph 密码从环境变量读取。服务端 worker group 也必须与任务空间的分配匹配;单 worker 快速上手可将 worker_group 设为 $,保留命名组时先按 Vermeer 快速上手 将该组绑定到任务空间。

 1import os
 2import time
 3
 4from pyvermeer.client.client import PyVermeerClient
 5from pyvermeer.structure.task_data import TaskCreateRequest
 6
 7client = PyVermeerClient(
 8    ip="127.0.0.1",
 9    port=6688,
10    token=os.getenv("VERMEER_TOKEN", ""),
11    timeout=(0.5, 15.0),
12    log_level="INFO",
13)
14
15# 列出 master 上的任务
16tasks = client.tasks.get_tasks()
17print(tasks.to_dict())
18
19# 从 HugeGraph 把图数据加载到 Vermeer
20create_response = client.tasks.create_task(
21    create_task=TaskCreateRequest(
22        task_type="load",
23        graph_name="DEFAULT-example",
24        params={
25            "load.hg_pd_peers": os.environ["VERMEER_PD_PEERS"],
26            "load.hugegraph_name": "DEFAULT/example/g",
27            "load.hugegraph_username": "admin",
28            "load.hugegraph_password": os.environ["HUGEGRAPH_PASSWORD"],
29            "load.parallel": "10",
30            "load.type": "hugegraph",
31        },
32    )
33)
34print(create_response.errcode, create_response.message)
35if create_response.errcode != 0:
36    raise RuntimeError(f"Could not create load task: {create_response.message}")
37
38def wait_task(task_id, success_state, poll_timeout=300.0):
39    deadline = time.monotonic() + poll_timeout
40    while True:
41        response = client.tasks.get_task(task_id)
42        if response.errcode != 0:
43            raise RuntimeError(f"Could not read task {task_id}: {response.message}")
44        task = response.task
45        print(task_id, task.state)
46        if task.state == success_state:
47            return task
48        if task.state in ("error", "canceled"):
49            raise RuntimeError(f"Task {task_id} ended with state {task.state}")
50        remaining = deadline - time.monotonic()
51        if remaining <= 0:
52            raise TimeoutError(f"Task {task_id} did not finish within {poll_timeout}s")
53        time.sleep(min(1.0, remaining))
54
55
56# 等待加载完成后再读取图
57wait_task(create_response.task.id, success_state="loaded")
58
59# 图加载完成后查看图信息
60print(client.graph.get_graph("DEFAULT-example").to_dict())
61
62# 在已加载的图上提交 PageRank 计算
63compute_response = client.tasks.create_task(
64    create_task=TaskCreateRequest(
65        task_type="compute",
66        graph_name="DEFAULT-example",
67        params={
68            "compute.algorithm": "pagerank",
69            "compute.parallel": "10",
70            "compute.max_step": "10",
71            "output.type": "local",
72            "output.parallel": "1",
73            "output.file_path": "result/pagerank",
74        },
75    )
76)
77if compute_response.errcode != 0:
78    raise RuntimeError(f"Could not create compute task: {compute_response.message}")
79wait_task(compute_response.task.id, success_state="complete")

加载任务以 loaded 表示成功,计算任务以 complete 表示成功;error 或 canceled 会中止示例。运行前设置 VERMEER_PD_PEERS,其值是 JSON 数组字符串,例如 export VERMEER_PD_PEERS='["hugegraph-pd:8686"]';其中地址必须能由 Vermeer master 访问,PD 返回的 Store 地址也必须能由 worker 访问。只有 master 配置为 token 鉴权时才设置 VERMEER_TOKEN;不启用鉴权时空字符串可用。

示例的 output.type=local 会把结果写到执行任务的 worker 本地文件系统,文件名以 result/pagerank 为前缀。容器部署时需把 worker 的结果目录挂载出来才能从宿主机读取。poll_timeout 是客户端轮询截止时间;检查期限之间的请求仍受 HTTP 超时和 SDK 重试影响,因此实际结束时间可能越过该值。超时只停止客户端等待,不会取消服务端任务。

不要把真实的 HugeGraph 密码写死在脚本或配置文件中,请像上面这样从环境变量或凭据管理系统读取。

保存并运行文档中的端到端示例

将上方完整的增强示例代码保存为 vermeer_client_example.py,放在 hugegraph-ai/ 仓库根目录。在该目录使用已安装 vermeer extra 的 workspace 环境运行:

1uv sync --extra vermeer
2export VERMEER_PD_PEERS='["hugegraph-pd:8686"]'
3read -s -r HUGEGRAPH_PASSWORD
4export HUGEGRAPH_PASSWORD
5uv run --extra vermeer python vermeer_client_example.py

输入密码后按回车。将 hugegraph-pd:8686 替换为 Vermeer master 可访问的 PD 地址;若 master 启用了 token 鉴权,还要从本机凭据管理方式设置 VERMEER_TOKEN。上述命令运行的是文档增强示例,不是包内原始 demo。

包内原始 demo

vermeer-python-client/src/pyvermeer/demo/task_demo.py 是另一份精简示例:它把客户端端口写为 8688,把 PD 地址写为 127.0.0.1:8686,并使用 xxx 占位用户名和密码。它不会读取本页增强示例使用的环境变量,也没有任务状态轮询或 PageRank 计算。若运行该文件,需单独调整其中的服务地址和 HugeGraph 凭据;不能用它替代上面的文档示例命令。

API 概览

PyVermeerClient 以属性的方式暴露各个 API 组,目前注册了 graph 和 tasks 两个组。

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.py 和 pyvermeer/api/worker.py 目前只有许可证头,也没有注册到客户端上。因此尽管 pyvermeer/structure/ 下已经有 MasterResponse 和 WorkersResponse,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,提供 errcode、message 属性和 to_dict() 方法。errcode 为 0 表示成功,1 表示错误,-1 表示响应体中没有该字段。

  • GraphsResponse.graphs 和 GraphResponse.graph 返回 VermeerGraph 对象,包含 name、space_name、status、create_time、update_time、vertex_count、edge_count、workers、worker_group、use_out_edges、use_property、use_out_degree、use_undirected、on_disk 和 backend_option。
  • TasksResponse.tasks、TaskResponse.task 和 TaskCreateResponse.task 返回 TaskInfo 对象,SDK 读取 id、state、create_user、create_type、create_time、start_time、update_time、graph_name、space_name、params、workers 和 error_message。
  • 时间字段由 python-dateutil 解析为 datetime 对象,空字符串会解析为 None。

当前服务端以 task_type 返回任务类型,而 SDK 的 TaskInfo.type 按 type 读取,因此该属性目前为空;服务端还返回的 statistics_result 不会被 SDK 的 TaskInfo 保留。轮询状态请使用 TaskInfo.state。这是当前源码的字段契约差异。

任务参数

客户端不会校验 params,键和值都会原样传给 Vermeer,因此可用的参数名由引擎决定,而不是由 SDK 决定。加载参数以及各算法的参数请参考 Vermeer 快速上手。

使用流程与直接调用 REST API 相同:先创建 load 任务把图读入 Vermeer,等待任务完成,再针对已加载的图创建计算任务。

异常

pyvermeer.utils.exception 定义了四种异常,都由底层的 requests 或 JSON 解析失败包装而来:

异常触发场景
ConnectErrorrequests.ConnectionError,无法连接 master
TimeOutErrorrequests.Timeout,连接或读取超时
JsonDecodeError响应体不是合法的 JSON
UnknownError请求过程中的其他失败
1from pyvermeer.utils.exception import ConnectError, TimeOutError
2
3try:
4    graphs = client.graph.get_graphs()
5except (ConnectError, TimeOutError) as error:
6    print(error)

客户端不检查响应的 HTTP 状态码,请通过返回对象的 errcode 和 message 判断是成功还是 Vermeer 端返回了错误。

代码检查

在 HugeGraph-AI 仓库根目录执行格式化和静态检查:

1./style/code_format_and_analysis.sh

源码位于 vermeer-python-client/src/pyvermeer/。目前有少量 src/tests/structure/test_task_data.py 结构测试,没有覆盖 HTTP API 的集成测试。

参考

3.3.7 - HugeGraph-MCP

hugegraph-mcp 通过 Model Context Protocol(MCP)向 AI 客户端提供 HugeGraph 工具, 包括 Schema 检查、结构化图查询、受控写入,以及可选的自然语言查询生成和图数据抽取。 服务使用 STDIO 传输,由 MCP 客户端启动本地进程;它不是 HugeGraph Server,也不提供独立的 HTTP MCP 端口。

普通图查询直接访问 HugeGraph Server。自然语言生成、抽取和向量刷新还需要 HugeGraph-LLM 服务,模型凭据配置在该服务中。

环境要求

  • 运行发布的 1.7.1 版本要求 Python >= 3.10(主线 master / 1.8.0+ 要求 Python >= 3.12); 单独运行 HugeGraph-LLM 时,请同时满足该模块的 Python 版本要求。
  • uv 和支持 STDIO 的 MCP 客户端。
  • 可从 MCP 进程访问的 HugeGraph Server 1.7.0 或更高版本。默认图路径为 DEFAULT/hugegraph,使用 graphspace API。
  • 已创建的图及具备相应权限的账号。服务端认证配置见认证与授权。

安装与连接

以下示例固定使用已发布的 hugegraph-mcp==1.7.1,不需要克隆代码仓库。 将地址、图路径和凭据替换为实际部署值。先使用只读模式验证连接,再按需要开放受支持的写入。

支持 mcpServers JSON 配置的客户端可添加:

 1{
 2  "mcpServers": {
 3    "hugegraph": {
 4      "command": "uvx",
 5      "args": ["hugegraph-mcp@1.7.1"],
 6      "env": {
 7        "HUGEGRAPH_URL": "http://127.0.0.1:8080",
 8        "HUGEGRAPH_GRAPH_PATH": "DEFAULT/hugegraph",
 9        "HUGEGRAPH_USER": "your-user",
10        "HUGEGRAPH_PASSWORD": "your-password",
11        "HUGEGRAPH_MCP_READONLY": "true"
12      }
13    }
14  }
15}

不同客户端的配置文件位置和结构可能不同,请按客户端说明填写相同的启动命令、参数和环境变量。 如果客户端找不到 uvx,将 command 改为本机 uvx 的绝对路径。修改配置后重启 MCP 进程。

也可在已配置上述环境变量的终端中启动:

1uvx hugegraph-mcp@1.7.1

进程启动后等待 MCP 客户端通过标准输入发送协议消息,不会打开网页。 stdout 用于 MCP JSON-RPC,不要将额外的 shell 输出写入该通道。

验证连接

通过客户端列出工具,再调用 inspect_graph_tool。以下 JSON 是 MCP tools/call 的参数内容, 不是向 HugeGraph REST API 直接发送的请求。

1{
2  "name": "inspect_graph_tool",
3  "arguments": {"include_raw_schema": true}
4}

确认返回 ok=true、data.hugegraph_server_status="available"。 从 Schema 中选择已有的顶点标签,将下例中的 person 替换为该标签:

1{
2  "name": "query_graph_data_tool",
3  "arguments": {
4    "target": "vertex",
5    "operation": "page",
6    "label": "person",
7    "limit": 5
8  }
9}

该工具属于默认的 16 工具集。分页时使用响应中的 next_page 作为下一次调用的 page, 并保留相同的查询条件。结果为空不一定表示连接失败,请同时检查图路径、标签和已有数据。

工具集与版本

工具集选择的是同一个包提供的工具分组,不是软件包版本、HugeGraph Server 版本或 MCP 协议版本。 1.7.1 的配置名称如下:

HUGEGRAPH_MCP_TOOLSET工具数量用途
未设置,或 v2_core16默认工具集,包含结构化查询和持久化写入计划工具
v110兼容工具集,保留较早的工具入口

其他任何值(包括 v2、core、legacy 或空字符串),在 1.7.1 中均会记录错误日志并回退到包含 10 个工具的 v1 兼容工具集。 两种工具集的 mcp_tool_contract_version 均为 2.0,该字段表示工具契约,不表示包版本。

工具集命名演进

最新源码已将默认工具集更名为 core,兼容工具集更名为 legacy。该规范将在后续版本正式发布;若使用 1.7.1 安装包,请继续遵循上述配置。

  • v2_core 对应新版 core,v1 对应新版 legacy;旧名称作为兼容别名保留,使用时将输出迁移提示。
  • 检查接口统一返回 core 或 legacy,依赖 data.toolset 或 meta.toolset 的客户端需同步适配。
  • 未设置变量时默认启用 core;空值或未知值将直接拦截启动,不再静默回退。
  • 工具集在启动时加载,变更配置后需重启客户端;切换兼容工具集不会绕过鉴权与只读约束。

工具能力

工具已注册不代表所有操作都可以执行。当前能力范围如下,实际工具参数以客户端的工具 Schema 为准。

功能工具使用范围
检查与设计inspect_graph_tool、inspect_schema_tool、design_schema_tool查看连接、Schema 和设计指导
结构化读取query_graph_data_tool按 ID、ID 列表、分页或条件读取顶点和边
Schema 创建apply_schema_tool校验和预览;默认工具集支持确认单个属性键、顶点标签或边标签创建
写入计划confirm_write_tool、get_write_status_tool、reconcile_write_tool确认、查询及协调持久化计划
图导入import_graph_data_toolextract 调用 AI;ingest 仅预览,table 当前禁用
图删除delete_graph_data_tool精确边删除可确认;顶点删除仅预览
属性变更mutate_graph_properties_tool仅预览,确认当前禁用
AI 生成与抽取generate_gremlin_tool、extract_graph_data_tool生成查询或抽取候选图数据,不自动执行生成的查询
向量刷新refresh_vid_embeddings_tool需要 AI、管理模式、允许写入以及显式确认;当前源码的服务侧门禁见下文
原始 Gremlinexecute_gremlin_read_tool、execute_gremlin_write_tool当前均返回 FEATURE_DISABLED;管理模式不能绕过

兼容工具集不包含 inspect_schema_tool、query_graph_data_tool、mutate_graph_properties_tool, 以及三个写入计划工具。原始 Gremlin 执行也不会因切换到兼容工具集而开放。

受控写入

需要写入时,将 HUGEGRAPH_MCP_READONLY 设为 false,并使用有相应权限的 HugeGraph 账号。 对于可确认的操作,先执行 dry-run,检查具体目标、变更内容和警告,再使用返回的 plan_id 确认:

1{
2  "name": "confirm_write_tool",
3  "arguments": {"plan_id": "<PLAN_ID>"}
4}

用 get_write_status_tool(plan_id) 查询持久化结果。APPLIED 表示全部操作已确认成功; PARTIAL 或 UNKNOWN 表示部分完成或结果尚不能确定,应先查询和协调状态,不要重新生成计划盲目重试。 已完成的同一计划再次确认会返回记录的结果,不会重复写入。

内置 SQLite 状态存储要求单个可写 MCP 实例,并需要可持久保存的状态目录。 多个客户端各自启动进程时,应先保持只读;多实例写入需要另行设计共享事务存储。 预览返回 confirmable=false 的操作不能通过关闭只读或开启管理模式强制执行。

配置

下表对应已发布的 1.7.1。MCP 图账号与 HugeGraph-LLM 的 API token 是两种不同的凭据。

环境变量默认值说明
HUGEGRAPH_URLhttp://127.0.0.1:8080MCP 进程访问的 HugeGraph 地址
HUGEGRAPH_GRAPH_PATHDEFAULT/hugegraphGRAPH_SPACE/GRAPH_NAME
HUGEGRAPH_GRAPHSPACE未设置覆盖 HUGEGRAPH_GRAPH_PATH 中的 graphspace
HUGEGRAPH_GRAPH未设置覆盖 HUGEGRAPH_GRAPH_PATH 中的图名
HUGEGRAPH_USERadminHugeGraph 用户名
HUGEGRAPH_PASSWORD空HugeGraph 密码
HUGEGRAPH_MCP_TOOLSETv2_core该版本支持 v2_core、v1
HUGEGRAPH_MCP_READONLYtrue禁止受控写入
HUGEGRAPH_MCP_ALLOW_AIfalse允许调用 HugeGraph-LLM
HUGEGRAPH_MCP_ADMIN_MODEfalse开放符合条件的管理操作
HUGEGRAPH_AI_URLhttp://127.0.0.1:8001HugeGraph-LLM 服务地址
HUGEGRAPH_AI_TOKEN未设置HugeGraph-LLM bearer token
HUGEGRAPH_AI_GRAPH_URL未设置不用于改变 AI 服务目标;当前源码已忽略此项
HUGEGRAPH_AI_TIMEOUT_SECONDS30AI HTTP 请求超时,单位为秒
HUGEGRAPH_MCP_STATE_DIRXDG 状态目录或 ~/.local/state/hugegraph-mcp写入计划与回执的持久化目录

可选 AI 功能

先按 HugeGraph-LLM 指南 配置并启动模型服务,再在 MCP 客户端的 env 中加入:

1{
2  "HUGEGRAPH_MCP_ALLOW_AI": "true",
3  "HUGEGRAPH_AI_URL": "http://127.0.0.1:8001",
4  "HUGEGRAPH_AI_TOKEN": "your-ai-service-token"
5}

这段内容应合并到前面的 env 对象中。生成和抽取可保持只读;向量刷新要求满足以下条件:

  • 客户端配置:HUGEGRAPH_MCP_READONLY=false、HUGEGRAPH_MCP_ADMIN_MODE=true,且调用时需传入 confirm=true。
  • 服务端配置(HugeGraph-LLM):需设置 ENABLE_LOGIN=true 与 HUGEGRAPH_LLM_ENABLE_THIN_WRITES=true,配置非默认的强 USER_TOKEN(避免使用弱默认值 4321), 并通过 MCP 的 HUGEGRAPH_AI_TOKEN 传递有效认证。若服务端未开启写入门禁,刷新请求将被拒绝并返回 FEATURE_DISABLED(“Legacy Thin API writes are disabled”)。

MCP 与 HugeGraph-LLM 必须连接至同一个底层 HugeGraph 实例。能力校验协议仅校验图名与图空间, 而实际刷新完全由 AI 服务依据其自身的 GRAPH_URL 独立执行;修改 MCP 的 HUGEGRAPH_URL 并不会改变 AI 服务的数据目标。 若 MCP 在宿主机运行,而 AI 在容器中运行,二者访问图服务的网络地址可能不同:应在 AI 服务侧配置 GRAPH_URL 为容器可访问的地址 (例如 http://server:8080),并确保 GRAPH_NAME 与 GRAPH_SPACE 与 MCP 目标一致;不要让容器通过 127.0.0.1 访问宿主机上的图服务。

能力校验协议: 新版协议要求调用 GET /vid-embeddings/refresh-capabilities 返回 protocol_version=1,并在刷新前传递预期图名与 graphspace 由服务端进行合法性校验;不支持该协议的服务将被拒绝。该机制用于保障多租户与图空间隔离,未发布该特性的旧版本不强制依赖。

常见问题

  • 客户端启动后没有工具:检查 uvx 路径、Python 版本和进程 stderr;终端进程等待协议输入是正常行为。
  • 找不到结构化查询工具:检查是否选择了兼容工具集。1.7.1 使用 v2_core,也可直接不设置工具集变量。
  • 返回 FEATURE_DISABLED:先检查能力表、只读、AI 和管理开关;部分操作是后端能力限制,不能仅靠修改配置开放。
  • AI 调用失败:检查服务地址、token、容器网络和 AI 日志。MCP 返回的服务不可用错误不一定意味着模型已下线。
  • 向量接口返回 400 或 429:检查提供商的单次输入条数及请求频率限制。每批最大条数和并发请求数是不同限制; 应在 HugeGraph-LLM 的向量适配与索引构建路径中处理,而不是更换 MCP 工具集。

工具响应中的 ok=false 表示失败,请同时检查 error.type、error.retryable 和 warnings, 不要只根据 MCP 连接成功或 HTTP 状态判断业务操作成功。

后续阅读

仓库 main 的文档随源码更新。使用固定发行包时,应先核对对应版本;本文安装示例固定为 1.7.1。

3.3.8 - HugeGraph-LLM SDK 快速上手

面向独立 Python 项目的轻量级 SDK,支持 Schema 设计、实体与关系抽取、图校验以及模型审阅修复。

hugegraph-llm-sdk 是面向独立 Python 项目的轻量级 SDK,提供编程式 Schema 设计、非结构化文本属性图抽取、遵循 HugeGraph 规则的结构校验,以及多轮模型审阅与有限修复能力。

与完整的 hugegraph-llm 应用不同,该 SDK 采用无界面(Headless)设计,无需依赖 HugeGraph Server、Gradio Web 界面、FastAPI 服务或向量数据库。基础运行环境仅依赖 pydantic>=2.14,<3。

Apache License 2.0 · Ask DeepWiki

环境要求与安装

  • Python 版本:>=3.12(在 Python 3.12、3.13 与 3.14 上均通过验证与支持)。
  • 发行包名:hugegraph-llm-sdk
  • 导入模块名:hugegraph_llm_sdk

从源码或本地 wheel 安装

当前 SDK 随 hugegraph-ai 源码提供,尚未发布到公共软件包索引。请从本地源码目录或自行构建的 wheel 安装。

1pip install -e /path/to/hugegraph-ai/hugegraph-llm-sdk
2# 或
3uv add --editable /path/to/hugegraph-ai/hugegraph-llm-sdk
4
5uv build --no-sources /path/to/hugegraph-ai/hugegraph-llm-sdk --out-dir /tmp/llm-sdk-dist
6pip install /tmp/llm-sdk-dist/hugegraph_llm_sdk-1.8.0-py3-none-any.whl

模型厂商适配器(Extras)

请从同一源码目录安装所需的适配器 extra:

1pip install -e "/path/to/hugegraph-ai/hugegraph-llm-sdk[openai]"
2pip install -e "/path/to/hugegraph-ai/hugegraph-llm-sdk[ollama]"
3pip install -e "/path/to/hugegraph-ai/hugegraph-llm-sdk[litellm]"
4# uv 示例:uv add --editable /path/to/hugegraph-ai/hugegraph-llm-sdk --extra openai

快速上手:最小示例

以下展示使用自定义模型函数完成“设计 Schema → 校验 Schema → 抽取并审阅属性图”的完整流程:

 1from hugegraph_llm_sdk import (
 2    FunctionModel,
 3    design_schema,
 4    validate_schema,
 5    extract_graph,
 6)
 7
 8# 1. 定义或封装大模型调用接口
 9model = FunctionModel(generate=lambda prompt: my_agent_model.invoke(prompt).content)
10
11# 2. 根据业务文本与问题设计图 Schema
12draft = design_schema(
13    texts=["Alice 在 Acme 集团工作,Bob 向 Alice 汇报工作。"],
14    questions=["每个人在哪个公司工作?谁向谁汇报?"],
15    model=model,
16)
17
18# 检查设计阶段标记的结构或语义问题
19if draft.issues:
20    print(f"Schema 设计问题: {draft.issues}")
21
22schema = draft.schema
23
24# 3. 按照 HugeGraph 规则对 Schema 结构进行合法性校验
25validation_issues = validate_schema(schema)
26assert not validation_issues, f"Schema 校验失败: {validation_issues}"
27
28# 4. 从文本中抽取属性图
29result = extract_graph(
30    texts="Alice 在 Acme 集团担任首席工程师。",
31    schema=schema,
32    model=model,
33)
34
35# 5. 处理分块抽取结果
36print(f"整体执行状态: {result.status}")  # 'succeeded'、'partial' 或 'failed'
37for chunk in result.chunks:
38    if chunk.status == "final":
39        print(f"抽取的子图数据: {chunk.graph}")
40    else:
41        print(f"分块 {chunk.index} 状态: {chunk.status}, 原因: {chunk.reason}, 问题: {chunk.issues}")

核心接口说明

接口名称签名说明
design_schema(texts, *, model, questions=(), example_schema=None, prompt=None) -> SchemaDraft根据文本与问题生成候选图结构草案(SchemaDraft(schema, issues))。
adesign_schema(texts, *, model, questions=(), example_schema=None, prompt=None) -> SchemaDraft异步版本的 Schema 设计接口。
validate_schema(schema) -> list[Issue]校验 Schema 结构是否符合 HugeGraph 属性图约束,不修改输入对象。
extract_graph(texts, *, schema, model=None, model_factory=None, review=True, options=None, prompts=None, validators=()) -> ExtractionResult执行分块图抽取、结构校验以及多轮审阅修复循环。
aextract_graph(texts, *, schema, model=None, model_factory=None, review=True, options=None, prompts=None, validators=()) -> ExtractionResult异步版本的图抽取接口。

Schema 校验规则

  • validate_schema 检查顶点标签、边标签、主键策略(DEFAULT、AUTOMATIC、PRIMARY_KEY、CUSTOMIZE_STRING、CUSTOMIZE_NUMBER、CUSTOMIZE_UUID)以及属性声明。
  • 省略 propertykeys 时,不对全局属性引用作硬性约束;省略标签的 properties 时,不限制其属性集合。
  • 显式声明 properties: [] 表示该标签严禁携带任何属性。
  • 边标签的 sort_keys 不能同时属于 nullable_keys;当 frequency 为 SINGLE 或 DEFAULT 时禁止排序键,为 MULTIPLE 时必须声明非空排序键。

模型适配器

SDK 在 hugegraph_llm_sdk.providers 模块中提供了常见大模型的适配器:

1from hugegraph_llm_sdk.providers.openai import OpenAIClient
2
3model = OpenAIClient(
4    api_key="your-api-key",
5    api_base="https://api.openai.com/v1",
6    model_name="gpt-4o-mini",
7)
  • FunctionModel:包装任意同步函数 generate(prompt: str) -> str 或异步函数 agenerate(prompt: str) -> str。
  • OpenAIClient:适用于 OpenAI 及兼容接口的适配器(支持 close() 与 await aclose() 显式资源释放)。
  • OllamaClient:适用于本地私有化 Ollama 服务的适配器。
  • LiteLLMClient:基于 LiteLLM 路由连接池的适配器。
  • ThreadedModel:包装同步模型,在异步事件循环中通过独立工作线程执行模型调用,避免阻塞主循环。

审阅与有限修复机制

默认情况下,属性图抽取会执行迭代审阅与有限自动修复流程:

1extract -> validate -> review
2              ^           |
3              |           +-- pass  -> final
4              |           +-- block -> blocked
5              +-- repair <- fix

审阅参数可通过 ExtractionOptions 进行配置:

 1from hugegraph_llm_sdk import ExtractionOptions, extract_graph
 2
 3options = ExtractionOptions(
 4    max_reviews=2,  # 每个分块的最大审阅轮数(范围 0–5,默认 2)
 5    max_fixes=1,    # 每个分块的最大自动修复尝试次数(范围 0–3,默认 1)
 6    max_workers=1,  # 并发执行的 Worker 数量(范围 1–8,默认 1)
 7)
 8
 9result = extract_graph(
10    texts="Bob 在 Beta 公司管理 Charlie。",
11    schema=schema,
12    model=model,
13    options=options,
14)

分块与整体状态

  • 分块状态(Chunk status):
    • final:子图成功通过结构校验与模型审阅。只有 final 状态的分块会被合并到全局 result.graph 中。
    • candidate:通过了结构校验,但审阅配额耗尽或未能完成最终核对。
    • blocked:未能通过 Schema 校验修复,或被模型审阅判定存在明显事实错误予以拦截。
    • failed:在准备、调用或解析阶段发生异常。
  • 整体状态(Aggregate status):
    • succeeded:所有文本分块均达成 final 状态。
    • partial:至少一个分块达成 final,但同时存在未完成(candidate、blocked 或 failed)的分块。
    • failed:没有任何分块达成 final 状态。

并发与异步批量抽取

当配置 max_workers > 1 时,必须传入无参 model_factory 可调用对象,而不是单一的 model 实例,以保证各并发线程状态隔离:

 1from hugegraph_llm_sdk import ExtractionOptions, extract_graph
 2from hugegraph_llm_sdk.providers.openai import OpenAIClient
 3
 4chunks = [
 5    "Alice 于 2022 年加入 Acme 集团。",
 6    "Bob 于 2023 年加入 Beta 科技。",
 7    "Charlie 与 Alice 在 Acme 集团共事。",
 8]
 9
10result = extract_graph(
11    texts=chunks,
12    schema=schema,
13    model_factory=lambda: OpenAIClient(api_key="your-api-key", model_name="gpt-4o-mini"),
14    options=ExtractionOptions(max_workers=3),
15)
16
17print(f"顶点总数: {len(result.graph.get('vertices', []))}")
18print(f"边总数: {len(result.graph.get('edges', []))}")

SDK 会自动管理由 model_factory 创建的实例生命周期,每批 Worker 执行完毕后自动释放对应连接资源。

与 HugeGraph-LLM 的关系

hugegraph-llm-sdk 与 hugegraph-llm 同属 hugegraph-ai 代码仓库:

1hugegraph-ai/
2├── hugegraph-llm-sdk/      # 独立轻量级 Python SDK(仅依赖 Pydantic)
3├── hugegraph-llm/          # 完整上层应用工程(FastAPI、Gradio 界面、GraphRAG、向量库)
4├── hugegraph-python-client/# HugeGraph Server 基础通信客户端(pyhugegraph)
5└── hugegraph-mcp/          # Model Context Protocol 服务端
  • hugegraph-llm-sdk:适合嵌入数据处理流水线、LLM Agent 工具链或外部 Python 应用中,专门负责 Schema 建模与属性图提取。
  • hugegraph-llm:面向终端用户的完整生产服务,提供 Web 界面、RESTful API(POST /graph/extract、POST /rag)、向量索引持久化与图数据直接入库能力。

3.4 - HugeGraph 图计算(OLAP)

HugeGraph-Computer 仓库包含两套部署和运行方式不同的图计算系统。通用图算法任务默认建议从 Go Vermeer 开始;需要 Java BSP/Pregel 分布式计算模型时,请使用 Computer。两者都可接入 HugeGraph,但配置和作业入口不能互换。

默认入口:Go Vermeer

flowchart TB
    Master["Master"] --> Workers["Workers"]
    Master -->|PD| PD["PD"]
    Workers -->|扫描| Store["Store"]
    Workers -.->|REST| Server["Server"]

当 load.type=hugegraph 时,Vermeer Master 通过 PD 查询分区元数据,Workers 直接扫描 HStore Store 分区。仅当 output.type=hugegraph 时,Workers 才通过 Server REST API 写回结果;其他数据源或输出配置不需要对应连接。

Java Computer

flowchart TB
    Config["作业配置"] --> Master["Master"] --> Workers["Workers"]
    Master -. BSP .-> Etcd["etcd"]
    Workers <-->|REST| Server["Server"]
    Workers <-->|HDFS| HDFS["HDFS(可选)"]

作业配置可由 Kubernetes Operator 或 YARN 提交。Workers 通过 REST API 从 HugeGraph Server 读取图数据,并可按输出配置写回计算结果;选择 HDFS 输入或输出时,Workers 直接访问 HDFS。Master 使用 etcd 协调 BSP 作业。

  • Vermeer 快速上手 — 基于 Go 的内存优先高性能图计算引擎,适用于通用 OLAP 算法秒级/分钟级快速执行。
  • Computer 快速上手 — 基于 Java BSP/Pregel 模型的分布式图计算框架,支持大规模超步迭代分析。
  • Computer 配置参考 — Computer 任务配置项及 Kubernetes Operator CRD 参数参考。
  • Computer 源码仓库 — 包含 Vermeer 与 Computer 两套计算引擎的官方代码仓库。

3.4.1 - HugeGraph-Vermeer 快速上手

Vermeer 高性能内存图计算:一次启动、多次执行,支持 15+ OLAP 算法及秒到分钟级计算,涵盖部署、数据加载、PageRank 和社区发现。

一、Vermeer 概述

1.1 运行架构

Vermeer 是使用 Go 编写的高性能内存优先图计算框架,支持一次启动、多次执行,以及 15+ OLAP 图算法的极速计算,大部分算法可在秒到分钟级完成。实际耗时取决于图规模、算法参数和可用资源。当前由一个 master 调度,可连接多个 worker。

master 是负责通信、转发、汇总的节点,计算量和占用资源量较少。worker 是计算节点,用于存储图数据和运行计算任务,占用大量内存和 cpu。grpc 和 rest 模块分别负责内部通信和外部调用。

启动时,程序先设置内置默认值,再读取工作目录下 config/<env>.ini 的 [default] 节,最后由显式命令行参数覆盖对应配置;例如 --env=master 读取 config/master.ini。Docker 镜像把仓库中的配置复制到 /go/bin/config/,并以 /go/bin/ 为工作目录。挂载宿主机目录到 /go/bin/config 会遮住镜像自带文件,因此该目录必须包含实际使用的 ini 文件。普通 INI 配置键不会自动映射环境变量。部署专用凭据设置还支持 VERMEER_PD_PASSWORD_FILE、VERMEER_PD_PEERS、VERMEER_HUGEGRAPH_CREDENTIALS_FILE 及文档中的签名因子/密码文件设置。

默认端口如下:

角色配置键默认地址用途
masterhttp_peer0.0.0.0:6688REST API;宿主机客户端访问此端口
mastergrpc_peer0.0.0.0:6689worker 连接 master 的 gRPC 端口
workerhttp_peer0.0.0.0:6788worker HTTP 服务
workergrpc_peer0.0.0.0:6789worker gRPC 监听地址,同时会通告给 master 供节点间通信

Docker 示例只把 master 的 HTTP 端口发布到宿主机回环地址 127.0.0.1:6688:6688;master 和 worker 的 gRPC 端口留在容器网络内部。

flowchart LR
  Client["curl / Python 客户端"] -->|"HTTP :6688"| Master["master"]
  Worker["worker"] <-->|"双向 gRPC:master :6689,worker :6789"| Master
  Master -->|"gRPC 查询分区"| PD["HugeGraph PD"]
  Worker -->|"gRPC 扫描分区"| Store["HugeGraph Store"]

1.2 运行方法

Helm:与 HugeGraph、Hubble 一起部署 Vermeer

HugeGraph Helm Chart 支持一键拉起原生 Vermeer 内存图计算引擎,默认保持关闭。 在 HugeGraph 仓库根目录下,开启 Vermeer 并启动:

1helm install hugegraph ./helm/hugegraph -n hugegraph --create-namespace \
2  -f helm/hugegraph/values-single.yaml \
3  --set vermeer.enabled=true --set vermeer.mode=standalone \
4  --wait --timeout 20m

Vermeer 核心文件与配置结构

  • helm/hugegraph/
    • examples/
      • values-vermeer-standalone.yaml单机预设(单个 Pod 同时运行 Master 与 Worker 容器)
      • values-vermeer-cluster.yaml集群预设(独立 Master Pod + 多 Worker Pods 分布式计算)
    • templates/
      • vermeer-master.yamlMaster 调度节点编排
      • vermeer-worker.yamlWorker 内存计算节点编排
      • vermeer-auth-secret.yaml管理员密码与 Hubble 内部调用服务令牌
    • docs/
      • vermeer.mdVermeer 算法调用、参数映射与运维指引

架构与运行模式:

  • 单机模式(standalone):Master 与 Worker 运行在同一个 Pod 中,开销小,适合小规模图计算测试。
  • 集群模式(cluster):设 vermeer.mode=cluster 与 vermeer.worker.replicas=3,提供独立的 Master 协调节点与多个分布式 Worker 计算节点。
  • 图服务协同:Master 通过 gRPC 向 PD 查询分区信息,Worker 直连 Store 扫描图数据切片;Hubble 会自动注入 Master 地址与通信令牌,在可视化界面中一键加载图并执行 15+ 种图算法。

核心注意事项:

  1. 保持元数据命名空间一致:保留 Chart 默认的 metadataCluster: hg-test。该值统一了 Server 的 HG_SERVER_CLUSTER 与 Store 的 PD_CLUSTER,确保 Schema 正确读取;切勿随意修改该值,以免计算加载时报 Schema missing。
  2. 访问原生 Web 控制台:easy 模式通过 <release>-vermeer-master Service 分配的 HTTP NodePort, 打开 http://<可达节点IP>:<NodePort>/;strict 默认 ClusterIP,可用 kubectl -n hugegraph port-forward svc/<release>-vermeer-master 6688:6688 在本机访问。 vermeer.service.type: null 继承模式默认值,显式 ClusterIP 保持私有,显式 NodePort 则开放需要登录的 HTTP/UI。 内部 Master/Worker RPC 与 Worker HTTP 仍保持私有;standalone / cluster 不改变上述访问选择。 在 Admin credential 处填入 <release>-vermeer-admin Secret 的 password(无需用户名),登录后获得 24 小时会话。 新密码在 easy 下为 6 位随机字母数字,strict 下为 16 位;升级与模式切换保留既有凭据。
  3. 详细镜像固定策略、持久卷配置及运维命令可参考 Helm 可选引擎指南 与 Vermeer 部署指南。
警告

生产环境必须启用 HugeGraph Server 认证与授权、IP 白名单和最小权限授权,并保留 audit-*.log 审计记录。Server Auth 不会保护 Vermeer、PD 和 Store 的独立接口;这些 HTTP、gRPC 端口必须限制在可信网络及调用方范围内,Vermeer 对外入口需配置访问控制。

独立手动部署时,默认 master.ini 配置为 auth=none,下方 Docker 示例仅发布至回环地址;若需远程访问,务必在配置文件中启用 auth=token。Helm 部署在两种模式下均要求 Token 鉴权,easy 默认仅通过 NodePort 开放原生 HTTP/UI。

下面两种 Docker 启动方式都需要先准备一个宿主机配置目录。请在 Vermeer 仓库根目录执行,将项目提供的 master.ini 和 worker.ini 模板复制到该目录;挂载会覆盖镜像里的 /go/bin/config,所以不要把空目录或整个用户主目录挂进去:

1CONFIG_DIR="$HOME/vermeer-config"
2mkdir -p "$CONFIG_DIR"
3cp config/master.ini config/worker.ini "$CONFIG_DIR/"

master.ini 保留 HTTP/gRPC 监听地址 0.0.0.0:6688 和 0.0.0.0:6689。Compose 示例为网络分配固定地址 172.20.0.10(master)和 172.20.0.11(worker),因此将复制后的 worker.ini 中这些配置设为:

1[default]
2http_peer=0.0.0.0:6788
3grpc_peer=172.20.0.11:6789
4master_peer=172.20.0.10:6689
5run_mode=worker
6worker_group=$

此单 worker 示例将 worker_group 设为 $,表示未绑定命名组时使用的通用组;请在 ini 文件中原样写入美元符号。仓库模板默认是 worker_group=default,若保留命名组,需先将它绑定到任务所在的空间或图,再提交任务。例如默认空间为 $DEFAULT 时,可执行:

1curl --fail --show-error -X POST \
2  'http://localhost:6688/admin/workers/alloc/default/%24DEFAULT'

该接口响应 errcode=0 表示绑定成功;启用 token 鉴权时还需带上授权请求头。master_peer 必须指向 worker 所在网络能访问的 master gRPC 地址。grpc_peer 同时用于 worker 监听和向 master 通告自己的地址,不能设为不可从其他容器访问的 0.0.0.0。如果更改网络子网或地址,需同步修改此处的 IP;多个 worker 还需要各自唯一且可互相访问的 grpc_peer 地址。

  1. 方案一:Docker Compose(推荐)

在 Vermeer 仓库根目录运行。可以修改仓库已有的 docker-compose.yaml,也可以使用下面的配置。仓库文件当前将整个 ~/ 挂载到配置目录且没有发布 master HTTP 端口,运行前必须按示例更换挂载路径并增加端口映射:

 1services:
 2  vermeer-master:
 3    image: hugegraph/vermeer
 4    container_name: vermeer-master
 5    ports:
 6      - "127.0.0.1:6688:6688"
 7    volumes:
 8      - /home/user/vermeer-config:/go/bin/config:ro
 9    command: --env=master
10    networks:
11      vermeer_network:
12        ipv4_address: 172.20.0.10 # master 固定地址
13
14  vermeer-worker:
15    image: hugegraph/vermeer
16    container_name: vermeer-worker
17    volumes:
18      - /home/user/vermeer-config:/go/bin/config:ro
19    command: --env=worker
20    networks:
21      vermeer_network:
22        ipv4_address: 172.20.0.11 # worker 固定地址
23
24networks:
25  vermeer_network:
26    driver: bridge
27    ipam:
28      config:
29        - subnet: 172.20.0.0/24 # 按需更换子网

把 /home/user/vermeer-config 换成上面实际的配置目录绝对路径。若修改 vermeer_network 的子网或固定 IP,也要同步更新 worker.ini 中的 grpc_peer 和 master_peer。不要复用默认 worker.ini 的 grpc_peer=0.0.0.0:6789 作为容器间通告地址。

在项目目录构建镜像并启动:

1# 构建镜像(在项目根 vermeer 目录)
2docker build -t hugegraph/vermeer .
3
4# 启动(在 vermeer 根目录)
5docker-compose up -d
6# 或使用新版 CLI:
7# docker compose up -d

查看日志 / 停止 / 删除:

1docker-compose logs -f
2docker-compose down
  1. 方案二:通过 docker run 单独启动(手动创建网络并分配静态 IP)

将 CONFIG_DIR 设为上面准备的配置目录,并确保复制后的 worker.ini 已按固定容器地址设置 grpc_peer 和 master_peer。该示例中的 CONFIG_DIR 需替换为实际的绝对路径。

构建镜像:

1docker build -t hugegraph/vermeer .

创建自定义 bridge 网络(一次性操作):

1docker network create --driver bridge \
2  --subnet 172.20.0.0/24 \
3  vermeer_network

运行 master(调整 CONFIG_DIR 为您的绝对配置路径,可以根据实际情况调整IP):

1CONFIG_DIR=/home/user/vermeer-config
2
3docker run -d \
4  --name vermeer-master \
5  --network vermeer_network --ip 172.20.0.10 \
6  -p 127.0.0.1:6688:6688 \
7  -v ${CONFIG_DIR}:/go/bin/config:ro \
8  hugegraph/vermeer \
9  --env=master

运行 worker:

1docker run -d \
2  --name vermeer-worker \
3  --network vermeer_network --ip 172.20.0.11 \
4  -v ${CONFIG_DIR}:/go/bin/config:ro \
5  hugegraph/vermeer \
6  --env=worker

查看日志 / 停止 / 删除:

1docker logs -f vermeer-master
2docker logs -f vermeer-worker
3
4docker stop vermeer-master vermeer-worker
5docker rm vermeer-master vermeer-worker
6
7# 删除自定义网络(如果需要)
8docker network rm vermeer_network
  1. 方案三:从源码构建

构建。具体请参照 Vermeer Readme。

1go build

从 Vermeer 仓库根目录启动,例如 ./vermeer --env=master 和 ./vermeer --env=worker01。worker01.ini 中的 grpc_peer 应填写可由 master 和其他 worker 访问、且本机可以绑定的地址;master_peer 指向 master 的 gRPC 监听地址。

启动 master 后,在宿主机验证 HTTP 端口:

1curl --fail --show-error http://localhost:6688/graphs

请求应返回 HTTP 200,JSON 响应中的 errcode 为 0。

1.3 身份认证、Token 工具与部署凭据

当在 master.ini 中启用 auth=token(或命令行参数 -auth token)时,应将 Master 签名因子保存在受保护的独立文件(0600 权限)中, 而非放置在启动参数内。基于文件的认证机制采用 v2 HMAC-SHA256 Base58 编码 token,具备恒定时间 MAC 校验能力,防止降级为不安全的旧协议。

1. 生成基于文件的签名因子

启动 Master 前先生成签名因子文件:

1umask 077
2openssl rand -hex 32 > config/token-factor

配置环境变量 VERMEER_AUTH_TOKEN_FACTOR_FILE=/path/to/token-factor,或在 master.ini 中设置 auth_token_factor_file。环境变量优先级高于 INI 文件, 两者均高于行内 auth_token_factor。文件必须为有效的 UTF-8 编码且至少包含 16 个有效字符,不可全为空白字符。配置无效或不可读的文件会导致 Master 在监听网络端口前直接退出(Fail-Closed),绝不会静默回退至行内或默认签名因子。

2. 使用 /go/bin/vermeer-token 生成认证 Token

Vermeer 运行时容器镜像已内置打包 /go/bin/vermeer-token CLI 工具(源自 cmd/vermeer-token)。该工具无需运行 Master 或访问 Kubernetes API, 即可直接生成合法的 v2 Base58 token:

Docker 命令
1docker run --rm --user "$(id -u):$(id -g)" -v "$PWD/config:/tokens" \
2  --entrypoint /go/bin/vermeer-token \
3  hugegraph/vermeer:latest -user admin -space '$DEFAULT' \
4  -factor-file /tokens/token-factor -output-file /tokens/admin-token -i -quiet
Go 源码
1go run ./cmd/vermeer-token -user admin -space '$DEFAULT' \
2  -factor-file config/token-factor -output-file config/admin-token -i -quiet

参数说明:

  • -user:用户名(默认:foo)。
  • -space:图空间名称(默认:bar;系统默认空间填写 $DEFAULT)。
  • -factor-file:签名因子文件路径(必填;不再接受行内 -factor)。
  • -output-file:以 0600 权限将 Base58 token 原子写入指定文件,不会向标准输出打印密钥。
  • -quiet:在未指定 -output-file 时仅输出 token 字符串,方便脚本捕获。
  • -client:客户端标识(默认:hg)。
  • -i:生成永不过期的永久 token(普通 token 默认 24 小时过期)。

调用 REST 接口时,将 token 填入 HTTP 请求头:

1curl -H "Authorization: Bearer <token>" http://localhost:6688/graphs

3. Kubernetes Secret 密码文件与凭据隔离

为了方便直接挂载 Kubernetes Secret 原始密码文件而无需封装为 JSON,Worker 支持通过密码文件注入连接凭据:

  • 配置 VERMEER_HUGEGRAPH_USERNAME 与 VERMEER_HUGEGRAPH_PASSWORD_FILE(或在 worker.ini 中配置 hugegraph_username 与 hugegraph_password_file)。 两项配置必须成对提供;若任一项配置后文件缺失或不可读,数据加载将直接失败。
  • 密码文件内容被原样读取,完整保留引号、反斜杠、空格及末尾换行符。
  • 若同时配置了显式 JSON 凭据文件(VERMEER_HUGEGRAPH_CREDENTIALS_FILE 或 hugegraph_credentials_file),JSON 文件拥有更高优先级。
  • PD 认证凭据:支持挂载 VERMEER_PD_PASSWORD_FILE(或 pd_password_file)。使用部署凭据时,必须同时配置 VERMEER_PD_PEERS(pd_peers), 确保 Worker 仅通过受信任的 PD 节点发现 Schema。
  • 部署凭据仅在进程内部加载时使用,绝不会持久化至任务元数据中,也不会通过查询接口泄露。
  • 可通过 grpc_dial_timeout 或 VERMEER_GRPC_DIAL_TIMEOUT(默认 5s)设定 Worker 建立 gRPC 连接的超时阈值。

二、任务创建类 rest api

2.1 简介

创建任务的流程是先提交 load 任务,等待图加载完成,再提交 compute 任务。同一张已加载的图可重复用于计算,不会因任务完成而自动删除。异步接口返回创建结果和任务信息(包括任务 ID),不代表任务已经完成;同步接口会一直等待任务进入成功或失败状态,调用方及代理的 HTTP 超时需足够长。任务状态可通过查询接口读取:加载成功为 loaded,计算成功为 complete,失败为 error,取消为 canceled,其余状态仍在等待或执行中。图在加载中或错误状态时不能用于计算;删除图要求图处于可删除状态且当前未被使用。

可以使用的 url 如下:

  • 异步接口:POST http://master_ip:port/tasks/create,从响应的 task.id 取得任务 ID。
  • 同步接口:POST http://master_ip:port/tasks/create/sync,等待该任务结束后返回。
  • 查询单个任务:GET http://master_ip:port/task/{task_id};响应中的 errcode 为 0 表示查询成功,再按 task.state 判断业务状态。异步任务应在客户端设置轮询截止时间;到时只停止客户端等待,不会自动取消服务端任务。
  • 查询保留结果:GET http://master_ip:port/tasks/value/{task_id}(或 /api/v1/tasks/value/{id})。
  • 集群健康与遥测快照:GET http://master_ip:port/api/v1/admin/cluster(需管理员 token;参见第四节)。
  • 图空间计算可用性探针:GET http://master_ip:port/api/v1/workers/availability(图空间粒度就绪检测)。

原生客户端使用 POST /api/v1/tasks/create,请求包含 graph、task_type(load、reload 或 compute)及扁平的字符串 params 映射。 计算算法名填写 params["compute.algorithm"],不是顶层 algorithm。 响应中的原生 task.id 通过 GET /api/v1/task/{id} 查询状态,通过 GET /api/v1/tasks/value/{id} 查询保留结果。 POST /api/v1/tasks 不提交任务:修复后返回 HTTP 405 和 Allow: GET;旧构建可能返回误导性的 {"code":200},但实际并未创建任务。 详见 原生 API 示例。

Vermeer Master HTTP 遵循 Helm 模式默认值:easy 为 NodePort,strict 为 ClusterIP;RPC 与 Worker 端口保持内部访问。 原生 UI 管理员使用 <release>-vermeer-admin 中的密码。自动化 API 使用服务 token,放入 Authorization: Bearer <token>, UI 管理密码不能当作该 token。Chart 会自动为 Hubble 配置服务 token。

2.2 加载图数据

以下示例列出常用的加载参数;引擎会按具体加载器读取参数,未被加载器使用的键不会改变行为。

vermeer提供三种加载方式:

  1. 从本地加载

load.vertex_files 和 load.edge_files 是“worker 地址主机部分到文件路径”的映射;路径由对应 worker 进程读取。容器部署时,数据文件必须先挂载进 worker 容器,并填写容器内路径。在上面的 Compose 示例中,应将主机数据目录挂到 worker 的 /data(例如增加 - /host/data:/data:ro),并把映射键设为 grpc_peer 中的 172.20.0.11;其他部署则使用各自 worker 上报地址的主机部分。

可以预先获取数据集,例如 twitter-2010 数据集。获取方式:https://snap.stanford.edu/data/twitter-2010.html,第一个 twitter-2010.txt.gz 即可。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "load",
 4 "graph": "testdb",
 5 "params": {
 6  "load.parallel": "50",
 7  "load.type": "local",
 8  "load.vertex_files": "{\"172.20.0.11\":\"/data/twitter-2010.v_[0,99]\"}",
 9  "load.edge_files": "{\"172.20.0.11\":\"/data/twitter-2010.e_[0,99]\"}",
10  "load.use_out_degree": "1",
11  "load.use_outedge": "1"
12 }
13}
  1. 从hugegraph加载

request 示例:

将请求中的地址、图名和凭据替换为实际连接信息。

 1POST http://localhost:6688/tasks/create
 2{
 3  "task_type": "load",
 4  "graph": "testdb",
 5  "params": {
 6    "load.parallel": "50",
 7    "load.type": "hugegraph",
 8    "load.hg_pd_peers": "[\"<pd-address-reachable-from-vermeer>:8686\"]",
 9    "load.hugegraph_name": "DEFAULT/hugegraph2/g",
10    "load.hugegraph_username": "admin",
11    "load.hugegraph_password": "<your-password-here>",
12    "load.use_out_degree": "1",
13    "load.use_outedge": "1"
14  }
15}

Vermeer master 使用 load.hg_pd_peers 连接 PD 并查询分区,worker 再连接 PD 返回的 Store 地址读取数据。因此这些服务地址必须能从对应的 Vermeer 容器或主机访问;在 Docker 容器里,127.0.0.1 指向容器自身,不能用来代替宿主机或另一容器的地址。

  1. 从hdfs加载

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3  "task_type": "load",
 4  "graph": "testdb",
 5  "params": {
 6    "load.parallel": "50",
 7    "load.type": "hdfs",
 8    "load.hdfs_namenode": "name_node1:9000",
 9    "load.hdfs_conf_path": "/path/to/conf",
10    "load.krb_realm": "EXAMPLE.COM",
11    "load.krb_name": "user@EXAMPLE.COM",
12    "load.krb_keytab_path": "/path/to/keytab",
13    "load.krb_conf_path": "/path/to/krb5.conf",
14    "load.hdfs_use_krb": "1",
15    "load.vertex_files": "/data/graph/vertices",
16    "load.edge_files": "/data/graph/edges",
17    "load.use_out_degree": "1",
18    "load.use_outedge": "1"
19  }
20}

2.3 输出计算结果

当前有实际写入器的结果方式为 local、hdfs 和 hugegraph,通过 output.type 指定;none 表示不写出结果。源码保留 afs 类型常量,但当前主线没有注册 AFS 加载器或写入器。指定 output.need_statistics 为 1 时,统计结果会写入任务信息;统计算子的适用范围取决于对应算法实现。

以下示例列出常用的计算和结果输出参数;算法支持的参数以 Vermeer 当前实现为准。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "pagerank",
 7 "compute.parallel": "10",
 8 "compute.max_step": "10",
 9 "output.type": "local",
10 "output.parallel": "1",
11 "output.file_path": "result/pagerank"
12  }
13}

output.type=local 的结果写在执行任务的 worker 本地文件系统中;容器部署时,如需从宿主机读取结果,请将 worker 的输出目录挂载出来。

2.4 通过 Hubble 提交与集成

使用 Chart 管理的原生集成时,POST /api/v1.3/vermeer/task 用于加载或重新加载图,不是计算接口。 该接口接收 graphspace、graph、task_type:"load" 与可选加载调优参数;等图加载完成后,再通过图级计算接口提交算法:

1curl -b hubble.cookies -X POST \
2  'http://localhost:8088/api/v1.3/graphspaces/DEFAULT/graphs/hugegraph/algorithms/vermeer' \
3  -H 'Content-Type: application/json' \
4  -d '{"params":{"compute.algorithm":"pagerank","compute.parallel":1,"compute.max_step":10,"pagerank.damping":0.85,"pagerank.diff_threshold":0.00001}}'

参数名与示例值来自当前 Hubble PageRank 表单:

参数含义示例
compute.algorithm支持的算法名pagerank
compute.parallel计算并行度1
compute.max_step最大迭代步数10
pagerank.dampingPageRank 阻尼系数0.85
pagerank.diff_threshold收敛阈值0.00001

当前 Hubble 接受 pagerank、wcc、lpa、degree、closeness_centrality、betweenness_centrality、triangle_count、kcore 与 sssp。 其他算法请使用对应表单中的参数,不能沿用 PageRank 的专属键。 直连适配器接受 compute.*、当前算法的 <algorithm>.* 与 output.need_statistics,具体参数值仍由 Vermeer 校验。 输出存储由 Hubble 管理,不能指定任意输出路径或传入 Server 凭据。

Hubble 响应封装的 data.task_id 是任务 ID,请保留正负号:原生 Vermeer 任务会映射为负数 ID。 使用同一图的 GET /api/v1.3/graphspaces/DEFAULT/graphs/hugegraph/async-tasks/{id} 查询状态; 成功后通过 GET .../async-tasks/{id}/values?cursor=0&limit=100 读取结果分页。 不要把 Hubble ID 直接传给 Server 原生 /tasks/{id}。 图状态 loaded 只表示加载成功。计算返回 HTTP 400 时,应结合被拒绝的完整请求与响应排查定位。

三、支持的算法

3.1 PageRank

PageRank 算法又称网页排名算法,是一种由搜索引擎根据网页(节点)之间相互的超链接进行计算的技

术,用来体现网页(节点)的相关性和重要性。

  • 如果一个网页被很多其他网页链接到,说明这个网页比较重要,也就是其 PageRank 值会相对较高。
  • 如果一个 PageRank 值很高的网页链接到其他网页,那么被链接到的网页的 PageRank 值会相应地提高。

PageRank 算法适用于网页排序、社交网络重点人物发掘等场景。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "pagerank",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/pagerank",
11 "compute.max_step":"10"
12 }
13}

3.2 WCC(弱连通分量)

弱连通分量,计算无向图中所有联通的子图,输出各顶点所属的弱联通子图 id,表明各个点之间的连通性,区分不同的连通社区。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "wcc",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/wcc",
11 "compute.max_step":"10"
12 }
13}

3.3 LPA(标签传播)

标签传递算法,是一种图聚类算法,常用在社交网络中,用于发现潜在的社区。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "lpa",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/lpa",
11 "compute.max_step":"10"
12 }
13}

3.4 Degree Centrality(度中心性)

度中心性算法,算法用于计算图中每个节点的度中心性值,支持无向图和有向图。度中心性是衡量节点重要性的重要指标,节点与其它节点的边越多,则节点的度中心性值越大,节点在图中的重要性也就越高。在无向图中,度中心性的计算是基于边信息统计节点出现次数,得出节点的度中心性的值,在有向图中则基于边的方向进行筛选,基于输入边或输出边信息统计节点出现次数,得到节点的入度值或出度值。它表明各个点的重要性,一般越重要的点度数越高。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "degree",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/degree",
11 "degree.direction":"both"
12 }
13}

3.5 Closeness Centrality(紧密中心性)

紧密中心性(Closeness Centrality)用于计算一个节点到所有其他可达节点的最短距离的倒数,进行累积后归一化的值。紧密中心度可以用来衡量信息从该节点传输到其他节点的时间长短。节点的“Closeness Centrality”越大,其在所在图中的位置越靠近中心,适用于社交网络中关键节点发掘等场景。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "closeness_centrality",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/closeness_centrality",
11 "closeness_centrality.sample_rate":"0.01"
12 }
13}

3.6 Betweenness Centrality(中介中心性算法)

中介中心性算法(Betweeness Centrality)判断一个节点具有"桥梁"节点的值,值越大说明它作为图中两点间必经路径的可能性越大,典型的例子包括社交网络中的共同关注的人。适用于衡量社群围绕某个节点的聚集程度。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "betweenness_centrality",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/betweenness_centrality",
11 "betweenness_centrality.sample_rate":"0.01"
12 }
13}

3.7 Triangle Count(三角形计数)

三角形计数算法,用于计算通过每个顶点的三角形个数,适用于计算用户之间的关系,关联性是不是成三角形。三角形越多,代表图中节点关联程度越高,组织关系越严密。社交网络中的三角形表示存在有凝聚力的社区,识别三角形有助于理解网络中个人或群体的聚类和相互联系。在金融网络或交易网络中,三角形的存在可能表示存在可疑或欺诈活动,三角形计数可以帮助识别可能需要进一步调查的交易模式。

输出的结果为 每个顶点对应一个 Triangle Count,即为每个顶点所在三角形的个数。

注:该算法为无向图算法,忽略边的方向。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "triangle_count",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/triangle_count"
11 }
12}

3.8 K-Core

K-Core 算法,标记所有度数为 K 的顶点,适用于图的剪枝,查找图的核心部分。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "kcore",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/kcore",
11 "kcore.degree_k":"5"
12 }
13}

3.9 SSSP(单元最短路径)

单源最短路径算法,求一个点到其他所有点的最短距离。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "sssp",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/degree",
11 "sssp.source":"tom"
12 }
13}

3.10 KOUT

以一个点为起点,获取这个点的 k 层的节点。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "kout",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/kout",
11 "kout.source":"tom",
12 "compute.max_step":"6"
13 }
14}

3.11 Louvain

Louvain 算法是一种基于模块度的社区发现算法。其基本思想是网络中节点尝试遍历所有邻居的社区标签,并选择最大化模块度增量的社区标签。在最大化模块度之后,每个社区看成一个新的节点,重复直到模块度不再增大。

Vermeer 上实现的分布式 Louvain 算法受节点顺序、并行计算等因素影响,并且由于 Louvain 算法由于其遍历顺序的随机导致社区压缩也具有一定的随机性,导致重复多次执行可能存在不同的结果。但整体趋势不会有大的变化。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "louvain",
 7 "compute.parallel":"10",
 8 "compute.max_step":"1000",
 9 "louvain.threshold":"0.0000001",
10 "louvain.resolution":"1.0",
11 "louvain.step":"10",
12 "output.type":"local",
13 "output.parallel":"1",
14 "output.file_path":"result/louvain"
15  }
16 }

3.12 Jaccard 相似度系数

Jaccard index , 又称为 Jaccard 相似系数(Jaccard similarity coefficient)用于比较有限样本集之间的相似性与差异性。Jaccard 系数值越大,样本相似度越高。用于计算一个给定的源点,与图中其他所有点的 Jaccard 相似系数。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "jaccard",
 7 "compute.parallel":"10",
 8 "compute.max_step":"2",
 9 "jaccard.source":"123",
10 "output.type":"local",
11 "output.parallel":"1",
12 "output.file_path":"result/jaccard"
13 }
14}

3.13 Personalized PageRank

个性化的 pagerank 的目标是要计算所有节点相对于用户 u 的相关度。从用户 u 对应的节点开始游走,每到一个节点都以 1-d 的概率停止游走并从 u 重新开始,或者以 d 的概率继续游走,从当前节点指向的节点中按照均匀分布随机选择一个节点往下游走。用于给定一个起点,计算此起点开始游走的个性化 pagerank 得分。适用于社交推荐等场景。

由于计算需要使用出度,需要在读取图时需要设置 load.use_out_degree 为 1。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "ppr",
 7 "compute.parallel":"100",
 8 "compute.max_step":"10",
 9 "ppr.source":"123",
10 "ppr.damping":"0.85",
11 "ppr.diff_threshold":"0.00001",
12 "output.type":"local",
13 "output.parallel":"1",
14 "output.file_path":"result/ppr"
15 }
16}

3.14 全图 Kout

计算图的所有节点的k度邻居(不包含自己以及1~k-1度的邻居),由于全图kout算法内存膨胀比较厉害,目前k限制在1和2,另外,全局kout算法支持过滤功能( 参数如:“compute.filter”:“risk_level==1”),在计算第k度的是时候进行过滤条件的判断,符合过滤条件的进入最终结果集,算法最终输出是符合条件的邻居个数。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "kout_all",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"10",
10 "output.file_path":"result/kout",
11 "compute.max_step":"2",
12 "compute.filter":"risk_level==1"
13 }
14}

3.15 集聚系数 clustering coefficient

集聚系数表示一个图中节点聚集程度的系数。在现实的网络中,尤其是在特定的网络中,由于相对高密度连接点的关系,节点总是趋向于建立一组严密的组织关系。集聚系数算法(Cluster Coefficient)用于计算图中节点的聚集程度。本算法为局部集聚系数。局部集聚系数可以测量图中每一个结点附近的集聚程度。

request 示例:

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "clustering_coefficient",
 7 "compute.parallel":"100",
 8 "compute.max_step":"10",
 9 "output.type":"local",
10 "output.parallel":"1",
11 "output.file_path":"result/cc"
12 }
13}

3.16 SCC(强连通分量)

在有向图的数学理论中,如果一个图的每一个顶点都可从该图其他任意一点到达,则称该图是强连通的。在任意有向图中能够实现强连通的部分我们称其为强连通分量。它表明各个点之间的连通性,区分不同的连通社区。

 1POST http://localhost:6688/tasks/create
 2{
 3 "task_type": "compute",
 4 "graph": "testdb",
 5 "params": {
 6 "compute.algorithm": "scc",
 7 "compute.parallel":"10",
 8 "output.type":"local",
 9 "output.parallel":"1",
10 "output.file_path":"result/scc",
11 "compute.max_step":"200"
12 }
13}

四、集群监控与遥测(Cluster Monitoring & Telemetry)

Vermeer 提供了面向运维看板(如 Apache HugeGraph Hubble)和云原生编排系统(如 Kubernetes / Helm 探针)的专用 REST 接口。

4.1 集群健康与遥测快照(GET /api/v1/admin/cluster)

GET /api/v1/admin/cluster 返回只读、带版本号的集群运行状态快照(schema_version: 1)。在开启 auth=token 的部署中, 该接口需要管理员 token(Authorization: Bearer <admin-token>),并执行标准 /admin 鉴权过滤。

健康与就绪语义

  • 仅注册不代表就绪。Worker 必须已注册、连接 Master,并使 load、compute、superstep 三个任务流均就绪。
  • Master 未就绪、无 Worker 或存在未就绪 Worker 时,集群状态为 DEGRADED;聚合原因分别为 master_initializing / service_offline、no_workers 或 workers_not_ready。其余情况为 UP。
  • metric_status 是对象,包含 availability(AVAILABLE、UNAVAILABLE 或 UNSUPPORTED)、observed_at 与可选 reason。
  • Master 检查项为 http_ready、initialized、service_online;Worker 检查项为 registered、connection_ready 和三个 *_stream_ready 字段。
  • Worker 遥测在管理器锁外使用整批 800 ms 截止时间,不影响就绪判定。

请求与响应示例

1curl -H "Authorization: Bearer <admin-token>" \
2  http://localhost:6688/api/v1/admin/cluster
 1{
 2  "schema_version": 1,
 3  "observed_at": 1730419200000,
 4  "status": "UP",
 5  "registered_workers": 1,
 6  "ready_workers": 1,
 7  "master": {
 8    "id": "master", "name": "Vermeer Master", "role": "MASTER",
 9    "grpc_peer": "127.0.0.1:6689", "version": "1.8.0",
10    "launch_time": "2026-11-01T08:00:00Z", "status": "UP", "ready": true,
11    "checks": {"http_ready": true, "initialized": true, "service_online": true},
12    "metrics": {"cpu_cores": 0.15, "rss_bytes": 134217728, "sample_window_seconds": 10.0},
13    "metric_status": {"availability": "AVAILABLE", "observed_at": 1730419200000}
14  },
15  "workers": [{
16    "id": "worker-1", "name": "worker-1", "role": "WORKER", "group": "default",
17    "grpc_peer": "127.0.0.1:6789", "version": "1.8.0",
18    "launch_time": "2026-11-01T08:00:05Z", "status": "UP", "ready": true,
19    "checks": {"registered": true, "connection_ready": true, "load_stream_ready": true,
20      "compute_stream_ready": true, "superstep_stream_ready": true},
21    "metrics": {"cpu_cores": 1.42, "rss_bytes": 2147483648, "sample_window_seconds": 10.0},
22    "metric_status": {"availability": "AVAILABLE", "observed_at": 1730419200000}
23  }]
24}

4.2 图空间 Worker 可用性探针(GET /api/v1/workers/availability)

GET /api/v1/workers/availability 专为 Kubernetes 与 Helm 探针提供图空间粒度的计算可用性检测。

  • 请求方式:携带调用者凭据以确定目标图空间。
  • 响应格式:当目标图空间具备可用计算资源时返回 {"available": true},否则返回 {"available": false}。
  • 判定规则:当前空间可访问的 common、space 或 graph Worker 分组中必须至少包含一个 Worker,且该组内所有已注册 Worker 都必须通过全部就绪检查。 仅注册在其他空间分组的 Worker 不会计入当前空间的可用性。

🚧, 后续随时更新完善,欢迎随时提出建议和意见。

3.4.2 - HugeGraph-Computer 快速上手

1. 组件说明

HugeGraph-Computer 是基于 BSP(Bulk Synchronous Parallel,批量同步并行)模型的 Java 分布式图计算框架,算法按超步迭代运行。它可由 Kubernetes Operator 或 YARN 调度,也可在单机上启动 master 和 worker 进程进行小规模试跑。

它与同一仓库中的 Vermeer 是两套实现:Computer 使用 Java/BSP 运行时,面向分布式计算;Vermeer 是 Go 实现的内存图计算平台,采用 master-worker 结构。两者共享 HugeGraph 数据源,但部署和任务配置不能互换。

Computer 支持从 HugeGraph 或 HDFS 读取图数据,并可将结果写回 HugeGraph 或 HDFS。运行时可把部分数据溢写到磁盘;能否完成任务仍取决于输入规模、资源和配置,不应把溢写能力理解为不受资源限制。

2. 前置条件与连接

构建和运行 Computer 在示例固定的 1.7.0 版本需使用 JDK 11(主线 1.8.0+ 及 master 要求 JDK 17 或更高版本,包括集群中各计算节点与 Worker); 源码构建还需要 Maven 3.6.3 或更高版本(1.7.0 需 Maven 3.5+)。在自定义 Java 应用程序中嵌入运行 Computer 1.8.0+ 时,必须配置以下 JVM 运行选项: --add-opens=java.base/java.io=ALL-UNNAMED(用于缓冲文件复制)与 --add-opens=java.base/java.lang=ALL-UNNAMED(用于 SOFA RPC 动态代理生成); 官方发行包启动脚本 bin/start-computer.sh 及 Kubernetes Operator 已自动配置上述参数。PageRank 示例要求一个已启动且包含待计算图数据的 HugeGraph-Server,以及可供 master、worker 访问的 etcd。

服务示例地址或端口用途
HugeGraph-Serverhttp://127.0.0.1:8080读取图数据并写回算法结果;以 hugegraph.url 为准。
etcdhttp://127.0.0.1:2379BSP 作业协调;以 bsp.etcd_endpoints 为准。
Computer master RPCTCP 8190worker 连接 master;发行配置中的端口。
Computer worker 数据传输本地默认由系统分配;K8s Operator 默认 8099worker 之间传输顶点和消息。跨主机时需保证公告地址和端口可达。
MinIO(K8s 清单)HTTP 9000用于输入分区快照。Computer 1.7.0 清单把 Service 的 9000 错映射到 MinIO Console 的 9090;启用快照前需将 targetPort 改为 9000。默认 snapshot.write=false、snapshot.load=false,不启用快照时无需访问 MinIO。
cert-manager(K8s)集群内服务Operator 清单使用 cert-manager.io/v1 的 Certificate、Issuer 和 CA 注入功能;部署 Operator 前必须先安装兼容版本。
HDFS按集群配置(CI 测试使用 Hadoop 3.5.0)仅当输入或输出配置为 HDFS 时需要。CI 测试使用兼容 Java 17 的 Hadoop 3.5.0 镜像。

Kubernetes 作业中的 hugegraph.url 必须是各计算 Pod 都能访问的地址,不能填仅在个人电脑上可用的 localhost。如果启用了 HugeGraph 认证, 应在配置中填写用户名和密码,并为 REST 查询使用对应凭据。容器化与 Kubernetes 部署中,计算镜像(如 hugegraph/hugegraph-computer:latest)基于 Java 17 运行时构建。

警告

生产环境必须为 HugeGraph Server 开启认证与授权(见认证与授权说明)并保留 Server 审计日志(标准日志文件为 audit-*.log),为 Computer 使用只具备作业所需读写权限的专用账号,并为 Server 网络入口设置来源 IP 白名单。hugegraph.username 和 hugegraph.password 只是 Computer 连接 Server 的凭据,不能替代 Server 端认证。

更多配置项见Computer 配置参考。

3. 获取源码并构建发行包

Apache HugeGraph 下载目录按版本提供 Computer 源码包,不提供单独的预编译 Computer 二进制包。下面以 VERSION=1.7.0 为例;该发布版的源码包和构建产物文件名含 -incubating-,其他版本请按下载目录中的实际文件名调整。

 1VERSION=1.7.0 # 替换为要下载的发布版本
 2ARCHIVE="apache-hugegraph-computer-incubating-${VERSION}-src.tar.gz"
 3DOWNLOAD_BASE="https://downloads.apache.org/hugegraph/${VERSION}"
 4curl -fLO "${DOWNLOAD_BASE}/${ARCHIVE}"
 5curl -fLO "${DOWNLOAD_BASE}/${ARCHIVE}.sha512"
 6curl -fLO "${DOWNLOAD_BASE}/${ARCHIVE}.asc"
 7curl -fLO https://downloads.apache.org/hugegraph/KEYS
 8shasum -a 512 -c "${ARCHIVE}.sha512"
 9gpg --import KEYS
10gpg --verify "${ARCHIVE}.asc" "${ARCHIVE}"
11tar -xzf "${ARCHIVE}"
12cd "apache-hugegraph-computer-incubating-${VERSION}-src/computer"
13mvn clean package -DskipTests
14tar -xzf "target/apache-hugegraph-computer-incubating-${VERSION}.tar.gz"
15cd "apache-hugegraph-computer-incubating-${VERSION}"

从当前 master 构建时可直接克隆并打包:

1git clone https://github.com/apache/hugegraph-computer.git
2cd hugegraph-computer/computer
3mvn clean package -DskipTests

发行包由 computer/computer-dist 组装,包含 bin/start-computer.sh、运行依赖 lib/、内置算法 algorithm/builtin-algorithm.jar 及默认配置 conf/computer.properties、conf/log4j2.xml。源码默认配置位于 computer/computer-dist/src/assembly/static/conf/computer.properties。1.7.0 发布源码的构建产物带 -incubating-,当前 master 的发行名不带该标记,且版本号由源码 POM 决定;不要混用两种源码对应的 tar 包名。

4. 单机运行 PageRank

先编辑发行目录中的 conf/computer.properties,按实际环境修改 HugeGraph 地址、图名和认证信息,并确认 bsp.etcd_endpoints 指向可访问的 etcd。默认配置已选择内置 PageRankParams;master 和 worker 必须使用同一份配置及相同的 job.id。每个并行作业应使用不同的 job.id。

在两个终端中都从发行目录启动进程。启动脚本默认读取 conf/computer.properties,也可用 -c 指定配置文件:

终端一:Master
1# 启动 Computer Master 进程
2bin/start-computer.sh -d local -r master
终端二:Worker
1# 启动 Computer Worker 进程
2bin/start-computer.sh -d local -r worker

master 会等待配置要求的 worker 注册后运行作业。查看两个终端输出;默认日志配置也会在当前发行目录的 logs/ 下写入 master 和 worker 日志。只有进程启动成功并不代表计算完成,应确认 master 日志中输入、超步计算和输出阶段均正常结束。

PageRank 参数类将结果写回 HugeGraph,属性名为 page_rank。运行前先检查图中每个目标顶点类型都允许此属性;Computer 会按 DOUBLE、OLAP_COMMON 创建属性键,但不会把它加入顶点类型。若属性键不存在,可先创建:

1curl --fail --request POST \
2  --header 'Content-Type: application/json' \
3  --data '{"name":"page_rank","data_type":"DOUBLE","cardinality":"SINGLE","write_type":"OLAP_COMMON"}' \
4  'http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/propertykeys'

如果该属性键已存在,确认其类型为 DOUBLE 且 write_type 为 OLAP_COMMON。先列出图中的顶点类型,再对每个要计算的类型添加可空的 page_rank 属性;把示例中的 person 替换为实际类型名:

1curl --fail --compressed \
2  'http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels'
3
4curl --fail --request PUT \
5  --header 'Content-Type: application/json' \
6  --data '{"name":"person","properties":["page_rank"],"nullable_keys":["page_rank"]}' \
7  'http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels/person?action=append'

若图当前读模式不显示 OLAP 写入,可由管理员把读模式设为 ALL:

1curl --fail --request PUT \
2  --header 'Content-Type: application/json' \
3  --data '"ALL"' \
4  'http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph_read_mode'

查询顶点以确认结果属性:

1curl --fail --compressed \
2  'http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices?limit=3'

需要认证时,在 curl 命令中添加 --user "$HG_USER:$HG_PASSWORD"。读模式接口和权限说明见图读模式 REST API。

5. 在 Kubernetes 中运行 PageRank

先确保 HugeGraph-Server 对计算 Pod 可达,并按 cert-manager 官方安装文档安装与集群兼容的 cert-manager。Computer Operator 清单会部署 Operator、etcd 和 MinIO;CRD 与 Operator 清单应使用同一 Computer 发行版本。下面以 1.7.0 发布版为例:

1VERSION=1.7.0 # CRD 和 Operator 清单使用同一发布版本
2kubectl apply -f "https://raw.githubusercontent.com/apache/hugegraph-computer/${VERSION}/computer/computer-k8s-operator/manifest/hugegraph-computer-crd.v1.yaml"
3kubectl apply -f "https://raw.githubusercontent.com/apache/hugegraph-computer/${VERSION}/computer/computer-k8s-operator/manifest/hugegraph-computer-operator.yaml"
4kubectl rollout status deployment/hugegraph-computer-operator-controller-manager \
5  -n hugegraph-computer-operator-system --timeout=120s
可选:启用 MinIO 快照(1.7.0)

1.7.0 清单中的 MinIO Service 把 S3 API 的 9000 端口映射到了 Console 的 9090;启用快照时先修正映射,并将 snapshot.minio_endpoint 设为 http://hugegraph-computer-operator-minio.hugegraph-computer-operator-system.svc:9000。默认不启用快照时可跳过。

1kubectl patch service hugegraph-computer-operator-minio \
2  -n hugegraph-computer-operator-system \
3  --type=json \
4  -p='[{"op":"replace","path":"/spec/ports/0/targetPort","value":9000}]'

把 HugeGraph 地址替换为计算 Pod 能访问的服务地址后,提交 HugeGraphComputerJob。示例使用 Docker Hub 官方镜像 hugegraph/hugegraph-computer:latest(基于 Java 17 运行时)和内置 PageRank 算法包。若在 Kubernetes 或 Docker 环境下测试 HDFS 输入输出, 请搭配兼容 Java 17 的 Apache Hadoop 3.5.0 存储集群或镜像使用。自定义算法可打包进镜像并通过 jarFile 指定,也可通过 remoteJarUri 从 HTTP(S) 地址下载。 分区数需不小于 worker 数量。

将以下 YAML 保存为 pagerank-job.yaml,然后应用该文件:

 1apiVersion: operator.hugegraph.apache.org/v1
 2kind: HugeGraphComputerJob
 3metadata:
 4  namespace: hugegraph-computer-operator-system
 5  name: pagerank-sample
 6spec:
 7  jobId: pagerank-sample
 8  algorithmName: page_rank
 9  image: hugegraph/hugegraph-computer:latest # 官方 Docker Hub 镜像
10  jarFile: /hugegraph/hugegraph-computer/algorithm/builtin-algorithm.jar
11  pullPolicy: IfNotPresent
12  workerInstances: 1
13  masterCpu: 500m
14  workerCpu: 500m
15  masterMemory: 1Gi
16  workerMemory: 2Gi
17  computerConf:
18    job.partitions_count: "1"
19    algorithm.params_class: org.apache.hugegraph.computer.algorithm.centrality.pagerank.PageRankParams
20    hugegraph.url: http://hugegraph-server:8080
21    hugegraph.name: hugegraph
1kubectl apply -f pagerank-job.yaml
2kubectl get hcjob pagerank-sample -n hugegraph-computer-operator-system --watch

SUCCEEDED 表示作业完成。Operator 默认会在作业完成后删除 CR 和计算资源;需要保留结果或排查失败作业时,可按需展开下方说明。

可选:保留作业状态、查看日志或清理资源

Operator 默认 AUTO_DESTROY_POD=true,短作业的 CR 和 Pod 可能在查看前被清理。若要保留它们,请在提交作业前关闭该选项,并等待 Controller 新 Pod 就绪后再提交;该设置必须改在 Java Operator 的 controller 容器中:

1kubectl set env deployment/hugegraph-computer-operator-controller-manager \
2  -n hugegraph-computer-operator-system \
3  --containers=controller AUTO_DESTROY_POD=false
4kubectl rollout status deployment/hugegraph-computer-operator-controller-manager \
5  -n hugegraph-computer-operator-system --timeout=120s

查看运行信息或失败日志:

1kubectl logs --follow <master-pod-name> -n hugegraph-computer-operator-system
2kubectl logs --follow <worker-pod-name> -n hugegraph-computer-operator-system

查询完结果后删除 CR 以清理关联资源,并恢复默认策略:

1kubectl delete hcjob pagerank-sample -n hugegraph-computer-operator-system
2kubectl set env deployment/hugegraph-computer-operator-controller-manager \
3  -n hugegraph-computer-operator-system \
4  --containers=controller AUTO_DESTROY_POD=true

PageRank 写回 HugeGraph 后按上一节设置读模式并查询。若改用 HDFS 输出,结果位于 output.hdfs_path_prefix/<job.id>/ 下,文件名和分区布局由作业配置决定。

完整 CRD 字段见Computer 配置参考中的 CRD 说明。

6. 内置算法与开发入口

当前源码中的内置算法包括:

  • 中心性:PageRank、Betweenness Centrality、Closeness Centrality、Degree Centrality。
  • 社区与结构:Clustering Coefficient、K-core、LPA、Triangle Count、WCC。
  • 路径与采样:环检测、带过滤的环检测、单源最短路径、Random Walk。

算法实现位于 computer/computer-algorithm。自定义算法需要遵循 Computer API 并打包为可加载的 JAR;模块划分和开发入口见Computer README。

3.4.3 - HugeGraph-Computer 配置参考

Computer 配置选项

表格中的默认值来自 computer-api 模块的 ComputerOptions.java;发行包的 conf/computer.properties 显式设置的值以“代码默认值(发行包:实际值)”标注。rpc.* 等通用配置由 HugeGraph Commons 提供,以下会单独标出发行包实际值。

配置文件从哪里来

  • 源码模板:computer/computer-dist/src/assembly/static/conf/computer.properties;日志配置模板为同目录的 log4j2.xml。Maven package 阶段将模板复制进发行目录的 conf/,并将运行依赖和内置算法 JAR 装入 lib/、algorithm/。模板由源码维护,没有单独的配置生成命令。
  • 单机、YARN:启动脚本默认读取发行目录的 conf/computer.properties,可使用 bin/start-computer.sh -c <配置文件路径> 覆盖;master 和 worker 应读到同一组作业参数。
  • Kubernetes Operator:用户在 CRD 的 spec.computerConf 中提供键值;Operator 将它写成 ConfigMap,挂载为容器内的 computer.properties。Operator 会补入作业 ID、worker 数量、Pod 地址和未指定时的 etcd 地址,并在未指定或设为 0 时将数据传输端口设为 8099、master RPC 端口设为 8190。transport.server_host 与 rpc.server_host 会被设置为 Pod IP。作业容器启动脚本只对 ${POD_IP}、${HOSTNAME}、${POD_NAME}、${POD_NAMESPACE} 做环境变量替换。
  • Kubernetes 作业镜像必须包含 Computer 运行时。算法 JAR 可以预置在镜像内并由 CRD 的 jarFile 指向,也可以通过 remoteJarUri 设置 HTTP(S) 地址,让启动脚本下载并加载。示例与字段见Computer 快速上手及下方 CRD 表。

Apache HugeGraph 下载目录提供各发布版本的 Computer 源码包,不提供单独的预编译二进制包。1.7.0 的发布源码包名含 -incubating-;在该 tag 的 computer/ Maven 聚合工程运行 mvn clean package -DskipTests 后,发行包也带 -incubating-。当前 master 的发行名不含该标记,版本号由 POM 决定。源码包不能作为已构建发行包直接启动。

警告

表格中的空 HugeGraph 凭据和 MinIO 示例密钥仅适用于本地或演示环境。生产环境必须为 HugeGraph Server 开启认证与授权(见认证与授权说明)并保留 Server 审计日志(标准日志文件为 audit-*.log),为 Computer 配置最小必要权限的 Server 账号,并为 Server 网络入口设置来源 IP 白名单;不要将示例 MinIO 密钥用于生产。


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"" (空)可选的 etcd 作业键名前缀,可用于隔离不同命名空间;它不是 Kubernetes metadata.namespace,Operator 不会自动填入。
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 中):

1snapshot.write=true
2snapshot.name=pagerank-snapshot-20260201

示例:MinIO 快照(在 K8s CRD computerConf 中):

1computerConf:
2  snapshot.write: "true"
3  snapshot.name: "pagerank-snapshot-v1"
4  snapshot.minio_endpoint: "http://minio:9000"
5  snapshot.minio_access_key: "my-access-key"
6  snapshot.minio_secret_key: "my-secret-key"
7  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.1worker 数据服务监听并向其他 worker 公告的地址。多主机场景必须使用其他节点可达的地址;Operator 会改为 Pod IP。
transport.server_port0(发行包:0;K8s Operator:8099)worker 数据传输监听端口。单机值 0 表示系统分配端口;Operator 会将 K8s 默认值改为固定端口 8099,以便 Pod 间通信。
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网络通信不稳定时的重试次数。

7.9 Master RPC 配置

以下两个键由 HugeGraph Commons 的 RPC 配置定义;computer.properties 发行模板显式设置了主机和端口。Kubernetes Operator 会公告 Pod IP,并在未指定有效端口时使用 8190。

配置项发行包值说明
rpc.server_host127.0.0.1(K8s:Pod IP)Master RPC 服务地址,worker 必须能访问此地址。
rpc.server_port8190(K8s 默认:8190)Master RPC 监听端口;集群安全组和网络策略须允许 worker 连接。

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:2379(发行包:http://127.0.0.1:2379)etcd 客户端端点;多个地址用逗号分隔。K8s Operator 在未由 computerConf 指定时使用 Operator 的 INTERNAL_ETCD_URL。
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. 系统管理配置

以下配置在 Kubernetes 作业中由 Operator 自动补齐或覆盖。除非自定义了 Operator 或网络,不应手动覆盖这些值;job.namespace 是可选的用户配置,见基础配置表。

配置项管理者说明
bsp.etcd_endpointsK8s Operator仅在 computerConf 未设置时,取 Operator 的 INTERNAL_ETCD_URL。
transport.server_hostK8s Operator覆盖为 Pod IP;worker 需要互相访问。
transport.server_portK8s Operator未设置或为 0 时设置为 8099,不是随机端口。
job.idK8s Operator自动从 CRD 设置为作业 ID
job.workers_countK8s Operator自动从 CRD workerInstances 设置
rpc.server_hostK8s Operator覆盖为 master Pod IP。
rpc.server_portK8s Operator未设置或为 0 时设置为 8190。
rpc.remote_urlComputer 启动流程读取配置时会移除该项,不应作为作业配置设置。

为什么禁止修改:

  • BSP/RPC 配置:必须与实际部署的 etcd/RPC 服务匹配。手动覆盖会破坏协调。
  • 作业配置:必须与 K8s CRD 规范匹配。不匹配会导致 worker 数量错误。
  • 传输配置:必须使用 worker 互相可达的 Pod IP 和端口;K8s 的默认端口为 8099。

K8s Operator 配置选项

注意:选项需要通过环境变量设置进行转换,例如 k8s.internal_etcd_url => INTERNAL_ETCD_URL

配置项默认值说明
k8s.auto_destroy_podtrue作业完成或失败后是否删除作业 CR;CR 删除后 Operator 会清理关联计算资源。
k8s.close_reconciler_timeout120关闭 reconciler 的最大超时时间(毫秒)。
k8s.internal_etcd_url代码默认 http://127.0.0.1:2379;发行清单覆盖为 http://hugegraph-computer-operator-etcd.hugegraph-computer-operator-system:2379Operator 作业使用的 etcd URL。使用随附清单时实际值是 etcd Service 地址。
k8s.internal_minio_url代码默认 http://127.0.0.1:9000;发行清单覆盖为 http://hugegraph-computer-operator-minio.hugegraph-computer-operator-system:9000Operator 为作业补入的 MinIO 地址;仅启用 MinIO 快照时需要。
k8s.max_reconcile_retry3reconcile 的最大重试次数。
k8s.probe_backlog50服务健康探针的最大积压。
k8s.probe_port9892controller 绑定的用于服务健康探针的端口。
k8s.ready_check_internal1000检查就绪的时间间隔(毫秒)。
k8s.ready_timeout30000检查就绪的最大超时时间(毫秒)。
k8s.reconciler_count代码默认 Runtime.getRuntime().availableProcessors();发行清单覆盖为 6reconciler 线程的最大数量。
k8s.resync_period600000被监视资源进行 reconcile 的最小频率。
k8s.timezoneAsia/Shanghaicomputer 作业和 operator 的时区。
k8s.watch_namespacehugegraph-computer-operator-system监视自定义资源的命名空间。随附发行清单也设置为此值;使用 * 可监视所有命名空间。

HugeGraph-Computer CRD

1.7.0 CRD: https://github.com/apache/hugegraph-computer/blob/1.7.0/computer/computer-k8s-operator/manifest/hugegraph-computer-crd.v1.yaml

字段默认值说明必填
algorithmName算法名称。true
jobId作业 ID。true
imageComputer 作业使用的容器镜像,必须包含 Computer 运行时。目标算法 JAR 可预置在镜像内,或通过 remoteJarUri 下载。true
computerConfcomputer 配置选项的映射。true
workerInstancesworker 实例数量,将覆盖 ‘job.workers_count’ 选项。true
pullPolicy未设置时由 Kubernetes 按镜像标签决定:latest 为 Always,其他标签为 IfNotPresent可显式设置 Always、Never 或 IfNotPresent;CRD 未提供默认值。详见 镜像拉取策略。false
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
jarFile容器镜像内算法 JAR 的路径。false
remoteJarUri算法 JAR 的 HTTP(S) 地址;启动脚本会下载该 JAR 并加载。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-operator-systemhugegraph-computer 系统的命名空间。
k8s.pull_secret_names[]拉取镜像的 pull-secret 名称。

4 - HugeGraph-Server 配置

本节介绍 HugeGraph-Server 的配置文件、可用选项、认证和 HTTPS 设置。

后端配置

4.1 - Server 启动指南

1 概述

默认配置位于发行包解压目录的 conf/ 下。HBase、Kerberos 和 HTTPS 等外部文件可以由用户提供到其他路径,详见对应的后端、认证和 HTTPS 页面。

主要的配置文件包括:gremlin-server.yaml、rest-server.properties 和 hugegraph.properties

HugeGraphServer 内部集成了 GremlinServer 和 RestServer,而 gremlin-server.yaml 和 rest-server.properties 就是用来配置这两个 Server 的。

  • GremlinServer:GremlinServer 接收 Gremlin 请求并调用图引擎。
  • RestServer:提供 RESTful API,根据不同的 HTTP 请求,调用对应的 Core API,如果用户请求体是 gremlin 语句,则会转发给 GremlinServer,实现对图数据的操作。

下面对这三个配置文件逐一介绍。

警告

生产环境必须配置 Server 鉴权与网络边界

本页的认证配置属于 HugeGraph Server。生产环境必须按 Server 认证与授权配置启用 Auth、配置 IP 白名单和最小权限,并保留、保护 Server audit-*.log。示例中注释掉的认证配置表示默认未启用。

发行包把默认配置放在安装目录的 conf/ 下;这些文件来自 Server 仓库的静态发行素材,构建时随包复制。未在配置文件中出现的选项采用代码定义的默认值;配置文件显式写入的值会覆盖该默认值。 本页的默认文件行为按固定 Server 主线 2f827d6 核对;实际使用的发布包应以其自身版本对应的配置文件和入口脚本为准。

文件来源和用途装载行为
conf/gremlin-server.yaml随发行包提供;配置 Gremlin Server。start-hugegraph.sh 将它作为 Server 启动参数传入。
conf/rest-server.properties按固定 Server 主线构建时随发行包提供;配置 REST Server、PD、认证等。启动脚本和 Server 进程读取;对应主线构建的容器入口脚本也会在启动前更新其中受支持的选项。
conf/graphs/hugegraph.properties随发行包提供的默认图配置,使用 RocksDB。init-store.sh 和 Server 应用初始化都会扫描该目录;初始化阶段会尝试加载其中的图配置。graph.load_from_local_config 默认 false,控制管理器构造阶段预加载。图配置变化通过重启 Server 应用。
conf/graphs/hstore.properties.template随发行包提供的 HStore 模板;其他图配置由用户按需创建。HStore 镜像在构建时把模板改名为 hugegraph.properties;裸发行包用户可复制模板并修改。

完整的默认文件见Server 主线源码:gremlin-server.yaml、rest-server.properties、hugegraph.properties 和 hstore.properties.template。

以下 Docker 环境变量行为仅适用于从 master 主线构建的镜像,不会把任意环境变量名转换为配置项。该版本的入口脚本在初始化和启动前处理 HG_SERVER_BACKEND、HG_SERVER_PD_PEERS、HG_SERVER_USE_PD、HG_SERVER_CLUSTER、HG_SERVER_REST_URL、HG_SERVER_URLS_TO_PD、HG_SERVER_DEPLOY_IN_K8S、HG_SERVER_MIN_FREE_MEMORY、HG_SERVER_AUTH_TOKEN_SECRET、HG_SERVER_INIT_STORE_ENABLED 和 PASSWORD;历史发布镜像需按各自 tag 对应的 entrypoint 核实支持项。见 Docker entrypoint。

2 gremlin-server.yaml

只展示启动时常调整的选项;完整文件及序列化器、插件配置见上方源码链接。

发行包中的 host 和 port 默认行是注释;未指定时使用 127.0.0.1:8182。若要修改监听地址,取消注释并设置这两项:

1#host: 127.0.0.1
2#port: 8182
3evaluationTimeout: 30000
4channelizer: org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer
5graphs: {}
6ssl: { enabled: false }

通常只需关注 channelizer、host 和 port。图不在 Gremlin Server 的 graphs 段加载;REST 侧管理器会在 Server 应用初始化时扫描 graphs 目录并尝试载入本地图配置。graph.load_from_local_config 控制管理器构造阶段的预加载;默认 false 不会关闭应用初始化阶段的本地加载。

  • channelizer:默认的 WsAndHttpChannelizer 同时支持 WebSocket 和 HTTP。Gremlin-Console 使用 WebSocket,HugeGraph-Client、Loader 和 Hubble 使用 HTTP;

默认 GremlinServer 是服务在 127.0.0.1:8182,如果需要修改,配置 host、port 即可

  • host:部署 GremlinServer 机器的机器名或 IP,GremlinServer 不直接暴露给用户,由 RestServer 转发 Gremlin 请求;
  • port:部署 GremlinServer 机器的端口;

同时需要在 rest-server.properties 中增加对应的配置项 gremlinserver.url=http://host:port

3 rest-server.properties

下面是可用的 rest-server.properties 示例。主线模板未写出 graph.load_from_local_config,源码默认值为 false。示例中设为 true 是可选的:它开启管理器构造阶段预加载;Server 应用初始化阶段仍会扫描并尝试加载本地图配置。

 1# bind url
 2# could use '0.0.0.0' or specified (real)IP to expose external network access
 3restserver.url=http://127.0.0.1:8080
 4#restserver.enable_graphspaces_filter=false
 5# gremlin server url, need to be consistent with host and port in gremlin-server.yaml
 6#gremlinserver.url=127.0.0.1:8182
 7
 8graphs=./conf/graphs
 9graph.load_from_local_config=true
10
11# The maximum thread ratio for batch writing, only take effect if the batch.max_write_threads is 0
12batch.max_write_ratio=80
13batch.max_write_threads=0
14
15# configuration of arthas (optional disabled commands, for example jad,mc)
16arthas.telnet_port=8562
17arthas.http_port=8561
18arthas.ip=127.0.0.1
19arthas.disabled_commands=
20
21# authentication configs
22#auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator
23# for admin password, By default, it is pa and takes effect upon the first startup
24#auth.admin_pa=pa
25#auth.graph_store=hugegraph
26
27# use pd
28# usePD=true
29
30# slow query log
31log.slow_query_threshold=1000
32# bytes of request body recorded as-is (may contain sensitive literals), 0 to disable
33log.slow_query_body_limit=512
34
35# jvm(in-heap) memory usage monitor, set 1 to disable it
36memory_monitor.threshold=0.85
37memory_monitor.period=2000
  • restserver.url:RestServer 提供服务的 url,根据实际环境修改。如果其他 IP 地址无法访问,可以尝试修改为特定的地址;或修改为 http://0.0.0.0 来监听来自任何 IP 地址的请求,这种方案较为便捷,但需要留意服务可被访问的网络范围;
  • graphs:图配置文件所在目录,默认值是 ./conf/graphs。init-store.sh 会扫描该目录;Server 应用初始化也会扫描并尝试加载其中的 properties 文件;
  • graph.load_from_local_config:默认 false,控制构造阶段预加载;不会禁止 Server 应用初始化阶段的本地加载,也不是安全隔离开关。图配置变化通过重启 Server 应用。

自 HugeGraph 1.8.0 起,推荐使用规范的 snake_case 配置项: arthas.telnet_port、arthas.http_port、arthas.ip 与 arthas.disabled_commands。 旧版 camelCase 命名仍作为兼容回退;显式配置的 snake_case 值优先。 升级说明:发行包附带的 rest-server.properties 模板默认包含 snake_case 配置。 若此前配置了自定义 camelCase 键名,建议迁移至对应的 snake_case 键以避免被模板默认值覆盖。 详细在线诊断方法、权限要求及认证配置请参见 Arthas 诊断代理。

配置项 gremlinserver.url 是 GremlinServer 为 RestServer 提供服务的 url,该配置项默认为 http://127.0.0.1:8182,如需修改,需要和 gremlin-server.yaml 中的 host 和 port 相匹配;该值可以像模板那样省略协议前缀,缺失时会自动补上 http://。

4 hugegraph.properties

hugegraph.properties 是随发行包提供的默认图配置;每个额外的图都应在 conf/graphs 下提供自己的 properties 文件。这里展示选择默认 RocksDB 后端所需的关键配置,完整文件见上方源码链接。

1gremlin.graph=org.apache.hugegraph.HugeFactory
2backend=rocksdb
3serializer=binary
4store=hugegraph

重点关注未注释的几项:

  • gremlin.graph:GremlinServer 的启动入口,用户不要修改此项;开启鉴权时才改为 org.apache.hugegraph.auth.HugeFactoryAuthProxy;
  • vertex.cache_type / edge.cache_type:缓存实现,可选值为 l1 和 l2,默认 l2;
  • backend:使用的后端存储。1.7.0 支持 memory、rocksdb、hstore 和 hbase;
  • serializer:schema、vertex 和 edge 写入后端时使用的序列化器。RocksDB 使用 binary;
  • store:图在后端使用的存储名称;
  • task.schedule_period、task.retry、task.wait_timeout:异步任务的调度周期(秒)、重试次数和等待超时(秒)。调度器由后端决定,hstore 使用分布式调度器,其余后端使用本地调度器;旧的 task.scheduler_type 键已被忽略;
  • search.text_analyzer / search.text_analyzer_mode:全文索引使用的分词器及其模式。可选分词器为 ansj、hanlp、smartcn、jieba、jcseg、mmseg4j 和 ikanalyzer,每种分词器有各自的模式取值;
  • rocksdb.data_path:backend 为 rocksdb 时此项才有意义,rocksdb 的数据目录,默认为 rocksdb-data/data
  • rocksdb.wal_path:backend 为 rocksdb 时此项才有意义,rocksdb 的日志目录,默认为 rocksdb-data/wal

5 多图配置

一个 Server 可以加载多个图,每个图使用单独的 properties 文件。下面创建 RocksDB 图 hugegraph_rocksdb 和内存图 hugegraph_memory。

[可选]:修改 rest-server.properties

通过修改 rest-server.properties 中的 graphs 配置项来设置图的配置文件目录。默认配置为 graphs=./conf/graphs;需要其他目录时调整 graphs。下面将 graph.load_from_local_config 设为 true,作为管理器构造阶段预加载的可选设置;应用初始化仍会读取该目录中的本地图配置:

1graphs=./conf/graphs
2graph.load_from_local_config=true

在 conf/graphs 路径下基于 hugegraph.properties 创建 hugegraph_memory.properties 和 hugegraph_rocksdb.properties。

hugegraph_memory.properties 修改如下:

1backend=memory
2serializer=text
3store=hugegraph_memory

hugegraph_rocksdb.properties 修改如下:

1backend=rocksdb
2serializer=binary
3
4store=hugegraph_rocksdb

停止 Server,初始化执行 init-store.sh(为新的图创建数据库),重新启动 Server

1$ ./bin/stop-hugegraph.sh
 1$ ./bin/init-store.sh
 2
 3Initializing HugeGraph Store...
 42023-06-11 14:16:14 [main] [INFO] o.a.h.u.ConfigUtil - Scanning option 'graphs' directory './conf/graphs'
 52023-06-11 14:16:14 [main] [INFO] o.a.h.c.InitStore - Init graph with config file: ./conf/graphs/hugegraph_rocksdb.properties
 6...
 72023-06-11 14:16:15 [main] [INFO] o.a.h.StandardHugeGraph - Graph 'hugegraph_rocksdb' has been initialized
 82023-06-11 14:16:15 [main] [INFO] o.a.h.c.InitStore - Init graph with config file: ./conf/graphs/hugegraph_memory.properties
 9...
102023-06-11 14:16:16 [main] [INFO] o.a.h.StandardHugeGraph - Graph 'hugegraph_memory' has been initialized
112023-06-11 14:16:16 [main] [INFO] o.a.h.StandardHugeGraph - Close graph standardhugegraph[hugegraph_rocksdb]
12...
132023-06-11 14:16:16 [main] [INFO] o.a.h.HugeFactory - HugeFactory shutdown
142023-06-11 14:16:16 [hugegraph-shutdown] [INFO] o.a.h.HugeFactory - HugeGraph is shutting down
15Initialization finished.
1$ ./bin/start-hugegraph.sh
2
3Starting HugeGraphServer in daemon mode...
4Connecting to HugeGraphServer (http://127.0.0.1:8080/graphs)...OK
5Started [pid 21614]

查看创建的图:

1curl http://127.0.0.1:8080/graphspaces/DEFAULT/graphs
2
3{"graphs":["hugegraph_rocksdb","hugegraph_memory"]}

查看某个图的信息:

1curl http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph_memory
2
3{"name":"hugegraph_memory","backend":"memory"}
1curl http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph_rocksdb
2
3{"name":"hugegraph_rocksdb","backend":"rocksdb"}

4.2 - Server 完整配置手册

表格中的默认值指选项未在配置文件中显式设置时采用的源码默认值;发行包配置文件可能写入不同的值并覆盖它,实际运行值应以对应安装包的配置文件为准。

Gremlin Server 配置项

对应配置文件gremlin-server.yaml

config optiondefault valuedescription
host127.0.0.1The host or ip of Gremlin Server.
port8182The listening port of Gremlin Server.
graphs{}图由 Server 动态加载,不要在此处配置。
evaluationTimeout30000Gremlin 脚本执行超时,单位为毫秒。
channelizerorg.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer同时处理 WebSocket 和 HTTP 请求。
maxContentLength65536Server 接受的单个请求的最大字节数。
maxChunkSize8192HTTP 请求分块的最大字节数。
maxHeaderSize8192HTTP 请求头的最大字节数。
resultIterationBatchSize64流式返回结果集时,每批返回的结果条数。
ssl.enabledfalseGremlin Server 是否启用 TLS。
authentication未配置启用认证时配置认证器、处理器和 rest-server.properties 路径。

Rest Server & API 配置项

对应配置文件rest-server.properties

config optiondefault valuedescription
graphs./conf/graphs图配置 properties 文件所在目录。
graph.load_from_local_configfalse控制构造阶段预加载。应用初始化仍扫描并尝试加载本地配置,false 不会阻止本地加载。图配置变化通过重启 Server 应用。
graphs.enable_dynamic_create_droptrueWhether to enable create or drop graph dynamically.
init_store.enabledtrueWhether init-store initializes the local backend stores and the built-in admin account. Set false in distributed deployments (PD/HStore) where the storage side already owns the metadata.
server.id空字符串The optional legacy id of hugegraph-server.
server.rolemasterThe role of nodes in the cluster, available types are [master, worker, computer]
server.node_idnode-id1The node id of the server.
server.node_roleworkerThe node role of the server.
server.graphspaceDEFAULTThe graph space of the server.
server.service_idDEFAULTThe service id of the server.
server.path_graphspaceDEFAULTThe default path graph space of the server.
server.start_ignore_single_graph_errortrueWhether to start ignore single graph error.
server.event_hub_threads1The event hub threads of server.
restserver.urlhttp://127.0.0.1:8080The url for listening of graph server.
ssl.keystore_fileconf/hugegraph-server.keystoreThe path of server keystore file used when https protocol is enabled.
ssl.keystore_passwordhugegraphThe password of the server keystore file when the https protocol is enabled.
white_ip.statusdisableThe status of whether enable white ip.
restserver.max_worker_threads2 * CPUsThe maximum worker threads of rest server.
restserver.task_threadsmax(4, CPUs / 2)The task threads of rest server.
restserver.min_free_memory64The minimum free memory(MB) of rest server, requests will be rejected when the available memory of system is lower than this value.
restserver.request_timeout30The time in seconds within which a request must complete, -1 means no timeout.
restserver.connection_idle_timeout30The time in seconds to keep an inactive connection alive, -1 means no timeout.
restserver.connection_max_requests256The max number of HTTP requests allowed to be processed on one keep-alive connection, -1 means unlimited.
gremlinserver.urlhttp://127.0.0.1:8182The url of gremlin server.
gremlinserver.max_route2 * CPUsThe max route number for gremlin server.
gremlinserver.timeout30The timeout in seconds of waiting for gremlin server.
batch.max_edges_per_batch2500The maximum number of edges submitted per batch.
batch.max_vertices_per_batch2500The maximum number of vertices submitted per batch.
batch.max_write_ratio70The maximum thread ratio for batch writing, only take effect if the batch.max_write_threads is 0.
batch.max_write_threads0The maximum threads for batch writing, if the value is 0, the actual value will be set to batch.max_write_ratio * restserver.max_worker_threads.
raft.group_peers127.0.0.1:8090The rpc address of raft group initial peers.
auth.authenticatorThe class path of authenticator implementation. e.g., org.apache.hugegraph.auth.StandardAuthenticator, or a custom implementation.
auth.graph_storehugegraphThe name of graph used to store authentication information, like users, only for org.apache.hugegraph.auth.StandardAuthenticator.
auth.admin_papaServer 启动路径初始化内置 admin 账户时使用,默认值为公开的 pa,生产部署前必须显式设置强密码。本地持久化后端首次初始化由 init-store.sh 交互式读取密码。
auth.remote_urlIf the address is empty, it provide auth service, otherwise it is auth client and also provide auth service through rpc forwarding. The remote url can be set to multiple addresses, which are concat by ‘,’.
exception.allow_tracetrueWhether to allow exception trace stack.
memory_monitor.threshold0.85Threshold for JVM memory usage monitoring, 1 means disabling the memory monitoring task.
memory_monitor.period2000The period in ms of JVM memory usage monitoring, in each period we will detect the jvm memory usage and take corresponding actions.
log.slow_query_threshold1000The threshold time(ms) of logging slow query, 0 means logging slow query is disabled.
log.slow_query_body_limit512慢查询日志记录的请求体最大字节数,0 表示不记录。记录的前缀原样写入,可能包含敏感的 Gremlin 或 Cypher 字面量。

角色选举配置项 server.role_election 和 server.role.* 仅适用于 1.7.0 及更早版本。之后的版本不再读取这些配置项:若仍然设置,服务可以正常启动,并为每个配置项输出一条警告日志。

PD/Meta 配置项 (分布式模式)

对应配置文件rest-server.properties

config optiondefault valuedescription
usePDfalseWhether use pd.
pd.peers127.0.0.1:8686The pd server peers, separated with commas.
clusterhg-testThe cluster name.
pd.stores_wait_timeout300等待 PD 中达到 pd.initial-store-count 的 Store 处于活跃状态的秒数,之后才打开 hstore 图;范围为 0..2147483647,0 表示不等待。
metrics.data_to_pdtrueWhether to report metrics data to pd.
meta.endpointshttp://127.0.0.1:2379meta 端点的 URL。当前代码中没有任何地方读取该配置项,设置后不会生效;meta 连接由 pd.peers 建立。
meta.use_cafalseWhether to use ca to meta server.
meta.caThe ca file of meta server.
meta.client_caThe client ca file of meta server.
meta.client_keyThe client key file of meta server.

HStore 后端还会从图配置文件 {graph-name}.properties 中读取以下两项,默认值 0 表示由 PD 决定:

config optiondefault valuedescription
hstore.partition_count0Number of partitions, which PD controls partitions based on.
hstore.shard_count0Number of copies, which PD controls partition copies based on.

认证数据图配置项

以下选项写在 auth.graph_store 指定图的 properties 文件中,默认文件为 conf/graphs/hugegraph.properties。auth.authenticator、auth.graph_store、auth.admin_pa 和 auth.remote_url 则配置在上方的 rest-server.properties 表中。

config optiondefault valuedescription
auth.audit_log_rate1000.0每用户认证审计日志的最大输出速率,单位为条/秒,取非负数。运行时截断为整数:1.9 按 1 条/秒,0 或小于 1 的值会抑制审计日志;建议使用正整数。
auth.cache_capacity10240每个认证缓存的容量上限,取非负整数。
auth.cache_expire600认证客户端和服务端缓存的过期时间,单位为秒,取非负整数。
auth.token_expire86400JWT token 的有效期,单位为秒,取非负整数。
auth.token_secret32 个随机字节经 Base64 编码认证数据图的配置项;默认密钥不写回文件。若需跨重启或跨节点验证 token,应在每个节点的认证图配置中设置同一个强随机值。HS256 密钥按 UTF-8 字节计至少 32 字节。

基本配置项

基本配置项及后端配置项对应配置文件:{graph-name}.properties,如hugegraph.properties

config optiondefault valuedescription
gremlin.graphorg.apache.hugegraph.HugeFactoryGremlin entrance to create graph.
backendmemoryThe data store type. For version 1.7.0+ the allowed values are [memory, rocksdb, hstore, hbase]; the shipped conf/graphs/hugegraph.properties sets rocksdb and conf/graphs/hstore.properties.template sets hstore. Note: cassandra, scylladb, mysql, postgresql were removed in 1.7.0 (use <= 1.5.x for legacy backends).
serializertextThe serializer for backend store, built-in values are [text, binary, binaryscatter]; a backend may register its own, like hbase. The shipped graph templates set binary.
serializer.buffer_max_capacity134217728The process-wide max capacity of one serialization buffer in bytes.
storehugegraphThe backend database namespace.
store.connection_detect_interval600The interval in seconds for detecting connections, if the idle time of a connection exceeds this value, detect it and reconnect if needed before using, value 0 means detecting every time.
store.graphgThe graph table name, which store vertex, edge and property.
graphspaceDEFAULTThe graph space name.
alias.graph.idThe graph alias id.
graph.read_modeOLTP_ONLYThe graph read mode, which could be ALL | OLTP_ONLY | OLAP_ONLY.
pd.peers127.0.0.1:8686The addresses of pd nodes, separated with commas. Only used by the hstore backend.
pd.clusterhg图连接 PD 元数据时使用的集群名前缀,适用于 usePD=false;若 Server 以 usePD=true 启动,则优先使用 REST 配置中的 cluster。此值在进程内绑定一次。
schema.illegal_name_regex.\s+$|~.The regex specified the illegal format for schema name.
schema.cache_capacity10000The max cache size(items) of schema cache.
schema.init_templateThe template schema used to init graph.
schema.index_rebuild_using_pushdowntrueWhether to use pushdown when to create/rebuild index.
vertex.cache_typel2The type of vertex cache, allowed values are [l1, l2].
vertex.cache_capacity10000000The max cache size(items) of vertex cache.
vertex.cache_expire600The expiration time in seconds of vertex cache.
vertex.check_customized_id_existfalseWhether to check the vertices exist for those using customized id strategy.
vertex.default_labelvertexThe default vertex label.
vertex.tx_capacity10000The max size(items) of vertices(uncommitted) in transaction.
vertex.check_adjacent_vertex_existfalseWhether to check the adjacent vertices of edges exist.
vertex.lazy_load_adjacent_vertextrueWhether to lazy load adjacent vertices of edges.
vertex.part_edge_commit_size5000Whether to enable the mode to commit part of edges of vertex, enabled if commit size > 0, 0 means disabled.
vertex.encode_primary_key_numbertrueWhether to encode number value of primary key in vertex id.
vertex.remove_left_index_at_overwritefalseWhether remove left index at overwrite.
edge.cache_typel2The type of edge cache, allowed values are [l1, l2].
edge.cache_capacity1000000The max cache size(items) of edge cache.
edge.cache_expire600The expiration time in seconds of edge cache.
edge.tx_capacity10000The max size(items) of edges(uncommitted) in transaction.
query.page_size500The size of each page when querying by paging.
query.batch_size1000The size of each batch when querying by batch.
query.ignore_invalid_datatrueWhether to ignore invalid data of vertex or edge.
query.index_intersect_threshold1000The maximum number of intermediate results to intersect indexes when querying by multiple single index properties.
query.max_indexes_available1The upper limit of the number of indexes that can be used to query.
query.dedup_optionlimitThe way to dedup data, allowed values are [limit, global].
query.trust_indexfalseWhether to trust index.
query.ramtable_edges_capacity20000000The maximum number of edges in ramtable, include OUT and IN edges.
query.ramtable_enablefalseWhether to enable ramtable for query of adjacent edges.
query.ramtable_vertices_capacity10000000The maximum number of vertices in ramtable, generally the largest vertex id is used as capacity.
query.optimize_aggregate_by_indexfalseWhether to optimize aggregate query(like count) by index.
oltp.concurrent_depth10The min depth to enable concurrent oltp algorithm.
oltp.concurrent_threadsmax(10, CPUs / 2)Thread number to concurrently execute oltp algorithm.
oltp.collection_typeECThe implementation type of collections used in oltp algorithm, allowed values are [JCF, EC, FU].
oltp.query_batch_size10000The size of each batch when executing oltp algorithm.
oltp.query_batch_avg_degree_ratio0.95The ratio of exponential approximation for average degree of iterator when executing oltp algorithm.
oltp.query_batch_expect_degree100000000The expect sum of degree in each batch when executing oltp algorithm.
rate_limit.read0The max rate(times/s) to execute query of vertices/edges.
rate_limit.write0The max rate(items/s) to add/update/delete vertices/edges.
task.schedule_period10Period time in seconds when scheduler to schedule task.
task.wait_timeout10Timeout in seconds for waiting for the task to complete, such as when truncating or clearing the backend.
task.retry0Task retry times, allowed range is [0, 3].
task.input_size_limit16777216The job input size limit in bytes.
task.result_size_limit16777216The job result size limit in bytes.
task.sync_deletionfalseWhether to delete schema or expired data synchronously.
task.ttl_delete_batch1The batch size used to delete expired data.
computer.config./conf/computer.yamlThe config file path of computer job.
k8s.operator_template./conf/operator-template.yamlThe path of operator container template.
k8s.quota_template./conf/resource-quota-template.yamlThe path of resource quota template.
search.text_analyzerikanalyzerChoose a text analyzer for searching the vertex/edge properties, available type are [ansj, hanlp, smartcn, jieba, jcseg, mmseg4j, ikanalyzer]. The shipped graph templates set jieba. If use ‘ikanalyzer’, need download jar from ‘https://github.com/apache/hugegraph-doc/raw/ik_binary/dist/server/ikanalyzer-2012_u6.jar' to lib directory
search.text_analyzer_modesmartSpecify the mode for the text analyzer, the available mode of analyzer are {ansj: [BaseAnalysis, IndexAnalysis, ToAnalysis, NlpAnalysis], hanlp: [standard, nlp, index, nShort, shortest, speed], smartcn: [], jieba: [SEARCH, INDEX], jcseg: [Simple, Complex], mmseg4j: [Simple, Complex, MaxWord], ikanalyzer: [smart, max_word]}.
snowflake.datacenter_id0The datacenter id of snowflake id generator.
snowflake.force_stringfalseWhether to force the snowflake long id to be a string.
snowflake.worker_id0The worker id of snowflake id generator.
memory.modeoff-heapThe memory mode used for query in HugeGraph.
memory.max_capacity1073741824The maximum memory capacity in bytes that can be managed for all queries in HugeGraph.
memory.one_query_max_capacity104857600The maximum memory capacity in bytes that can be managed for a query in HugeGraph.
memory.alignment8The alignment used for round memory size.
Raft 配置项 (已废弃)

发行包中的图配置模板已将这些配置项标注为废弃。它们仅在 raft.mode=true 时生效,且 raft.group_peers 从 rest-server.properties 读取,而不是图配置文件。

config optiondefault valuedescription
raft.modefalseWhether the backend storage works in raft mode.
raft.safe_readfalseWhether to use linearly consistent read.
raft.path./raftlogThe log path of current raft node.
raft.use_replicator_pipelinetrueWhether to use replicator line, when turned on it multiple logs can be sent in parallel, and the next log doesn’t have to wait for the ack message of the current log to be sent.
raft.election_timeout10000Timeout in milliseconds to launch a round of election.
raft.snapshot_interval3600The interval in seconds to trigger snapshot save.
raft.snapshot_threads4The thread number used to do snapshot.
raft.snapshot_parallel_compressfalseWhether to enable parallel compress.
raft.snapshot_compress_threads4The thread number used to do snapshot compress.
raft.snapshot_decompress_threads4The thread number used to do snapshot decompress.
raft.backend_threadsCPUsThe thread number used to apply task to backend.
raft.read_index_threads8The thread number used to execute reading index.
raft.read_strategyReadOnlyLeaseBasedThe linearizability of read strategy, allowed values are [ReadOnlyLeaseBased, ReadOnlySafe].
raft.apply_batch1The apply batch size to trigger disruptor event handler.
raft.queue_size16384The disruptor buffers size for jraft RaftNode, StateMachine and LogManager.
raft.queue_publish_timeout60The timeout in second when publish event into disruptor.
raft.rpc_threadsmax(CPUs * 2, 80)The rpc threads for jraft RPC layer.
raft.rpc_connect_timeout5000The rpc connect timeout in milliseconds for jraft rpc.
raft.rpc_timeout60The general rpc timeout in seconds for jraft rpc.
raft.install_snapshot_rpc_timeout36000The install snapshot rpc timeout in seconds for jraft rpc.
raft.rpc_buf_low_water_mark10485760The ChannelOutboundBuffer’s low water mark of netty, when buffer size less than this size, the method ChannelOutboundBuffer.isWritable() will return true, it means that low downstream pressure or good network.
raft.rpc_buf_high_water_mark20971520The ChannelOutboundBuffer’s high water mark of netty, only when buffer size exceed this size, the method ChannelOutboundBuffer.isWritable() will return false, it means that the downstream pressure is too great to process the request or network is very congestion, upstream needs to limit rate at this time.

RocksDB 后端配置项

config optiondefault valuedescription
backendMust be set to rocksdb.
serializerMust be set to binary.
rocksdb.providerrocksdb兼容 RocksDB 的运行时提供者。可选值为 rocksdb 和 topling。
rocksdb.data_pathrocksdb-data/dataThe path for storing data of RocksDB.
rocksdb.wal_pathrocksdb-data/walThe path for storing WAL of RocksDB.
rocksdb.sst_pathThe path for ingesting SST file into RocksDB.
rocksdb.data_disks[]The optimized disks for storing data of RocksDB. The format of each element: STORE/TABLE: /path/disk.Allowed keys are [g/vertex, g/edge_out, g/edge_in, g/vertex_label_index, g/edge_label_index, g/range_int_index, g/range_float_index, g/range_long_index, g/range_double_index, g/secondary_index, g/search_index, g/shard_index, g/unique_index, g/olap]
rocksdb.log_levelINFOThe info log level of RocksDB.
rocksdb.num_levels7Set the number of levels for this database.
rocksdb.compaction_styleLEVELSet compaction style for RocksDB: LEVEL/UNIVERSAL/FIFO.
rocksdb.optimize_modetrueOptimize for heavy workloads and big datasets.
rocksdb.bulkload_modefalseSwitch to the mode to bulk load data into RocksDB.
rocksdb.compression_per_level[none, none, snappy, snappy, snappy, snappy, snappy]The compression algorithms for different levels of RocksDB, allowed values are none/snappy/z/bzip2/lz4/lz4hc/xpress/zstd.
rocksdb.bottommost_compressionnoneThe compression algorithm for the bottommost level of RocksDB, allowed values are none/snappy/z/bzip2/lz4/lz4hc/xpress/zstd.
rocksdb.compressionsnappyThe compression algorithm for compressing blocks of RocksDB, allowed values are none/snappy/z/bzip2/lz4/lz4hc/xpress/zstd.
rocksdb.max_background_jobs8Maximum number of concurrent background jobs, including flushes and compactions.
rocksdb.max_subcompactions4The value represents the maximum number of threads per compaction job.
rocksdb.delayed_write_rate16777216The rate limit in bytes/s of user write requests when need to slow down if the compaction gets behind.
rocksdb.max_open_files-1The maximum number of open files that can be cached by RocksDB, -1 means no limit.
rocksdb.max_manifest_file_size104857600The max size of manifest file in bytes.
rocksdb.skip_stats_update_on_db_openfalseWhether to skip statistics update when opening the database, setting this flag true allows us to not update statistics.
rocksdb.skip_check_sst_size_on_db_openfalseWhether to skip checking sizes of all sst files when opening the database.
rocksdb.max_file_opening_threads16The max number of threads used to open files.
rocksdb.max_total_wal_size0Total size of WAL files in bytes. Once WALs exceed this size, we will start forcing the flush of column families related, 0 means no limit.
rocksdb.bytes_per_sync0Allows OS to incrementally sync SST files to disk while they are being written, asynchronously in the background. Issue one request for every bytes_per_sync written. 0 turns it off.
rocksdb.wal_bytes_per_sync0Allows OS to incrementally sync WAL files to disk while they are being written, asynchronously in the background. Issue one request for every bytes_per_sync written. 0 turns it off.
rocksdb.strict_bytes_per_syncfalseWhen true, guarantees SST/WAL files have at most bytes_per_sync/wal_bytes_per_sync bytes submitted for writeback at any given time. This can be used to handle cases where processing speed exceeds I/O speed.
rocksdb.db_write_buffer_size0Total size of write buffers in bytes across all column families, 0 means no limit.
rocksdb.log_readahead_size0The number of bytes to prefetch when reading the log. 0 means the prefetching is disabled.
rocksdb.compaction_readahead_size0The number of bytes to perform bigger reads when doing compaction. If running RocksDB on spinning disks, you should set this to at least 2MB. 0 means the prefetching is disabled.
rocksdb.row_cache_capacity0The capacity in bytes of global cache for table-level rows. 0 means the row_cache is disabled.
rocksdb.delete_obsolete_files_period21600The periodicity in seconds when obsolete files get deleted, 0 means always do full purge.
rocksdb.write_buffer_size134217728Amount of data in bytes to build up in memory.
rocksdb.max_write_buffer_number6The maximum number of write buffers that are built up in memory.
rocksdb.min_write_buffer_number_to_merge2The minimum number of write buffers that will be merged together.
rocksdb.max_write_buffer_number_to_maintain0The total maximum number of write buffers to maintain in memory for conflict checking when transactions are used.
rocksdb.memtable_bloom_size_ratio0.0If prefix-extractor is set and memtable_bloom_size_ratio is not 0, or if memtable_whole_key_filtering is set true, create bloom filter for memtable with the size of write_buffer_size * memtable_bloom_size_ratio. If it is larger than 0.25, it is santinized to 0.25.
rocksdb.memtable_whole_key_filteringfalseEnable whole key bloom filter in memtable, it can potentially reduce CPU usage for point-look-ups. Note this will only take effect if memtable_bloom_size_ratio > 0.
rocksdb.memtable_huge_page_size0The page size for huge page TLB for bloom in memtable. If <= 0, not allocate from huge page TLB but from malloc.
rocksdb.inplace_update_supportfalseAllows thread-safe inplace updates if a put key exists in current memtable and sizeof new value is smaller.
rocksdb.level_compaction_dynamic_level_bytesfalseWhether to enable level_compaction_dynamic_level_bytes, if it’s enabled we give max_bytes_for_level_multiplier a priority against max_bytes_for_level_base, the bytes of base level is dynamic for a more predictable LSM tree, it is useful to limit worse case space amplification. Turning this feature on/off for an existing DB can cause unexpected LSM tree structure so it’s not recommended.
rocksdb.max_bytes_for_level_base536870912The upper-bound of the total size of level-1 files in bytes.
rocksdb.max_bytes_for_level_multiplier10.0The ratio between the total size of level (L+1) files and the total size of level L files for all L.
rocksdb.target_file_size_base67108864The target file size for compaction in bytes.
rocksdb.target_file_size_multiplier1The size ratio between a level L file and a level (L+1) file.
rocksdb.level0_file_num_compaction_trigger2Number of files to trigger level-0 compaction.
rocksdb.level0_slowdown_writes_trigger20Soft limit on number of level-0 files for slowing down writes.
rocksdb.level0_stop_writes_trigger36Hard limit on number of level-0 files for stopping writes.
rocksdb.soft_pending_compaction_bytes_limit68719476736The soft limit to impose on pending compaction in bytes.
rocksdb.hard_pending_compaction_bytes_limit274877906944The hard limit to impose on pending compaction in bytes.
rocksdb.allow_mmap_writesfalseAllow the OS to mmap file for writing.
rocksdb.allow_mmap_readsfalseAllow the OS to mmap file for reading sst tables.
rocksdb.use_direct_readsfalseEnable the OS to use direct I/O for reading sst tables.
rocksdb.use_direct_io_for_flush_and_compactionfalseEnable the OS to use direct read/writes in flush and compaction.
rocksdb.use_fsyncfalseIf true, then every store to stable storage will issue a fsync.
rocksdb.atomic_flushfalseIf true, flushing multiple column families and committing their results atomically to MANIFEST. Note that it’s not necessary to set atomic_flush=true if WAL is always enabled.
rocksdb.format_version5The format version of BlockBasedTable, allowed values are 0~5.
rocksdb.index_typekBinarySearchThe index type used to lookup between data blocks with the sst table, allowed values are [kBinarySearch,kHashSearch,kTwoLevelIndexSearch,kBinarySearchWithFirstKey].
rocksdb.data_block_index_typekDataBlockBinarySearchThe search type used to point lookup in data block with the sst table, allowed values are [kDataBlockBinarySearch,kDataBlockBinaryAndHash].
rocksdb.data_block_hash_table_util_ratio0.75The hash table utilization ratio value of entries/buckets. It is valid only when data_block_index_type=kDataBlockBinaryAndHash.
rocksdb.block_size4096Approximate size of user data packed per block, Note that it corresponds to uncompressed data.
rocksdb.block_size_deviation10The percentage of free space used to close a block.
rocksdb.block_restart_interval16The block restart interval for delta encoding in blocks.
rocksdb.block_cache_capacity8388608The amount of block cache in bytes that will be used by RocksDB, 0 means no block cache.
rocksdb.cache_index_and_filter_blockstrueSet this option true if we’d put index/filter blocks to the block cache.
rocksdb.pin_l0_filter_and_index_blocks_in_cachetrueSet this option true if we’d pin L0 index/filter blocks to the block cache.
rocksdb.bloom_filter_bits_per_key-1The bits per key in bloom filter, a good value is 10, which yields a filter with ~ 1% false positive rate. Set bloom_filter_bits_per_key > 0 to enable bloom filter, -1 means no bloom filter (0~0.5 round down to no filter).
rocksdb.bloom_filter_block_based_modefalseIf bloom filter is enabled, set this option true to use block based filter rather than full filter.
rocksdb.bloom_filter_whole_key_filteringtrueIf bloom filter is enabled, set this option true to place whole keys in the bloom filter, else place the prefix of keys when prefix-extractor is set.
rocksdb.optimize_filters_for_hitstrueIf bloom filter is enabled, this flag allows us to not store filters for the last level. set this option true to optimize the filters mainly for cases where keys are found rather than also optimize for keys missed.
rocksdb.partition_filters_and_indexesfalseIf bloom filter is enabled, set this option true to use partitioned full filters and indexes for each sst file. This option is incompatible with block-based filters.
rocksdb.pin_top_level_index_and_filtertrueIf partition_filters_and_indexes is set true, set this option true if we’d pin top-level index of partitioned filter and index blocks to the block cache.
rocksdb.prefix_extractor_n_bytes0The prefix-extractor uses the first N bytes of a key as its prefix, it will use the full key when a key is shorter than the N. 0 means unset prefix-extractor.
K8s 配置项 (可选)

对应配置文件rest-server.properties

config optiondefault valuedescription
server.use_k8sfalseWhether to use k8s to support multiple tenancy.
server.deploy_in_k8sfalseWhether to deploy server in k8s.
server.urls_to_pdhttp://0.0.0.0:8080Used as the server address reserved for PD and provided to clients, only used when starting the server in k8s.
server.k8s_urlhttps://127.0.0.1:8888The url of k8s.
server.k8s_use_cafalseWhether to use ca to k8s api server.
server.k8s_caThe ca file of k8s api server.
server.k8s_client_caThe client ca file of k8s api server.
server.k8s_client_keyThe client key file of k8s api server.
k8s.apifalseThe k8s api start status when the computer service is enabled.
k8s.namespacehugegraph-computer-systemThe namespace used for k8s work when the computer service is enabled.
k8s.kubeconfigThe k8s kube config file when the computer service is enabled.
k8s.hugegraph_urlThe hugegraph url for k8s work when the computer service is enabled.
k8s.enable_internal_algorithmtrueWhether to open k8s internal algorithm.
service.access_pd_namehgService name for server to access pd service.
service.access_pd_tokenService token for server to access pd service.
server.k8s_oltp_image127.0.0.1/kgs_bd/hugegraphserver:3.0.0The oltp server image of k8s.
server.k8s_olap_imagehugegraph/hugegraph-server:v1The olap server image of k8s.
server.k8s_storage_imagehugegraph/hugegraph-server:v1The storage server image of k8s.
server.default_oltp_k8s_namespacehugegraph-serverThe default oltp namespace for HugeGraph default graph space.
server.default_olap_k8s_namespacehugegraph-computer-systemThe default olap namespace for HugeGraph default graph space.
k8s.internal_algorithm[page-rank, degree-centrality, wcc, triangle-count, rings, rings-with-filter, betweenness-centrality, closeness-centrality, lpa, links, kcore, louvain, clustering-coefficient, ppr, subgraph-match]The names of the built-in k8s algorithms.
k8s.algorithmsSee ServerOptions.K8S_ALGORITHMSThe name:paramsClass mapping of the built-in k8s algorithms.
k8s.internal_algorithm_image_url空K8s 内置算法使用的镜像地址。
Arthas 诊断配置项(可选)

对应配置文件为 rest-server.properties。 自 HugeGraph 1.8.0 起生效。

配置项默认值说明
arthas.telnet_port8562管理员通过 PUT /arthas 激活时使用的 Arthas telnet 端口。
arthas.http_port8561管理员激活时使用的 Arthas HTTP 端口。
arthas.ip127.0.0.1监听地址;管理员可显式选择其他有效地址,包括 0.0.0.0。
arthas.disabled_commands空API 激活时可选的禁用命令,以逗号分隔,例如 jad,mc;本地脚本不受此项约束。

旧名称 arthas.telnetPort、arthas.httpPort 与 arthas.disabledCommands 仍兼容作为回退项;显式配置的 snake_case 选项优先。 发行包内的 bin/arthas.sh 可直接免配置进行本地诊断。 详细激活方式、权限要求及认证配置请参见 Arthas 诊断代理。

RPC Server 配置项

对应配置文件rest-server.properties

config optiondefault valuedescription
rpc.server_hostThe hosts/ips bound by rpc server to provide services, empty value means not enabled.
rpc.server_port8090The port bound by rpc server to provide services.
rpc.server_adaptive_portfalseWhether the bound port is adaptive, if it’s enabled, when the port is in use, automatically +1 to detect the next available port. Note that this process is not atomic, so there may still be port conflicts.
rpc.server_timeout30The timeout(in seconds) of rpc server execution.
rpc.remote_urlThe remote urls of rpc peers, it can be set to multiple addresses, which are concat by ‘,’, empty value means not enabled.
rpc.client_connect_timeout20The timeout(in seconds) of rpc client connect to rpc server.
rpc.client_reconnect_period10The period(in seconds) of rpc client reconnect to rpc server.
rpc.client_read_timeout40The timeout(in seconds) of rpc client read from rpc server.
rpc.client_retries3Failed retry number of rpc client calls to rpc server.
rpc.client_load_balancerconsistentHashThe rpc client uses a load-balancing algorithm to access multiple rpc servers in one cluster. Default value is ‘consistentHash’, means forwarding by request parameters.
rpc.protocolboltRpc communication protocol, client and server need to be specified the same value.
rpc.serializationhessian2Rpc serialization type, client and server must set the same value. Note: If you choose ‘protobuf’, you need to add the relative IDL file. (Could refer PD/Store *.proto)
rpc.config_order999Sofa-RPC configuration file loading order, the larger the more later loading.
rpc.logger_implcom.alipay.sofa.rpc.log.SLF4JLoggerImplSofa-RPC log implementation class.
HBase 后端配置项
config optiondefault valuedescription
backendMust be set to hbase.
serializerMust be set to hbase.
hbase.hostslocalhostThe hostnames or ip addresses of HBase zookeeper, separated with commas.
hbase.port2181The port address of HBase zookeeper.
hbase.threads_max64The max threads num of hbase connections.
hbase.znode_parent/hbaseThe znode parent path of HBase zookeeper.
hbase.zk_retry3The recovery retry times of HBase zookeeper.
hbase.truncate_timeout30The timeout in seconds of waiting for store truncate.
hbase.aggregation_timeout43200The timeout in seconds of waiting for aggregation.
hbase.kerberos_enablefalseIs Kerberos authentication enabled for HBase.
hbase.kerberos_keytabThe HBase’s key tab file for kerberos authentication.
hbase.kerberos_principalThe HBase’s principal for kerberos authentication.
hbase.krb5_conf/etc/krb5.confKerberos configuration file, including KDC IP, default realm, etc.
hbase.hbase_site/etc/hbase/conf/hbase-site.xmlThe HBase’s configuration file
hbase.enable_partitiontrueIs pre-split partitions enabled for HBase.
hbase.vertex_partitions10The number of partitions of the HBase vertex table.
hbase.edge_partitions30The number of partitions of the HBase edge table.

≤ 1.5 版本配置 (Legacy)

以下后端存储在 1.7.0+ 版本中不再支持,仅在 1.5.x 及更早版本中可用:

Cassandra 后端配置项
config optiondefault valuedescription
backendMust be set to cassandra.
serializerMust be set to cassandra.
cassandra.hostlocalhostThe seeds hostname or ip address of cassandra cluster.
cassandra.port9042The seeds port address of cassandra cluster.
cassandra.connect_timeout5The cassandra driver connect server timeout(seconds).
cassandra.read_timeout20The cassandra driver read from server timeout(seconds).
cassandra.keyspace.strategySimpleStrategyThe replication strategy of keyspace, valid value is SimpleStrategy or NetworkTopologyStrategy.
cassandra.keyspace.replication[3]The keyspace replication factor of SimpleStrategy, like ‘[3]’.Or replicas in each datacenter of NetworkTopologyStrategy, like ‘[dc1:2,dc2:1]’.
cassandra.usernameThe username to use to login to cassandra cluster.
cassandra.passwordThe password corresponding to cassandra.username.
cassandra.compression_typenoneThe compression algorithm of cassandra transport: none/snappy/lz4.
cassandra.jmx_port=71997199The port of JMX API service for cassandra.
cassandra.aggregation_timeout43200The timeout in seconds of waiting for aggregation.
ScyllaDB 后端配置项
config optiondefault valuedescription
backendMust be set to scylladb.
serializerMust be set to scylladb.

其它与 Cassandra 后端一致。

MySQL & PostgreSQL 后端配置项
config optiondefault valuedescription
backendMust be set to mysql.
serializerMust be set to mysql.
jdbc.drivercom.mysql.jdbc.DriverThe JDBC driver class to connect database.
jdbc.urljdbc:mysql://127.0.0.1:3306The url of database in JDBC format.
jdbc.usernamerootThe username to login database.
jdbc.password******The password corresponding to jdbc.username.
jdbc.ssl_modefalseThe SSL mode of connections with database.
jdbc.reconnect_interval3The interval(seconds) between reconnections when the database connection fails.
jdbc.reconnect_max_times3The reconnect times when the database connection fails.
jdbc.storage_engineInnoDBThe storage engine of backend store database, like InnoDB/MyISAM/RocksDB for MySQL.
jdbc.postgresql.connect_databasetemplate1The database used to connect when init store, drop store or check store exist.
PostgreSQL 后端配置项
config optiondefault valuedescription
backendMust be set to postgresql.
serializerMust be set to postgresql.

其它与 MySQL 后端一致。

PostgreSQL 后端的 driver 和 url 应该设置为:

  • jdbc.driver=org.postgresql.Driver
  • jdbc.url=jdbc:postgresql://localhost:5432/

4.3 - HugeGraph 内置用户权限与扩展权限配置及使用

概述

HugeGraph 内置 StandardAuthenticator,支持多用户认证和基于“用户、用户组、操作、资源”的权限控制。

初始化会创建超级管理员 admin。管理员可创建用户、用户组及资源,并分配或撤销权限。用户通过所属组获得读、写、删除和执行等权限。

资源用 type、label 和 properties 描述可访问的数据。同一资源中的条件需同时满足,多个资源之间满足其一即可。

下面的关系表示用户仅可读取北京地区的数据。

1// 场景:某用户只有北京地区的数据读取权限
2user(name=xx) -belong-> group(name=xx) -access(read)-> target(graph=graph1, resource={label: person, city: Beijing})

配置用户认证

HugeGraph 目前默认未启用用户认证功能,需通过修改配置文件来启用该功能。

警告

生产环境必须启用鉴权

HugeGraph 默认不启用用户认证。生产环境必须启用认证与授权、设置非默认强管理员密码、启用并维护 Server IP 白名单,并按最小权限为用户授权;不得将 Gremlin、Cypher 等查询接口直接暴露到公网。Server 标准配置会将鉴权代理记录写入 audit-*.log,部署时必须保留并限制这些日志的读取权限。auth.audit_log_rate 只限制每用户的日志输出速率,不是审计日志的启停开关。

StandardAuthenticator 支持多用户认证和细粒度权限控制。也可以实现 HugeAuthenticator 接口来接入已有的用户系统。

用户认证使用 HTTP Basic Authentication。Basic 后面的值是 用户名:密码 的 Base64 编码。使用 curl 时可直接通过 -u 传入凭据。

1curl -u 'admin:<password>' \
2  http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels
警告

保护 Basic Authentication 凭据

Basic Authentication 只对 用户名:密码 做 Base64 编码,不会加密凭据。通过网络发送时必须使用 HTTPS;相关设置见 HTTPS 配置。

警告

旧版本 JWT 风险

HugeGraph-Server 1.5.0 之前的版本在鉴权模式下存在 JWT 相关安全隐患。使用受影响版本时必须升级,或按该版本要求修改 JWT token 的 secretKey。

auth.token_secret 由认证数据图的配置读取。默认认证图名为 hugegraph,因此配置文件通常是 conf/graphs/hugegraph.properties;如果修改了 auth.graph_store,应改为对应图的 properties 文件。 核心配置默认会生成 32 个随机字节并以 Base64 编码,该默认值不会自行写回配置文件;重启后或多个 Server 节点之间无法依赖各自生成的默认值保持一致。若需要令已有 token 在重启后继续有效,或让多个节点验证同一 token,请为认证图显式配置同一个强随机密钥。

Server 将配置字符串按 UTF-8 编码后交给 JJWT 的 HS256 签名器,密钥至少需要 32 字节;这是字节长度要求,不代表任意 32 字符串都具有足够随机性。下面的命令在本机生成 32 个随机字节并以 Base64 编码。

1# 在每个 Server 节点的认证图配置中填写同一个值
2auth.token_secret=<本机生成的密钥>

可在本机终端生成密钥,再通过安全方式填入认证图配置;不要把实际密钥提交到代码库或公开日志。

1openssl rand -base64 32

token 的有效期由 auth.token_expire 决定,默认为 86400 秒。

auth.token_expire 和 auth.token_secret 都属于 auth.graph_store 指定的认证数据图配置;rest-server.properties 中的同名项不会覆盖认证图配置。

StandardAuthenticator 模式

StandardAuthenticator 在后端存储用户及密码哈希,并按用户角色控制访问。修改以下三处配置后,按启动顺序初始化并重启服务。

在 conf/gremlin-server.yaml 中配置认证器及 REST 配置路径。

1authentication: {
2  authenticator: org.apache.hugegraph.auth.StandardAuthenticator,
3  authenticationHandler: org.apache.hugegraph.auth.WsAndHttpBasicAuthHandler,
4  config: {tokens: conf/rest-server.properties}
5}

在 conf/rest-server.properties 中配置认证器和权限数据存储图。

1auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator
2auth.graph_store=hugegraph
3# Server 启动路径首次创建内置 admin 账号时使用,默认值为公开的 pa,生产部署前务必显式设置强密码
4# 本地持久化后端首次启用 StandardAuthenticator 时,init-store.sh 会交互式读取密码
5#auth.admin_pa=<your-admin-password>
6
7# auth client config
8# 如果是分开部署 GraphServer 和 AuthServer,还需要指定下面的配置,地址填写 AuthServer 的 IP:RPC 端口
9#auth.remote_url=127.0.0.1:8899,127.0.0.1:8898,127.0.0.1:8897

auth.graph_store 指定保存认证数据的图,名称必须与 conf/graphs/ 中的图配置对应。

在每个受保护图的配置文件 conf/graphs/<graph>.properties 中设置 gremlin.graph。

1gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy

权限 API 的调用方式见 Authentication API 文档。

自定义用户认证系统

实现 org.apache.hugegraph.auth.HugeAuthenticator 接口,再将两处 authenticator 配置指向该实现,即可接入已有用户系统。

基于鉴权模式启动

下面的顺序适用于本地持久化后端,例如 RocksDB。先完成上面的配置,再初始化认证数据。 HStore/PD 部署的管理员由 PD 启动路径创建,须按该部署的配置设置 auth.admin_pa,不要照搬本地后端的交互式初始化流程。

  1. 停止 Server。

    1bin/stop-hugegraph.sh
  2. 初始化认证数据。

    1bin/init-store.sh

    首次创建 admin 时,按提示输入强密码。已有图数据会保留;已有 admin 时不会重新设置其密码。 此命令补充后端与认证系统信息,不需要删除原有存储目录。

  3. 启动并检查认证。

    1bin/start-hugegraph.sh
    2curl -u admin \
    3  http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels

    curl 会提示输入密码。正确密码应返回 HTTP 200;不带凭据或使用错误密码应返回 HTTP 401。 启动失败时先检查日志和认证图配置,不要通过清空数据来重试。

使用 Docker 时开启鉴权模式

使用 Docker 部署时,官方镜像支持通过环境变量直接启用鉴权模式。请根据部署场景选择对应路径:

将占位符替换为实际镜像标签或 digest:

1export HUGEGRAPH_IMAGE='<image:tag-or-digest>'
2read -r -s -p 'Admin password: ' PASSWORD
3printf '\n'
4export PASSWORD

提示输入管理员密码后执行启动命令。为保障凭据安全,请避免将密码以明文形式提交到共享 Compose 文件中。 JWT 密钥仍按上面的配置持久保存到认证图配置;多节点必须使用同一个值。

Docker run

创建一个新容器,并仅向本机开放 REST 端口。

1docker run -d --name server \
2  -p 127.0.0.1:8080:8080 \
3  -e PASSWORD \
4  "$HUGEGRAPH_IMAGE"
5unset PASSWORD

入口脚本完成认证配置和首次初始化后启动 Server。接着阅读检查认证结果。

Docker Compose

将下面的内容保存为 compose.yaml。必填变量缺失时,Compose 会报错,避免意外启动无认证服务。 在同一终端中启动服务。

1services:
2  server:
3    image: ${HUGEGRAPH_IMAGE:?Set HUGEGRAPH_IMAGE}
4    container_name: server
5    ports:
6      - "127.0.0.1:8080:8080"
7    environment:
8      PASSWORD: ${PASSWORD:?Set PASSWORD}
1docker compose up -d
2unset PASSWORD

以后重新创建容器前,需要重新设置这些变量。保留已有数据卷,并按部署要求持久保存配置。 接着阅读检查认证结果。

既有容器

此路径适用于原先未开启认证、使用本地持久化后端的官方 Server 容器。 先备份数据,并确认配置、后端数据及 conf-bak 均位于容器挂载的持久卷中。 官方镜像将 /hugegraph-server 声明为卷;自定义镜像应先检查挂载位置。 HStore/PD 或外部认证服务使用各自的管理员初始化流程。

  1. 停止原容器,使用同一镜像和数据卷打开临时维护容器。

    1SERVER_IMAGE=$(docker inspect --format '{{.Image}}' server)
    2docker stop server
    3docker run --rm -it --volumes-from server \
    4  --entrypoint bash "$SERVER_IMAGE"

    原容器须保持停止,防止两个 JVM 同时打开本地数据库。--entrypoint bash 使维护容器只打开终端。

  2. 在维护容器内修改配置并初始化。

    1cd /hugegraph-server
    2bin/enable-auth.sh

    enable-auth.sh 首次运行时将原配置保存到 conf-bak,然后修改默认 hugegraph 图和认证配置。 如果 conf-bak 已存在,脚本会跳过修改,须按StandardAuthenticator 模式检查三处配置。 使用其他认证图时也应手动配置对应文件。 按上面的配置将强随机 JWT 密钥写入认证图配置,再运行初始化命令。

    1bin/init-store.sh
    2exit

    按提示输入管理员密码,确认初始化成功后退出。

  3. 在宿主机启动原容器。

    1docker start server

    不需要删除 docker/init_complete 标记。后续 PASSWORD 环境变量的变化不会修改已存储的管理员密码。

检查认证结果

等待 Server 启动后,在宿主机执行以下请求验证。-u admin 会交互式提示输入密码:

1curl -sS -o /dev/null -w '%{http_code}\n' \
2  http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels
3curl -sS -o /dev/null -w '%{http_code}\n' -u admin \
4  http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels

未携带凭据的请求预期返回 401 Unauthorized,输入正确密码的请求返回 200 OK(若输入错误密码则同样返回 401)。 注:当前主线版本 URL 包含 /graphspaces/DEFAULT,1.7.0 等历史版本请省略 graphspace 前缀(直接使用 /graphs/hugegraph/...)。 若未提供凭据仍返回 200,说明鉴权未成功启用,请检查配置并重启 Server。

4.4 - 配置 HugeGraphServer 使用 https 协议

概述

HugeGraphServer 默认使用的是 http 协议,可以配置成 https。

警告

HTTPS 不替代服务端鉴权与访问控制

HTTPS 保护传输链路,但不限制调用者权限。生产环境必须使用 HTTPS,并按 Server 认证与授权配置启用 Server Auth、IP 白名单和最小权限授权,同时保留、保护 Server audit-*.log。若由反向代理终结 TLS,还必须限制到 Server 后端端口的网络访问。

警告

生产环境使用专用服务端证书

若启动时找不到 conf/hugegraph-server.keystore,脚本会下载共享的演示 keystore,其密码为公开值 hugegraph。生产环境必须使用专用证书和 keystore 密码,并限制私钥文件的读取权限。

服务端配置

修改 conf/rest-server.properties 配置文件,将 restserver.url 的 schema 部分改为 https。

1# 将协议设置为 https
2restserver.url=https://127.0.0.1:8080
3# 服务端 keystore 文件路径,当协议为 https 时该默认值自动生效,可按需修改此项
4ssl.keystore_file=conf/hugegraph-server.keystore
5# 服务端 keystore 文件密码,当协议为 https 时该默认值自动生效,可按需修改此项
6ssl.keystore_password=******

由于 keystore 文件没有声明许可证,发行包中并不包含它。当 restserver.url 以 https 开头而 conf/hugegraph-server.keystore 不存在时,bin/start-hugegraph.sh 会在启动前从 hugegraph-doc 仓库的 binary-1.5 分支下载该文件,其密码为 hugegraph。 这两项都是 ssl.keystore_file 和 ssl.keystore_password 的默认值,用户可以生成自己的 keystore 文件及密码,然后修改这两个配置项。

客户端配置

在 HugeGraph-Client 中使用 https

在构造 HugeClient 时传入 https 相关的配置,代码示例:

1String url = "https://localhost:8080";
2String graphName = "hugegraph";
3HugeClientBuilder builder = HugeClient.builder(url, graphName);
4// 客户端 keystore 文件路径
5String trustStoreFilePath = "hugegraph.truststore";
6// 客户端 keystore 密码
7String trustStorePassword = "******";
8builder.configSSL(trustStoreFilePath, trustStorePassword);
9HugeClient hugeClient = builder.build();

注意:HugeGraph-Client 在 1.9.0 版本以前是直接以 new 的方式创建,并且不支持 https 协议,在 1.9.0 版本以后改成以 builder 的方式创建,并支持配置 https 协议。

在 HugeGraph-Loader 中使用 https

启动导入任务时,在命令行中添加如下选项:

1# https
2--protocol https
3# 客户端证书文件路径,当指定 --protocol 为 https 时,默认值 conf/hugegraph.truststore 自动生效,可按需修改
4--trust-store-file {file}
5# 客户端证书文件密码,当指定 --protocol 为 https 时,默认值 hugegraph 自动生效,可按需修改
6--trust-store-password {password}

hugegraph-loader 的 conf 目录下已经放了一个默认的客户端证书文件 hugegraph.truststore,其密码是 hugegraph。

在 HugeGraph-Tools 中使用 https

执行命令时,在命令行中添加如下选项:

1# 客户端证书文件路径,当 url 中使用 https 协议时,默认值 conf/hugegraph.truststore 自动生效,可按需修改
2--trust-store-file {file}
3# 客户端证书文件密码,当 url 中使用 https 协议时,默认值 hugegraph 自动生效,可按需修改
4--trust-store-password {password}
5# 执行迁移命令时,当 --target-url 中使用 https 协议时,默认值 conf/hugegraph.truststore 自动生效,可按需修改
6--target-trust-store-file {target-file}
7# 执行迁移命令时,当 --target-url 中使用 https 协议时,默认值 hugegraph 自动生效,可按需修改
8--target-trust-store-password {target-password}

hugegraph-tools 的 conf 目录下已经放了一个默认的客户端证书文件 hugegraph.truststore,其密码是 hugegraph。

如何生成证书文件

本部分给出生成证书的示例,如果默认的证书已经够用,或者已经知晓如何生成,可跳过。

服务端

  1. ⽣成服务端私钥,并且导⼊到服务端 keystore ⽂件中,server.keystore 是给服务端⽤的,其中保存着⾃⼰的私钥
1keytool -genkey -alias serverkey -keyalg RSA -keystore server.keystore

过程中根据需求填写描述信息,默认证书的描述信息如下:

1名字和姓⽒:hugegraph
2组织单位名称:hugegraph
3组织名称:hugegraph
4城市或区域名称:BJ
5州或省份名称:BJ
6国家代码:CN
  1. 根据服务端私钥,导出服务端证书
1keytool -export -alias serverkey -keystore server.keystore -file server.crt

server.crt 就是服务端的证书

客户端

1keytool -import -alias serverkey -file server.crt -keystore client.truststore

client.truststore 是给客户端⽤的,其中保存着受信任的证书

4.5 - 配置 RocksDB 后端

概述

RocksDB 是一个嵌入式的 LSM-tree 键值存储。使用 rocksdb 后端时,HugeGraph-Server 把全部图数据保存在 服务进程内部的 RocksDB 实例中,不需要额外部署存储服务。发布包中的 conf/graphs/hugegraph.properties 默认使用的就是这个后端。

从 1.7.0 版本开始,服务端只接受 memory、rocksdb、hbase 和 hstore 作为后端。rocksdb 后端把 数据写在单台服务器的本地磁盘上,不支持共享存储,因此多个服务无法基于同一个数据目录提供同一个图。 分布式部署请使用 hstore 后端,配合 PD 与 Store。

RocksDB 的 JNI 依赖在 hugegraph-rocksdb/pom.xml 中固定为 8.10.2 版本,因此磁盘格式与各配置项的 语义都以 RocksDB 8.10 为准。

该后端上报的驱动版本是 1.11,在初始化图时会写入 system store 的 meta 表中。

选择后端

在图配置文件(conf/graphs/<graph>.properties)中设置后端与序列化器:

 1gremlin.graph=org.apache.hugegraph.HugeFactory
 2
 3backend=rocksdb
 4serializer=binary
 5
 6store=hugegraph
 7
 8# rocksdb backend config
 9#rocksdb.data_path=/path/to/disk
10#rocksdb.wal_path=/path/to/disk
  • backend=rocksdb 选择 RocksDB 存储实现。
  • serializer=binary 是发布包模板为该后端使用的序列化器。内置的序列化器为 binary、binaryscatter 和 text。
  • store 是该图在后端中的库名,同时也是存储实现拿到的图名的一部分。

首次启动前执行一次 bin/init-store.sh 创建各个 store,然后再启动服务。bin/init-store.sh 与 bin/hugegraph-server.sh 都会加载 RocksDB 库,数据目录在执行这些脚本的机器上创建。

发布包会为打包时 backend.properties 中列出的每个后端注册配置项空间和存储实现,该文件的取值来自 hugegraph.backends 构建属性。默认构建会注册 rocksdb, hbase, hstore;使用 -Drocksdb-only 构建会 激活 rocksdb-only profile,产出的发布包只注册 rocksdb。未注册的后端在启动时会报 Not exists BackendStoreProvider。

注册过程还会额外注册一个名字 rocksdbsst,它对应的实现写出 SST 文件而不是打开一个可用的数据库。 该名字不在允许的后端列表中,因此 backend=rocksdbsst 会被拒绝并报 backend is illegal: rocksdbsst。 如果要把 SST 文件导入普通的 rocksdb 图,请使用下面介绍的 rocksdb.sst_path。

数据目录结构

有两个目录需要关注:rocksdb.data_path(默认 rocksdb-data/data)和 rocksdb.wal_path (默认 rocksdb-data/wal)。相对路径基于服务的工作目录解析,也就是安装目录。

每个图会打开三个 store:m 存放 schema,g 存放图数据,s 是 system store。store 名会拼接到上面 两个路径之后,因此一个默认的单图安装目录如下:

RocksDB 数据目录

  • rocksdb-data/
    • data/
      • m/schema store:属性键、顶点/边/索引标签、计数器
      • g/graph store:顶点、边、索引表、olap 表
      • s/system store:任务、服务信息、后端 meta(驱动版本)
    • wal/
      • m/
      • g/
      • s/

后端的每张表在所属 store 中对应一个 RocksDB 列族,名字形如 <database>+<table>,其中 database 由图名 推导得到。已有数据目录中的列族总是会被重新打开,因此旧版本创建的表仍然可读。

还需要注意:

  • 两个图不能共用同一个数据路径。通过 API 基于已有配置克隆创建图时,存储实现会在 rocksdb.data_path 和 rocksdb.wal_path 后面追加 _<newGraph>。删除这样的图会同时删除这两个目录。
  • 快照创建在数据目录旁边:数据路径的最后两段会加上前缀重写,因此在默认路径下 graph store 的快照位于 rocksdb-data/<prefix>_data/g。恢复快照时会先关闭实例,删除数据目录,再把快照移动到原位置。
  • 设置了 rocksdb.data_disks 时,其中列出的表会在指定路径下作为独立的 RocksDB 实例打开,而不再放在 rocksdb.data_path 下。服务最多并发打开 8 个实例,打开最多等待 600 秒,会话关闭最多等待 30 秒。

路径与日志配置项

config optiondefault valuedescription
rocksdb.data_pathrocksdb-data/dataRocksDB 数据存储路径,不允许为空。
rocksdb.data_disks[]为部分表指定独立磁盘,每个元素格式为 STORE/TABLE: /path/disk。允许的键为 [g/vertex, g/edge_out, g/edge_in, g/vertex_label_index, g/edge_label_index, g/range_int_index, g/range_float_index, g/range_long_index, g/range_double_index, g/secondary_index, g/search_index, g/shard_index, g/unique_index, g/olap]。磁盘路径不能与 rocksdb.data_path 相同。
rocksdb.wal_pathrocksdb-data/walRocksDB WAL 存储路径,不允许为空。
rocksdb.sst_path(空)待导入 RocksDB 的 SST 文件所在路径,为空表示不导入。
rocksdb.log_levelINFORocksDB 的日志级别,可选值:DEBUG、INFO、WARN、ERROR、FATAL、HEADER。

压缩与合并配置项

config optiondefault valuedescription
rocksdb.num_levels7数据库的层数,取值范围 1 到 2^31-1。
rocksdb.compaction_styleLEVELRocksDB 的 compaction 策略:LEVEL/UNIVERSAL/FIFO。
rocksdb.optimize_modetrue针对高负载和大数据量做优化,具体行为见下文的配置项生效方式一节。
rocksdb.bulkload_modefalse切换到批量导入数据的模式。
rocksdb.compression_per_level[none, none, snappy, snappy, snappy, snappy, snappy]各层使用的压缩算法,可选值为 none/snappy/z/bzip2/lz4/lz4hc/xpress/zstd。列表必须为空,或者元素个数正好等于 rocksdb.num_levels。
rocksdb.bottommost_compressionnone最底层使用的压缩算法,可选值为 none/snappy/z/bzip2/lz4/lz4hc/xpress/zstd。
rocksdb.compressionsnappy压缩数据块使用的压缩算法,可选值为 none/snappy/z/bzip2/lz4/lz4hc/xpress/zstd。

数据库级配置项

config optiondefault valuedescription
rocksdb.max_background_jobs8后台任务(包括 flush 和 compaction)的最大并发数,取值范围 1 到 2^31-1。
rocksdb.max_subcompactions4单个 compaction 任务使用的最大线程数,取值范围 1 到 2^31-1。
rocksdb.delayed_write_rate16777216(16 MB/s)当 compaction 落后需要降速时,用户写请求的限速值,单位字节每秒。
rocksdb.max_open_files-1RocksDB 可缓存的最大打开文件数,-1 表示不限制。
rocksdb.max_manifest_file_size104857600(100 MB)manifest 文件的最大字节数。
rocksdb.skip_stats_update_on_db_openfalse打开数据库时是否跳过统计信息更新,设为 true 表示不更新统计信息。
rocksdb.skip_check_sst_size_on_db_openfalse打开数据库时是否跳过检查所有 sst 文件的大小。
rocksdb.max_file_opening_threads16打开文件使用的最大线程数,取值范围 1 到 2^31-1。
rocksdb.max_total_wal_size0WAL 文件的总大小上限,单位字节。超过后会强制 flush 相关的列族,0 表示不限制。
rocksdb.bytes_per_sync0允许操作系统在后台异步地增量同步正在写入的 SST 文件,每写入这么多字节发起一次请求,0 表示关闭。
rocksdb.wal_bytes_per_sync0同上,作用于 WAL 文件,0 表示关闭。
rocksdb.strict_bytes_per_syncfalse为 true 时保证任意时刻提交回写的 SST/WAL 数据不超过 bytes_per_sync/wal_bytes_per_sync 字节,可用于处理写入速度超过 I/O 速度的场景。
rocksdb.db_write_buffer_size0所有列族 write buffer 的总大小上限,单位字节,0 表示不限制。
rocksdb.log_readahead_size0读取日志时预取的字节数,0 表示关闭预取。
rocksdb.compaction_readahead_size0compaction 时批量读取的字节数。如果 RocksDB 跑在机械盘上,建议至少设为 2MB,0 表示关闭预取。
rocksdb.row_cache_capacity0表级行缓存的全局容量,单位字节,0 表示关闭 row_cache。
rocksdb.delete_obsolete_files_period21600(6 小时)删除废弃文件的周期,单位秒,0 表示每次都做完整清理。该值传给 RocksDB 前会换算成微秒。

Memtable 配置项

config optiondefault valuedescription
rocksdb.write_buffer_size134217728(128 MB)在内存中累积的数据量,单位字节,最小 1 MB。该值针对单个列族生效。
rocksdb.max_write_buffer_number6内存中累积的 write buffer 的最大个数,取值范围 1 到 2^31-1。
rocksdb.min_write_buffer_number_to_merge2会被合并到一起的 write buffer 的最小个数,取值范围 1 到 2^31-1。
rocksdb.max_write_buffer_number_to_maintain0使用事务时,为冲突检查在内存中保留的 write buffer 总数上限。
rocksdb.memtable_bloom_size_ratio0.0设置了 prefix-extractor 且该值不为 0,或者 memtable_whole_key_filtering 为 true 时,为 memtable 创建大小为 write_buffer_size * memtable_bloom_size_ratio 的布隆过滤器。大于 0.25 的取值会被收敛为 0.25,取值范围 0.0 到 1.0。
rocksdb.memtable_whole_key_filteringfalse在 memtable 中启用全键布隆过滤器,可以降低点查的 CPU 开销。只有 memtable_bloom_size_ratio > 0 时才生效。
rocksdb.memtable_huge_page_size0memtable 中布隆过滤器使用的 huge page TLB 的页大小,小于等于 0 时不从 huge page TLB 分配,改用 malloc。
rocksdb.inplace_update_supportfalse当写入的键已存在于当前 memtable 且新值更小时,允许线程安全的原地更新。

层级大小与写入限流配置项

config optiondefault valuedescription
rocksdb.level_compaction_dynamic_level_bytesfalse是否启用 level_compaction_dynamic_level_bytes。启用后 max_bytes_for_level_multiplier 的优先级高于 max_bytes_for_level_base,基准层的大小是动态的,LSM tree 更可预测,有助于限制最差情况下的空间放大。对已有数据库开关该特性可能造成异常的 LSM tree 结构,因此不推荐改动。
rocksdb.max_bytes_for_level_base536870912(512 MB)level-1 文件总大小的上限,单位字节,最小 1 MB。
rocksdb.max_bytes_for_level_multiplier10.0对所有层 L,第 L+1 层文件总大小与第 L 层文件总大小的比值,最小 1.0。
rocksdb.target_file_size_base67108864(64 MB)compaction 的目标文件大小,单位字节,最小 1 MB。
rocksdb.target_file_size_multiplier1第 L 层文件与第 L+1 层文件的大小比值。
rocksdb.level0_file_num_compaction_trigger2触发 level-0 compaction 的文件数。
rocksdb.level0_slowdown_writes_trigger20触发写入降速的 level-0 文件数软上限。
rocksdb.level0_stop_writes_trigger36触发停写的 level-0 文件数硬上限。
rocksdb.soft_pending_compaction_bytes_limit68719476736(64 GB)待 compaction 数据量的软上限,单位字节,最小 1 GB。
rocksdb.hard_pending_compaction_bytes_limit274877906944(256 GB)待 compaction 数据量的硬上限,单位字节,最小 1 GB。

文件 I/O 配置项

config optiondefault valuedescription
rocksdb.allow_mmap_writesfalse允许操作系统以 mmap 方式写文件。
rocksdb.allow_mmap_readsfalse允许操作系统以 mmap 方式读取 sst 文件。
rocksdb.use_direct_readsfalse读取 sst 文件时使用直接 I/O。
rocksdb.use_direct_io_for_flush_and_compactionfalseflush 和 compaction 时使用直接读写。
rocksdb.use_fsyncfalse为 true 时每次持久化都会执行 fsync。
rocksdb.atomic_flushfalse为 true 时多个列族的 flush 结果会原子地提交到 MANIFEST。WAL 一直开启的情况下不必设置该项。

SST 表格式与块缓存配置项

config optiondefault valuedescription
rocksdb.format_version5BlockBasedTable 的格式版本,可选值为 0~5。
rocksdb.index_typekBinarySearchsst 文件中数据块之间查找使用的索引类型,可选值为 [kBinarySearch, kHashSearch, kTwoLevelIndexSearch, kBinarySearchWithFirstKey]。
rocksdb.data_block_index_typekDataBlockBinarySearchsst 文件数据块内点查使用的查找类型,可选值为 [kDataBlockBinarySearch, kDataBlockBinaryAndHash]。
rocksdb.data_block_hash_table_util_ratio0.75哈希表 entries/buckets 的使用率,仅在 data_block_index_type=kDataBlockBinaryAndHash 时有效,取值范围 0.0 到 1.0。
rocksdb.block_size4096(4 KB)每个块中打包的用户数据的近似大小,注意对应的是未压缩的数据。
rocksdb.block_size_deviation10用于结束一个块的空闲空间百分比,取值范围 0 到 100。
rocksdb.block_restart_interval16块内增量编码的 restart 间隔。
rocksdb.block_cache_capacity8388608(8 MB)RocksDB 使用的块缓存大小,单位字节,0 表示不使用块缓存。每个列族都会创建一个该大小的独立缓存。

布隆过滤器配置项

只有 rocksdb.bloom_filter_bits_per_key 大于等于 0 时,本组的配置项才会被读取。默认值 -1 表示不启用 布隆过滤器,此时本表中其他配置项都不生效,包括索引和过滤块的缓存相关项。

config optiondefault valuedescription
rocksdb.bloom_filter_bits_per_key-1布隆过滤器中每个键占用的位数,10 是一个不错的取值,对应约 1% 的误判率。大于 0 表示启用布隆过滤器,-1 表示不启用(0~0.5 向下取整为不启用)。
rocksdb.bloom_filter_block_based_modefalse启用布隆过滤器时,设为 true 表示使用 block based filter 而不是 full filter。
rocksdb.bloom_filter_whole_key_filteringtrue启用布隆过滤器时,设为 true 表示把完整的键放入布隆过滤器,否则在设置了 prefix-extractor 时放入键的前缀。
rocksdb.cache_index_and_filter_blockstrue设为 true 表示把索引块和过滤块放入块缓存。
rocksdb.pin_l0_filter_and_index_blocks_in_cachetrue设为 true 表示把 L0 的索引块和过滤块固定在块缓存中。
rocksdb.optimize_filters_for_hitstrue启用布隆过滤器时,该开关允许不为最后一层存储过滤器,设为 true 表示主要针对命中的场景优化过滤器,而不是同时优化未命中的场景。该项在过滤器关闭时也会生效。
rocksdb.partition_filters_and_indexesfalse启用布隆过滤器时,设为 true 表示每个 sst 文件使用分区的 full filter 和索引。该项与 block based filter 不兼容。开启后索引类型会被强制为 kTwoLevelIndexSearch,元数据块大小取 rocksdb.block_size。
rocksdb.pin_top_level_index_and_filtertrue当 partition_filters_and_indexes 为 true 时,设为 true 表示把分区过滤块和索引块的顶层索引固定在块缓存中。
rocksdb.prefix_extractor_n_bytes0prefix-extractor 取键的前 N 个字节作为前缀,键长度小于 N 时使用完整键,0 表示不设置 prefix-extractor。

配置项的生效方式

服务为每个 store 和每个列族构建一次 RocksDB 的选项对象,因此上面任何配置项的修改都在下次启动服务时 生效。

  • rocksdb.optimize_mode=true 会在应用上表中的取值之前先套用一组预设:数据库层面把并行度提高到可用 处理器数的一半(至少 1),允许 memtable 并发写入,并开启写线程自适应让出;列族层面调用 RocksDB 的 level-style 和 universal-style compaction 预设。显式配置项在之后应用,因此配置文件中写明的取值会覆盖 预设。
  • rocksdb.bulkload_mode=true 会关闭自动 compaction,把三个 level-0 触发阈值提高到 int 最大值,把两个 待 compaction 上限提高到 long 最大值。导入结束后要关闭它并重启,否则 compaction 不会运行。
  • rocksdb.block_cache_capacity=0 表示彻底关闭块缓存,而不是不限制大小。
  • rocksdb.prefix_extractor_n_bytes 大于 0 时会安装一个该长度的 capped prefix extractor。
  • 所有列族都使用 uint64add merge 操作符,计数器表依赖它。
  • 数据库不存在时会自动创建,avoid_unnecessary_blocking_io 和 write_dbid_to_manifest 始终开启。

内存说明

RocksDB 的缓存和 write buffer 都是本地内存分配,不属于 bin/hugegraph-server.sh 中设置的 JVM 堆。 GET /metrics/backend 接口会返回存储的使用量:内存数值是所有已打开列族的块缓存用量、固定在块缓存中的 用量、预估的 table reader 内存(索引块和过滤块)以及全部 memtable 大小之和,取自 RocksDB 的属性。

有两个配置项的实际占用会随列族数量成倍增长:

  • rocksdb.block_cache_capacity 为每个列族创建一个缓存实例,因此一台服务的块缓存总量大致等于该值乘以 所有图的 m、g、s 三个 store 中已打开表的数量,再加上 rocksdb.data_disks 额外打开的实例。
  • rocksdb.write_buffer_size 乘以 rocksdb.max_write_buffer_number 限定的是单个列族的 memtable 内存。 rocksdb.db_write_buffer_size 限制一个 store 内所有列族的总量,默认值 0 表示没有这个限制。

rocksdb.row_cache_capacity 不同:它是每个 store 一个缓存,0 表示关闭。

导入 SST 文件

设置 rocksdb.sst_path 即开启导入。打开 store 时以及每次创建表时,服务会遍历 <sst_path>/<column family>/ 目录,收集其中所有非空的 *.sst 文件,导入到对应的列族。导入采用移动 文件的方式而不是复制,因此源目录会被导入过程消耗掉。

raft 模式

RocksDB 后端仍然可以运行在 raft 状态机之后:raft.mode=true 时,本地后端的存储实现会被 raft 实现包装。 包装层会拒绝共享存储的后端,因此 rocksdb 可用而 hbase 不可用。raft 模式下 RocksDB 会话写入时关闭 WAL 且不做 sync,因为状态机可以通过快照加 raft 日志恢复,而该后端支持快照。

使用时需要注意:

  • bin/init-store.sh 在初始化后端时会强制把 raft.mode 置为 false,因此初始化过程不会走 raft。
  • 发布包中的 conf/graphs/hugegraph.properties 已把 raft 相关配置标记为废弃。1.7.0 及之后版本的分布式 部署改用 hstore 后端,配合 PD 与 Store。
  • raft 成员管理接口位于 graphspaces/{graphspace}/graphs/{graph}/raft/ 之下,包括 list_peers、 get_leader、set_leader、transfer_leader、add_peer 和 remove_peer。bin/raft-tools.sh 封装了 同样的操作,但它拼接的 URL 中仍然没有 graphspace 段,在 1.7.0 的服务上需要调整路径才能使用。
  • 其余 raft.* 配置项见 Server 配置选项。

后端能力

该后端的特性开关决定了哪些操作可以下推给存储:

  • 支持按键前缀扫描、按键范围扫描、分页查询、范围条件和 order-by。
  • RocksDB 内部没有索引,因此按名字查询 schema、按标签查询以及按标签删除边由服务端完成,而不是由存储 完成。
  • 通过 RocksDB 的 write batch 支持事务。
  • 支持快照,raft 模式和备份依赖该能力。
  • 不支持共享存储,一个数据目录属于一台服务。
  • 支持 olap 属性,对应的表会作为额外的列族创建。
  • 存储本身不会让数据过期,因此服务端在读取时过滤掉 TTL 已到期的元素。
  • 存储层不支持 in、contains、contains_key 条件,不支持聚合属性,也不支持原地更新顶点或边的属性。

riscv64 平台说明

在 Linux riscv64 上,RocksDB 的 JNI 库需要 libatomic.so.1。bin/util.sh 会查找该库并在 bin/hugegraph-server.sh、bin/init-store.sh 和 bin/dump-store.sh 启动 JVM 之前把它加入 LD_PRELOAD。如果找不到,这些脚本会以 RISC-V RocksDB requires libatomic.so.1; install libatomic1 退出,安装 libatomic1 包即可解决。

4.6 - 配置 HStore 分布式后端

1 概述

hstore 是 HugeGraph 的分布式存储后端。图使用该后端时,HugeGraph-Server 本地磁盘上不保存任何图数据,数据由另外两个进程负责:

  • HugeGraph-PD(Placement Driver)保存集群元数据:已注册的 Store 列表、每个图的分区布局、分区到 Store 的映射关系、图的 Schema 以及 Schema 的 id 计数器。
  • HugeGraph-Store 保存实际的键值数据,并通过 Raft 在多个 Store 节点之间复制。

Server 进程内嵌了 PD 客户端和 Store 客户端。每次读写时,它先向 PD 查询该 key 属于哪个分区、当前哪个 Store 节点是这个分区的 leader,然后把请求直接发给这个 Store 节点。

服务端的适配层是 hugegraph-hstore 模块,它以后端名 hstore 注册,驱动版本为 1.13。

选择 hstore 影响的不只是数据写到哪里,Server 还会根据后端类型切换下列行为:

方面使用 hstore使用本地后端
Schema 存储通过 PD 元数据驱动读写 SchemaSchema 保存在 m store 中
Schema id通过 PD 客户端由 PD 分配由 schema store 分配
System store没有独立的 system store,系统数据写入 graph store独立的 s store
任务调度器distributedlocal
权限管理器StandardAuthManagerV2StandardAuthManager
后端版本校验读取 graph store读取 system store
init-store.sh跳过该图,元数据由 PD 和 Store 负责创建本地 store

2 前置条件

hstore 不能独立工作。在 Server 打开 hstore 图之前,PD 集群和至少一个 Store 节点必须已经运行,并且启动顺序如下:

  1. PD,先启动以便组成 Raft 组。
  2. Store,通过 gRPC 向 PD 注册。gRPC 地址出现在 PD 自身 pd.initial-store-list 中的 Store 会直接进入 Up 状态;不在该列表中、并且 PD 从未见过它处于 Up 或 Offline 的 Store 会注册为 Pending, 需要先激活才能提供数据服务。
  3. Server,随后从 PD 读回 Store 列表。

服务端需要关注的默认端口:

进程gRPC 端口REST 端口
PD86868620
Store85008520

服务端的 pd.peers 指向 PD 的 gRPC 端口,而不是 REST 端口。

另外两个进程的安装与配置方式,参见 安装/构建 HugeGraph-PD 和 安装/构建 HugeGraph-Store。

3 选择 hstore 后端

3.1 图配置文件

在图的属性文件(例如 conf/graphs/hugegraph.properties)中设置后端:

1backend=hstore
2serializer=binary
3store=hugegraph
4pd.peers=127.0.0.1:8686

关于这四个配置项:

  • backend=hstore 选择该适配层。自 1.7.0 起允许的取值为 memory、rocksdb、hbase 和 hstore。 发行包中做校验的位置对该值不区分大小写。
  • serializer=binary 是必需的。注册 hstore 后端时只注册了配置空间和存储 provider,并没有注册自己的 序列化器,适配层就是按二进制序列化器编写的。serializer 的内置默认值是 text,因此必须显式写出该项。
  • store=hugegraph 是 PD 看到的图名中的命名空间部分。Server 以 <graphspace>/<store> 打开 provider, 每个底层 store 再追加自己的后缀,因此 PD 中每个 store 对应一个图条目:图数据是 DEFAULT/hugegraph/g,schema store 位是 DEFAULT/hugegraph/m。graphspace 默认为 DEFAULT, g 和 m 是固定的。
  • pd.peers 是以逗号分隔的 PD gRPC 地址列表。适配层从图配置中读取该项,而不是从 rest-server.properties 中读取,图级别的元数据连接也使用同一个值。

如果图配置文件中没有 pd.peers,那么在加载图时,只要 usePD 为 true 或者后端是 hstore, Server 会把 rest-server.properties 中的值复制到图配置里。不过在图配置文件中显式写出该项更清晰。

3.2 rest-server.properties

1# use pd
2usePD=true
3pd.peers=127.0.0.1:8686

usePD=true 让 Server 在启动时从 PD 加载元数据。在这条路径上,它会把元数据管理器连接到 PD,创建内置的 admin 账号和默认图空间,加载图空间与服务,创建内部的系统图(后端固定为 hstore),并加载 PD 中保存的图配置。

它和图级别的 backend=hstore 是两个独立的开关:一个图可以使用 hstore 而 usePD 保持默认的 false,此时 Server 不会走基于 PD 的元数据路径。发行包自带的测试启动脚本在后端为 hstore 时会设置该项。

3.3 发行包中的模板文件

发行包在 conf/graphs/hstore.properties.template 中提供了一份该后端的现成图配置文件。它与 hugegraph.properties 的差别是:把 backend 设为 hstore、不注释 pd.peers=127.0.0.1:8686、 并且不包含内存管理配置段。

hstore 的 Docker 镜像会自动套用这份模板:它删除 conf/graphs/hugegraph.properties,再把模板重命名过去,因此容器启动时就已经选好了 hstore 后端。

本地构建的发行包默认编译了 hstore provider。rocksdb-only 这个 Maven profile 会把编译进去的后端列表 收窄为只有 rocksdb,backend=hstore 在 provider 工厂检查后会报 Not exists BackendStoreProvider: hstore。

4 hstore 配置项

hstore 配置空间中只有下面两个配置项,它们写在图的属性文件里。

配置项默认值说明
hstore.partition_count0分区数量,PD 依据该值控制分区(Number of partitions)。
hstore.shard_count0副本数量,PD 依据该值控制分区副本(Number of copies)。

4.1 hstore.partition_count

每个 graph store 第一次被打开时,Server 会把这个数字连同图名一起发给 PD。取负值会在此处被拒绝,报错信息为 The value of hstore.partition_count cannot be less than 0.

PD 对该值的处理方式:

  • 0,也就是默认值,表示交给 PD 决定。对图数据 store,PD 使用自身集群级别的分区总数,该总数由 pd.initial-store-list 中的条目数量、partition.store-max-shard-count 和 partition.default-shard-count 推算得出;对 /m 和 /s store 固定使用 1。
  • 取值在 1 到该总数之间时,按原值使用。
  • 取值大于该总数时,会被下调到该总数。

该数字在 store 首次向 PD 注册时生效,之后再修改属性文件不会让已有的图重新分区。

4.2 hstore.shard_count

hstore.shard_count 声明在 hstore 配置空间中,属性文件里也接受该项,但当前版本服务端没有任何代码读取它:适配层读取的只有 hstore.partition_count 一项。实际生效的副本数由 PD 的配置决定,即 PD application.yml 中的 partition.default-shard-count。

5 只在 hstore 模式下生效的其他配置项

下列配置项位于公共的 rest-server.properties 和图属性文件中,但只有在使用 PD 和 hstore 后端时才生效,或者才会改变行为。source 列给出该配置项在本轮核对的 Server 主线提交 2f827d6 中的声明位置(文件与行号)。

配置项文件默认值在 hstore 模式下的作用source
pd.peersrest-server.properties127.0.0.1:8686用于元数据、服务发现和系统图的 PD 地址ServerOptions.java:195-201
pd.peers{graph}.properties127.0.0.1:8686后端适配层自身使用的 PD 地址CoreOptions.java:649-654
usePDrest-server.propertiesfalseServer 启动时是否从 PD 加载元数据ServerOptions.java:401-407
clusterrest-server.propertieshg-test集群名,作为所有 PD 元数据 key 的前缀ServerOptions.java:187-193
init_store.enabledrest-server.propertiestruePD/Store 部署下应设为 false,元数据已由存储侧负责ServerOptions.java:382-390
graph.load_from_local_configrest-server.propertiesfalse控制构造阶段预加载。应用初始化仍扫描并尝试加载本地配置,false 不会阻止本地加载。图配置变化通过重启 Server 应用。ServerOptions.java:366-372
auth.graph_storerest-server.propertieshugegraph保存权限数据的图,关闭 init-store 时会校验它使用 hstore 后端ServerOptions.java:602-609
graphspace{graph}.propertiesDEFAULTPD 看到的图名的第一段CoreOptions.java:679-685

init-store.sh 从不初始化 hstore 图。在开启的路径上,它扫描 conf/graphs 并跳过后端为 hstore 的每一个图。如果用 init_store.enabled=false 整体关闭这一步,它会改为校验 admin 账号仍然能在 PD 启动路径上被创建: usePD 必须为 true、权限图必须存在于本地配置中且后端为 hstore、auth.admin_pa 必须显式设置为非空值。否则启动会直接失败,而不是使用公开的默认密码创建账号。

6 Server 如何通过 PD 发现 Store

适配层在进程中第一次打开 hstore 图时,一次性构建这些客户端:

  1. 用 pd.peers 构建 PD 客户端配置,带上 PD 的鉴权凭据,并开启客户端侧的分区缓存。
  2. 创建进程级的 PD 客户端。
  3. 用该 PD 客户端创建进程级的 Store 客户端。

创建 Store 客户端时,会把一个基于 PD 的分区器同时注册为 Store 客户端节点管理器的 node provider、 partitioner 和 notifier。路由逻辑全部在这个分区器中:

  • 单点和前缀请求:向 PD 查询拥有该 key 的分区,取该分区的 leader 副本,把请求发到对应的 store id。
  • 按 code 的范围扫描:按 code 逐个遍历分区直到覆盖整个范围,每个分区产生一个目标 Store。
  • 全图扫描:向 PD 查询该图的活跃 Store,并向全部 Store 扇出请求。
  • Store 地址解析:通过 PD 把 store id 解析成主机和端口。
  • 缓存失效:当某个 Store 返回分区 leader 已迁移时,notifier 会更新 PD 客户端缓存中的分区 leader 并使过期的分区条目失效,之后的请求就会跟随新的 leader。

由于 Store 列表来自 PD 而不是配置文件,增删 Store 节点只需要针对同一个 PD 集群启动或停止它,服务端不需要改任何配置。

7 后端能力

hstore 并不支持本地后端的所有查询形式。对用户可见的差异如下:

特性是否支持
按 key 前缀扫描支持
按 key 范围扫描支持
带范围条件的查询支持
带 order by 的查询支持
分页查询支持
OLAP 属性支持
Task 和 Server 顶点支持
Scan token不支持
按名称查询 Schema不支持
按 label 查询不支持
带 in 条件的查询不支持
带 contains 的查询不支持
带 contains key 的查询不支持
按输入 id 顺序排序不支持
按 label 删除边不支持
更新顶点属性不支持
更新边属性不支持
事务不支持
Number 类型不支持
聚合属性不支持
TTL不支持

不支持按输入 id 顺序排序,是因为多节点批量扫描会按 Store 对输入 key 分组,从而丢失全局顺序;不支持更新顶点和边属性,是因为属性被存放在单个 cell 中。

8 验证

Server 启动后,后端指标接口会返回 PD 当前认为处于活跃状态的 Store 数量:

1curl http://localhost:8080/metrics/backend

响应中的 nodes 就是 PD 返回的活跃 Store 数量。nodes 为 0 说明 Server 连上了 PD,但 PD 中没有状态为 Up 的 Store,通常是 Store 节点还没注册,或者因为不在 PD 的 pd.initial-store-list 中而注册成了 Pending。

4.7 - 配置 HBase 后端

概述

HBase 后端将图数据存储在 Apache HBase 表中。HugeGraph 仅作为 HBase 客户端:它通过 HBase 的 ZooKeeper 集群连接,为每个图创建一个 HBase namespace,并在其中创建该图的 schema 表、数据表和索引表。计数查询由 HBase 的 AggregateImplementation 协处理器完成,HugeGraph 在创建每张表时都会挂载该协处理器。

注意:HBase 后端已废弃,计划在 HugeGraph 2.0 中移除。新部署请使用 hstore(分布式)或 rocksdb(内嵌,默认值),已有的 HBase 部署请规划迁移。

自 1.7.0 起,发行包内置的后端只有 hstore、rocksdb、hbase 和 memory。HBase provider 上报的后端驱动版本为 1.12。

支持的 HBase 版本

客户端 jar 固定为 HBase 2.6.5(hbase-endpoint 加 hbase-shaded-client)。服务端要求 HBase 2.x:当检测到的 HBase 版本低于 2.0 时,scan 逻辑会把 inclusive stop row 改写为 exclusive 并追加一个 0 字节,因为该版本之前 inclusive stop row 不生效。CI 任务和本地 Docker 镜像都使用 HBase 2.6.5,后端也是针对这个版本做测试的。

选择该后端

修改需要使用 HBase 的图的 conf/graphs/hugegraph.properties:

1backend=hbase
2serializer=hbase
3
4# namespace 名称由该值推导得出
5store=hugegraph
6
7hbase.hosts=localhost
8hbase.port=2181
9hbase.znode_parent=/hbase

注意:serializer 必须设置为 hbase,而不是 binary。HBase 序列化器是 BinarySerializer 的子类,它不在 rowkey 中写入 id 前缀,并写入预分区的顶点表和边表所需要的分区前缀。使用 serializer=binary 时这两点都不生效。

然后初始化后端并启动服务:

1./bin/init-store.sh
2./bin/start-hugegraph.sh

默认发行包构建时包含 rocksdb, hbase, hstore 三个后端,无需额外引入 jar。使用 rocksdb-only Maven profile 构建的发行包不包含 HBase 后端,此时 backend=hbase 会以 Not exists BackendStoreProvider: hbase 打开失败。

下面所有配置项都位于图配置文件(conf/graphs/hugegraph.properties)中,而不是 rest-server.properties。只有当发行包包含 hbase 后端时,这些配置项才会被注册。

连接配置项

配置项默认值说明
hbase.hostslocalhostHBase ZooKeeper 的主机名或 IP 地址,多个以逗号分隔,不允许为空。对应 hbase.zookeeper.quorum。
hbase.port2181HBase ZooKeeper 的端口,取值范围 1 到 65535。对应 hbase.zookeeper.property.clientPort。
hbase.znode_parent/hbaseHBase ZooKeeper 的 znode 父路径,不允许为空。对应 zookeeper.znode.parent。
hbase.zk_retry3HBase ZooKeeper 的恢复重试次数,取值范围 0 到 1000。对应 zookeeper.recovery.retry。
hbase.threads_max64HBase 连接的最大线程数,取值范围 1 到 1000。对应 hbase.hconnection.threads.max,HBase 自身默认值为 256,这里取更小的值以避免内存溢出。

超时配置项

配置项默认值说明
hbase.truncate_timeout30等待后端 truncate 的超时时间,单位秒,必须为正数。该超时按 store 计算,而一个图有三个 store,因此一次 truncate 最多耗时该值的三倍。
hbase.aggregation_timeout43200(12 小时)等待聚合的超时时间,单位秒,必须为正数。它会设置计数查询所用聚合客户端的 hbase.rpc.timeout。

Kerberos 与 HBase 配置文件配置项

配置项默认值说明
hbase.kerberos_enablefalse是否为 HBase 启用 Kerberos 认证。
hbase.krb5_conf/etc/krb5.confKerberos 配置文件,包含 KDC IP、默认 realm 等。会被设置为 java.security.krb5.conf 系统属性。
hbase.hbase_site/etc/hbase/conf/hbase-site.xmlHBase 的配置文件。无论是否启用 Kerberos,每次建立连接时都会把它作为配置资源加载。
hbase.kerberos_principal(空)Kerberos 认证使用的 HBase principal。
hbase.kerberos_keytab(空)Kerberos 认证使用的 HBase keytab 文件。

当 hbase.kerberos_enable=true 时,HugeGraph 会在连接上把 hadoop.security.authentication 和 hbase.security.authentication 设置为 kerberos,然后在打开连接之前用配置的 principal 从 keytab 登录。因此 Kerberos 环境下 hbase.krb5_conf、hbase.hbase_site、hbase.kerberos_principal 和 hbase.kerberos_keytab 四项都必须有效:

1hbase.kerberos_enable=true
2hbase.krb5_conf=/etc/krb5.conf
3hbase.hbase_site=/etc/hbase/conf/hbase-site.xml
4hbase.kerberos_principal=hugegraph/host@EXAMPLE.COM
5hbase.kerberos_keytab=/etc/security/keytabs/hugegraph.keytab

即使关闭 Kerberos,hbase.hbase_site 也会被读取,路径不存在时相当于加载了一个空资源。当需要上述配置项之外的 HBase 设置时,把它指向集群自身的 hbase-site.xml。

预分区配置项

配置项默认值说明
hbase.enable_partitiontrue是否为 HBase 启用预分区。它同时决定后端是否声明支持前缀扫描和范围扫描。
hbase.vertex_partitions10HBase 顶点表的分区数,不允许为负数。
hbase.edge_partitions30HBase 边表的分区数,不允许为负数。

启用预分区后,顶点表按 hbase.vertex_partitions 个 region 创建,两张边表各按 hbase.edge_partitions 个 region 创建,序列化器会在 rowkey 前面加上 id 哈希得到的分区前缀。

注意:请在初始化后端之前,按实际数据量和 region server 数量调整分区数。它对导入速度影响很大,并且只在建表时生效。

关闭 hbase.enable_partition 会恢复不带前缀的原始 rowkey。作为交换,后端此时会声明支持前缀扫描和范围扫描,这两类扫描在预分区 rowkey 下无法工作。

Namespace 与表结构

每个图对应一个 HBase namespace,名称为 <graphspace>/<store> 转小写,并把 / 替换为 _,因为 HBase namespace 名称只允许字母数字和 _ 字符。在默认配置 graphspace=DEFAULT、store=hugegraph 下,namespace 为 default_hugegraph。

在该 namespace 内,一个图包含三个 store:schema store m、graph store g 和 system store s:

Store表
schema (m)VL、EL、PK、IL、C、m_si
graph (g)g_v、g_oe、g_ie、g_si、g_vi、g_ei、g_ii、g_fi、g_li、g_di、g_ai、g_hi、g_ui
system (s)s_v、s_oe、s_ie、s_si、s_vi、s_ei、s_ii、s_fi、s_li、s_di、s_ai、s_hi、s_ui、M

g_v 是顶点表,g_oe 和 g_ie 分别是出边表和入边表,其余 g_* 表依次是二级索引、顶点标签索引、边标签索引、范围索引(int、float、long、double)、全文索引、shard 索引和唯一索引表。所有表都只有一个名为 f 的列族,并且都在建表时挂载了 org.apache.hadoop.hbase.coprocessor.AggregateImplementation 协处理器。只有 g_v、g_oe 和 g_ie 会预分区,system store 中同名的那几张表按单个 region 创建。

system store 中的 M 表保存 init-store.sh 写入的后端版本。truncate 图时会排除该表,因为丢失它会导致下次启动的版本校验失败。清空图会删除这些表;连同存储空间一起清空则会删除整个 namespace。

GET /metrics/backend 会返回 HBase 集群状态:cluster_id、master_name、average_load、hbase_version、region_count、leaving_servers、nodes、region_servers,以及一个 servers map,其中包含每个 region server 的堆内存、磁盘、请求数和 region 明细。PUT /graphspaces/{graphspace}/graphs/{name}/compact 会请求 HBase 对该图的所有表做 compaction。

使用 Docker 做本地测试

Server 仓库中的 docker/hbase 会构建一个 HBase 2.6.5 单机镜像(hugegraph/hbase:2.6.5,容器名 hg-hbase-test),用于本地开发和测试。以下命令都在仓库根目录执行。

为运行在宿主机上的 HugeGraph 启动 HBase:

1docker compose -p hg-hbase -f docker/hbase/docker-compose.hbase.yml build --no-cache hbase
2HBASE_MASTER_HOSTNAME=localhost HBASE_REGIONSERVER_HOSTNAME=localhost \
3docker compose -p hg-hbase -f docker/hbase/docker-compose.hbase.yml up -d
4until docker exec hg-hbase-test nc -z localhost 2181 >/dev/null 2>&1; do sleep 2; done

为运行在同一个 Docker 网络中的容器化 HugeGraph 启动 HBase:

1HBASE_HOSTNAME=hbase docker compose -p hg-hbase -f docker/hbase/docker-compose.hbase.yml up -d

对外公布的主机名很重要:容器启动时会把 HBASE_MASTER_HOSTNAME 和 HBASE_REGIONSERVER_HOSTNAME 写入自己的 hbase-site.xml,未设置时回退到 HBASE_HOSTNAME(默认 hbase)。如果客户端无法解析这个主机名,即使 ZooKeeper 可用,也会报 UnknownHostException: hbase:16000。

映射到宿主机的端口:

端口服务
2181ZooKeeper,与 hbase.port 默认值一致
16000HBase Master RPC
16010HBase Master Web UI,http://localhost:16010
16020HBase RegionServer RPC
16030HBase RegionServer Web UI,http://localhost:16030

针对它运行后端测试:

1mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,hbase

停止并删除数据卷:

1docker compose -p hg-hbase -f docker/hbase/docker-compose.hbase.yml down -v

该镜像会分别启动 ZooKeeper、master 和 region server 三个守护进程,并等到 master 上报有存活的 server 之后才开始 tail 日志,因此首次启动会比较慢。请给 Docker 分配至少 4 GB 内存。compose 的健康检查也因此设置了 90 秒的 start period。

限制

HBase 后端不支持以下特性:

  • 事务。rollback 只会丢弃尚未提交的批次,而 commit 是逐表写入的,因此跨表不是原子的。
  • 原地更新单个顶点或边属性,以及合并顶点属性。属性存放在一个 cell 中,因此会重写整个属性列。
  • 按名称查询 schema,以及仅按标签查询顶点或边。这两者都需要 HBase 二级索引。
  • 按标签删除边。
  • 带 in 条件、contains 条件或 contains_key 条件的查询。
  • 聚合属性和 OLAP 属性。
  • 原生数值类型(后端特性 supportsNumberType 为关闭状态)。
  • scan token。
  • hbase.enable_partition 为 true 时的前缀扫描和范围扫描。
  • 除 count 以外的聚合函数,其它聚合函数会被拒绝。
  • 快照。创建或恢复后端快照会抛出 UnsupportedOperationException。

已支持的特性包括顶点和边的 TTL、分页查询、order by 查询、范围条件,以及按输入 id 排序。

5 - 客户端与 API

通过 RESTful API、多语言客户端/SDK 与 Gremlin Console 连接并操作 HugeGraph。

HugeGraph 提供多层次的访问与接入方式,涵盖标准化 RESTful API、多语言客户端/SDK 以及命令行交互式控制台。当前 Server REST API 使用图空间(GraphSpace)和图名称组成资源路径;具体路径以各 API 页面和 Server 的 OpenAPI 页面为准。

模块指引

  • RESTful API

    基于 HTTP 的 REST 接口规范,覆盖图空间管理、元数据定义、顶点与边 CRUD、任务管理、指标监控等全量服务端能力。

  • 客户端/SDK

    提供 Java、Python、Go 等语言的官方客户端 SDK,支持管理 Schema、读写顶点与边数据、执行 Gremlin 查询及调用高级图算法。

  • Gremlin Console

    基于 Apache TinkerPop 的交互式命令行控制台,适合离线图操作、连接 Server 调试脚本与快速验证图遍历。

5.1 - HugeGraph RESTful API

本目录介绍当前 master 的 REST API。历史版本用法请切换到对应的多版本文档: HugeGraph 1.7 RESTful API 或 HugeGraph 1.5 RESTful API。

默认图空间名是 DEFAULT。

HugeGraph 提供了完备的 RESTful HTTP API,涵盖 Schema 管理、图数据读写、图实例与图空间运维、认证鉴权及分析计算。默认图空间名为 DEFAULT。

Server 启动后,可直接访问 http://localhost:8080/swagger-ui/index.html 在线查看 OpenAPI 交互文档与调试接口(参见 Swagger UI 使用示例)。

5.1.1 - Graphspace API

Graphspace(图空间)REST 接口:多租户与资源隔离的创建、查看、更新与删除,以及使用前置条件与限制。

2.0 Graphspace

在 HugeGraph 中,多租户是通过图空间(graph space)来实现的,资源的分配和隔离可以通过图空间进行。

重要前置条件:

  1. 目前图空间功能只支持在 hstore 模式下使用。
  2. 如果非 hstore 模式,则只能使用默认的图空间 DEFAULT,且不支持创建、删除和更新图空间的操作。
  3. 注意在 rest-server.properties 中,设置 usePD=true,并且 hugegraph.properties 中,设置 backend=hstore
  4. 生产环境必须启用 Server 认证与授权,并将新建图空间的 auth 设为 true。生产管理员密码必须替换公开默认值 pa(由 auth.admin_pa 配置)。
  5. 本页所有接口都只在 PD 模式下可用,单机模式下会返回 400 和 GraphSpace management is not supported in standalone mode 错误信息。
警告

限制图空间列表和详情接口的访问

GET /graphspaces 和 GET /graphspaces/{graphspace} 均未声明 @RolesAllowed;Server 未启用鉴权时这两个接口可匿名调用,启用鉴权后也没有方法级管理员角色限制。详情响应包含 dp_username 和 dp_password。生产环境必须将 white_ip.status 设为 enable 并通过 IP 白名单 API 启用、维护名单。网关必须按调用者身份或角色,仅允许管理员和可信运维调用方访问这两条路径;只限制来源 IP 范围仍会让同一网段的普通已认证业务账号读取 DP 凭据。Server 网络策略必须仅允许可信网关的出口地址访问 API 端口,阻断客户端绕过网关的直连路径。网关须记录这两条路径的调用身份、来源和结果;Server audit-*.log 用于鉴权授权记录,不能替代这两条路径的网关访问审计。业务账号须按最小权限授权。

2.0.1 创建一个图空间

Method & Url
1POST http://localhost:8080/graphspaces
Request Body

注意:目前 cpu,内存,以及 k8s 相关功能暂未开放

名称是否必填类型默认值取值范围说明
name是String小写字母、数字和下划线组成,首字符必须是小写字母,长度不超过 48图空间的名字
nickname否Stringname 的值在所有图空间中必须唯一图空间的显示名
description否String图空间的描述信息
cpu_limit是Int> 0CPU 核数
memory_limit是Int> 0内存大小,单位 GB
storage_limit是Int> 0图空间的数据占据的磁盘空间上限,单位 GB
compute_cpu_limit否Int0>= 0针对图计算的额外资源配置,单位 cores。当该字段不配置或者配置为 0 时,会由 cpu_limit 字段的值进行覆盖
compute_memory_limit否Int0>= 0针对图计算的额外内存配置,单位 GB。当该字段不配置或者配置为 0 时,会由 memory_limit 字段的值进行覆盖
oltp_namespace否String""OLTP 的 k8s 命名空间
olap_namespace否String""OLAP 的 k8s 命名空间。当 olap_namespace 和 oltp_namespace 的值相同时,其配置的资源限额会进行合并
storage_namespace否String""存储的 k8s 命名空间
operator_image_path否String""图计算 operator 的镜像地址:在创建图空间时,允许指定对应的图计算镜像并交由 K8S 进行统一管理
internal_algorithm_image_url否String""图计算的算法镜像地址:在创建图空间时,允许指定图计算的算法镜像并交由 K8S 进行统一管理
max_graph_number是Int> 0图空间的图数目的上限
max_role_number否Int0图空间的角色数目的上限
auth否Booleanfalsetrue, false图空间是否支持权限认证
configs否Map其他配置信息
 1{
 2  "name": "gs1",
 3  "description": "1st graph space",
 4  "max_graph_number": 100,
 5  "cpu_limit": 1000,
 6  "memory_limit": 8192,
 7  "storage_limit": 1000000,
 8  "max_role_number": 10,
 9  "auth": true,
10  "configs": {}
11}
Response Status
1201
Response Body
 1{
 2  "name": "gs1",
 3  "nickname": "gs1",
 4  "description": "1st graph space",
 5  "cpu_limit": 1000,
 6  "memory_limit": 8192,
 7  "storage_limit": 1000000,
 8  "compute_cpu_limit": 0,
 9  "compute_memory_limit": 0,
10  "oltp_namespace": "hugegraph-server",
11  "olap_namespace": "hugegraph-server",
12  "storage_namespace": "hugegraph-server",
13  "operator_image_path": "127.0.0.1/hugegraph-registry/hugegraph-computer-operator:3.1.1",
14  "internal_algorithm_image_url": "127.0.0.1/hugegraph-registry/hugegraph-computer-algorithm:3.1.1",
15  "max_graph_number": 100,
16  "max_role_number": 10,
17  "cpu_used": 0,
18  "memory_used": 0,
19  "storage_used": 0,
20  "storage_used_kb": 0,
21  "storage_percent": 0.0,
22  "graph_number_used": 0,
23  "role_number_used": 0,
24  "auth": true,
25  "creator": "admin",
26  "create_time": "2024-05-01 12:00:00",
27  "update_time": "2024-05-01 12:00:00"
28}

2.0.2 列出系统所有图空间

Method & Url
1GET http://localhost:8080/graphspaces
Response Status
1200
Response Body
1{
2  "graphSpaces": [
3    "gs1",
4    "DEFAULT"
5  ]
6}

2.0.3 查看某个图空间

Params

路径参数说明:

  • graphspace: 图空间名称
Method & Url
1GET http://localhost:8080/graphspaces/gs1
Response Status
1200
Response Body
 1{
 2  "name": "gs1",
 3  "nickname": "gs1",
 4  "description": "1st graph space",
 5  "cpu_limit": 1000,
 6  "memory_limit": 8192,
 7  "storage_limit": 1000000,
 8  "oltp_namespace": "hugegraph-server",
 9  "olap_namespace": "hugegraph-server",
10  "storage_namespace": "hugegraph-server",
11  "operator_image_path": "127.0.0.1/hugegraph-registry/hugegraph-computer-operator:3.1.1",
12  "internal_algorithm_image_url": "127.0.0.1/hugegraph-registry/hugegraph-computer-algorithm:3.1.1",
13  "compute_cpu_limit": 0,
14  "compute_memory_limit": 0,
15  "max_graph_number": 100,
16  "max_role_number": 10,
17  "cpu_used": 0,
18  "memory_used": 0,
19  "storage_used": 0,
20  "storage_used_kb": 0,
21  "storage_percent": 0.0,
22  "graph_number_used": 0,
23  "role_number_used": 0,
24  "auth": true,
25  "creator": "admin",
26  "create_time": "2024-05-01 12:00:00",
27  "update_time": "2024-05-01 12:00:00",
28  "dp_username": "gs1_dp",
29  "dp_password": "a1b2c3d4e5f60718"
30}

上述 dp_username 和 dp_password 是文档示例值。实际详情响应会返回对应图空间的 DP 凭据,应按敏感凭据保护。

2.0.4 更新某个图空间

注意:auth 鉴权配置,在创建图空间的过程一旦确定下来,不允许更新

说明

动态配额更新与资源约束:

  • 动态配额更新:管理员可通过 PUT /graphspaces/{name} 并携带 {"action":"update","update":{...}} 动态调整配额(包括 max_graph_number、 max_role_number、cpu_limit、memory_limit、storage_limit)。更新前建议先通过 GET /graphspaces/{name} 读取当前配置,并保留未修改字段的原值。
  • 计算资源配额继承:当 compute_cpu_limit: 0 或 compute_memory_limit: 0(或创建时缺省)时,表示持续继承主图空间的 cpu_limit 和 memory_limit。 数值 0 代表继承,既非无限制也非分配 0 资源。
  • 配额超限约束:图数量达到 max_graph_number 时,新建图请求将被拒绝并返回 reach graph limit;存储占用超过 storage_limit 时,PD 会将该图空间内的图标记为 ReadOnly(只读),待后续巡检检测到占用降至配额以下后自动恢复 ReadWrite。
  • 高精度存储指标:响应体在保留以 GB 为单位的整数 storage_used 字段外,新增了 storage_used_kb 字段以支持 1GB 以下的高精度用量展示,storage_percent 比率直接基于该 KB 精度值计算得出。
Params

路径参数说明:

  • graphspace: 图空间名称

请求体说明:

  • action: 标记本次操作为 Update 动作,取值固定为 “update”
  • update: 即将更新的值,下述参数都应置于 update 中
名称是否必填类型默认值取值范围说明
name是String必须与路径中的图空间名一致图空间名称
nickname否String在所有图空间中必须唯一图空间的显示名
description否String图空间的描述信息
cpu_limit是Int> 0OLTP HugeGraphServer 的 CPU 核数
memory_limit是Int> 0OLTP HugeGraphServer 的内存大小,单位 GB
storage_limit是Int> 0图空间的数据占据的磁盘空间上限,单位 GB
compute_cpu_limit否Int0>= 0针对图计算的额外资源配置,单位 cores。当该字段不配置或者配置为 0 时,会由 cpu_limit 字段的值进行覆盖
compute_memory_limit否Int0>= 0针对图计算的额外内存配置,单位 GB。当该字段不配置或者配置为 0 时,会由 memory_limit 字段的值进行覆盖
oltp_namespace否StringOLTP 的 k8s 命名空间
olap_namespace否StringOLAP 的 k8s 命名空间。当 olap_namespace 和 oltp_namespace 的值相同时,其配置的资源限额会进行合并
storage_namespace否String存储的 k8s 命名空间
operator_image_path否String图计算 operator 的镜像地址:在更新图空间时,允许指定对应的图计算镜像并交由 K8S 进行统一管理
internal_algorithm_image_url否String图计算的算法镜像地址:在更新图空间时,允许指定图计算的算法镜像并交由 K8S 进行统一管理
max_graph_number是Int> 0图空间的图数目的上限
max_role_number否Int图空间的角色数目的上限
Method & Url
1PUT http://localhost:8080/graphspaces/gs1
Request Body
 1{
 2  "action": "update",
 3  "update": {
 4    "name": "gs1",
 5    "description": "1st graph space",
 6    "cpu_limit": 2000,
 7    "memory_limit": 40960,
 8    "storage_limit": 2048,
 9    "oltp_namespace": "hugegraph-server",
10    "olap_namespace": "hugegraph-server",
11    "operator_image_path": "127.0.0.1/hugegraph-registry/hugegraph-computer-operator:3.1.1",
12    "internal_algorithm_image_url": "127.0.0.1/hugegraph-registry/hugegraph-computer-algorithm:3.1.1",
13    "max_graph_number": 1000,
14    "max_role_number": 100
15  }
16}
Response Status
1200
Response Body
 1{
 2  "name": "gs1",
 3  "nickname": "gs1",
 4  "description": "1st graph space",
 5  "cpu_limit": 2000,
 6  "memory_limit": 40960,
 7  "storage_limit": 2048,
 8  "oltp_namespace": "hugegraph-server",
 9  "olap_namespace": "hugegraph-server",
10  "storage_namespace": "hugegraph-server",
11  "operator_image_path": "127.0.0.1/hugegraph-registry/hugegraph-computer-operator:3.1.1",
12  "internal_algorithm_image_url": "127.0.0.1/hugegraph-registry/hugegraph-computer-algorithm:3.1.1",
13  "compute_cpu_limit": 0,
14  "compute_memory_limit": 0,
15  "max_graph_number": 1000,
16  "max_role_number": 100,
17  "cpu_used": 0,
18  "memory_used": 0,
19  "storage_used": 0,
20  "storage_used_kb": 0,
21  "storage_percent": 0.0,
22  "graph_number_used": 0,
23  "role_number_used": 0,
24  "auth": true,
25  "creator": "admin",
26  "create_time": "2024-05-01 12:00:00",
27  "update_time": "2024-05-01 12:30:00"
28}

2.0.5 删除某个图空间

Params

路径参数说明:

  • graphspace: 图空间名称
Method & Url
1DELETE http://localhost:8080/graphspaces/gs1
Response Status
1204

注意:删除图空间,会导致图空间的全部资源被释放。

2.0.6 列出系统所有图空间及其详情

Params

请求参数说明:

  • prefix: 只返回名称或显示名以该前缀开头的图空间
Method & Url
1GET http://localhost:8080/graphspaces/profile
Response Status
1200
Response Body

每条记录包含与 GET /graphspaces/{graphspace} 相同的字段,并额外带上 authed、default、create_time 和 update_time。authed 表示当前用户是否可以进入该图空间:当图空间开启了鉴权,而当前用户既不是管理员、也不是该空间的管理员或成员时为 false。default 目前恒为 false,默认图空间功能尚未实现。

 1[
 2  {
 3    "name": "gs1",
 4    "nickname": "gs1",
 5    "description": "1st graph space",
 6    "cpu_limit": 1000,
 7    "memory_limit": 8192,
 8    "storage_limit": 1000000,
 9    "compute_cpu_limit": 0,
10    "compute_memory_limit": 0,
11    "oltp_namespace": "hugegraph-server",
12    "olap_namespace": "hugegraph-server",
13    "storage_namespace": "hugegraph-server",
14    "max_graph_number": 100,
15    "max_role_number": 10,
16    "cpu_used": 0,
17    "memory_used": 0,
18    "storage_used": 0,
19    "storage_used_kb": 0,
20    "storage_percent": 0.0,
21    "graph_number_used": 0,
22    "role_number_used": 0,
23    "auth": true,
24    "creator": "admin",
25    "authed": true,
26    "default": false,
27    "create_time": "2024-05-01 12:00:00",
28    "update_time": "2024-05-01 12:30:00"
29  }
30]

默认角色

每个图空间内置四种默认角色,可以一次性把一整组权限赋给某个用户或角色:

  • space:图空间管理员,只有管理员可以授予
  • space_member:图空间成员
  • analyst:图空间分析师
  • observer:只读角色,传入 graph 时可以收窄到单个图

user 既可以是用户名,也可以是角色名。当前用户是否具备某个默认角色也可以通过 GET /graphspaces/{graphspace}/auth/managers/default 查询,参见 Authentication API。

2.0.7 授予默认角色

Params

路径参数说明:

  • graphspace: 图空间名称

请求体说明:

  • user: 用户名或角色名,必填
  • role: 取值为 space、space_member、analyst、observer 之一,必填
  • graph: 图名称,选填,只在 role=observer 时生效
Method & Url
1POST http://localhost:8080/graphspaces/gs1/role
Request Body
1{
2  "user": "boss",
3  "role": "analyst"
4}
Response Status
1201
Response Body

只有在单个图上授予角色时才会回显 graph。

1{
2  "user": "boss",
3  "role": "analyst",
4  "graphSpace": "gs1"
5}

2.0.8 查询默认角色

Params

路径参数说明:

  • graphspace: 图空间名称

请求参数说明:

  • user: 用户名或角色名,必填
  • role: 默认角色名称,必填
  • graph: 图名称,选填,只在 role=observer 时生效
Method & Url
1GET http://localhost:8080/graphspaces/gs1/role?user=boss&role=analyst
Response Status
1200
Response Body
1{
2  "check": true
3}

2.0.9 回收默认角色

Params

路径参数说明:

  • graphspace: 图空间名称

请求参数说明:

  • user: 用户名或角色名,必填
  • role: 默认角色名称,必填
  • graph: 图名称,选填,只在 role=observer 时生效
Method & Url
1DELETE http://localhost:8080/graphspaces/gs1/role?user=boss&role=analyst
Response Status
1204

Schema 模板

Schema 模板把一段 Gremlin schema 脚本以名称保存下来,创建图时通过 schema 字段引用它来初始化图,参见 Graphs API。模板可以由它的创建者、图空间管理员或系统管理员修改和删除。

2.0.10 创建 schema 模板

Params

路径参数说明:

  • graphspace: 图空间名称

请求体说明:

  • name: 模板名称,必填
  • schema: Gremlin schema 脚本,必填
Method & Url
1POST http://localhost:8080/graphspaces/gs1/schematemplates
Request Body
1{
2  "name": "template1",
3  "schema": "schema.propertyKey('name').asText().ifNotExist().create();"
4}
Response Status
1201
Response Body
1{
2  "name": "template1",
3  "schema": "schema.propertyKey('name').asText().ifNotExist().create();",
4  "creator": "admin",
5  "create": "2024-05-01 12:00:00.000",
6  "create_time": "2024-05-01 12:00:00.000",
7  "update": "2024-05-01 12:00:00.000",
8  "update_time": "2024-05-01 12:00:00.000"
9}

2.0.11 列出图空间的全部 schema 模板

Method & Url
1GET http://localhost:8080/graphspaces/gs1/schematemplates
Response Status
1200
Response Body
1{
2  "schema_templates": [
3    "template1"
4  ]
5}

2.0.12 查看某个 schema 模板

Method & Url
1GET http://localhost:8080/graphspaces/gs1/schematemplates/template1
Response Status
1200

2.0.13 修改某个 schema 模板

只能修改 schema,模板名称不可修改。

Method & Url
1PUT http://localhost:8080/graphspaces/gs1/schematemplates/template1
Request Body
1{
2  "schema": "schema.propertyKey('age').asInt().ifNotExist().create();"
3}
Response Status
1200

2.0.14 删除某个 schema 模板

Method & Url
1DELETE http://localhost:8080/graphspaces/gs1/schematemplates/template1
Response Status
1204

5.1.2 - Schema API

Schema(图模式)REST 接口:查询图的完整模式定义,包括属性键、顶点标签、边标签和索引标签的统一视图。

1.1 Schema

HugeGraph 提供单一接口获取某个图的全部 Schema 信息,包括:PropertyKey、VertexLabel、EdgeLabel 和 IndexLabel。

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph_name}/schema
2
3e.g: GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema
Response Status
1200
Response Body
  1{
  2    "propertykeys": [
  3        {
  4            "id": 7,
  5            "name": "price",
  6            "data_type": "DOUBLE",
  7            "cardinality": "SINGLE",
  8            "aggregate_type": "NONE",
  9            "write_type": "OLTP",
 10            "properties": [],
 11            "status": "CREATED",
 12            "user_data": {
 13                "~create_time": "2023-05-08 17:49:05.316"
 14            }
 15        },
 16        {
 17            "id": 6,
 18            "name": "date",
 19            "data_type": "TEXT",
 20            "cardinality": "SINGLE",
 21            "aggregate_type": "NONE",
 22            "write_type": "OLTP",
 23            "properties": [],
 24            "status": "CREATED",
 25            "user_data": {
 26                "~create_time": "2023-05-08 17:49:05.309"
 27            }
 28        },
 29        {
 30            "id": 3,
 31            "name": "city",
 32            "data_type": "TEXT",
 33            "cardinality": "SINGLE",
 34            "aggregate_type": "NONE",
 35            "write_type": "OLTP",
 36            "properties": [],
 37            "status": "CREATED",
 38            "user_data": {
 39                "~create_time": "2023-05-08 17:49:05.287"
 40            }
 41        },
 42        {
 43            "id": 2,
 44            "name": "age",
 45            "data_type": "INT",
 46            "cardinality": "SINGLE",
 47            "aggregate_type": "NONE",
 48            "write_type": "OLTP",
 49            "properties": [],
 50            "status": "CREATED",
 51            "user_data": {
 52                "~create_time": "2023-05-08 17:49:05.280"
 53            }
 54        },
 55        {
 56            "id": 5,
 57            "name": "lang",
 58            "data_type": "TEXT",
 59            "cardinality": "SINGLE",
 60            "aggregate_type": "NONE",
 61            "write_type": "OLTP",
 62            "properties": [],
 63            "status": "CREATED",
 64            "user_data": {
 65                "~create_time": "2023-05-08 17:49:05.301"
 66            }
 67        },
 68        {
 69            "id": 4,
 70            "name": "weight",
 71            "data_type": "DOUBLE",
 72            "cardinality": "SINGLE",
 73            "aggregate_type": "NONE",
 74            "write_type": "OLTP",
 75            "properties": [],
 76            "status": "CREATED",
 77            "user_data": {
 78                "~create_time": "2023-05-08 17:49:05.294"
 79            }
 80        },
 81        {
 82            "id": 1,
 83            "name": "name",
 84            "data_type": "TEXT",
 85            "cardinality": "SINGLE",
 86            "aggregate_type": "NONE",
 87            "write_type": "OLTP",
 88            "properties": [],
 89            "status": "CREATED",
 90            "user_data": {
 91                "~create_time": "2023-05-08 17:49:05.250"
 92            }
 93        }
 94    ],
 95    "vertexlabels": [
 96        {
 97            "id": 1,
 98            "name": "person",
 99            "id_strategy": "PRIMARY_KEY",
100            "primary_keys": [
101                "name"
102            ],
103            "nullable_keys": [
104                "age",
105                "city"
106            ],
107            "index_labels": [
108                "personByAge",
109                "personByCity",
110                "personByAgeAndCity"
111            ],
112            "properties": [
113                "name",
114                "age",
115                "city"
116            ],
117            "status": "CREATED",
118            "ttl": 0,
119            "enable_label_index": true,
120            "user_data": {
121                "~create_time": "2023-05-08 17:49:05.336"
122            }
123        },
124        {
125            "id": 2,
126            "name": "software",
127            "id_strategy": "CUSTOMIZE_NUMBER",
128            "primary_keys": [],
129            "nullable_keys": [],
130            "index_labels": [
131                "softwareByPrice"
132            ],
133            "properties": [
134                "name",
135                "lang",
136                "price"
137            ],
138            "status": "CREATED",
139            "ttl": 0,
140            "enable_label_index": true,
141            "user_data": {
142                "~create_time": "2023-05-08 17:49:05.347"
143            }
144        }
145    ],
146    "edgelabels": [
147        {
148            "id": 1,
149            "name": "knows",
150            "source_label": "person",
151            "target_label": "person",
152            "frequency": "SINGLE",
153            "sort_keys": [],
154            "nullable_keys": [],
155            "index_labels": [
156                "knowsByWeight"
157            ],
158            "properties": [
159                "weight",
160                "date"
161            ],
162            "status": "CREATED",
163            "ttl": 0,
164            "enable_label_index": true,
165            "user_data": {
166                "~create_time": "2023-05-08 17:49:08.437"
167            }
168        },
169        {
170            "id": 2,
171            "name": "created",
172            "source_label": "person",
173            "target_label": "software",
174            "frequency": "SINGLE",
175            "sort_keys": [],
176            "nullable_keys": [],
177            "index_labels": [
178                "createdByDate",
179                "createdByWeight"
180            ],
181            "properties": [
182                "weight",
183                "date"
184            ],
185            "status": "CREATED",
186            "ttl": 0,
187            "enable_label_index": true,
188            "user_data": {
189                "~create_time": "2023-05-08 17:49:08.446"
190            }
191        }
192    ],
193    "indexlabels": [
194        {
195            "id": 1,
196            "name": "personByAge",
197            "base_type": "VERTEX_LABEL",
198            "base_value": "person",
199            "index_type": "RANGE_INT",
200            "fields": [
201                "age"
202            ],
203            "status": "CREATED",
204            "user_data": {
205                "~create_time": "2023-05-08 17:49:05.375"
206            }
207        },
208        {
209            "id": 2,
210            "name": "personByCity",
211            "base_type": "VERTEX_LABEL",
212            "base_value": "person",
213            "index_type": "SECONDARY",
214            "fields": [
215                "city"
216            ],
217            "status": "CREATED",
218            "user_data": {
219                "~create_time": "2023-05-08 17:49:06.898"
220            }
221        },
222        {
223            "id": 3,
224            "name": "personByAgeAndCity",
225            "base_type": "VERTEX_LABEL",
226            "base_value": "person",
227            "index_type": "SECONDARY",
228            "fields": [
229                "age",
230                "city"
231            ],
232            "status": "CREATED",
233            "user_data": {
234                "~create_time": "2023-05-08 17:49:07.407"
235            }
236        },
237        {
238            "id": 4,
239            "name": "softwareByPrice",
240            "base_type": "VERTEX_LABEL",
241            "base_value": "software",
242            "index_type": "RANGE_DOUBLE",
243            "fields": [
244                "price"
245            ],
246            "status": "CREATED",
247            "user_data": {
248                "~create_time": "2023-05-08 17:49:07.916"
249            }
250        },
251        {
252            "id": 5,
253            "name": "createdByDate",
254            "base_type": "EDGE_LABEL",
255            "base_value": "created",
256            "index_type": "SECONDARY",
257            "fields": [
258                "date"
259            ],
260            "status": "CREATED",
261            "user_data": {
262                "~create_time": "2023-05-08 17:49:08.454"
263            }
264        },
265        {
266            "id": 6,
267            "name": "createdByWeight",
268            "base_type": "EDGE_LABEL",
269            "base_value": "created",
270            "index_type": "RANGE_DOUBLE",
271            "fields": [
272                "weight"
273            ],
274            "status": "CREATED",
275            "user_data": {
276                "~create_time": "2023-05-08 17:49:08.963"
277            }
278        },
279        {
280            "id": 7,
281            "name": "knowsByWeight",
282            "base_type": "EDGE_LABEL",
283            "base_value": "knows",
284            "index_type": "RANGE_DOUBLE",
285            "fields": [
286                "weight"
287            ],
288            "status": "CREATED",
289            "user_data": {
290                "~create_time": "2023-05-08 17:49:09.473"
291            }
292        }
293    ]
294}

5.1.3 - PropertyKey API

PropertyKey(属性键)REST 接口:定义图中所有属性的数据类型和基数约束,是构建图模式的基础元素。

1.2 PropertyKey

Params 说明:

  • name:属性类型名称,必填
  • data_type:属性类型数据类型,包括:bool、byte、int、long、float、double、text、date、uuid、blob,默认 text 类型 (代表 string 字符串类型)
  • cardinality:属性类型基数,包括:single、list、set,默认 single (代表单属性值)

请求体字段说明:

  • id:属性类型 id 值
  • properties:属性的属性,对于属性而言,此项为空
  • user_data:设置属性类型的通用信息,比如可设置 age 属性的取值范围,最小为 0,最大为 100;目前此项不做任何校验,只为后期拓展提供预留入口

1.2.1 创建一个 PropertyKey

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/propertykeys
Request Body
1{
2    "name": "age",
3    "data_type": "INT",
4    "cardinality": "SINGLE"
5}
Response Status
1202
Response Body
 1{
 2    "property_key": {
 3        "id": 1,
 4        "name": "age",
 5        "data_type": "INT",
 6        "cardinality": "SINGLE",
 7        "aggregate_type": "NONE",
 8        "write_type": "OLTP",
 9        "properties": [],
10        "status": "CREATED",
11        "user_data": {
12            "~create_time": "2022-05-13 13:47:23.745"
13        }
14    },
15    "task_id": 0
16}

1.2.2 为已存在的 PropertyKey 添加或移除 userdata

Params
  • action: 表示当前行为是添加还是移除,取值为append(添加)和eliminate(移除)
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/propertykeys/age?action=append
Request Body
1{
2    "name": "age",
3    "user_data": {
4        "min": 0,
5        "max": 100
6    }
7}
Response Status
1202
Response Body
 1{
 2    "property_key": {
 3        "id": 1,
 4        "name": "age",
 5        "data_type": "INT",
 6        "cardinality": "SINGLE",
 7        "aggregate_type": "NONE",
 8        "write_type": "OLTP",
 9        "properties": [],
10        "status": "CREATED",
11        "user_data": {
12            "min": 0,
13            "max": 100,
14            "~create_time": "2022-05-13 13:47:23.745"
15        }
16    },
17    "task_id": 0
18}

1.2.3 获取所有的 PropertyKey

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/propertykeys
Response Status
1200
Response Body
 1{
 2    "propertykeys": [
 3        {
 4            "id": 3,
 5            "name": "city",
 6            "data_type": "TEXT",
 7            "cardinality": "SINGLE",
 8            "properties": [],
 9            "user_data": {}
10        },
11        {
12            "id": 2,
13            "name": "age",
14            "data_type": "INT",
15            "cardinality": "SINGLE",
16            "properties": [],
17            "user_data": {}
18        },
19        {
20            "id": 5,
21            "name": "lang",
22            "data_type": "TEXT",
23            "cardinality": "SINGLE",
24            "properties": [],
25            "user_data": {}
26        },
27        {
28            "id": 4,
29            "name": "weight",
30            "data_type": "DOUBLE",
31            "cardinality": "SINGLE",
32            "properties": [],
33            "user_data": {}
34        },
35        {
36            "id": 6,
37            "name": "date",
38            "data_type": "TEXT",
39            "cardinality": "SINGLE",
40            "properties": [],
41            "user_data": {}
42        },
43        {
44            "id": 1,
45            "name": "name",
46            "data_type": "TEXT",
47            "cardinality": "SINGLE",
48            "properties": [],
49            "user_data": {}
50        },
51        {
52            "id": 7,
53            "name": "price",
54            "data_type": "INT",
55            "cardinality": "SINGLE",
56            "properties": [],
57            "user_data": {}
58        }
59    ]
60}

1.2.4 根据 name 获取 PropertyKey

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/propertykeys/age

其中,age为要获取的 PropertyKey 的名称

Response Status
1200
Response Body
 1{
 2    "id": 1,
 3    "name": "age",
 4    "data_type": "INT",
 5    "cardinality": "SINGLE",
 6    "aggregate_type": "NONE",
 7    "write_type": "OLTP",
 8    "properties": [],
 9    "status": "CREATED",
10    "user_data": {
11        "min": 0,
12        "max": 100,
13        "~create_time": "2022-05-13 13:47:23.745"
14    }
15}

1.2.5 根据 name 删除 PropertyKey

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/propertykeys/age

其中,age为要删除的 PropertyKey 的名称

Response Status
1202
Response Body
1{
2    "task_id" : 0
3}

5.1.4 - VertexLabel API

VertexLabel(顶点标签)REST 接口:定义顶点类型、ID策略及关联的属性,决定顶点的结构和约束规则。

1.3 VertexLabel

假设已经创建好了 1.1.3 中列出来的 PropertyKeys

Params 说明

  • id:顶点类型 id 值
  • name:顶点类型名称,必填
  • id_strategy: 顶点类型的 ID 策略,主键 ID、自动生成、自定义字符串、自定义数字、自定义 UUID,默认主键 ID
  • properties: 顶点类型关联的属性类型
  • primary_keys: 主键属性,当 ID 策略为 PRIMARY_KEY 时必须有值,其他 ID 策略时必须为空;
  • enable_label_index:是否开启类型索引,默认关闭
  • index_names:顶点类型创建的索引,详情见 3.4
  • nullable_keys:可为空的属性
  • user_data:设置顶点类型的通用信息,作用同属性类型

1.3.1 创建一个 VertexLabel

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels
Request Body
 1{
 2    "name": "person",
 3    "id_strategy": "DEFAULT",
 4    "properties": [
 5        "name",
 6        "age"
 7    ],
 8    "primary_keys": [
 9        "name"
10    ],
11    "nullable_keys": [],
12    "enable_label_index": true
13}
Response Status
1201
Response Body
 1{
 2    "id": 1,
 3    "primary_keys": [
 4        "name"
 5    ],
 6    "id_strategy": "PRIMARY_KEY",
 7    "name": "person2",
 8    "index_names": [
 9    ],
10    "properties": [
11        "name",
12        "age"
13    ],
14    "nullable_keys": [
15    ],
16    "enable_label_index": true,
17    "user_data": {}
18}

从 hugegraph-server v0.11.2 版本开始支持顶点的 TTL 功能。顶点的 TTL 是通过 VertexLabel 来设置的。比如希望 person 类型的顶点存活时间为一天,需要在创建 person VertexLabel 的时候将 TTL 字段设置为 86400000,即单位为毫秒。

 1{
 2    "name": "person",
 3    "id_strategy": "DEFAULT",
 4    "properties": [
 5        "name",
 6        "age"
 7    ],
 8    "primary_keys": [
 9        "name"
10    ],
11    "nullable_keys": [],
12    "ttl": 86400000,
13    "enable_label_index": true
14}

另外,当顶点中带有"创建时间"的属性且希望以"创建时间"属性作为计算顶点存活时间的起点时,可以设置 VertexLabel 中的 ttl_start_time 字段。比如 person VertexLabel 有 createdTime 属性,且 createdTime 是 Date 类型的参数,希望 person 类型的顶点从创建开始存活一天的时间,那么创建 person VertexLabel 的 Request Body 如下:

 1{
 2    "name": "person",
 3    "id_strategy": "DEFAULT",
 4    "properties": [
 5        "name",
 6        "age",
 7        "createdTime"
 8    ],
 9    "primary_keys": [
10        "name"
11    ],
12    "nullable_keys": [],
13    "ttl": 86400000,
14    "ttl_start_time": "createdTime",
15    "enable_label_index": true
16}

1.3.2 为已存在的 VertexLabel 添加 properties 或 userdata,或者移除 userdata(目前不支持移除 properties)

Params
  • action: 表示当前行为是添加还是移除,取值为append(添加)和eliminate(移除)
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels/person?action=append
Request Body
 1{
 2    "name": "person",
 3    "properties": [
 4        "city"
 5    ],
 6    "nullable_keys": ["city"],
 7    "user_data": {
 8        "super": "animal"
 9    }
10}
Response Status
1200
Response Body
 1{
 2    "id": 1,
 3    "primary_keys": [
 4        "name"
 5    ],
 6    "id_strategy": "PRIMARY_KEY",
 7    "name": "person",
 8    "index_names": [
 9    ],
10    "properties": [
11        "city",
12        "name",
13        "age"
14    ],
15    "nullable_keys": [
16        "city"
17    ],
18    "enable_label_index": true,
19    "user_data": {
20        "super": "animal"
21    }
22}

1.3.3 获取所有的 VertexLabel

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels
Response Status
1200
Response Body
 1{
 2    "vertexlabels": [
 3        {
 4            "id": 1,
 5            "primary_keys": [
 6                "name"
 7            ],
 8            "id_strategy": "PRIMARY_KEY",
 9            "name": "person",
10            "index_names": [
11            ],
12            "properties": [
13                "city",
14                "name",
15                "age"
16            ],
17            "nullable_keys": [
18                "city"
19            ],
20            "enable_label_index": true,
21            "user_data": {
22                "super": "animal"
23            }
24        },
25        {
26            "id": 2,
27            "primary_keys": [
28                "name"
29            ],
30            "id_strategy": "PRIMARY_KEY",
31            "name": "software",
32            "index_names": [
33            ],
34            "properties": [
35                "price",
36                "name",
37                "lang"
38            ],
39            "nullable_keys": [
40                "price"
41            ],
42            "enable_label_index": false,
43            "user_data": {}
44        }
45    ]
46}

1.3.4 根据 name 获取 VertexLabel

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels/person
Response Status
1200
Response Body
 1{
 2    "id": 1,
 3    "primary_keys": [
 4        "name"
 5    ],
 6    "id_strategy": "PRIMARY_KEY",
 7    "name": "person",
 8    "index_names": [
 9    ],
10    "properties": [
11        "city",
12        "name",
13        "age"
14    ],
15    "nullable_keys": [
16        "city"
17    ],
18    "enable_label_index": true,
19    "user_data": {
20        "super": "animal"
21    }
22}

1.3.5 根据 name 删除 VertexLabel

删除 VertexLabel 会导致删除对应的顶点以及相关的索引数据,会产生一个异步任务

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexlabels/person
Response Status
1202
Response Body
1{
2    "task_id": 1
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1(其中"1"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

5.1.5 - EdgeLabel API

EdgeLabel(边标签)REST 接口:定义边类型、源顶点和目标顶点的关系约束,构建图的连接规则。

1.4 EdgeLabel

假设已经创建好了 1.2.3 中的 PropertyKeys 和 1.3.3 中的 VertexLabels

Params 说明

  • name:顶点类型名称,必填
  • source_label: 源顶点类型的名称,必填
  • target_label: 目标顶点类型的名称,必填
  • frequency:两个点之间是否可以有多条边,可以取值 SINGLE 和 MULTIPLE,非必填,默认值 SINGLE
  • properties: 边类型关联的属性类型,选填
  • sort_keys: 当允许关联多次时,指定区分键属性列表
  • nullable_keys:可为空的属性,选填,默认可为空
  • enable_label_index:是否开启类型索引,默认关闭

1.4.1 创建一个 EdgeLabel

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelabels
Request Body
 1{
 2    "name": "created",
 3    "source_label": "person",
 4    "target_label": "software",
 5    "frequency": "SINGLE",
 6    "properties": [
 7        "date"
 8    ],
 9    "sort_keys": [],
10    "nullable_keys": [],
11    "enable_label_index": true
12}
Response Status
1201
Response Body
 1{
 2    "id": 1,
 3    "sort_keys": [
 4    ],
 5    "source_label": "person",
 6    "name": "created",
 7    "index_names": [
 8    ],
 9    "properties": [
10        "date"
11    ],
12    "target_label": "software",
13    "frequency": "SINGLE",
14    "nullable_keys": [
15    ],
16    "enable_label_index": true,
17    "user_data": {}
18}

从 hugegraph-server v0.11.2 版本开始支持边的 TTL 功能。边的 TTL 是通过 EdgeLabel 来设置的。比如希望 knows 类型的边存活时间为一天,需要在创建 knows EdgeLabel 的时候将 TTL 字段设置为 86400000,即单位为毫秒。

 1{
 2    "id": 1,
 3    "sort_keys": [
 4    ],
 5    "source_label": "person",
 6    "name": "knows",
 7    "index_names": [
 8    ],
 9    "properties": [
10        "date",
11        "createdTime"
12    ],
13    "target_label": "person",
14    "frequency": "SINGLE",
15    "nullable_keys": [
16    ],
17    "enable_label_index": true,
18    "ttl": 86400000,
19    "user_data": {}
20}

另外,当边中带有"创建时间"的属性且希望以"创建时间"属性作为计算边存活时间的起点时,可以设置 EdgeLabel 中的 ttl_start_time 字段。比如 knows EdgeLabel 有 createdTime 属性,且 createdTime 是 Date 类型的参数,希望 knows 类型的边从创建开始存活一天的时间,那么创建 knows EdgeLabel 的 Request Body 如下:

 1{
 2    "id": 1,
 3    "sort_keys": [
 4    ],
 5    "source_label": "person",
 6    "name": "knows",
 7    "index_names": [
 8    ],
 9    "properties": [
10        "date",
11        "createdTime"
12    ],
13    "target_label": "person",
14    "frequency": "SINGLE",
15    "nullable_keys": [
16    ],
17    "enable_label_index": true,
18    "ttl": 86400000,
19    "ttl_start_time": "createdTime",
20    "user_data": {}
21}

1.4.2 为已存在的 EdgeLabel 添加 properties 或 userdata,或者移除 userdata(目前不支持移除 properties)

Params
  • action: 表示当前行为是添加还是移除,取值为append(添加)和eliminate(移除)
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelabels/created?action=append
Request Body
1{
2    "name": "created",
3    "properties": [
4        "weight"
5    ],
6    "nullable_keys": [
7        "weight"
8    ]
9}
Response Status
1200
Response Body
 1{
 2    "id": 2,
 3    "sort_keys": [
 4    ],
 5    "source_label": "person",
 6    "name": "created",
 7    "index_names": [
 8    ],
 9    "properties": [
10        "date",
11        "weight"
12    ],
13    "target_label": "software",
14    "frequency": "SINGLE",
15    "nullable_keys": [
16        "weight"
17    ],
18    "enable_label_index": true,
19    "user_data": {}
20}

1.4.3 获取所有的 EdgeLabel

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelabels
Response Status
1200
Response Body
 1{
 2    "edgelabels": [
 3        {
 4            "id": 1,
 5            "sort_keys": [
 6            ],
 7            "source_label": "person",
 8            "name": "created",
 9            "index_names": [
10            ],
11            "properties": [
12                "date",
13                "weight"
14            ],
15            "target_label": "software",
16            "frequency": "SINGLE",
17            "nullable_keys": [
18                "weight"
19            ],
20            "enable_label_index": true,
21            "user_data": {}
22        },
23        {
24            "id": 2,
25            "sort_keys": [
26            ],
27            "source_label": "person",
28            "name": "knows",
29            "index_names": [
30            ],
31            "properties": [
32                "date",
33                "weight"
34            ],
35            "target_label": "person",
36            "frequency": "SINGLE",
37            "nullable_keys": [
38            ],
39            "enable_label_index": false,
40            "user_data": {}
41        }
42    ]
43}

1.4.4 根据 name 获取 EdgeLabel

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelabels/created
Response Status
1200
Response Body
 1{
 2    "id": 1,
 3    "sort_keys": [
 4    ],
 5    "source_label": "person",
 6    "name": "created",
 7    "index_names": [
 8    ],
 9    "properties": [
10        "date",
11        "city",
12        "weight"
13    ],
14    "target_label": "software",
15    "frequency": "SINGLE",
16    "nullable_keys": [
17        "city",
18        "weight"
19    ],
20    "enable_label_index": true,
21    "user_data": {}
22}

1.4.5 根据 name 删除 EdgeLabel

删除 EdgeLabel 会导致删除对应的边以及相关的索引数据,会产生一个异步任务

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelabels/created
Response Status
1202
Response Body
1{
2    "task_id": 1
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1(其中"1"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

5.1.6 - IndexLabel API

IndexLabel(索引标签)REST 接口:为顶点和边的属性创建索引,加速基于属性的查询和过滤操作。

1.5 IndexLabel

假设已经创建好了 1.1.3 中的 PropertyKeys、1.2.3 中的 VertexLabels 以及 1.3.3 中的 EdgeLabels

1.5.1 创建一个 IndexLabel

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexlabels
Request Body
1{
2    "name": "personByCity",
3    "base_type": "VERTEX_LABEL",
4    "base_value": "person",
5    "index_type": "SECONDARY",
6    "fields": [
7        "city"
8    ]
9}
Response Status
1202
Response Body
 1{
 2    "index_label": {
 3        "id": 1,
 4        "base_type": "VERTEX_LABEL",
 5        "base_value": "person",
 6        "name": "personByCity",
 7        "fields": [
 8            "city"
 9        ],
10        "index_type": "SECONDARY"
11    },
12    "task_id": 2
13}

1.5.2 获取所有的 IndexLabel

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexlabels
Response Status
1200
Response Body
 1{
 2    "indexlabels": [
 3        {
 4            "id": 3,
 5            "base_type": "VERTEX_LABEL",
 6            "base_value": "software",
 7            "name": "softwareByPrice",
 8            "fields": [
 9                "price"
10            ],
11            "index_type": "RANGE"
12        },
13        {
14            "id": 4,
15            "base_type": "EDGE_LABEL",
16            "base_value": "created",
17            "name": "createdByDate",
18            "fields": [
19                "date"
20            ],
21            "index_type": "SECONDARY"
22        },
23        {
24            "id": 1,
25            "base_type": "VERTEX_LABEL",
26            "base_value": "person",
27            "name": "personByCity",
28            "fields": [
29                "city"
30            ],
31            "index_type": "SECONDARY"
32        },
33        {
34            "id": 3,
35            "base_type": "VERTEX_LABEL",
36            "base_value": "person",
37            "name": "personByAgeAndCity",
38            "fields": [
39                "age",
40                "city"
41            ],
42            "index_type": "SECONDARY"
43        }
44    ]
45}

1.5.3 根据 name 获取 IndexLabel

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexlabels/personByCity
Response Status
1200
Response Body
 1{
 2    "id": 1,
 3    "base_type": "VERTEX_LABEL",
 4    "base_value": "person",
 5    "name": "personByCity",
 6    "fields": [
 7        "city"
 8    ],
 9    "index_type": "SECONDARY"
10}

1.5.4 根据 name 删除 IndexLabel

删除 IndexLabel 会导致删除相关的索引数据,响应为任务 ID,会产生一个异步任务。当前 Server 接口没有 delete_all 查询参数。

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexlabels/personByCity
Response Status
1202
Response Body
1{
2    "task_id": 1
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1(其中"1"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

1.5.5 为已存在的 IndexLabel 添加或移除 userdata

该方式只能修改 user_data,请求体中不能带 base_type、base_value 和 index_type。

Params
  • action: 表示当前行为是添加还是移除,取值为 append(添加)和 eliminate(移除)
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexlabels/personByCity?action=append
Request Body
1{
2    "name": "personByCity",
3    "user_data": {
4        "comment": "index on city"
5    }
6}
Response Status
1200
Response Body
 1{
 2    "id": 1,
 3    "base_type": "VERTEX_LABEL",
 4    "base_value": "person",
 5    "name": "personByCity",
 6    "fields": [
 7        "city"
 8    ],
 9    "index_type": "SECONDARY",
10    "user_data": {
11        "comment": "index on city",
12        "~create_time": "2022-05-13 13:47:23.745"
13    }
14}

5.1.7 - Rebuild API

Rebuild(重建索引)REST 接口:重建图模式的索引,确保索引数据与图数据保持一致性。

1.6 Rebuild

重建顶点、边或索引标签使用 PUT .../jobs/rebuild/{type}/{name}:目标标签不存在时返回 HTTP 404; 已有标签返回 HTTP 202 与任务 ID,应轮询任务结果后再确认重建完成。

1.6.1 重建 IndexLabel

Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/indexlabels/personByCity
Response Status
1202
Response Body
1{
2    "task_id": 1
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1(其中"1"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

1.6.2 VertexLabel 对应的全部索引重建

Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/vertexlabels/person
Response Status
1202
Response Body
1{
2    "task_id": 2
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2(其中"2"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

1.6.3 EdgeLabel 对应的全部索引重建

Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/edgelabels/created
Response Status
1202
Response Body
1{
2    "task_id": 3
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/3(其中"3"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

5.1.8 - Vertex API

Vertex(顶点)REST 接口:创建、查询、更新和删除图中的顶点数据,支持批量操作和条件过滤。

2.1 Vertex

顶点类型中的 Id 策略决定了顶点的 Id 类型,其对应的 id 类型如下:

顶点 ID 策略
Id_Strategyid type
AUTOMATICnumber
PRIMARY_KEYstring
CUSTOMIZE_STRINGstring
CUSTOMIZE_NUMBERnumber
CUSTOMIZE_UUIDuuid

顶点的 GET/PUT/DELETE API 中 url 的 id 部分应该传入带有类型信息的 id 值,这个类型信息通过 json 串是否带引号来表示,也就是说:

  • 当 id 类型为 number 时,url 中的 id 不带引号,例如 xxx/vertices/123456
  • 当 id 类型为 string 时,url 中的 id 带引号,例如 xxx/vertices/"123456";在命令行或客户端转义保留字符时编码为 %221%3Amarko%22

追加属性使用 PUT .../vertices/{id}?action=append 并提交对应 JSON 属性体。


接下来的示例需要先根据以下 groovy 脚本创建图 schema

 1schema.propertyKey("name").asText().ifNotExist().create();
 2schema.propertyKey("age").asInt().ifNotExist().create();
 3schema.propertyKey("city").asText().ifNotExist().create();
 4schema.propertyKey("weight").asDouble().ifNotExist().create();
 5schema.propertyKey("lang").asText().ifNotExist().create();
 6schema.propertyKey("price").asDouble().ifNotExist().create();
 7schema.propertyKey("hobby").asText().valueList().ifNotExist().create();
 8
 9schema.vertexLabel("person").properties("name", "age", "city", "weight", "hobby").primaryKeys("name").nullableKeys("age", "city", "weight", "hobby").ifNotExist().create();
10schema.vertexLabel("software").properties("name", "lang", "price").primaryKeys("name").nullableKeys("lang", "price").ifNotExist().create();
11
12schema.indexLabel("personByAge").onV("person").by("age").range().ifNotExist().create();

2.1.1 创建一个顶点

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

Method & Url

1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices

Request Body

1{
2    "label": "person",
3    "properties": {
4        "name": "marko",
5        "age": 29
6    }
7}

Response Status

1201

Response Body

1{
2    "id": "1:marko",
3    "label": "person",
4    "type": "vertex",
5    "properties": {
6        "name": "marko",
7        "age": 29
8    }
9}

2.1.2 创建多个顶点

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

Method & Url

1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/batch

Request Body

 1[
 2    {
 3        "label": "person",
 4        "properties": {
 5            "name": "marko",
 6            "age": 29
 7        }
 8    },
 9    {
10        "label": "software",
11        "properties": {
12            "name": "ripple",
13            "lang": "java",
14            "price": 199
15        }
16    }
17]

Response Status

1201

Response Body

1[
2    "1:marko",
3    "2:ripple"
4]

2.1.3 更新顶点属性

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
  • id: 顶点 id,需要包含引号,例如"1:marko"

Method & Url

1PUT http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/"1:marko"?action=append

Request Body

1{
2    "label": "person",
3    "properties": {
4        "age": 30,
5        "city": "Beijing"
6    }
7}

注意:属性的取值有三种类别,分别为 single、set 和 list。single 表示增加或更新属性值,set 或 list 表示追加属性值。

Response Status

1200

Response Body

 1{
 2    "id": "1:marko",
 3    "label": "person",
 4    "type": "vertex",
 5    "properties": {
 6        "name": "marko",
 7        "age": 30,
 8        "city": "Beijing"
 9    }
10}

2.1.4 批量更新顶点属性

功能说明

批量更新顶点的属性时,可以选择多种更新策略,如下:

  • SUM: 数值累加
  • BIGGER: 原值和新值 (数字、日期) 取更大的
  • SMALLER: 原值和新值 (数字、日期) 取更小的
  • UNION: Set 属性取并集
  • INTERSECTION: Set 属性取交集
  • APPEND: List 属性追加元素
  • ELIMINATE: List/Set属性删除元素
  • OVERRIDE: 覆盖已有属性,如果新属性为 null,则仍然使用旧属性

假设原顶点的属性如下:

 1{
 2    "vertices": [
 3        {
 4            "id": "2:lop",
 5            "label": "software",
 6            "type": "vertex",
 7            "properties": {
 8                "name": "lop",
 9                "lang": "java",
10                "price": 328
11            }
12        },
13        {
14            "id": "1:josh",
15            "label": "person",
16            "type": "vertex",
17            "properties": {
18                "name": "josh",
19                "age": 32,
20                "city": "Beijing",
21                "weight": 0.1,
22                "hobby": [
23                    "reading",
24                    "football"
25                ]
26            }
27        }
28    ]
29}

通过以下命令新增顶点:

1curl -H "Content-Type: application/json" -d '[{"label":"person","properties":{"name":"josh","age":32,"city":"Beijing","weight":0.1,"hobby":["reading","football"]}},{"label":"software","properties":{"name":"lop","lang":"java","price":328}}]' http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/batch

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

Method & Url

1PUT http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/batch

Request Body

 1{
 2    "vertices": [
 3        {
 4            "label": "software",
 5            "type": "vertex",
 6            "properties": {
 7                "name": "lop",
 8                "lang": "c++",
 9                "price": 299
10            }
11        },
12        {
13            "label": "person",
14            "type": "vertex",
15            "properties": {
16                "name": "josh",
17                "city": "Shanghai",
18                "weight": 0.2,
19                "hobby": [
20                    "swimming"
21                ]
22            }
23        }
24    ],
25    "update_strategies": {
26        "price": "BIGGER",
27        "age": "OVERRIDE",
28        "city": "OVERRIDE",
29        "weight": "SUM",
30        "hobby": "UNION"
31    },
32    "create_if_not_exist": true
33}

Response Status

1200

Response Body

 1{
 2    "vertices": [
 3        {
 4            "id": "2:lop",
 5            "label": "software",
 6            "type": "vertex",
 7            "properties": {
 8                "name": "lop",
 9                "lang": "c++",
10                "price": 328
11            }
12        },
13        {
14            "id": "1:josh",
15            "label": "person",
16            "type": "vertex",
17            "properties": {
18                "name": "josh",
19                "age": 32,
20                "city": "Shanghai",
21                "weight": 0.3,
22                "hobby": [
23                    "reading",
24                    "football",
25                    "swimming"
26                ]
27            }
28        }
29    ]
30}

结果分析如下:

  • lang 属性未指定更新策略,直接用新值覆盖旧值,无论新值是否为 null;
  • price 属性指定 BIGGER 的更新策略,旧属性值为 328,新属性值为 299,所以仍然保留了旧属性值 328;
  • age 属性指定 OVERRIDE 更新策略,而新属性值中未传入 age,相当于 age 为 null,所以仍然保留了原属性值 32;
  • city 属性也指定了 OVERRIDE 更新策略,且新属性值不为 null,所以覆盖了旧值;
  • weight 属性指定了 SUM 更新策略,旧属性值为 0.1,新属性值为 0.2,最后的值为 0.3;
  • hobby 属性(基数为 Set)指定了 UNION 更新策略,所以新值与旧值取了并集;

其他更新策略的使用方式与此类似,此处不再详述。

2.1.5 删除顶点属性

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
  • id: 顶点 id,需要包含引号,例如"1:marko"

Method & Url

1PUT http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/"1:marko"?action=eliminate

Request Body

1{
2    "label": "person",
3    "properties": {
4        "city": "Beijing"
5    }
6}

注意:这里会直接删除属性(删除 key 和所有 value),无论其属性的取值是 single、set 或 list。

Response Status

1200

Response Body

1{
2    "id": "1:marko",
3    "label": "person",
4    "type": "vertex",
5    "properties": {
6        "name": "marko",
7        "age": 30
8    }
9}

2.1.6 获取符合条件的顶点

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

请求参数说明:

  • label: 顶点的类型
  • properties: 属性键值对(索引覆盖要求见下文)
  • keep_start_p: 默认为 false,设置为 true 时不会自动转义范围匹配表达式,例如 properties={"age":"P.gt(18)"} 会被当作精确匹配,即 age 属性等于字符串 “P.gt(18)”
  • offset: 偏移量,默认为 0
  • limit: 查询结果的最大数目,默认为 100
  • page: 分页的页号

以上参数都是可选的,page 不能与非 0 的 offset 同时使用,其余参数之间可以任意组合。

指定 label 且该标签使用 PRIMARY_KEY ID 策略时,如果 properties 为所有主键字段提供精确值(P.eq 与 P.within 均视作精确值),查询直接按 ID 检索顶点,取回后再验证其余属性条件,无需属性索引。 若主键字段齐全但其中任一字段使用了 P.eq、P.within、P.contains 以外的谓词(如 P.neq、P.gt、P.between、P.textcontains 等),查询在进入属性索引阶段前即被拒绝,即使存在匹配索引也不例外。P.contains 用于主键字段时走单元素 ID 查找,不会被拦截。

对于其他 properties 查询:指定 label 时,该标签需要有与查询条件匹配的属性索引。候选标签是指声明了全部待查非 OLAP 属性的顶点标签(包括暂无数据的标签)。

普通查询不可见的标签(包括正在删除的标签)不计入候选集,不需要索引覆盖。若所有候选标签均不可见或正在删除(或指定的 label 本身不可见或正在删除),查询直接返回空结果,不报索引错误。若没有任何 Schema 标签声明待查属性,仍会报索引错误。注意:仅建立标签索引不等于属性已建立索引。

若查询包含 OLAP 属性且读取模式已开放 OLAP 数据,HugeGraph 使用全局共享的 OLAP 索引,这类属性无需每个候选标签单独建立索引。

错误触发规则:查询值与属性类型兼容,但缺少匹配索引或只覆盖了部分候选标签,均会报索引错误;仅当所有候选标签均被完整覆盖时,查询才通过索引执行。查询值与属性类型不兼容时,若已找到匹配索引则可能返回空结果(跳过部分覆盖检查);若无任何匹配索引仍报索引错误。查询不会自动回退到全量扫描。

说明

部分覆盖检查与候选标签不可见时返回空结果的机制自 1.8.0 起生效。早期版本仅返回命中索引标签的匹配结果,且在无标签具备匹配索引时直接报索引错误。

属性键值对由属性名称和属性值组成 JSON 格式的对象,可以使用多个属性键值对作为查询条件,属性值支持精确匹配和范围匹配,精确匹配的形式如properties={"age":29},范围匹配的形式如properties={"age":"P.gt(29)"},范围匹配支持以下表达式:

表达式说明
P.eq(number)属性值等于 number 的顶点
P.neq(number)属性值不等于 number 的顶点
P.lt(number)属性值小于 number 的顶点
P.lte(number)属性值小于等于 number 的顶点
P.gt(number)属性值大于 number 的顶点
P.gte(number)属性值大于等于 number 的顶点
P.between(number1,number2)属性值大于等于 number1 且小于 number2 的顶点
P.inside(number1,number2)属性值大于 number1 且小于 number2 的顶点
P.outside(number1,number2)属性值小于 number1 且大于 number2 的顶点
P.within(value1,value2,value3,…)属性值等于任何一个给定 value 的顶点

查询所有 age 为 29 且 label 为 person 的顶点

Method & Url

1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices?label=person&properties={"age":29}&limit=1

Response Status

1200

Response Body

 1{
 2    "vertices": [
 3        {
 4            "id": "1:marko",
 5            "label": "person",
 6            "type": "vertex",
 7            "properties": {
 8                "name": "marko",
 9                "age": 30
10            }
11        }
12    ]
13}

分页查询所有顶点,获取第一页(page 不带参数值),限定 3 条

通过以下命令新增顶点:

1curl -H "Content-Type: application/json" -d '[{"label":"person","properties":{"name":"peter","age":29,"city":"Shanghai"}},{"label":"person","properties":{"name":"vadas","age":27,"city":"Hongkong"}}]' http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/batch

Method & Url

1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices?page&limit=3

Response Status

1200

Response Body

 1{
 2    "vertices": [
 3        {
 4            "id": "2:lop",
 5            "label": "software",
 6            "type": "vertex",
 7            "properties": {
 8                "name": "lop",
 9                "lang": "c++",
10                "price": 328
11            }
12        },
13        {
14            "id": "1:josh",
15            "label": "person",
16            "type": "vertex",
17            "properties": {
18                "name": "josh",
19                "age": 32,
20                "city": "Shanghai",
21                "weight": 0.3,
22                "hobby": [
23                    "reading",
24                    "football",
25                    "swimming"
26                ]
27            }
28        },
29        {
30            "id": "1:marko",
31            "label": "person",
32            "type": "vertex",
33            "properties": {
34                "name": "marko",
35                "age": 30
36            }
37        }
38    ],
39    "page": "CIYxOnBldGVyAAAAAAAAAAM="
40}

返回的 body 里面是带有下一页的页号信息的,"page": "CIYxOnBldGVyAAAAAAAAAAM=",在查询下一页的时候将该值赋给 page 参数。

分页查询所有顶点,获取下一页(page 带上上一页返回的 page 值),限定 3 条

Method & Url

1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices?page=CIYxOnBldGVyAAAAAAAAAAM=&limit=3

Response Status

1200

Response Body

 1{
 2    "vertices": [
 3        {
 4            "id": "1:peter",
 5            "label": "person",
 6            "type": "vertex",
 7            "properties": {
 8                "name": "peter",
 9                "age": 29,
10                "city": "Shanghai"
11            }
12        },
13        {
14            "id": "1:vadas",
15            "label": "person",
16            "type": "vertex",
17            "properties": {
18                "name": "vadas",
19                "age": 27,
20                "city": "Hongkong"
21            }
22        },
23        {
24            "id": "2:ripple",
25            "label": "software",
26            "type": "vertex",
27            "properties": {
28                "name": "ripple",
29                "lang": "java",
30                "price": 199
31            }
32        }
33    ],
34    "page": null
35}

当"page": null时,表示已经没有下一页了(注:如果后端使用的是 Cassandra,为了提高性能,当返回的页数刚好是最后一页时,返回的 page 值可能不为空,但是如果用这个 page 值再请求下一页数据时,就会返回 空数据 和 page = null,其他情况也类似)

2.1.7 根据 Id 获取顶点

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
  • id: 顶点 id,需要包含引号,例如"1:marko"

Method & Url

1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/"1:marko"

Response Status

1200

Response Body

1{
2    "id": "1:marko",
3    "label": "person",
4    "type": "vertex",
5    "properties": {
6        "name": "marko",
7        "age": 30
8    }
9}

2.1.8 根据 Id 删除顶点

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
  • id: 顶点 id,需要包含引号,例如"1:marko"

请求参数说明:

  • label: 顶点类型,可选参数

仅根据 Id 删除顶点

Method & Url

1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/"1:marko"

Response Status

1204

根据 Label+Id 删除顶点

通过指定 Label 参数和 Id 来删除顶点时,一般来说其性能比仅根据 Id 删除会更好。

Method & Url

1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices/"1:marko"?label=person

Response Status

1204

5.1.9 - Edge API

Edge(边)REST 接口:创建、查询、更新和删除顶点之间的关系数据,支持批量操作和方向查询。

2.2 Edge

顶点 id 格式的修改也影响到了边的 id 以及源顶点和目标顶点 id 的格式

EdgeId 是由 src-vertex-id + direction + label + sort-values + tgt-vertex-id 拼接而成,但是这里的顶点 id 类型不是通过引号区分的,而是根据前缀区分:

  • 当 id 类型为 number 时,EdgeId 的顶点 id 前有一个前缀 L ,形如 “L123456>1»L987654”
  • 当 id 类型为 string 时,EdgeId 的顶点 id 前有一个前缀 S ,形如 “S1:peter>1»S2:lop”

边 ID 使用 Server 的原始边 ID 格式,转义 URL 保留字符时不要额外加 JSON 引号。不能把顶点 ID 编码规则直接套到边 ID 上。 追加属性使用 PUT .../edges/{id}?action=append 并提交对应 JSON 属性体。 删除边时按后端要求提供 DELETE .../edges/{id}?label={label} 的标签参数。


接下来的示例需要先根据以下 groovy 脚本创建图 schema

 1import org.apache.hugegraph.HugeFactory
 2import org.apache.tinkerpop.gremlin.structure.T
 3
 4conf = "conf/graphs/hugegraph.properties"
 5graph = HugeFactory.open(conf)
 6schema = graph.schema()
 7
 8schema.propertyKey("name").asText().ifNotExist().create()
 9schema.propertyKey("age").asInt().ifNotExist().create()
10schema.propertyKey("city").asText().ifNotExist().create()
11schema.propertyKey("weight").asDouble().ifNotExist().create()
12schema.propertyKey("lang").asText().ifNotExist().create()
13schema.propertyKey("date").asText().ifNotExist().create()
14schema.propertyKey("price").asInt().ifNotExist().create()
15
16schema.vertexLabel("person").properties("name", "age", "city").primaryKeys("name").ifNotExist().create()
17schema.vertexLabel("software").properties("name", "lang", "price").primaryKeys("name").ifNotExist().create()
18schema.indexLabel("personByCity").onV("person").by("city").secondary().ifNotExist().create()
19schema.indexLabel("personByAgeAndCity").onV("person").by("age", "city").secondary().ifNotExist().create()
20schema.indexLabel("softwareByPrice").onV("software").by("price").range().ifNotExist().create()
21schema.edgeLabel("knows").sourceLabel("person").targetLabel("person").properties("date", "weight").ifNotExist().create()
22schema.edgeLabel("created").sourceLabel("person").targetLabel("software").properties("date", "weight").ifNotExist().create()
23schema.indexLabel("createdByDate").onE("created").by("date").secondary().ifNotExist().create()
24schema.indexLabel("createdByWeight").onE("created").by("weight").range().ifNotExist().create()
25schema.indexLabel("knowsByWeight").onE("knows").by("weight").range().ifNotExist().create()
26
27marko = graph.addVertex(T.label, "person", "name", "marko", "age", 29, "city", "Beijing")
28vadas = graph.addVertex(T.label, "person", "name", "vadas", "age", 27, "city", "Hongkong")
29lop = graph.addVertex(T.label, "software", "name", "lop", "lang", "java", "price", 328)
30josh = graph.addVertex(T.label, "person", "name", "josh", "age", 32, "city", "Beijing")
31ripple = graph.addVertex(T.label, "software", "name", "ripple", "lang", "java", "price", 199)
32peter = graph.addVertex(T.label, "person", "name", "peter", "age", 35, "city", "Shanghai")
33
34graph.tx().commit()
35g = graph.traversal()

2.2.1 创建一条边

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图

请求体说明:

  • label:边类型名称,必填
  • outV:源顶点 id,必填
  • inV:目标顶点 id,必填
  • outVLabel:源顶点类型,必填
  • inVLabel:目标顶点类型,必填
  • properties: 边关联的属性,对象内部结构为:
    1. name:属性名称
    2. value:属性值
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges
Request Body
 1{
 2    "label": "created",
 3    "outV": "1:marko",
 4    "inV": "2:lop",
 5    "outVLabel": "person",
 6    "inVLabel": "software",
 7    "properties": {
 8        "date": "20171210",
 9        "weight": 0.4
10    }
11}
Response Status
1201
Response Body
 1{
 2    "id": "S1:marko>2>>S2:lop",
 3    "label": "created",
 4    "type": "edge",
 5    "outV": "1:marko",
 6    "outVLabel": "person",
 7    "inV": "2:lop",
 8    "inVLabel": "software",
 9    "properties": {
10        "weight": 0.4,
11        "date": "20171210"
12    }
13}

2.2.2 创建多条边

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图

请求参数说明:

  • check_vertex:是否检查顶点存在 (true | false),当设置为 true 而待插入边的源顶点或目标顶点不存在时会报错,默认为 true

请求体说明:

  • 边信息的列表
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/batch
Request Body
 1[
 2    {
 3        "label": "knows",
 4        "outV": "1:marko",
 5        "inV": "1:vadas",
 6        "outVLabel": "person",
 7        "inVLabel": "person",
 8        "properties": {
 9            "date": "20160110",
10            "weight": 0.5
11        }
12    },
13    {
14        "label": "knows",
15        "outV": "1:marko",
16        "inV": "1:josh",
17        "outVLabel": "person",
18        "inVLabel": "person",
19        "properties": {
20            "date": "20130220",
21            "weight": 1.0
22        }
23    }
24]
Response Status
1201
Response Body
1[
2    "S1:marko>1>>S1:vadas",
3    "S1:marko>1>>S1:josh"
4]

2.2.3 更新边属性

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图
  • id:待操作的边 id

请求参数说明:

  • action:append 操作

请求体说明:

  • 边信息
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop?action=append
Request Body
1{
2    "properties": {
3        "weight": 1.0
4    }
5}

注意:属性的取值是有三种类别的,分别是 single、set 和 list。如果是 single,表示增加或更新属性值;如果是 set 或 list,则表示追加属性值

Response Status
1200
Response Body
 1{
 2    "id": "S1:marko>2>>S2:lop",
 3    "label": "created",
 4    "type": "edge",
 5    "outV": "1:marko",
 6    "outVLabel": "person",
 7    "inV": "2:lop",
 8    "inVLabel": "software",
 9    "properties": {
10        "weight": 1.0,
11        "date": "20171210"
12    }
13}

2.2.4 批量更新边属性

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图

请求体说明:

  • edges:边信息的列表
  • update_strategies:对于每个属性,可以单独设置其更新策略,包括:
    • SUM:仅支持 number 类型
    • BIGGER/SMALLER:仅支持 date/number 类型
    • UNION/INTERSECTION:仅支持 set 类型
    • APPEND/ELIMINATE:仅支持 collection 类型
    • OVERRIDE
  • check_vertex:是否检查顶点存在 (true | false),当设置为 true 而待插入边的源顶点或目标顶点不存在时会报错,默认为 true
  • create_if_not_exist:目前只支持设定为 true
Method & Url
1PUT http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/batch
Request Body
 1{
 2    "edges": [
 3        {
 4            "label": "knows",
 5            "outV": "1:marko",
 6            "inV": "1:vadas",
 7            "outVLabel": "person",
 8            "inVLabel": "person",
 9            "properties": {
10                "date": "20160111",
11                "weight": 1.0
12            }
13        },
14        {
15            "label": "knows",
16            "outV": "1:marko",
17            "inV": "1:josh",
18            "outVLabel": "person",
19            "inVLabel": "person",
20            "properties": {
21                "date": "20130221",
22                "weight": 0.5
23            }
24        }
25    ],
26    "update_strategies": {
27        "weight": "SUM",
28        "date": "OVERRIDE"
29    },
30    "check_vertex": false,
31    "create_if_not_exist": true
32}
Response Status
1200
Response Body
 1{
 2    "edges": [
 3        {
 4            "id": "S1:marko>1>>S1:vadas",
 5            "label": "knows",
 6            "type": "edge",
 7            "outV": "1:marko",
 8            "outVLabel": "person",
 9            "inV": "1:vadas",
10            "inVLabel": "person",
11            "properties": {
12                "weight": 1.5,
13                "date": "20160111"
14            }
15        },
16        {
17            "id": "S1:marko>1>>S1:josh",
18            "label": "knows",
19            "type": "edge",
20            "outV": "1:marko",
21            "outVLabel": "person",
22            "inV": "1:josh",
23            "inVLabel": "person",
24            "properties": {
25                "weight": 1.5,
26                "date": "20130221"
27            }
28        }
29    ]
30}

2.2.5 删除边属性

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图
  • id:待操作的边 id

请求参数说明:

  • action:eliminate 操作

请求体说明:

  • 边信息
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop?action=eliminate
Request Body
1{
2    "properties": {
3        "weight": 1.0
4    }
5}

注意:这里会直接删除属性(删除 key 和所有 value),无论其属性的取值是 single、set 或 list

Response Status
1400
Response Body

无法删除未设置为 nullable 的属性

1{
2    "exception": "class java.lang.IllegalArgumentException",
3    "message": "Can't remove non-null edge property 'p[weight->1.0]'",
4    "cause": ""
5}

2.2.6 获取符合条件的边

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图

请求参数说明:

  • vertex_id: 顶点 id
  • direction: 边的方向 (OUT | IN | BOTH),默认为 BOTH
  • label: 边的标签
  • properties: 属性键值对(索引覆盖要求见下文)
  • keep_start_p: 默认为 false,当设置为 true 后,不会自动转义范围匹配输入的表达式,例如此时 properties={"age":"P.gt(0.8)"} 会被理解为精确匹配,即 age 属性等于 “P.gt(0.8)”
  • offset:偏移,默认为 0
  • limit: 查询数目,默认为 100
  • page: 页号

未指定 vertex_id 时,properties 在全图范围内查询边。指定 label 时,该标签需有与查询条件匹配的属性索引;若指定的是未单独建索引的子边标签,可以使用其父标签(查询可见的)上的匹配索引,同级其他子标签的边会被自动过滤。

候选标签是可直接存边且声明了全部待查非 OLAP 属性的边标签(包括当前没有边的标签)。普通查询不可见的标签(包括正在删除的标签)不计入候选集,不需要索引覆盖。若所有候选标签均不可见或正在删除(或指定的 label 本身不可见或正在删除),查询返回空结果,不报索引错误。若没有任何 Schema 标签声明待查属性,仍会报索引错误。

未指定 label 时:base 父边标签不直接存边,子标签全部被覆盖时无需再为父标签单独建立索引。可以使用当前查询可见的父标签上的匹配索引覆盖子标签,也可以为每个候选子标签单独建立索引。父标签因隐藏或正在删除而被排除时,其索引不能用于覆盖子标签。仅有标签索引不等于属性已建立索引。

错误触发规则:查询值与属性类型兼容,但缺少匹配索引或只覆盖了部分候选标签,均会报索引错误;仅当所有候选标签均被完整覆盖时,查询才通过索引执行。查询值与属性类型不兼容时,若已找到匹配索引则可能返回空结果(跳过部分覆盖检查);若无任何匹配索引仍报索引错误。查询不会自动回退到全量扫描。

说明

部分覆盖检查、子边标签复用父标签索引,以及候选标签不可见时返回空结果的机制,自 1.8.0 起生效。早期版本仅使用指定标签自身建立的索引,未指定 label 时仅返回命中索引标签的匹配结果,且在无标签具备匹配索引时直接报索引错误。

指定 vertex_id 时,查询过滤该顶点的邻接边,不适用上述全图查询的索引覆盖要求。

属性键值对由 JSON 格式的属性名称和属性值组成,允许多个属性键值对作为查询条件,属性值支持精确匹配和范围匹配,精确匹配时形如 properties={"weight":0.8},范围匹配时形如 properties={"age":"P.gt(0.8)"},范围匹配支持的表达式如下:

表达式说明
P.eq(number)属性值等于 number 的边
P.neq(number)属性值不等于 number 的边
P.lt(number)属性值小于 number 的边
P.lte(number)属性值小于等于 number 的边
P.gt(number)属性值大于 number 的边
P.gte(number)属性值大于等于 number 的边
P.between(number1,number2)属性值大于等于 number1 且小于 number2 的边
P.inside(number1,number2)属性值大于 number1 且小于 number2 的边
P.outside(number1,number2)属性值小于 number1 且大于 number2 的边
P.within(value1,value2,value3,…)属性值等于任何一个给定 value 的边
P.textcontains(value)属性值包含给定 value 的边 (string 类型)
P.contains(value)属性值包含给定 value 的边 (collection 类型)

查询与顶点 person:marko(vertex_id=“1:marko”) 相连且 label 为 knows 的且 date 属性等于 “20160111” 的边

Method & Url
1GET http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges?vertex_id="1:marko"&label=knows&properties={"date":"P.within(\"20160111\")"}
Response Status
1200
Response Body
 1{
 2    "edges": [
 3        {
 4            "id": "S1:marko>1>>S1:vadas",
 5            "label": "knows",
 6            "type": "edge",
 7            "outV": "1:marko",
 8            "outVLabel": "person",
 9            "inV": "1:vadas",
10            "inVLabel": "person",
11            "properties": {
12                "weight": 1.5,
13                "date": "20160111"
14            }
15        }
16    ]
17}

分页查询所有边,获取第一页(page 不带参数值),限定 2 条

Method & Url
1GET http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges?page&limit=2
Response Status
1200
Response Body
 1{
 2    "edges": [
 3        {
 4            "id": "S1:marko>1>>S1:josh",
 5            "label": "knows",
 6            "type": "edge",
 7            "outV": "1:marko",
 8            "outVLabel": "person",
 9            "inV": "1:josh",
10            "inVLabel": "person",
11            "properties": {
12                "weight": 1.5,
13                "date": "20130221"
14            }
15        },
16        {
17            "id": "S1:marko>1>>S1:vadas",
18            "label": "knows",
19            "type": "edge",
20            "outV": "1:marko",
21            "outVLabel": "person",
22            "inV": "1:vadas",
23            "inVLabel": "person",
24            "properties": {
25                "weight": 1.5,
26                "date": "20160111"
27            }
28        }
29    ],
30    "page": "EoYxOm1hcmtvgggCAIQyOmxvcAAAAAAAAAAC"
31}

返回的 body 里面是带有下一页的页号信息的,"page": "EoYxOm1hcmtvgggCAIQyOmxvcAAAAAAAAAAC",在查询下一页的时候将该值赋给 page 参数

分页查询所有边,获取下一页(page 带上上一页返回的 page 值),限定 2 条

Method & Url
1GET http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges?page=EoYxOm1hcmtvgggCAIQyOmxvcAAAAAAAAAAC&limit=2
Response Status
1200
Response Body
 1{
 2    "edges": [
 3        {
 4            "id": "S1:marko>2>>S2:lop",
 5            "label": "created",
 6            "type": "edge",
 7            "outV": "1:marko",
 8            "outVLabel": "person",
 9            "inV": "2:lop",
10            "inVLabel": "software",
11            "properties": {
12                "weight": 1.0,
13                "date": "20171210"
14            }
15        }
16    ],
17    "page": null
18}

此时 "page": null 表示已经没有下一页了

注:后端为 Cassandra 时,为了性能考虑,返回页恰好为最后一页时,返回 page 值可能非空,通过该 page 再请求下一页数据时则返回 空数据 及 page = null,其他情况类似

2.2.7 根据 id 获取边

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图
  • id:待操作的边 id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop
Response Status
1200
Response Body
 1{
 2    "id": "S1:marko>2>>S2:lop",
 3    "label": "created",
 4    "type": "edge",
 5    "outV": "1:marko",
 6    "outVLabel": "person",
 7    "inV": "2:lop",
 8    "inVLabel": "software",
 9    "properties": {
10        "weight": 1.0,
11        "date": "20171210"
12    }
13}

2.2.8 根据 id 删除边

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph:待操作的图
  • id:待操作的边 id

请求参数说明:

  • label: 边的标签

仅根据 id 删除边

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/S1:marko>2>>S2:lop
Response Status
1204

根据 label + id 删除边

通过指定 label 参数和 id 来删除边时,一般来说其性能比仅根据 id 删除会更好

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/edges/S1:marko>1>>S1:vadas?label=knows
Response Status
1204

5.1.10 - Traverser API

Traverser(图遍历)REST 接口:执行复杂的图算法和路径查询,包括最短路径、K近邻、相似度计算等高级分析功能。

3.1 traverser API 概述

HugeGraphServer 为 HugeGraph 图数据库提供了 RESTful API 接口。除了顶点和边的 CRUD 基本操作以外,还提供了一些遍历(traverser)方法,我们称为traverser API。这些遍历方法实现了一些复杂的图算法,方便用户对图进行分析和挖掘。

HugeGraph 支持的 Traverser API 包括:

  • K-out API,根据起始顶点,查找恰好 N 步可达的邻居,分为基础版和高级版:
    • 基础版使用 GET 方法,根据起始顶点,查找恰好 N 步可达的邻居
    • 高级版使用 POST 方法,根据起始顶点,查找恰好 N 步可达的邻居,与基础版的不同在于:
      • 支持只统计邻居数量
      • 支持顶点和边属性过滤
      • 支持返回到达邻居的最短路径
  • K-neighbor API,根据起始顶点,查找 N 步以内可达的所有邻居,分为基础版和高级版:
    • 基础版使用 GET 方法,根据起始顶点,查找 N 步以内可达的所有邻居
    • 高级版使用 POST 方法,根据起始顶点,查找 N 步以内可达的所有邻居,与基础版的不同在于:
      • 支持只统计邻居数量
      • 支持顶点和边属性过滤
      • 支持返回到达邻居的最短路径
  • Same Neighbors,查询顶点的共同邻居。GET 接口用于查询两个顶点的共同邻居;POST 批量接口用于在单次请求中独立计算多组顶点对的共同邻居。
  • Jaccard Similarity API,计算 jaccard 相似度,包括两种:
    • 一种是使用 GET 方法,计算两个顶点的邻居的相似度(交并比)
    • 一种是使用 POST 方法,在全图中查找与起点的 jaccard similarity 最高的 N 个点
  • Shortest Path API,查找两个顶点之间的最短路径
  • All Shortest Paths,查找两个顶点间的全部最短路径
  • Weighted Shortest Path,查找起点到目标点的带权最短路径
  • Single Source Shortest Path,查找一个点到其他各个点的加权最短路径
  • Multi Node Shortest Path,查找指定顶点集之间两两最短路径
  • Paths API,查找两个顶点间的全部路径,分为基础版和高级版:
    • 基础版使用 GET 方法,根据起点和终点,查找两个顶点间的全部路径
    • 高级版使用 POST 方法,根据一组起点和一组终点,查找两个集合间符合条件的全部路径
  • Customized Paths API,从一批顶点出发,按(一种)模式遍历经过的全部路径
  • Template Path API,指定起点和终点以及起点和终点间路径信息,查找符合的路径
  • Crosspoints API,查找两个顶点的交点(共同祖先或者共同子孙)
  • Customized Crosspoints API,从一批顶点出发,按多种模式遍历,最后一步到达的顶点的交点
  • Rings API,从起始顶点出发,可到达的环路路径
  • Rays API,从起始顶点出发,可到达边界的路径(即无环路径)
  • Fusiform Similarity API,查找一个顶点的梭形相似点
  • Adamic-Adar API,计算两个顶点的 Adamic-Adar 指标
  • Resource Allocation API,计算两个顶点的资源分配指标
  • Edge Existence API,查询两个顶点之间存在的边
  • Count API,统计经过若干步遍历后可达的顶点数量,不返回顶点本身
  • Vertices API
    • 按 ID 批量查询顶点;
    • 获取顶点的分区;
    • 按分区查询顶点;
  • Edges API
    • 按 ID 批量查询边;
    • 获取边的分区;
    • 按分区查询边;

3.2. traverser API 详解

使用方法中的例子,都是基于 TinkerPop 官网给出的图:

TinkerPop 示例图

数据导入程序如下:

  1public class Loader {
  2    public static void main(String[] args) {
  3        HugeClient client = new HugeClient("http://127.0.0.1:8080", "hugegraph");
  4        SchemaManager schema = client.schema();
  5        schema.propertyKey("name").asText().ifNotExist().create();
  6        schema.propertyKey("age").asInt().ifNotExist().create();
  7        schema.propertyKey("city").asText().ifNotExist().create();
  8        schema.propertyKey("weight").asDouble().ifNotExist().create();
  9        schema.propertyKey("lang").asText().ifNotExist().create();
 10        schema.propertyKey("date").asText().ifNotExist().create();
 11        schema.propertyKey("price").asInt().ifNotExist().create();
 12
 13        schema.vertexLabel("person")
 14              .properties("name", "age", "city")
 15              .primaryKeys("name")
 16              .nullableKeys("age")
 17              .ifNotExist()
 18              .create();
 19
 20        schema.vertexLabel("software")
 21              .properties("name", "lang", "price")
 22              .primaryKeys("name")
 23              .nullableKeys("price")
 24              .ifNotExist()
 25              .create();
 26
 27        schema.indexLabel("personByCity")
 28              .onV("person")
 29              .by("city")
 30              .secondary()
 31              .ifNotExist()
 32              .create();
 33
 34        schema.indexLabel("personByAgeAndCity")
 35              .onV("person")
 36              .by("age", "city")
 37              .secondary()
 38              .ifNotExist()
 39              .create();
 40
 41        schema.indexLabel("softwareByPrice")
 42              .onV("software")
 43              .by("price")
 44              .range()
 45              .ifNotExist()
 46              .create();
 47
 48        schema.edgeLabel("knows")
 49              .multiTimes()
 50              .sourceLabel("person")
 51              .targetLabel("person")
 52              .properties("date", "weight")
 53              .sortKeys("date")
 54              .nullableKeys("weight")
 55              .ifNotExist()
 56              .create();
 57
 58        schema.edgeLabel("created")
 59              .sourceLabel("person").targetLabel("software")
 60              .properties("date", "weight")
 61              .nullableKeys("weight")
 62              .ifNotExist()
 63              .create();
 64
 65        schema.indexLabel("createdByDate")
 66              .onE("created")
 67              .by("date")
 68              .secondary()
 69              .ifNotExist()
 70              .create();
 71
 72        schema.indexLabel("createdByWeight")
 73              .onE("created")
 74              .by("weight")
 75              .range()
 76              .ifNotExist()
 77              .create();
 78
 79        schema.indexLabel("knowsByWeight")
 80              .onE("knows")
 81              .by("weight")
 82              .range()
 83              .ifNotExist()
 84              .create();
 85
 86        GraphManager graph = client.graph();
 87        Vertex marko = graph.addVertex(T.label, "person", "name", "marko",
 88                                       "age", 29, "city", "Beijing");
 89        Vertex vadas = graph.addVertex(T.label, "person", "name", "vadas",
 90                                       "age", 27, "city", "Hongkong");
 91        Vertex lop = graph.addVertex(T.label, "software", "name", "lop",
 92                                     "lang", "java", "price", 328);
 93        Vertex josh = graph.addVertex(T.label, "person", "name", "josh",
 94                                      "age", 32, "city", "Beijing");
 95        Vertex ripple = graph.addVertex(T.label, "software", "name", "ripple",
 96                                        "lang", "java", "price", 199);
 97        Vertex peter = graph.addVertex(T.label, "person", "name", "peter",
 98                                       "age", 35, "city", "Shanghai");
 99
100        marko.addEdge("knows", vadas, "date", "20160110", "weight", 0.5);
101        marko.addEdge("knows", josh, "date", "20130220", "weight", 1.0);
102        marko.addEdge("created", lop, "date", "20171210", "weight", 0.4);
103        josh.addEdge("created", lop, "date", "20091111", "weight", 0.4);
104        josh.addEdge("created", ripple, "date", "20171210", "weight", 1.0);
105        peter.addEdge("created", lop, "date", "20170324", "weight", 0.2);
106    }
107}

顶点 ID 为:

1"2:ripple",
2"1:vadas",
3"1:peter",
4"1:josh",
5"1:marko",
6"2:lop"

边 ID 为:

1"S1:peter>2>>S2:lop",
2"S1:josh>2>>S2:lop",
3"S1:josh>2>>S2:ripple",
4"S1:marko>1>20130220>S1:josh",
5"S1:marko>1>20160110>S1:vadas",
6"S1:marko>2>>S2:lop"

3.2.1 K-out API(GET,基础版)

3.2.1.1 功能介绍

根据起始顶点、方向、边的类型(可选)和深度 depth,查找从起始顶点出发恰好 depth 步可达的顶点

Params
  • source:起始顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • max_depth:步数,必填项
  • label:边的类型,选填项,默认代表所有 edge label
  • nearest:nearest 为 true 时,代表起始顶点到达结果顶点的最短路径长度为 depth,不存在更短的路径;nearest 为 false 时,代表起始顶点到结果顶点有一条长度为 depth 的路径(未必最短且可以有环),选填项,默认为 true
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的顶点的最大数目,选填项,默认为 10000000
3.2.1.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/kout?source="1:marko"&max_depth=2
Response Status
1200
Response Body
1{
2    "vertices":[
3        "2:ripple",
4        "1:peter"
5    ]
6}
3.2.1.3 适用场景

查找恰好 N 步关系可达的顶点。两个例子:

  • 家族关系中,查找一个人的所有孙子,person A 通过连续的两条“儿子”边到达的顶点集合。
  • 社交关系中发现潜在好友,例如:与目标用户相隔两层朋友关系的用户,可以通过连续两条“朋友”边到达的顶点。

3.2.2 K-out API(POST,高级版)

3.2.2.1 功能介绍

根据起始顶点、步骤(包括方向、边类型和过滤属性)和深度 depth,查找从起始顶点出发恰好 depth 步可达的顶点。

与 K-out 基础版的不同在于:

  • 支持只统计邻居数量
  • 支持边属性过滤
  • 支持返回到达邻居的最短路径
Params
  • source:起始顶点 id,必填项
  • steps: 从起始点出发的 Steps,必填项,结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • edge_steps:边 Step 集合,支持对单边的类型和属性过滤,如果为空,则不过滤
      • label:边类型
      • properties:边属性
    • vertex_steps:顶点 Step 集合,支持对单点的类型和属性过滤,如果为空,则不过滤
      • label:顶点类型
      • properties:顶点属性
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • max_depth:步数,必填项
  • nearest:nearest 为 true 时,代表起始顶点到达结果顶点的最短路径长度为 depth,不存在更短的路径;nearest 为 false 时,代表起始顶点到结果顶点有一条长度为 depth 的路径(未必最短且可以有环),选填项,默认为 true
  • count_only:Boolean 值,true 表示只统计结果的数目,不返回具体结果;false 表示返回具体的结果,默认为 false
  • with_path:true 表示返回起始点到每个邻居的最短路径,false 表示不返回起始点到每个邻居的最短路径,选填项,默认为 false
  • with_edge,选填项,默认为 false:
    • 如果设置为 true,则结果将包含所有边的完整信息,即路径中的所有边
      • 当 with_path 为 true 时,将返回所有路径中的边的完整信息
      • 当 with_path 为 false 时,不返回任何信息
    • 如果设置为 false,则仅返回边的 id
  • with_vertex,选填项,默认为 false:
    • 如果设置为 true,则结果将包含所有顶点的完整信息,即路径中的所有顶点
      • 当 with_path 为 true 时,将返回所有路径中的顶点的完整信息
      • 当 with_path 为 false 时,返回所有邻居顶点的完整信息
    • 如果设置为 false,则仅返回顶点的 id
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的顶点的最大数目,选填项,默认为 10000000
  • traverse_mode: 遍历方式,可选择“breadth_first_search”或“depth_first_search”作为参数,默认为“breadth_first_search”
3.2.2.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/kout
Request Body
 1{
 2    "source": "1:marko",
 3    "steps": {
 4        "direction": "BOTH",
 5        "edge_steps": [
 6            {
 7                "label": "knows",
 8                "properties": {
 9                    "weight": "P.gt(0.1)"
10                }
11            },
12            {
13                "label": "created",
14                "properties": {
15                    "weight": "P.gt(0.1)"
16                }
17            }
18        ],
19        "vertex_steps": [
20            {
21                "label": "person",
22                "properties": {
23                    "age": "P.lt(32)"
24                }
25            },
26            {
27                "label": "software",
28                "properties": {}
29            }
30        ],
31        "max_degree": 10000,
32        "skip_degree": 100000
33    },
34    "max_depth": 1,
35    "nearest": true,
36    "limit": 10000,
37    "with_vertex": true,
38    "with_path": true,
39    "with_edge": true
40}
Response Status
1200
Response Body
 1{
 2    "size": 2,
 3	"kout": [
 4        "1:vadas",
 5        "2:lop"
 6    ],
 7    "paths": [
 8        {
 9            "objects": [
10                "1:marko",
11                "2:lop"
12            ]
13        },
14        {
15            "objects": [
16                "1:marko",
17                "1:vadas"
18            ]
19        }
20    ],
21    "vertices": [
22        {
23            "id": "1:marko",
24            "label": "person",
25            "type": "vertex",
26            "properties": {
27                "name": "marko",
28                "age": 29,
29                "city": "Beijing"
30            }
31        },
32        {
33            "id": "1:vadas",
34            "label": "person",
35            "type": "vertex",
36            "properties": {
37                "name": "vadas",
38                "age": 27,
39                "city": "Hongkong"
40            }
41        },
42        {
43            "id": "2:lop",
44            "label": "software",
45            "type": "vertex",
46            "properties": {
47                "name": "lop",
48                "lang": "java",
49                "price": 328
50            }
51        }
52    ],
53    "edges": [
54        {
55            "id": "S1:marko>1>20160110>S1:vadas",
56            "label": "knows",
57            "type": "edge",
58            "outV": "1:marko",
59            "outVLabel": "person",
60            "inV": "1:vadas",
61            "inVLabel": "person",
62            "properties": {
63                "weight": 0.5,
64                "date": "20160110"
65            }
66        },
67        {
68            "id": "S1:marko>2>>S2:lop",
69            "label": "created",
70            "type": "edge",
71            "outV": "1:marko",
72            "outVLabel": "person",
73            "inV": "2:lop",
74            "inVLabel": "software",
75            "properties": {
76                "weight": 0.4,
77                "date": "20171210"
78            }
79        }
80    ]
81}
3.2.2.3 适用场景

参见 3.2.1.3

3.2.3 K-neighbor(GET,基础版)

3.2.3.1 功能介绍

根据起始顶点、方向、边的类型(可选)和深度 depth,查找包括起始顶点在内、depth 步之内可达的所有顶点

相当于:起始顶点、K-out(1)、K-out(2)、… 、K-out(max_depth) 的并集

Params
  • source: 起始顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • max_depth:步数,必填项
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • limit:返回的顶点的最大数目,也即遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
3.2.3.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/kneighbor?source=%221:marko%22&max_depth=2
Response Status
1200
Response Body
 1{
 2    "vertices":[
 3        "2:ripple",
 4        "1:marko",
 5        "1:josh",
 6        "1:vadas",
 7        "1:peter",
 8        "2:lop"
 9    ]
10}
3.2.3.3 适用场景

查找 N 步以内可达的所有顶点,例如:

  • 家族关系中,查找一个人五服以内所有子孙,person A 通过连续的 5 条“亲子”边到达的顶点集合。
  • 社交关系中发现好友圈子,例如目标用户通过 1 条、2 条、3 条“朋友”边可到达的用户可以组成目标用户的朋友圈子

3.2.4 K-neighbor API(POST,高级版)

3.2.4.1 功能介绍

根据起始顶点、步骤(包括方向、边类型和过滤属性)和深度 depth,查找从起始顶点出发 depth 步内可达的所有顶点。

与 K-neighbor 基础版的不同在于:

  • 支持只统计邻居数量
  • 支持边属性过滤
  • 支持返回到达邻居的最短路径
Params
  • source:起始顶点 id,必填项
  • steps: 从起始点出发的 Steps,必填项,结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • 从起始点出发的 Steps,必填项,结构如下:
      • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
      • edge_steps:边 Step 集合,支持对单边的类型和属性过滤,如果为空,则不过滤
        • label:边类型
        • properties:边属性
      • vertex_steps:顶点 Step 集合,支持对单点的类型和属性过滤,如果为空,则不过滤
        • label:顶点类型
        • properties:顶点属性
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • max_depth:步数,必填项
  • count_only:Boolean 值,true 表示只统计结果的数目,不返回具体结果;false 表示返回具体的结果,默认为 false
  • with_path:true 表示返回起始点到每个邻居的最短路径,false 表示不返回起始点到每个邻居的最短路径,选填项,默认为 false
  • with_edge,选填项,默认为 false:
    • 如果设置为 true,则结果将包含所有边的完整信息,即路径中的所有边
      • 当 with_path 为 true 时,将返回所有路径中的边的完整信息
      • 当 with_path 为 false 时,不返回任何信息
    • 如果设置为 false,则仅返回边的 id
  • with_vertex,选填项,默认为 false:
    • 如果设置为 true,则结果将包含所有顶点的完整信息,即路径中的所有顶点
      • 当 with_path 为 true 时,将返回所有路径中的顶点的完整信息
      • 当 with_path 为 false 时,返回所有邻居顶点的完整信息
    • 如果设置为 false,则仅返回顶点的 id
  • limit:返回的顶点的最大数目,选填项,默认为 10000000
3.2.4.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/kneighbor
Request Body
 1{
 2  	"source": "1:marko",
 3  	"steps": {
 4  	  	"direction": "BOTH",
 5  	  	"edge_steps": [
 6  	  	    {
 7  	  	        "label": "knows",
 8  	  	        "properties": {}
 9  	  	    },
10  	  	    {
11  	  	        "label": "created",
12  	  	        "properties": {}
13  	  	    }
14  	  	],
15  	  	"vertex_steps": [
16  	  	    {
17  	  	        "label": "person",
18  	  	        "properties": {
19  	  	            "age": "P.gt(28)"
20  	  	        }
21  	  	    },
22  	  	    {
23  	  	        "label": "software",
24  	  	        "properties": {}
25  	  	    }
26  	  	],
27  	  	"max_degree": 10000,
28  	  	"skip_degree": 100000
29  	},
30  	"max_depth": 3,
31  	"limit": 10000,
32  	"with_vertex": true,
33  	"with_path": true,
34  	"with_edge": true
35}
Response Status
1200
Response Body
  1{
  2    "size": 4,
  3	"kneighbor": [
  4        "1:josh",
  5        "2:lop",
  6        "1:peter",
  7        "2:ripple"
  8    ],
  9    "paths": [
 10        {
 11            "objects": [
 12                "1:marko",
 13                "2:lop"
 14            ]
 15        },
 16        {
 17            "objects": [
 18                "1:marko",
 19                "2:lop",
 20                "1:peter"
 21            ]
 22        },
 23        {
 24            "objects": [
 25                "1:marko",
 26                "1:josh"
 27            ]
 28        },
 29        {
 30            "objects": [
 31                "1:marko",
 32                "1:josh",
 33                "2:ripple"
 34            ]
 35        }
 36    ],
 37    "vertices": [
 38        {
 39            "id": "2:ripple",
 40            "label": "software",
 41            "type": "vertex",
 42            "properties": {
 43                "name": "ripple",
 44                "lang": "java",
 45                "price": 199
 46            }
 47        },
 48        {
 49            "id": "1:marko",
 50            "label": "person",
 51            "type": "vertex",
 52            "properties": {
 53                "name": "marko",
 54                "age": 29,
 55                "city": "Beijing"
 56            }
 57        },
 58        {
 59            "id": "1:josh",
 60            "label": "person",
 61            "type": "vertex",
 62            "properties": {
 63                "name": "josh",
 64                "age": 32,
 65                "city": "Beijing"
 66            }
 67        },
 68        {
 69            "id": "1:peter",
 70            "label": "person",
 71            "type": "vertex",
 72            "properties": {
 73                "name": "peter",
 74                "age": 35,
 75                "city": "Shanghai"
 76            }
 77        },
 78        {
 79            "id": "2:lop",
 80            "label": "software",
 81            "type": "vertex",
 82            "properties": {
 83                "name": "lop",
 84                "lang": "java",
 85                "price": 328
 86            }
 87        }
 88    ],
 89    "edges": [
 90        {
 91            "id": "S1:josh>2>>S2:ripple",
 92            "label": "created",
 93            "type": "edge",
 94            "outV": "1:josh",
 95            "outVLabel": "person",
 96            "inV": "2:ripple",
 97            "inVLabel": "software",
 98            "properties": {
 99                "weight": 1.0,
100                "date": "20171210"
101            }
102        },
103        {
104            "id": "S1:marko>2>>S2:lop",
105            "label": "created",
106            "type": "edge",
107            "outV": "1:marko",
108            "outVLabel": "person",
109            "inV": "2:lop",
110            "inVLabel": "software",
111            "properties": {
112                "weight": 0.4,
113                "date": "20171210"
114            }
115        },
116        {
117            "id": "S1:marko>1>20130220>S1:josh",
118            "label": "knows",
119            "type": "edge",
120            "outV": "1:marko",
121            "outVLabel": "person",
122            "inV": "1:josh",
123            "inVLabel": "person",
124            "properties": {
125                "weight": 1.0,
126                "date": "20130220"
127            }
128        },
129        {
130            "id": "S1:peter>2>>S2:lop",
131            "label": "created",
132            "type": "edge",
133            "outV": "1:peter",
134            "outVLabel": "person",
135            "inV": "2:lop",
136            "inVLabel": "software",
137            "properties": {
138                "weight": 0.2,
139                "date": "20170324"
140            }
141        }
142    ]
143}
3.2.4.3 适用场景

参见 3.2.3.3

3.2.5 Same Neighbors

3.2.5.1 功能介绍

查询两个点的共同邻居

Params
  • vertex:一个顶点 id,必填项
  • other:另一个顶点 id,必填项
  • direction:顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • limit:返回的共同邻居的最大数目,选填项,默认为 10000000
3.2.5.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/sameneighbors?vertex=%221:marko%22&other=%221:josh%22
Response Status
1200
Response Body
1{
2    "same_neighbors":[
3        "2:lop"
4    ]
5}
3.2.5.3 适用场景

查找两个顶点的共同邻居:

  • 社交关系中发现两个用户的共同粉丝或者共同关注用户

3.2.6 Jaccard Similarity (GET)

3.2.6.1 功能介绍

计算两个顶点的 jaccard similarity(两个顶点邻居的交集比上两个顶点邻居的并集)

对于并集非空的邻居集合 N(u) 和 N(v),上述定义可写为:

J(u,v)=∣N(u)∩N(v)∣∣N(u)∪N(v)∣J(u,v) = \frac{|N(u) \cap N(v)|}{|N(u) \cup N(v)|}
Params
  • vertex:一个顶点 id,必填项
  • other:另一个顶点 id,必填项
  • direction:顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
3.2.6.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/jaccardsimilarity?vertex="1:marko"&other="1:josh"
Response Status
1200
Response Body
1{
2    "jaccard_similarity": 0.2
3}
3.2.6.3 适用场景

用于评估两个点的相似性或者紧密度

3.2.7 Jaccard Similarity (POST)

3.2.7.1 功能介绍

计算与指定顶点的 jaccard similarity 最大的 N 个点

jaccard similarity 的计算方式为:两个顶点邻居的交集比上两个顶点邻居的并集

Params
  • vertex:一个顶点 id,必填项
  • 从起始点出发的 Step,必填项,结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • labels:边的类型列表
    • properties:通过属性的值过滤边
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • top:返回一个起点的 jaccard similarity 中最大的 top 个,选填项,默认为 100
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
3.2.7.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/jaccardsimilarity
Request Body
 1{
 2  "vertex": "1:marko",
 3  "step": {
 4    "direction": "BOTH",
 5    "labels": [],
 6    "max_degree": 10000,
 7    "skip_degree": 100000
 8  },
 9  "top": 3
10}
Response Status
1200
Response Body
1{
2    "2:ripple": 0.3333333333333333,
3    "1:peter": 0.3333333333333333,
4    "1:josh": 0.2
5}
3.2.7.3 适用场景

用于在图中找出与指定顶点相似性最高的顶点

3.2.8 Shortest Path

3.2.8.1 功能介绍

根据起始顶点、目的顶点、方向、边的类型(可选)和最大深度,查找一条最短路径

Params
  • source:起始顶点 id,必填项
  • target:目的顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • max_depth:最大步数,必填项
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
3.2.8.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/shortestpath?source="1:marko"&target="2:ripple"&max_depth=3
Response Status
1200
Response Body
1{
2    "path":[
3        "1:marko",
4        "1:josh",
5        "2:ripple"
6    ]
7}
3.2.8.3 适用场景

查找两个顶点间的最短路径,例如:

  • 社交关系网中,查找两个用户有关系的最短路径,即最近的朋友关系链
  • 设备关联网络中,查找两个设备最短的关联关系

3.2.9 All Shortest Paths

3.2.9.1 功能介绍

根据起始顶点、目的顶点、方向、边的类型(可选)和最大深度,查找两点间所有的最短路径

Params
  • source:起始顶点 id,必填项
  • target:目的顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • max_depth:最大步数,必填项
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
3.2.9.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/allshortestpaths?source="A"&target="Z"&max_depth=10
Response Status
1200
Response Body
 1{
 2    "paths":[
 3        {
 4            "objects": [
 5                "A",
 6                "B",
 7                "C",
 8                "Z"
 9            ]
10        },
11        {
12            "objects": [
13                "A",
14                "M",
15                "N",
16                "Z"
17            ]
18        }
19    ]
20}
3.2.9.3 适用场景

查找两个顶点间的所有最短路径,例如:

  • 社交关系网中,查找两个用户有关系的全部最短路径,即最近的朋友关系链
  • 设备关联网络中,查找两个设备全部的最短关联关系

3.2.10 Weighted Shortest Path

3.2.10.1 功能介绍

根据起始顶点、目的顶点、方向、边的类型(可选)和最大深度,查找一条带权最短路径

Params
  • source:起始顶点 id,必填项
  • target:目的顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • weight:边的权重属性,必填项,必须是数字类型的属性
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • with_vertex:true 表示返回结果包含完整的顶点信息(路径中的全部顶点),false 时表示只返回顶点 id,选填项,默认为 false
3.2.10.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/weightedshortestpath?source="1:marko"&target="2:ripple"&weight="weight"&with_vertex=true
Response Status
1200
Response Body
 1{
 2    "path": {
 3        "weight": 2.0,
 4        "vertices": [
 5            "1:marko",
 6            "1:josh",
 7            "2:ripple"
 8        ]
 9    },
10    "vertices": [
11        {
12            "id": "1:marko",
13            "label": "person",
14            "type": "vertex",
15            "properties": {
16                "name": "marko",
17                "age": 29,
18                "city": "Beijing"
19            }
20        },
21        {
22            "id": "1:josh",
23            "label": "person",
24            "type": "vertex",
25            "properties": {
26                "name": "josh",
27                "age": 32,
28                "city": "Beijing"
29            }
30        },
31        {
32            "id": "2:ripple",
33            "label": "software",
34            "type": "vertex",
35            "properties": {
36                "name": "ripple",
37                "lang": "java",
38                "price": 199
39            }
40        }
41    ]
42}
3.2.10.3 适用场景

查找两个顶点间的带权最短路径,例如:

  • 交通线路中查找从 A 城市到 B 城市花钱最少的交通方式

3.2.11 Single Source Shortest Path

3.2.11.1 功能介绍

从一个顶点出发,查找该点到图中其他顶点的最短路径(可选是否带权重)

Params
  • source:起始顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • weight:边的权重属性,选填项,必须是数字类型的属性,如果不填或者虽然填了但是边没有该属性,则权重为 1.0
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:查询到的目标顶点个数,也是返回的最短路径的条数,选填项,默认为 10
  • with_vertex:true 表示返回结果包含完整的顶点信息(路径中的全部顶点),false 时表示只返回顶点 id,选填项,默认为 false
3.2.11.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/singlesourceshortestpath?source="1:marko"&with_vertex=true
Response Status
1200
Response Body
  1{
  2    "paths": {
  3        "2:ripple": {
  4            "weight": 2.0,
  5            "vertices": [
  6                "1:marko",
  7                "1:josh",
  8                "2:ripple"
  9            ]
 10        },
 11        "1:josh": {
 12            "weight": 1.0,
 13            "vertices": [
 14                "1:marko",
 15                "1:josh"
 16            ]
 17        },
 18        "1:vadas": {
 19            "weight": 1.0,
 20            "vertices": [
 21                "1:marko",
 22                "1:vadas"
 23            ]
 24        },
 25        "1:peter": {
 26            "weight": 2.0,
 27            "vertices": [
 28                "1:marko",
 29                "2:lop",
 30                "1:peter"
 31            ]
 32        },
 33        "2:lop": {
 34            "weight": 1.0,
 35            "vertices": [
 36                "1:marko",
 37                "2:lop"
 38            ]
 39        }
 40    },
 41    "vertices": [
 42        {
 43            "id": "2:ripple",
 44            "label": "software",
 45            "type": "vertex",
 46            "properties": {
 47                "name": "ripple",
 48                "lang": "java",
 49                "price": 199
 50            }
 51        },
 52        {
 53            "id": "1:marko",
 54            "label": "person",
 55            "type": "vertex",
 56            "properties": {
 57                "name": "marko",
 58                "age": 29,
 59                "city": "Beijing"
 60            }
 61        },
 62        {
 63            "id": "1:josh",
 64            "label": "person",
 65            "type": "vertex",
 66            "properties": {
 67                "name": "josh",
 68                "age": 32,
 69                "city": "Beijing"
 70            }
 71        },
 72        {
 73            "id": "1:vadas",
 74            "label": "person",
 75            "type": "vertex",
 76            "properties": {
 77                "name": "vadas",
 78                "age": 27,
 79                "city": "Hongkong"
 80            }
 81        },
 82        {
 83            "id": "1:peter",
 84            "label": "person",
 85            "type": "vertex",
 86            "properties": {
 87                "name": "peter",
 88                "age": 35,
 89                "city": "Shanghai"
 90            }
 91        },
 92        {
 93            "id": "2:lop",
 94            "label": "software",
 95            "type": "vertex",
 96            "properties": {
 97                "name": "lop",
 98                "lang": "java",
 99                "price": 328
100            }
101        }
102    ]
103}
3.2.11.3 适用场景

查找从一个点出发到其他顶点的带权最短路径,比如:

  • 查找从北京出发到全国其他所有城市的耗时最短的乘车方案

3.2.12 Multi Node Shortest Path

3.2.12.1 功能介绍

查找指定顶点集两两之间的最短路径

Params
  • vertices:定义起始顶点,必填项,指定方式包括:
    • ids:通过顶点 id 列表提供起始顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询起始顶点
      • label:顶点的类型
      • properties:通过属性的值查询起始顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • step:表示从起始顶点到终止顶点走过的路径,必填项,Step 的结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • labels:边的类型列表
    • properties:通过属性的值过滤边
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • max_depth:步数,必填项
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • with_vertex:true 表示返回结果包含完整的顶点信息(路径中的全部顶点),false 时表示只返回顶点 id,选填项,默认为 false
3.2.12.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/multinodeshortestpath
Request Body
 1{
 2    "vertices": {
 3        "ids": ["382:marko", "382:josh", "382:vadas", "382:peter", "383:lop", "383:ripple"]
 4    },
 5    "step": {
 6        "direction": "BOTH",
 7        "properties": {
 8        }
 9    },
10    "max_depth": 10,
11    "capacity": 100000000,
12    "with_vertex": true
13}
Response Status
1200
Response Body
  1{
  2    "paths": [
  3        {
  4            "objects": [
  5                "382:peter",
  6                "383:lop"
  7            ]
  8        },
  9        {
 10            "objects": [
 11                "382:peter",
 12                "383:lop",
 13                "382:marko"
 14            ]
 15        },
 16        {
 17            "objects": [
 18                "382:peter",
 19                "383:lop",
 20                "382:josh"
 21            ]
 22        },
 23        {
 24            "objects": [
 25                "382:peter",
 26                "383:lop",
 27                "382:marko",
 28                "382:vadas"
 29            ]
 30        },
 31        {
 32            "objects": [
 33                "383:lop",
 34                "382:marko"
 35            ]
 36        },
 37        {
 38            "objects": [
 39                "383:lop",
 40                "382:josh"
 41            ]
 42        },
 43        {
 44            "objects": [
 45                "383:lop",
 46                "382:marko",
 47                "382:vadas"
 48            ]
 49        },
 50        {
 51            "objects": [
 52                "382:peter",
 53                "383:lop",
 54                "382:josh",
 55                "383:ripple"
 56            ]
 57        },
 58        {
 59            "objects": [
 60                "382:marko",
 61                "382:josh"
 62            ]
 63        },
 64        {
 65            "objects": [
 66                "383:lop",
 67                "382:josh",
 68                "383:ripple"
 69            ]
 70        },
 71        {
 72            "objects": [
 73                "382:marko",
 74                "382:vadas"
 75            ]
 76        },
 77        {
 78            "objects": [
 79                "382:marko",
 80                "382:josh",
 81                "383:ripple"
 82            ]
 83        },
 84        {
 85            "objects": [
 86                "382:josh",
 87                "383:ripple"
 88            ]
 89        },
 90        {
 91            "objects": [
 92                "382:josh",
 93                "382:marko",
 94                "382:vadas"
 95            ]
 96        },
 97        {
 98            "objects": [
 99                "382:vadas",
100                "382:marko",
101                "382:josh",
102                "383:ripple"
103            ]
104        }
105    ],
106    "vertices": [
107        {
108            "id": "382:peter",
109            "label": "person",
110            "type": "vertex",
111            "properties": {
112                "name": "peter",
113                "age": 29,
114                "city": "Shanghai"
115            }
116        },
117        {
118            "id": "383:lop",
119            "label": "software",
120            "type": "vertex",
121            "properties": {
122                "name": "lop",
123                "lang": "java",
124                "price": 328
125            }
126        },
127        {
128            "id": "382:marko",
129            "label": "person",
130            "type": "vertex",
131            "properties": {
132                "name": "marko",
133                "age": 29,
134                "city": "Beijing"
135            }
136        },
137        {
138            "id": "382:josh",
139            "label": "person",
140            "type": "vertex",
141            "properties": {
142                "name": "josh",
143                "age": 32,
144                "city": "Beijing"
145            }
146        },
147        {
148            "id": "382:vadas",
149            "label": "person",
150            "type": "vertex",
151            "properties": {
152                "name": "vadas",
153                "age": 27,
154                "city": "Hongkong"
155            }
156        },
157        {
158            "id": "383:ripple",
159            "label": "software",
160            "type": "vertex",
161            "properties": {
162                "name": "ripple",
163                "lang": "java",
164                "price": 199
165            }
166        }
167    ]
168}
3.2.12.3 适用场景

查找多个点之间的最短路径,比如:

  • 查找多个公司和法人之间的最短路径

3.2.13 Paths(GET,基础版)

3.2.13.1 功能介绍

根据起始顶点、目的顶点、方向、边的类型(可选)和最大深度等条件查找所有路径

Params
  • source:起始顶点 id,必填项
  • target:目的顶点 id,必填项
  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_depth:步数,必填项
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的路径的最大数目,选填项,默认为 10
3.2.13.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/paths?source="1:marko"&target="1:josh"&max_depth=5
Response Status
1200
Response Body
 1{
 2    "paths":[
 3        {
 4            "objects":[
 5                "1:marko",
 6                "1:josh"
 7            ]
 8        },
 9        {
10            "objects":[
11                "1:marko",
12                "2:lop",
13                "1:josh"
14            ]
15        }
16    ]
17}
3.2.13.3 适用场景

查找两个顶点间的所有路径,例如:

  • 社交网络中,查找两个用户所有可能的关系路径
  • 设备关联网络中,查找两个设备之间所有的关联路径

3.2.14 Paths(POST,高级版)

3.2.14.1 功能介绍

根据起始顶点、目的顶点、步骤(step)和最大深度等条件查找所有路径

Params
  • sources:定义起始顶点,必填项,指定方式包括:
    • ids:通过顶点 id 列表提供起始顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询起始顶点
      • label:顶点的类型
      • properties:通过属性的值查询起始顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • targets:定义终止顶点,必填项,指定方式包括:
    • ids:通过顶点 id 列表提供终止顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询终止顶点
      • label:顶点的类型
      • properties:通过属性的值查询终止顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • step:表示从起始顶点到终止顶点走过的路径,必填项,Step 的结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • labels:边的类型列表
    • properties:通过属性的值过滤边
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • max_depth:步数,必填项
  • nearest:nearest 为 true 时,代表起始顶点到达结果顶点的最短路径长度为 depth,不存在更短的路径;nearest 为 false 时,代表起始顶点到结果顶点有一条长度为 depth 的路径(未必最短且可以有环),选填项,默认为 true
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的路径的最大数目,选填项,默认为 10
  • with_vertex:true 表示返回结果包含完整的顶点信息(路径中的全部顶点),false 时表示只返回顶点 id,选填项,默认为 false
3.2.14.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/paths
Request Body
 1{
 2"sources": {
 3  "ids": ["1:marko"]
 4},
 5"targets": {
 6  "ids": ["1:peter"]
 7},
 8"step": {
 9"direction": "BOTH",
10  "properties": {
11    "weight": "P.gt(0.01)"
12  }
13},
14"max_depth": 10,
15"capacity": 100000000,
16"limit": 10000000,
17"with_vertex": false
18}
Response Status
1200
Response Body
 1{
 2    "paths": [
 3        {
 4            "objects": [
 5                "1:marko",
 6                "1:josh",
 7                "2:lop",
 8                "1:peter"
 9            ]
10        },
11        {
12            "objects": [
13                "1:marko",
14                "2:lop",
15                "1:peter"
16            ]
17        }
18    ]
19}
3.2.14.3 适用场景

查找两个顶点间的所有路径,例如:

  • 社交网络中,查找两个用户所有可能的关系路径
  • 设备关联网络中,查找两个设备之间所有的关联路径

3.2.15 Customized Paths

3.2.15.1 功能介绍

根据一批起始顶点、边规则(包括方向、边的类型和属性过滤)和最大深度等条件查找符合条件的所有的路径

Params
  • sources:定义起始顶点,必填项,指定方式包括:
    • ids:通过顶点 id 列表提供起始顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询起始顶点
      • label:顶点的类型
      • properties:通过属性的值查询起始顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • steps:表示从起始顶点走过的路径规则,是一组 Step 的列表。必填项。每个 Step 的结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • labels:边的类型列表
    • properties:通过属性的值过滤边
    • weight_by:根据指定的属性计算边的权重,sort_by 不为 NONE 时有效,与 default_weight 互斥
    • default_weight:当边没有属性作为权重计算值时,采取的默认权重,sort_by 不为 NONE 时有效,与 weight_by 互斥
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • sample:当需要对某个 step 的符合条件的边进行采样时设置,-1 表示不采样,默认为采样 100
  • sort_by:根据路径的权重排序,选填项,默认为 NONE:
    • NONE 表示不排序,默认值
    • INCR 表示按照路径权重的升序排序
    • DECR 表示按照路径权重的降序排序
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的路径的最大数目,选填项,默认为 10
  • with_vertex:true 表示返回结果包含完整的顶点信息(路径中的全部顶点),false 时表示只返回顶点 id,选填项,默认为 false
3.2.15.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/customizedpaths
Request Body
 1{
 2    "sources":{
 3        "ids":[
 4
 5        ],
 6        "label":"person",
 7        "properties":{
 8            "name":"marko"
 9        }
10    },
11    "steps":[
12        {
13            "direction":"OUT",
14            "labels":[
15                "knows"
16            ],
17            "weight_by":"weight",
18            "max_degree":-1
19        },
20        {
21            "direction":"OUT",
22            "labels":[
23                "created"
24            ],
25            "default_weight":8,
26            "max_degree":-1,
27            "sample":1
28        }
29    ],
30    "sort_by":"INCR",
31    "with_vertex":true,
32    "capacity":-1,
33    "limit":-1
34}
Response Status
1200
Response Body
 1{
 2    "paths":[
 3        {
 4            "objects":[
 5                "1:marko",
 6                "1:josh",
 7                "2:lop"
 8            ],
 9            "weights":[
10                1,
11                8
12            ]
13        }
14    ],
15    "vertices":[
16        {
17            "id":"1:marko",
18            "label":"person",
19            "type":"vertex",
20            "properties":{
21                "city":[
22                    {
23                        "id":"1:marko>city",
24                        "value":"Beijing"
25                    }
26                ],
27                "name":[
28                    {
29                        "id":"1:marko>name",
30                        "value":"marko"
31                    }
32                ],
33                "age":[
34                    {
35                        "id":"1:marko>age",
36                        "value":29
37                    }
38                ]
39            }
40        },
41        {
42            "id":"1:josh",
43            "label":"person",
44            "type":"vertex",
45            "properties":{
46                "city":[
47                    {
48                        "id":"1:josh>city",
49                        "value":"Beijing"
50                    }
51                ],
52                "name":[
53                    {
54                        "id":"1:josh>name",
55                        "value":"josh"
56                    }
57                ],
58                "age":[
59                    {
60                        "id":"1:josh>age",
61                        "value":32
62                    }
63                ]
64            }
65        },
66        {
67            "id":"2:lop",
68            "label":"software",
69            "type":"vertex",
70            "properties":{
71                "price":[
72                    {
73                        "id":"2:lop>price",
74                        "value":328
75                    }
76                ],
77                "name":[
78                    {
79                        "id":"2:lop>name",
80                        "value":"lop"
81                    }
82                ],
83                "lang":[
84                    {
85                        "id":"2:lop>lang",
86                        "value":"java"
87                    }
88                ]
89            }
90        }
91    ]
92}
3.2.15.3 适用场景

适合查找各种复杂的路径集合,例如:

  • 社交网络中,查找看过张艺谋所导演的电影的用户关注的大 V 的路径(张艺谋—>电影—->用户—>大 V)
  • 风控网络中,查找多个高风险用户的直系亲属的朋友的路径(高风险用户—>直系亲属—>朋友)

3.2.16 Template Paths

3.2.16.1 功能介绍

根据一批起始顶点、边规则(包括方向、边的类型和属性过滤)和最大深度等条件查找符合条件的所有的路径

Params
  • sources:定义起始顶点,必填项,指定方式包括:
    • ids:通过顶点 id 列表提供起始顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询起始顶点
      • label:顶点的类型
      • properties:通过属性的值查询起始顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • targets:定义终止顶点,必填项,指定方式包括:
    • ids:通过顶点 id 列表提供终止顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询终止顶点
      • label:顶点的类型
      • properties:通过属性的值查询终止顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • steps:表示从起始顶点走过的路径规则,是一组 Step 的列表。必填项。每个 Step 的结构如下:
    • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
    • labels:边的类型列表
    • properties:通过属性的值过滤边
    • max_times:当前 step 可以重复的次数,当为 N 时,表示从起始顶点可以经过当前 step 1-N 次
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • with_ring:Boolean 值,true 表示包含环路;false 表示不包含环路,默认为 false
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的路径的最大数目,选填项,默认为 10
  • with_vertex:true 表示返回结果包含完整的顶点信息(路径中的全部顶点),false 时表示只返回顶点 id,选填项,默认为 false
3.2.16.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/templatepaths
Request Body
 1{
 2  "sources": {
 3    "ids": [],
 4    "label": "person",
 5    "properties": {
 6      "name": "vadas"
 7    }
 8  },
 9  "targets": {
10    "ids": [],
11    "label": "software",
12    "properties": {
13      "name": "ripple"
14    }
15  },
16  "steps": [
17    {
18      "direction": "IN",
19      "labels": ["knows"],
20      "properties": {
21      },
22      "max_degree": 10000,
23      "skip_degree": 100000
24    },
25    {
26      "direction": "OUT",
27      "labels": ["created"],
28      "properties": {
29      },
30      "max_degree": 10000,
31      "skip_degree": 100000
32    },
33    {
34      "direction": "IN",
35      "labels": ["created"],
36      "properties": {
37      },
38      "max_degree": 10000,
39      "skip_degree": 100000
40    },
41    {
42      "direction": "OUT",
43      "labels": ["created"],
44      "properties": {
45      },
46      "max_degree": 10000,
47      "skip_degree": 100000
48    }
49  ],
50  "capacity": 10000,
51  "limit": 10,
52  "with_vertex": true
53}
Response Status
1200
Response Body
 1{
 2    "paths": [
 3        {
 4            "objects": [
 5                "1:vadas",
 6                "1:marko",
 7                "2:lop",
 8                "1:josh",
 9                "2:ripple"
10            ]
11        }
12    ],
13    "vertices": [
14        {
15            "id": "2:ripple",
16            "label": "software",
17            "type": "vertex",
18            "properties": {
19                "name": "ripple",
20                "lang": "java",
21                "price": 199
22            }
23        },
24        {
25            "id": "1:marko",
26            "label": "person",
27            "type": "vertex",
28            "properties": {
29                "name": "marko",
30                "age": 29,
31                "city": "Beijing"
32            }
33        },
34        {
35            "id": "1:josh",
36            "label": "person",
37            "type": "vertex",
38            "properties": {
39                "name": "josh",
40                "age": 32,
41                "city": "Beijing"
42            }
43        },
44        {
45            "id": "1:vadas",
46            "label": "person",
47            "type": "vertex",
48            "properties": {
49                "name": "vadas",
50                "age": 27,
51                "city": "Hongkong"
52            }
53        },
54        {
55            "id": "2:lop",
56            "label": "software",
57            "type": "vertex",
58            "properties": {
59                "name": "lop",
60                "lang": "java",
61                "price": 328
62            }
63        }
64    ]
65}
3.2.16.3 适用场景

适合查找各种复杂的模板路径,比如 personA -(朋友)-> personB -(同学)-> personC,其中"朋友"和"同学"边可以分别是最多 3 层和 4 层的情况

3.2.17 Crosspoints

3.2.17.1 功能介绍

根据起始顶点、目的顶点、方向、边的类型(可选)和最大深度等条件查找相交点

Params
  • source:起始顶点 id,必填项
  • target:目的顶点 id,必填项
  • direction:起始顶点到目的顶点的方向,目的点到起始点是反方向,BOTH 时不考虑方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_depth:步数,必填项
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的交点的最大数目,选填项,默认为 10
3.2.17.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/crosspoints?source="2:lop"&target="2:ripple"&max_depth=5&direction=IN
Response Status
1200
Response Body
 1{
 2    "crosspoints":[
 3        {
 4            "crosspoint":"1:josh",
 5            "objects":[
 6                "2:lop",
 7                "1:josh",
 8                "2:ripple"
 9            ]
10        }
11    ]
12}
3.2.17.3 适用场景

查找两个顶点的交点及其路径,例如:

  • 社交网络中,查找两个用户共同关注的话题或者大 V
  • 家族关系中,查找共同的祖先

3.2.18 Customized Crosspoints

3.2.18.1 功能介绍

根据一批起始顶点、多种边规则(包括方向、边的类型和属性过滤)和最大深度等条件查找符合条件的所有的路径终点的交集

Params
  • sources:定义起始顶点,必填项,指定方式包括:

    • ids:通过顶点 id 列表提供起始顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询起始顶点
      • label:顶点的类型
      • properties:通过属性的值查询起始顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • path_patterns:表示从起始顶点走过的路径规则,是一组规则的列表。必填项。每个规则是一个 PathPattern

    • 每个 PathPattern 是一组 Step 列表,每个 Step 结构如下:
      • direction:表示边的方向(OUT,IN,BOTH),默认是 BOTH
      • labels:边的类型列表
      • properties:通过属性的值过滤边
      • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
      • skip_degree:用于设置查询过程中舍弃超级顶点的最小边数,即当某个顶点的邻接边数目大于 skip_degree 时,完全舍弃该顶点。选填项,如果开启时,需满足 skip_degree >= max_degree 约束,默认为 0 (不启用),表示不跳过任何点 (注意:开启此配置后,遍历时会尝试访问一个顶点的 skip_degree 条边,而不仅仅是 max_degree 条边,这样有额外的遍历开销,对查询性能影响可能有较大影响,请确认理解后再开启)
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000

  • limit:返回的路径的最大数目,选填项,默认为 10

  • with_path:true 表示返回交点所在的路径,false 表示不返回交点所在的路径,选填项,默认为 false

  • with_vertex,选填项,默认为 false:

    • true 表示返回结果包含完整的顶点信息(路径中的全部顶点)
      • with_path 为 true 时,返回所有路径中的顶点的完整信息
      • with_path 为 false 时,返回所有交点的完整信息
    • false 时表示只返回顶点 id
3.2.18.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/customizedcrosspoints
Request Body
 1{
 2    "sources":{
 3        "ids":[
 4            "2:lop",
 5            "2:ripple"
 6        ]
 7    },
 8    "path_patterns":[
 9        {
10            "steps":[
11                {
12                    "direction":"IN",
13                    "labels":[
14                        "created"
15                    ],
16                    "max_degree":-1
17                }
18            ]
19        }
20    ],
21    "with_path":true,
22    "with_vertex":true,
23    "capacity":-1,
24    "limit":-1
25}
Response Status
1200
Response Body
 1{
 2    "crosspoints":[
 3        "1:josh"
 4    ],
 5    "paths":[
 6        {
 7            "objects":[
 8                "2:ripple",
 9                "1:josh"
10            ]
11        },
12        {
13            "objects":[
14                "2:lop",
15                "1:josh"
16            ]
17        }
18    ],
19    "vertices":[
20        {
21            "id":"2:ripple",
22            "label":"software",
23            "type":"vertex",
24            "properties":{
25                "price":[
26                    {
27                        "id":"2:ripple>price",
28                        "value":199
29                    }
30                ],
31                "name":[
32                    {
33                        "id":"2:ripple>name",
34                        "value":"ripple"
35                    }
36                ],
37                "lang":[
38                    {
39                        "id":"2:ripple>lang",
40                        "value":"java"
41                    }
42                ]
43            }
44        },
45        {
46            "id":"1:josh",
47            "label":"person",
48            "type":"vertex",
49            "properties":{
50                "city":[
51                    {
52                        "id":"1:josh>city",
53                        "value":"Beijing"
54                    }
55                ],
56                "name":[
57                    {
58                        "id":"1:josh>name",
59                        "value":"josh"
60                    }
61                ],
62                "age":[
63                    {
64                        "id":"1:josh>age",
65                        "value":32
66                    }
67                ]
68            }
69        },
70        {
71            "id":"2:lop",
72            "label":"software",
73            "type":"vertex",
74            "properties":{
75                "price":[
76                    {
77                        "id":"2:lop>price",
78                        "value":328
79                    }
80                ],
81                "name":[
82                    {
83                        "id":"2:lop>name",
84                        "value":"lop"
85                    }
86                ],
87                "lang":[
88                    {
89                        "id":"2:lop>lang",
90                        "value":"java"
91                    }
92                ]
93            }
94        }
95    ]
96}
3.2.18.3 适用场景

查询一组顶点通过多种路径在终点有交集的情况。例如:

  • 在商品图谱中,多款手机、学习机、游戏机通过不同的低级别的类目路径,最终都属于一级类目的电子设备

3.2.19 Rings

3.2.19.1 功能介绍

根据起始顶点、方向、边的类型(可选)和最大深度等条件查找可达的环路

例如:1 -> 25 -> 775 -> 14690 -> 25, 其中环路为 25 -> 775 -> 14690 -> 25

Params
  • source:起始顶点 id,必填项
  • direction:起始顶点发出的边的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_depth:步数,必填项
  • source_in_ring:环路是否包含起点,选填项,默认为 true
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的可达环路的最大数目,选填项,默认为 10
3.2.19.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/rings?source="1:marko"&max_depth=2
Response Status
1200
Response Body
 1{
 2    "rings":[
 3        {
 4            "objects":[
 5                "1:marko",
 6                "1:josh",
 7                "1:marko"
 8            ]
 9        },
10        {
11            "objects":[
12                "1:marko",
13                "1:vadas",
14                "1:marko"
15            ]
16        },
17        {
18            "objects":[
19                "1:marko",
20                "2:lop",
21                "1:marko"
22            ]
23        }
24    ]
25}
3.2.19.3 适用场景

查询起始顶点可达的环路,例如:

  • 风控项目中,查询一个用户可达的循环担保的人或者设备
  • 设备关联网络中,发现一个设备周围的循环引用的设备

3.2.20 Rays

3.2.20.1 功能介绍

根据起始顶点、方向、边的类型(可选)和最大深度等条件查找发散到边界顶点的路径

例如:1 -> 25 -> 775 -> 14690 -> 2289 -> 18379, 其中 18379 为边界顶点,即没有从 18379 发出的边

Params
  • source:起始顶点 id,必填项
  • direction:起始顶点发出的边的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_depth:步数,必填项
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
  • limit:返回的非环路的最大数目,选填项,默认为 10
3.2.20.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/rays?source="1:marko"&max_depth=2&direction=OUT
Response Status
1200
Response Body
 1{
 2    "rays":[
 3        {
 4            "objects":[
 5                "1:marko",
 6                "1:vadas"
 7            ]
 8        },
 9        {
10            "objects":[
11                "1:marko",
12                "2:lop"
13            ]
14        },
15        {
16            "objects":[
17                "1:marko",
18                "1:josh",
19                "2:ripple"
20            ]
21        },
22        {
23            "objects":[
24                "1:marko",
25                "1:josh",
26                "2:lop"
27            ]
28        }
29    ]
30}
3.2.20.3 适用场景

查找起始顶点到某种关系的边界顶点的路径,例如:

  • 家族关系中,查找一个人到所有还没有孩子的子孙的路径
  • 设备关联网络中,找到某个设备到终端设备的路径

3.2.21 Fusiform Similarity

3.2.21.1 功能介绍

按照条件查询一批顶点对应的"梭形相似点"。当两个顶点跟很多共同的顶点之间有某种关系的时候,我们认为这两个点为"梭形相似点"。举个例子说明"梭形相似点":“读者 A"读了 100 本书,可以定义读过这 100 本书中的 80 本以上的读者,是"读者 A"的"梭形相似点”

Params
  • sources:定义起始顶点,必填项,指定方式包括:

    • ids:通过顶点 id 列表提供起始顶点
    • label 和 properties:如果没有指定 ids,则使用 label 和 properties 的联合条件查询起始顶点
      • label:顶点的类型
      • properties:通过属性的值查询起始顶点

      注意:properties 中的属性值可以是列表,表示只要 key 对应的 value 在列表中就可以

  • label:边的类型,选填项,默认代表所有 edge label

  • direction:起始顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH

  • min_neighbors:最少邻居数目,邻居数目少于这个阈值时,认为起点不具备"梭形相似点"。比如想要找一个"读者 A"读过的书的"梭形相似点",那么min_neighbors为 100 时,表示"读者 A"至少要读过 100 本书才可以有"梭形相似点",必填项

  • alpha:相似度,代表:起点与"梭形相似点"的共同邻居数目占起点的全部邻居数目的比例,必填项

  • min_similars:“梭形相似点"的最少个数,只有当起点的"梭形相似点"数目大于或等于该值时,才会返回起点及其"梭形相似点”,选填项,默认值为 1

  • top:返回一个起点的"梭形相似点"中相似度最高的 top 个,必填项,0 表示全部

  • group_property:与min_groups一起使用,当起点跟其所有的"梭形相似点"某个属性的值有至少min_groups个不同值时,才会返回该起点及其"梭形相似点"。比如为"读者 A"推荐"异地"书友时,需要设置group_property为读者的"城市"属性,min_group至少为 2,选填项,不填代表不需要根据属性过滤

  • min_groups:与group_property一起使用,只有group_property设置时才有意义

  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000

  • capacity:遍历过程中最大的访问的顶点数目,选填项,默认为 10000000

  • limit:返回的结果数目上限(一个起点及其"梭形相似点"算一个结果),选填项,默认为 10

  • with_intermediary:是否返回起点及其"梭形相似点"共同关联的中间点,默认为 false

  • with_vertex,选填项,默认为 false:

    • true 表示返回结果包含完整的顶点信息
    • false 时表示只返回顶点 id
3.2.21.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/fusiformsimilarity
Request Body
 1{
 2    "sources":{
 3        "ids":[],
 4        "label": "person",
 5        "properties": {
 6            "name":"p1"
 7        }
 8    },
 9    "label":"read",
10    "direction":"OUT",
11    "min_neighbors":8,
12    "alpha":0.75,
13    "min_similars":1,
14    "top":0,
15    "group_property":"city",
16    "min_group":2,
17    "max_degree": 10000,
18    "capacity": -1,
19    "limit": -1,
20    "with_intermediary": false,
21    "with_vertex":true
22}
Response Status
1200
Response Body
 1{
 2    "similars": {
 3        "3:p1": [
 4            {
 5                "id": "3:p2",
 6                "score": 0.8888888888888888,
 7                "intermediaries": [
 8                ]
 9            },
10            {
11                "id": "3:p3",
12                "score": 0.7777777777777778,
13                "intermediaries": [
14                ]
15            }
16        ]
17    },
18    "vertices": [
19        {
20            "id": "3:p1",
21            "label": "person",
22            "type": "vertex",
23            "properties": {
24                "name": "p1",
25                "city": "Beijing"
26            }
27        },
28        {
29            "id": "3:p2",
30            "label": "person",
31            "type": "vertex",
32            "properties": {
33                "name": "p2",
34                "city": "Shanghai"
35            }
36        },
37        {
38            "id": "3:p3",
39            "label": "person",
40            "type": "vertex",
41            "properties": {
42                "name": "p3",
43                "city": "Beijing"
44            }
45        }
46    ]
47}
3.2.21.3 适用场景

查询一组顶点相似度很高的顶点。例如:

  • 跟一个读者有类似书单的读者
  • 跟一个玩家玩类似游戏的玩家

3.2.22 Vertices

3.2.22.1 根据顶点的 id 列表,批量查询顶点
Params
  • ids:要查询的顶点 id 列表
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/vertices?ids="1:marko"&ids="2:lop"
Response Status
1200
Response Body
 1{
 2    "vertices":[
 3        {
 4            "id":"1:marko",
 5            "label":"person",
 6            "type":"vertex",
 7            "properties":{
 8                "city":[
 9                    {
10                        "id":"1:marko>city",
11                        "value":"Beijing"
12                    }
13                ],
14                "name":[
15                    {
16                        "id":"1:marko>name",
17                        "value":"marko"
18                    }
19                ],
20                "age":[
21                    {
22                        "id":"1:marko>age",
23                        "value":29
24                    }
25                ]
26            }
27        },
28        {
29            "id":"2:lop",
30            "label":"software",
31            "type":"vertex",
32            "properties":{
33                "price":[
34                    {
35                        "id":"2:lop>price",
36                        "value":328
37                    }
38                ],
39                "name":[
40                    {
41                        "id":"2:lop>name",
42                        "value":"lop"
43                    }
44                ],
45                "lang":[
46                    {
47                        "id":"2:lop>lang",
48                        "value":"java"
49                    }
50                ]
51            }
52        }
53    ]
54}
3.2.22.2 获取顶点 Shard 信息

通过指定的分片大小 split_size,获取顶点分片信息(可以与 3.2.21.3 中的 Scan 配合使用来获取顶点)。

Params
  • split_size:分片大小,必填项
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/vertices/shards?split_size=67108864
Response Status
1200
Response Body
 1{
 2    "shards":[
 3        {
 4            "start": "0",
 5            "end": "2165893",
 6            "length": 0
 7        },
 8        {
 9            "start": "2165893",
10            "end": "4331786",
11            "length": 0
12        },
13        {
14            "start": "4331786",
15            "end": "6497679",
16            "length": 0
17        },
18        {
19            "start": "6497679",
20            "end": "8663572",
21            "length": 0
22        },
23        ......
24    ]
25}
3.2.22.3 根据 Shard 信息批量获取顶点

通过指定的分片信息批量查询顶点(Shard 信息的获取参见 3.2.21.2 Shard)。

Params
  • start:分片起始位置,必填项
  • end:分片结束位置,必填项
  • page:分页位置,选填项,默认为 null,不分页;当 page 为“”时表示分页的第一页,从 start 指示的位置开始
  • page_limit:分页获取顶点时,一页中顶点数目的上限,选填项,默认为 100000
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/vertices/scan?start=0&end=4294967295
Response Status
1200
Response Body
  1{
  2    "vertices":[
  3        {
  4            "id":"2:ripple",
  5            "label":"software",
  6            "type":"vertex",
  7            "properties":{
  8                "price":[
  9                    {
 10                        "id":"2:ripple>price",
 11                        "value":199
 12                    }
 13                ],
 14                "name":[
 15                    {
 16                        "id":"2:ripple>name",
 17                        "value":"ripple"
 18                    }
 19                ],
 20                "lang":[
 21                    {
 22                        "id":"2:ripple>lang",
 23                        "value":"java"
 24                    }
 25                ]
 26            }
 27        },
 28        {
 29            "id":"1:vadas",
 30            "label":"person",
 31            "type":"vertex",
 32            "properties":{
 33                "city":[
 34                    {
 35                        "id":"1:vadas>city",
 36                        "value":"Hongkong"
 37                    }
 38                ],
 39                "name":[
 40                    {
 41                        "id":"1:vadas>name",
 42                        "value":"vadas"
 43                    }
 44                ],
 45                "age":[
 46                    {
 47                        "id":"1:vadas>age",
 48                        "value":27
 49                    }
 50                ]
 51            }
 52        },
 53        {
 54            "id":"1:peter",
 55            "label":"person",
 56            "type":"vertex",
 57            "properties":{
 58                "city":[
 59                    {
 60                        "id":"1:peter>city",
 61                        "value":"Shanghai"
 62                    }
 63                ],
 64                "name":[
 65                    {
 66                        "id":"1:peter>name",
 67                        "value":"peter"
 68                    }
 69                ],
 70                "age":[
 71                    {
 72                        "id":"1:peter>age",
 73                        "value":35
 74                    }
 75                ]
 76            }
 77        },
 78        {
 79            "id":"1:josh",
 80            "label":"person",
 81            "type":"vertex",
 82            "properties":{
 83                "city":[
 84                    {
 85                        "id":"1:josh>city",
 86                        "value":"Beijing"
 87                    }
 88                ],
 89                "name":[
 90                    {
 91                        "id":"1:josh>name",
 92                        "value":"josh"
 93                    }
 94                ],
 95                "age":[
 96                    {
 97                        "id":"1:josh>age",
 98                        "value":32
 99                    }
100                ]
101            }
102        },
103        {
104            "id":"1:marko",
105            "label":"person",
106            "type":"vertex",
107            "properties":{
108                "city":[
109                    {
110                        "id":"1:marko>city",
111                        "value":"Beijing"
112                    }
113                ],
114                "name":[
115                    {
116                        "id":"1:marko>name",
117                        "value":"marko"
118                    }
119                ],
120                "age":[
121                    {
122                        "id":"1:marko>age",
123                        "value":29
124                    }
125                ]
126            }
127        },
128        {
129            "id":"2:lop",
130            "label":"software",
131            "type":"vertex",
132            "properties":{
133                "price":[
134                    {
135                        "id":"2:lop>price",
136                        "value":328
137                    }
138                ],
139                "name":[
140                    {
141                        "id":"2:lop>name",
142                        "value":"lop"
143                    }
144                ],
145                "lang":[
146                    {
147                        "id":"2:lop>lang",
148                        "value":"java"
149                    }
150                ]
151            }
152        }
153    ]
154}
3.2.22.4 适用场景
  • 按 id 列表查询顶点,可用于批量查询顶点,比如在 path 查询到多条路径之后,可以进一步查询某条路径的所有顶点属性。
  • 获取分片和按分片查询顶点,可以用来遍历全部顶点

3.2.23 Edges

3.2.23.1 根据边的 id 列表,批量查询边
Params
  • ids:要查询的边 id 列表
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/edges?ids="S1:josh>1>>S2:lop"&ids="S1:josh>1>>S2:ripple"
Response Status
1200
Response Body
 1{
 2    "edges": [
 3        {
 4            "id": "S1:josh>1>>S2:lop",
 5            "label": "created",
 6            "type": "edge",
 7            "inVLabel": "software",
 8            "outVLabel": "person",
 9            "inV": "2:lop",
10            "outV": "1:josh",
11            "properties": {
12                "date": "20091111",
13                "weight": 0.4
14            }
15        },
16        {
17            "id": "S1:josh>1>>S2:ripple",
18            "label": "created",
19            "type": "edge",
20            "inVLabel": "software",
21            "outVLabel": "person",
22            "inV": "2:ripple",
23            "outV": "1:josh",
24            "properties": {
25                "date": "20171210",
26                "weight": 1
27            }
28        }
29    ]
30}
3.2.23.2 获取边 Shard 信息

通过指定的分片大小 split_size,获取边分片信息(可以与 3.2.22.3 中的 Scan 配合使用来获取边)。

Params
  • split_size:分片大小,必填项
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/edges/shards?split_size=4294967295
Response Status
1200
Response Body
 1{
 2    "shards":[
 3        {
 4            "start": "0",
 5            "end": "1073741823",
 6            "length": 0
 7        },
 8        {
 9            "start": "1073741823",
10            "end": "2147483646",
11            "length": 0
12        },
13        {
14            "start": "2147483646",
15            "end": "3221225469",
16            "length": 0
17        },
18        {
19            "start": "3221225469",
20            "end": "4294967292",
21            "length": 0
22        },
23        {
24            "start": "4294967292",
25            "end": "4294967295",
26            "length": 0
27        }
28    ]
29}
3.2.23.3 根据 Shard 信息批量获取边

通过指定的分片信息批量查询边(Shard 信息的获取参见 3.2.22.2)。

Params
  • start:分片起始位置,必填项
  • end:分片结束位置,必填项
  • page:分页位置,选填项,默认为 null,不分页;当 page 为“”时表示分页的第一页,从 start 指示的位置开始
  • page_limit:分页获取边时,一页中边数目的上限,选填项,默认为 100000
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/edges/scan?start=0&end=3221225469
Response Status
1200
Response Body
 1{
 2    "edges":[
 3        {
 4            "id":"S1:peter>2>>S2:lop",
 5            "label":"created",
 6            "type":"edge",
 7            "inVLabel":"software",
 8            "outVLabel":"person",
 9            "inV":"2:lop",
10            "outV":"1:peter",
11            "properties":{
12                "weight":0.2,
13                "date":"20170324"
14            }
15        },
16        {
17            "id":"S1:josh>2>>S2:lop",
18            "label":"created",
19            "type":"edge",
20            "inVLabel":"software",
21            "outVLabel":"person",
22            "inV":"2:lop",
23            "outV":"1:josh",
24            "properties":{
25                "weight":0.4,
26                "date":"20091111"
27            }
28        },
29        {
30            "id":"S1:josh>2>>S2:ripple",
31            "label":"created",
32            "type":"edge",
33            "inVLabel":"software",
34            "outVLabel":"person",
35            "inV":"2:ripple",
36            "outV":"1:josh",
37            "properties":{
38                "weight":1,
39                "date":"20171210"
40            }
41        },
42        {
43            "id":"S1:marko>1>20130220>S1:josh",
44            "label":"knows",
45            "type":"edge",
46            "inVLabel":"person",
47            "outVLabel":"person",
48            "inV":"1:josh",
49            "outV":"1:marko",
50            "properties":{
51                "weight":1,
52                "date":"20130220"
53            }
54        },
55        {
56            "id":"S1:marko>1>20160110>S1:vadas",
57            "label":"knows",
58            "type":"edge",
59            "inVLabel":"person",
60            "outVLabel":"person",
61            "inV":"1:vadas",
62            "outV":"1:marko",
63            "properties":{
64                "weight":0.5,
65                "date":"20160110"
66            }
67        },
68        {
69            "id":"S1:marko>2>>S2:lop",
70            "label":"created",
71            "type":"edge",
72            "inVLabel":"software",
73            "outVLabel":"person",
74            "inV":"2:lop",
75            "outV":"1:marko",
76            "properties":{
77                "weight":0.4,
78                "date":"20171210"
79            }
80        }
81    ]
82}
3.2.23.4 适用场景
  • 按 id 列表查询边,可用于批量查询边
  • 获取分片和按分片查询边,可以用来遍历全部边

3.2.24 Adamic-Adar

3.2.24.1 功能介绍

计算两个顶点的 Adamic-Adar 指标,即每个共同邻居的度取对数后倒数之和。

Params
  • vertex:一个顶点 id,必填项
  • other:另一个顶点 id,必填项,不能与 vertex 相同
  • direction:顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • limit:参与计算的共同邻居的最大数目,选填项,默认为 10000000
3.2.24.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/adamicadar?vertex="1:marko"&other="1:josh"
Response Status
1200
Response Body

度为 0 的共同邻居会被跳过,因此两个顶点没有共同邻居时结果为 0.0。

1{
2    "adamic_adar": 0.9102392266268373
3}
3.2.24.3 适用场景

预测两个顶点之间是否可能出现连边,其中冷门的共同邻居比热门的共同邻居权重更高。

3.2.25 Resource Allocation

3.2.25.1 功能介绍

计算两个顶点的资源分配指标,即每个共同邻居的度的倒数之和。

Params
  • vertex:一个顶点 id,必填项
  • other:另一个顶点 id,必填项,不能与 vertex 相同
  • direction:顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
  • label:边的类型,选填项,默认代表所有 edge label
  • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,选填项,默认为 10000
  • limit:参与计算的共同邻居的最大数目,选填项,默认为 10000000
3.2.25.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/resourceallocation?vertex="1:marko"&other="1:josh"
Response Status
1200
Response Body
1{
2    "resource_allocation": 0.3333333333333333
3}
3.2.25.3 适用场景

连边预测,相比 Adamic-Adar 对高度数的共同邻居惩罚更强。

3.2.26 Edge Existence

3.2.26.1 功能介绍

查询起点和终点之间存在的边。

Params
  • source:起始顶点 id,必填项
  • target:目标顶点 id,必填项
  • label:边的类型,选填项,默认代表所有 edge label
  • sort_values:排序键的取值,当 edge label 的 frequency 为 MULTIPLE 时用于从多条平行边中选定一条,选填项,默认为空字符串
  • limit:返回的边的最大数目,选填项,默认为 100
3.2.26.2 使用方法
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/edgeexist?source="1:marko"&target="2:lop"
Response Status
1200
Response Body
 1{
 2    "edges":[
 3        {
 4            "id":"S1:marko>2>>S2:lop",
 5            "label":"created",
 6            "type":"edge",
 7            "inVLabel":"software",
 8            "outVLabel":"person",
 9            "inV":"2:lop",
10            "outV":"1:marko",
11            "properties":{
12                "weight":0.4,
13                "date":"20171210"
14            }
15        }
16    ]
17}
3.2.26.3 适用场景

判断两个顶点之间是否直接相连,并在一次请求中拿到连接边的属性。

3.2.27 Count

3.2.27.1 功能介绍

统计从起始顶点出发,经过若干步遍历后可达的顶点数量,不返回顶点本身。

Params
  • source:起始顶点 id,必填项
  • steps:遍历的步骤,必填项,每个 step 支持以下字段:
    • direction:顶点向外发散的方向(OUT,IN,BOTH),选填项,默认是 BOTH
    • labels:当前 step 的边类型列表,选填项,默认代表所有 edge label
    • properties:当前 step 的边属性过滤条件,选填项
    • max_degree:当前 step 中单个顶点遍历的最大邻接边数目,选填项,默认为 10000
    • skip_degree:当前 step 中跳过超级点的阈值,选填项,默认为 100000
  • contains_traversed:是否把中间各步到达的顶点也计入结果,选填项,默认为 false
  • dedup_size:用于去重的顶点数上限,-1 表示不限制,选填项,默认为 1000000
3.2.27.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/count
Request Body
 1{
 2    "source": "1:marko",
 3    "steps": [
 4        {
 5            "direction": "BOTH",
 6            "labels": [],
 7            "max_degree": 100,
 8            "skip_degree": 100
 9        },
10        {
11            "direction": "BOTH",
12            "labels": [],
13            "max_degree": 100,
14            "skip_degree": 100
15        },
16        {
17            "direction": "BOTH",
18            "labels": [],
19            "max_degree": 100,
20            "skip_degree": 100
21        }
22    ]
23}
Response Status
1200
Response Body
1{
2    "count": 3
3}
3.2.27.3 适用场景

只关心多步邻居的规模时使用,避免序列化和传输大量顶点。

3.2.28 Same Neighbors Batch (POST)

3.2.28.1 功能介绍

在单次批量 HTTP 请求中独立计算多组顶点对的共同邻居。 与接收单组顶点的 GET sameneighbors 接口不同,sameneighborsbatch 接收一个顶点对列表,并独立计算每一对顶点的共同邻居。

Params
  • vertex_list:顶点对列表,必填项。每个元素必须且仅包含两个非空的顶点 ID。数值型 ID 必须为 64 位整型范围内的整数(-9223372036854775808 至 9223372036854775807),也支持 String 和 UUID 格式。
  • direction:顶点向外发散的方向(OUT, IN, BOTH),选填项,默认是 BOTH。
  • label:边的类型过滤条件,选填项,默认代表所有 edge label。
  • max_degree:遍历过程中单个顶点访问的最大邻接边数,选填项,默认为 10000,必须为正数或 -1(不限制)。
  • limit:每组顶点对返回的共同邻居最大数目,选填项,默认为 10000000,必须为不超过 2147483647 的正数或 -1。
3.2.28.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/traversers/sameneighborsbatch
Request Body
 1{
 2  "vertex_list": [
 3    ["1:marko", "1:josh"],
 4    ["1:peter", "1:josh"]
 5  ],
 6  "direction": "BOTH",
 7  "label": "knows",
 8  "max_degree": 10000,
 9  "limit": 100
10}
Response Status
1200
Response Body

响应体包含与输入对顺序对应的二维数组 same_neighbors,以及包含遍历迭代计数和耗时的 measure:

 1{
 2  "same_neighbors": [
 3    [
 4      "2:lop"
 5    ],
 6    []
 7  ],
 8  "measure": {
 9    "vertice_iterations": 6,
10    "edge_iterations": 8,
11    "cost(ns)": 3000000
12  }
13}
说明

遍历开始前会对 vertex_list 中的所有顶点对执行校验。若存在非法或不支持的顶点 ID,请求将直接拒绝。 无共同邻居的顶点对返回空数组 []。measure 中的计数统计涵盖该批次的所有顶点对。

3.2.28.3 适用场景

批量查询多组候选顶点之间的共同好友、共同关注或关联实体(如社交推荐、协同过滤),避免发起大量连续串行的 HTTP 请求。

Python 调用方:异步全图任务使用 client.olap(),立即返回的 OLTP 查询使用 client.traverser() 或 client.rank(), 详见 Python 客户端指南。

5.1.11 - Rank API

Rank(图排序)REST 接口:执行图节点排序算法,如 PageRank、个性化 PageRank 等中心性分析。

4.1 rank API 概述

HugeGraphServer 除了上一节提到的遍历(traverser)方法,还提供了一类专门做推荐的方法,我们称为rank API,可在图中为一个点推荐与其关系密切的其它点。

4.2 rank API 详解

4.2.1 Personal Rank API

Personal Rank 算法典型场景是用于推荐应用中,根据某个点现有的出边,推荐具有相近 / 相同关系的其他点,比如根据某个人的阅读记录 / 习惯,向它推荐其他可能感兴趣的书,或潜在的书友,举例如下:

  1. 假设给定 1 个 Person 点 是 tom, 它喜欢 a,b,c,d,e 5 本书,我们的想给 tom 推荐一些书友,以及一些书,最容易的想法就是看看还有哪些人喜欢过这些书 (共同兴趣)
  2. 那么此时,需要有其它的 Person 点比如 neo, 他喜欢 b,d,f 3 本书,以及 jay, 它喜欢 c,d,e,g 4 本书,lee 它喜欢 a,d,e,f 4 本书
  3. 由于 tom 已经看过的书不需要重复推荐,所以返回结果里应该期望推荐有共同喜好的其他书友看过,但 tom 没看过的书,比如推荐 “f” 和 “g” 书,且优先级 f > g
  4. 此时再计算 tom 的个性化 rank 值,就会返回排序后 TopN 推荐的 书友 + 书 的结果了 (如果只需要推荐的书,选择 OTHER_LABEL 即可)
4.2.1.0 数据准备

上面是一个简单的例子,这里再提供一个公开的 1MB 测试数据集 MovieLens 为例,用户需下载该数据集,然后使用 HugeGraph-Loader 导入到 HugeGraph 中,简单起见,数据中顶点 user 和 movie 的属性都忽略,仅使用 id 字段即可,边 rating 的具体评分值也忽略。loader 使用的元数据文件和输入源映射文件内容如下:

 1////////////////////////////////////////////////////////////
 2// UserID::Gender::Age::Occupation::Zip-code
 3// MovieID::Title::Genres
 4// UserID::MovieID::Rating::Timestamp
 5////////////////////////////////////////////////////////////
 6
 7// Define schema
 8schema.propertyKey("id").asInt().ifNotExist().create();
 9schema.propertyKey("rate").asInt().ifNotExist().create();
10
11schema.vertexLabel("user")
12      .properties("id")
13      .primaryKeys("id")
14      .ifNotExist()
15      .create();
16schema.vertexLabel("movie")
17      .properties("id")
18      .primaryKeys("id")
19      .ifNotExist()
20      .create();
21
22schema.edgeLabel("rating")
23      .sourceLabel("user")
24      .targetLabel("movie")
25      .properties("rate")
26      .ifNotExist()
27      .create();
 1{
 2  "vertices": [
 3    {
 4      "label": "user",
 5      "input": {
 6        "type": "file",
 7        "path": "users.dat",
 8        "format": "TEXT",
 9        "delimiter": "::",
10        "header": ["UserID", "Gender", "Age", "Occupation", "Zip-code"]
11      },
12      "ignored": ["Gender", "Age", "Occupation", "Zip-code"],
13      "mapping": {
14          "UserID": "id"
15      }
16    },
17    {
18      "label": "movie",
19      "input": {
20        "type": "file",
21        "path": "movies.dat",
22        "format": "TEXT",
23        "delimiter": "::",
24        "header": ["MovieID", "Title", "Genres"]
25      },
26      "ignored": ["Title", "Genres"],
27      "mapping": {
28          "MovieID": "id"
29      }
30    }
31  ],
32  "edges": [
33    {
34      "label": "rating",
35      "source": ["UserID"],
36      "target": ["MovieID"],
37      "input": {
38        "type": "file",
39        "path": "ratings.dat",
40        "format": "TEXT",
41        "delimiter": "::",
42        "header": ["UserID", "MovieID", "Rating", "Timestamp"]
43      },
44      "ignored": ["Timestamp"],
45      "mapping": {
46          "UserID": "id",
47          "MovieID": "id",
48          "Rating": "rate"
49      }
50    }
51  ]
52}

注意将映射文件中input.path的值修改为自己本地的路径。

4.2.1.1 功能介绍

适用于二分图,给出所有源顶点相关的其他顶点及其相关性组成的列表。

二分图:也称二部图,是图论里的一种特殊模型,也是一种特殊的网络流。其最大的特点在于,可以将图里的顶点分为两个集合,两个集合之间的点有边相连,但集合内的点之间没有直接关联。

假设有一个用户和物品的二分图,基于随机游走的 PersonalRank 算法步骤如下:

  1. 选定一个起点用户 u,其初始权重为 1.0,从 Vu 开始游走(有 alpha 的概率走到邻居点,1 - alpha 的概率停留);
  2. 如果决定向外游走,那么会选取某一个类型的出边,例如 rating 来查找共同的打分人:
    1. 那就从当前节点的邻居节点中按照均匀分布随机选择一个,并且按照均匀分布划分权重值;
    2. 给源顶点补偿权重 1 - alpha;
    3. 重复步骤 2;
  3. 达到一定步数或达到精度后收敛,得到推荐列表。
Params

必填项:

  • source: 源顶点 id
  • label: 源点出发的某类边 label,须连接两类不同顶点

选填项:

  • alpha:每轮迭代时从某个点往外走的概率,与 PageRank 算法中的 alpha 类似,取值区间为 (0, 1], 默认值 0.85
  • max_degree: 查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000
  • max_depth: 迭代次数,取值区间为 [2, 5000], 默认值 5
  • with_label:筛选结果中保留哪些结果,可选以下三类,默认为 BOTH_LABEL
    • SAME_LABEL:仅保留与源顶点相同类别的顶点
    • OTHER_LABEL:仅保留与源顶点不同类别(二分图的另一端)的顶点
    • BOTH_LABEL:同时保留与源顶点相同和相反类别的顶点
  • limit: 返回的顶点的最大数目,默认为 100
  • max_diff: 提前收敛的精度差,默认为 0.0001 (后续实现)
  • sorted:返回的结果是否根据 rank 排序,为 true 时降序排列,反之不排序,默认为 true
4.2.1.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/personalrank
Request Body
1{
2    "source": "1:1",
3    "label": "rating",
4    "alpha": 0.6,
5    "max_depth": 15,
6    "with_label": "OTHER_LABEL",
7    "sorted": true,
8    "limit": 10
9}
Response Status
1200
Response Body
 1{
 2    "2:2858": 0.0005014026017816927,
 3    "2:1196": 0.0004336708357653617,
 4    "2:1210": 0.0004128083140214213,
 5    "2:593": 0.00038117341069881513,
 6    "2:480": 0.00037005373269728036,
 7    "2:1198": 0.000366641614652057,
 8    "2:2396": 0.0003622362410538888,
 9    "2:2571": 0.0003593312457300953,
10    "2:589": 0.00035922123055598566,
11    "2:110": 0.0003466135844390885
12}
4.2.1.3 适用场景

两类不同顶点连接形成的二分图中,给某个点推荐相关性最高的其他顶点,例如:

  • 阅读推荐: 找出优先给某人推荐的其他书籍, 也可以同时推荐共同喜好最高的书友 (例: 微信 “你的好友也在看 xx 文章” 功能)
  • 社交推荐: 找出拥有相同关注话题的其他博主, 也可以推荐可能感兴趣的新闻/消息 (例: Weibo 中的 “热点推荐” 功能)
  • 商品推荐: 通过某人现在的购物习惯, 找出应优先推给它的商品列表, 也可以给它推荐带货播主 (例: TaoBao 的 “猜你喜欢” 功能)

4.2.2 Neighbor Rank API

4.2.2.0 数据准备
 1public class Loader {
 2    public static void main(String[] args) {
 3        HugeClient client = new HugeClient("http://127.0.0.1:8080", "hugegraph");
 4        SchemaManager schema = client.schema();
 5
 6        schema.propertyKey("name").asText().ifNotExist().create();
 7
 8        schema.vertexLabel("person")
 9              .properties("name")
10              .useCustomizeStringId()
11              .ifNotExist()
12              .create();
13
14        schema.vertexLabel("movie")
15              .properties("name")
16              .useCustomizeStringId()
17              .ifNotExist()
18              .create();
19
20        schema.edgeLabel("follow")
21              .sourceLabel("person")
22              .targetLabel("person")
23              .ifNotExist()
24              .create();
25
26        schema.edgeLabel("like")
27              .sourceLabel("person")
28              .targetLabel("movie")
29              .ifNotExist()
30              .create();
31
32        schema.edgeLabel("directedBy")
33              .sourceLabel("movie")
34              .targetLabel("person")
35              .ifNotExist()
36              .create();
37
38        GraphManager graph = client.graph();
39
40        Vertex O = graph.addVertex(T.label, "person", T.id, "O", "name", "O");
41
42        Vertex A = graph.addVertex(T.label, "person", T.id, "A", "name", "A");
43        Vertex B = graph.addVertex(T.label, "person", T.id, "B", "name", "B");
44        Vertex C = graph.addVertex(T.label, "person", T.id, "C", "name", "C");
45        Vertex D = graph.addVertex(T.label, "person", T.id, "D", "name", "D");
46
47        Vertex E = graph.addVertex(T.label, "movie", T.id, "E", "name", "E");
48        Vertex F = graph.addVertex(T.label, "movie", T.id, "F", "name", "F");
49        Vertex G = graph.addVertex(T.label, "movie", T.id, "G", "name", "G");
50        Vertex H = graph.addVertex(T.label, "movie", T.id, "H", "name", "H");
51        Vertex I = graph.addVertex(T.label, "movie", T.id, "I", "name", "I");
52        Vertex J = graph.addVertex(T.label, "movie", T.id, "J", "name", "J");
53
54        Vertex K = graph.addVertex(T.label, "person", T.id, "K", "name", "K");
55        Vertex L = graph.addVertex(T.label, "person", T.id, "L", "name", "L");
56        Vertex M = graph.addVertex(T.label, "person", T.id, "M", "name", "M");
57
58        O.addEdge("follow", A);
59        O.addEdge("follow", B);
60        O.addEdge("follow", C);
61        D.addEdge("follow", O);
62
63        A.addEdge("follow", B);
64        A.addEdge("like", E);
65        A.addEdge("like", F);
66
67        B.addEdge("like", G);
68        B.addEdge("like", H);
69
70        C.addEdge("like", I);
71        C.addEdge("like", J);
72
73        E.addEdge("directedBy", K);
74        F.addEdge("directedBy", B);
75        F.addEdge("directedBy", L);
76
77        G.addEdge("directedBy", M);
78    }
79}
4.2.2.1 功能介绍

在一般图结构中,找出每一层与给定起点相关性最高的前 N 个顶点及其相关度,用图的语义理解就是:从起点往外走,走到各层各个顶点的概率。

Params
  • source: 源顶点 id,必填项
  • alpha:每轮迭代时从某个点往外走的概率,与 PageRank 算法中的 alpha 类似,必填项,取值区间为 (0, 1]
  • steps: 表示从起始顶点走过的路径规则,是一组 Step 的列表,每个 Step 对应结果中的一层,必填项。每个 Step 的结构如下:
    • direction:表示边的方向(OUT, IN, BOTH),默认是 BOTH
    • labels:边的类型列表,多个边类型取并集
    • max_degree:查询过程中,单个顶点遍历的最大邻接边数目,默认为 10000;当前也兼容参数名 degree。
    • skip_degree:当前层跳过超级点的阈值,默认为 0,表示不跳过
    • top:在结果中每一层只保留权重最高的前 N 个结果,默认为 10,最大值为 1000
  • capacity: 遍历过程中最大的访问的顶点数目,选填项,默认为 10000000
4.2.2.2 使用方法
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/traversers/neighborrank
Request Body
 1{
 2    "source":"O",
 3    "steps":[
 4        {
 5            "direction":"OUT",
 6            "labels":[
 7                "follow"
 8            ],
 9            "max_degree":-1,
10            "top":100
11        },
12        {
13            "direction":"OUT",
14            "labels":[
15                "follow",
16                "like"
17            ],
18            "max_degree":-1,
19            "top":100
20        },
21        {
22            "direction":"OUT",
23            "labels":[
24                "directedBy"
25            ],
26            "max_degree":-1,
27            "top":100
28        }
29    ],
30    "alpha":0.9,
31    "capacity":-1
32}
Response Status
1200
Response Body
 1{
 2    "ranks": [
 3        {
 4            "O": 1
 5        },
 6        {
 7            "B": 0.4305,
 8            "A": 0.3,
 9            "C": 0.3
10        },
11        {
12            "G": 0.17550000000000002,
13            "H": 0.17550000000000002,
14            "I": 0.135,
15            "J": 0.135,
16            "E": 0.09000000000000001,
17            "F": 0.09000000000000001
18        },
19        {
20            "M": 0.15795,
21            "K": 0.08100000000000002,
22            "L": 0.04050000000000001
23        }
24    ]
25}
4.2.2.3 适用场景

为给定的起点在不同的层中找到最应该推荐的顶点。

  • 比如:在观众、朋友、电影、导演的四层图结构中,根据某个观众的朋友们喜欢的电影,为这个观众推荐电影;或者根据这些电影是谁拍的,为其推荐导演。

Python 调用方:异步全图任务使用 client.olap(),立即返回的 OLTP 查询使用 client.traverser() 或 client.rank(), 详见 Python 客户端指南。

5.1.12 - Variable API

Variable(变量)REST 接口:存储和管理键值对形式的全局变量,支持图级别的配置和状态管理。

5.1 Variables

Variables 可以用来存储有关整个图的数据,数据按照键值对的方式存取

5.1.1 创建或者更新某个键值对

Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/variables/name
Request Body
1{
2  "data": "tom"
3}
Response Status
1200
Response Body
1{
2    "name": "tom"
3}

5.1.2 列出全部键值对

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/variables
Response Status
1200
Response Body
1{
2    "name": "tom"
3}

5.1.3 列出某个键值对

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/variables/name
Response Status
1200
Response Body
1{
2    "name": "tom"
3}

5.1.4 删除某个键值对

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/variables/name
Response Status
1204

5.1.13 - Graphs API

Graphs(图管理)REST 接口:管理图实例的生命周期,包括创建、查询、克隆、清空和删除图数据库。

6.1 Graphs

警告

生产环境必须启用 Server 认证与授权,通过 IP 白名单及最小权限控制图管理接口的访问,并保留 audit-*.log 审计记录。下文非鉴权配置仅用于隔离的本地测试。

本页介绍当前 master 的 Graphs API。历史版本的路径和请求体请切换到对应多版本页面: 1.7 版 Graphs API 或 1.5 版 Graphs API。

启用鉴权时,创建、克隆、删除、清空、修改图显示名、读取图配置、设置读模式和手动压缩等操作要求图空间管理权限(space);管理员可按权限继承规则满足。创建或恢复快照、设置数据模式允许图空间管理者或该图所有者操作;列表、详情、数据模式读取和读模式读取按图读取权限校验。Raft API 另要求图空间成员权限。

  • GET /apis 是资源索引。索引中的资源路径属于 Server 根地址,应使用 /versions、/graphspaces 与 /gremlin,不要再加 /apis 前缀。旧版索引没有前导斜杠,应相对 Server 根路径解析,不能拼到索引目录下面。网关另有公开路径前缀时,保留该前缀。
  • GET /graphspaces 仅支持 PD 模式;独立部署模式请使用 GET /graphs 列出已配置的图。
  • 动态建图使用 POST /graphspaces/{space}/graphs/{graph},并提供后端要求的图配置。POST /graphs 不是建图接口。旧形态 /graphs 能列出图,并不表示 GraphSpace API 不存在。运行 SeaTunnel 自带 sink 示例前,请按 SeaTunnel 指南 先创建目标图。

6.1.1 列出图空间中全部的图

Params

路径参数说明:

  • graphspace: 图空间名称
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs
Response Status
1200
Response Body
1{
2    "graphs": [
3        "hugegraph",
4        "hugegraph1"
5    ]
6}

6.1.2 查看某个图的信息

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph
Response Status
1200
Response Body
1{
2    "name": "hugegraph",
3    "backend": "rocksdb"
4}

6.1.3 清空某个图的全部数据,包括 schema、vertex、edge 和 index 等

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

请求参数说明:

由于清空图是一个比较危险的操作,为避免用户误调用,我们给 API 添加了用于确认的参数:

  • confirm_message: 默认为I'm sure to delete all data
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/clear?confirm_message=I%27m+sure+to+delete+all+data
Response Status
1204

6.1.4 克隆一个图

HugeGraph 提供两种图克隆方式:

  1. 模式一:仅配置克隆(Configuration Clone):仅复制源图的配置信息,不复制 Schema、顶点或边数据。
  2. 模式二:Schema 克隆(Schema Clone,Server API 0.73+):在同一图空间内复制源图配置及属性键、顶点标签和索引标签,不复制顶点与边数据。
模式一:仅配置克隆

通过图创建端点配合查询参数 clone_graph_name 复制源图配置。

说明

在 PD 模式下,若源图配置了 schema.init_template,克隆出的新图也会继承该配置并基于模板初始化 Schema。

Params

路径参数:

  • graphspace: 图空间名称
  • graph: 要创建的新图名称

查询参数:

  • clone_graph_name: 源图名称。注意必须作为 Query 参数传入,不能放在请求体 JSON 中。
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/cloneGraph?clone_graph_name=hugegraph
Request Body (可选)

可选择传入 JSON 配置覆盖源图配置(例如自定义存储目录等):

1{
2  "gremlin.graph": "org.apache.hugegraph.HugeFactory",
3  "backend": "rocksdb",
4  "serializer": "binary",
5  "store": "cloneGraph",
6  "rocksdb.data_path": "./rks-data-xx",
7  "rocksdb.wal_path": "./rks-data-xx"
8}
说明
  1. RocksDB 存储路径不能与现有图冲突,需指定不同目录。
  2. 如需开启权限认证,需设置 "gremlin.graph": "org.apache.hugegraph.auth.HugeFactoryAuthProxy"。
Response Status
1201
Response Body
1{
2  "name": "cloneGraph",
3  "nickname": "cloneGraph",
4  "backend": "rocksdb",
5  "description": ""
6}
模式二:Schema 克隆(Server API 0.73+)

自 HugeGraph 1.8.0(Server REST API 0.73+)起提供同步的 Schema 克隆接口。该接口在同一图空间内创建新图,并复制源图的所有属性键、顶点标签及相关索引,但不复制顶点与边数据。复制时会自动清空 schema.init_template,以准确复制源图当时的实际 Schema。

克隆期间请保持源图 Schema 不变。开启鉴权时,调用该接口需要图空间管理权限(Space Admin)。

注意

暂不支持包含边标签(EdgeLabel)的源图:由于部分后端存储无法可靠还原边标签的继承层级,若源图包含任何边标签,服务端将在创建目标图前直接拦截拒绝;克隆过程中若有新增边标签也会报错中断。

警告

非原子操作与残留清理:Schema 复制不是原子事务。若在创建目标图后复制 Schema 元素失败,新图可能处于部分初始化的状态且对外可见。服务端不会自动回滚或删除已建的图;遇到失败需排查并显式调用删除接口清理该目标图后再重试。

Params

路径参数:

  • graphspace: 图空间名称
  • graph: 要创建的目标图名称

查询参数:

  • source: 同一图空间内的源图名称(必填)
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/schema_copy/schema-clone?source=vertices_only
Request Body (可选)

仅支持通过 JSON 指定 nickname(可选):

1{
2  "nickname": "Schema copy"
3}
Response Status
1201
Response Body
1{
2  "name": "schema_copy",
3  "nickname": "Schema copy",
4  "backend": "rocksdb"
5}

6.1.5 创建一个图

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph-xx
Request Body

创建一个图(设置 Content-Type: application/json)

gremlin.graph 配置说明:

  • 鉴权模式:"gremlin.graph": "org.apache.hugegraph.auth.HugeFactoryAuthProxy"(生产环境必须使用)
  • 非鉴权模式:"gremlin.graph": "org.apache.hugegraph.HugeFactory"

注意:如果 backend 是 hstore,请确保 HugeGraph-Server 已正确配置 PD,参见 HStore 配置。调度器由后端类型决定:hstore 使用分布式调度器,其他后端使用本地调度器。

选填字段及其默认值:

  • gremlin.graph 默认为 org.apache.hugegraph.HugeFactory
  • backend 在 PD 模式下默认为 hstore,否则默认为 rocksdb
  • serializer 默认为 binary
  • store 默认为图名称
  • nickname 设置图的显示名,在图空间内必须唯一
  • schema 指定初始化该图所用的 schema 模板,会被保存为 schema.init_template
  • description 会原样返回在响应中

RocksDB 示例:

1{
2  "gremlin.graph": "org.apache.hugegraph.auth.HugeFactoryAuthProxy",
3  "backend": "rocksdb",
4  "serializer": "binary",
5  "store": "hugegraph",
6  "rocksdb.data_path": "./rks-data-xx",
7  "rocksdb.wal_path": "./rks-data-xx"
8}

HStore 示例:

1{
2  "gremlin.graph": "org.apache.hugegraph.auth.HugeFactoryAuthProxy",
3  "backend": "hstore",
4  "serializer": "binary",
5  "store": "hugegraph2",
6  "pd.peers": "127.0.0.1:8686"
7}

Note: Rocksdb 存储路径不能与现有图相同(需使用不同的目录)

Response Status
1201
Response Body
1{
2    "name": "hugegraph2",
3    "nickname": "hugegraph2",
4    "backend": "rocksdb",
5    "description": ""
6}

6.1.6 删除某个图及其全部数据

启用鉴权时需要图空间管理权限(space)。

删图前停止所有使用该图的 Server 的写入和任务,并在失败及重试期间持续保持停止状态。 所有 Server 上的删除完成且经确认前,不得重建同名图。通知送达不构成集群范围的屏障。

执行删除的 Server 会关闭新任务准入,并等待实际执行、取消回调和事务清理结束。 配置的任务等待超时(task.wait_timeout,单位秒)时,会在移除数据、配置或元数据前拒绝删除;待执行对象退出后再重试。 因任务未排空而拒绝删除后,任务准入仍保持关闭。若要在破坏性清理前恢复正常用图,保持写入和任务生产者停止, 等待全部已准入任务和取消清理结束后再重启 Server;重启不会恢复已经移除的数据或元数据。 仅关闭调度器时,尚未开始的持久化任务仍保留在存储中。

删图不是事务操作,破坏性清理后的失败不会恢复已移除的数据或元数据。执行对象或原生资源的清理结果不确定时需要人工检查, 不能强制移除调度器,也不能仅凭任务 Future 已完成就恢复写入。 在启用 PD 且 graph.load_from_local_config=true 的部署中,若因使用本地配置而拒绝删除, 移除对应配置文件并重启 Server 仅会阻止 Server 继续加载该图,其后端存储数据仍会保留。

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

请求参数说明:

由于删除图是一个比较危险的操作,为避免用户误调用,我们给 API 添加了用于确认的参数:

  • confirm_message: 默认为I'm sure to drop the graph
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/graphA?confirm_message=I%27m%20sure%20to%20drop%20the%20graph
Response Status
1204

6.1.7 列出图空间中全部的图及其配置

对当前用户有读权限的每个图返回一条记录,其中包含该图的配置(形如密码、密钥、token、凭证、私钥的配置项会被过滤掉)以及下面这些字段。当前用户的默认图会排在前面。

Params

路径参数说明:

  • graphspace: 图空间名称

请求参数说明:

  • prefix: 只返回名称或显示名以该前缀开头的图
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/profile
Response Status
1200
Response Body

default_update_time 只在该图是当前用户的默认图时返回,create_time 只在该图记录了创建时间时返回。

 1[
 2  {
 3    "backend": "rocksdb",
 4    "serializer": "binary",
 5    "store": "hugegraph",
 6    "name": "hugegraph",
 7    "nickname": "hugegraph",
 8    "graphspace_nickname": "DEFAULT",
 9    "default": true,
10    "default_update_time": "2024-05-01 12:30:00",
11    "create_time": "2024-05-01 12:00:00"
12  }
13]

6.1.8 修改某个图的显示名

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

请求参数说明:

  • action: 固定为 update
  • update: 需要修改的字段。name 必填且必须与路径中的图名一致,nickname 是新的显示名,在图空间内必须唯一。
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph
Request Body
1{
2  "action": "update",
3  "update": {
4    "name": "hugegraph",
5    "nickname": "MyGraph"
6  }
7}
Response Status
1200
Response Body
1{
2  "hugegraph": "updated"
3}

6.1.9 管理当前用户的默认图

默认图是按用户记录的,因此下面的接口都以调用者的身份生效。它们依赖权限系统,未开启权限的单机模式下会返回 400 和 GraphSpace management is not supported in standalone mode。

设置默认图
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/default
Response Status
1200
Response Body
1{
2  "default_graph": [
3    "hugegraph"
4  ]
5}
取消默认图
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/default
Response Status
1200
Response Body
1{
2  "default_graph": []
3}
查看默认图
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/default
Response Status
1200
Response Body
1{
2  "default_graph": [
3    "hugegraph"
4  ]
5}

6.1.10 重新加载图空间中的图

图配置变化通过重启 Server 应用。热重载恢复尚未实现,不要使用此接口进行配置维护。 当前未启用 PD 的执行路径中,reload 会调用删图流程,可能清空后端数据。重启完成并确认加载了预期图之前,持续停止写入和任务。 下方请求及响应仅说明 API 格式,不代表维护或恢复保障。

Params

路径参数说明:

  • graphspace: 图空间名称

请求参数说明:

  • action: 固定为 reload
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/manage
Request Body
1{
2  "action": "reload"
3}
Response Status
1200
Response Body
1{
2  "graphs": "reloaded"
3}

6.1.11 克隆图 Schema

从 Server API 版本 0.73 起,支持将同一图空间内已有源图的 Schema 同步克隆到新建的目标图中。 该接口会同步复制源图的全部属性类型(Property Key)、顶点类型(Vertex Label)和索引标签(Index Label)。

说明

该接口仅复制 Schema,不复制图中的顶点和边数据。若源图包含任何边类型(Edge Label),接口将在创建目标图前直接拒绝, 因为部分后端存储无法安全保留边类型所需的层次元数据。克隆期间应停止对源图 Schema 进行修改。 若目标图创建后克隆过程出错,目标图可能处于部分 Schema 状态,需人工排查并显式删除后重试。

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 要创建的目标图名称

请求参数说明:

  • source: 被克隆的源图名称(必填)
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/cloned_target_graph/schema-clone?source=hugegraph
Request Body (可选)

可选的 JSON 请求体,仅支持设置目标图的 nickname(设置 Content-Type: application/json):

1{
2  "nickname": "ClonedGraph"
3}
Response Status
1201
Response Body
1{
2  "name": "cloned_target_graph",
3  "nickname": "ClonedGraph",
4  "backend": "rocksdb"
5}

6.2 Conf

6.2.1 查看某个图的配置

Method & Url
1GET
2http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/conf
Response Status
1200
Response Body
 1# gremlin entrence to create graph
 2gremlin.graph=org.apache.hugegraph.HugeFactory
 3# cache config
 4#schema.cache_capacity=1048576
 5#graph.cache_capacity=10485760
 6#graph.cache_expire=600
 7
 8# schema illegal name template
 9#schema.illegal_name_regex=\s+|~.*
10
11#vertex.default_label=vertex
12
13backend=rocksdb
14serializer=binary
15
16store=hugegraph
17...=

6.3 Mode

合法的图模式包括:NONE,RESTORING,MERGING,LOADING

  • None 模式(默认),元数据和图数据的写入属于正常状态。特别的:
    • 元数据(schema)创建时不允许指定 ID
    • 图数据(vertex)在 id strategy 为 Automatic 时,不允许指定 ID
  • LOADING:批量导入数据时自动启用,特别的:
    • 添加顶点/边时,不会检查必填属性是否传入

Restore 时存在两种不同的模式:Restoring 和 Merging

  • Restoring 模式,恢复到一个新图中,特别的:
    • 元数据(schema)创建时允许指定 ID
    • 图数据(vertex)在 id strategy 为 Automatic 时,允许指定 ID
  • Merging 模式,合并到一个已存在元数据和图数据的图中,特别的:
    • 元数据(schema)创建时不允许指定 ID
    • 图数据(vertex)在 id strategy 为 Automatic 时,允许指定 ID

正常情况下,图模式为 None,当需要 Restore 图时,需要根据需要临时修改图模式为 Restoring 模式或者 Merging 模式,并在完成 Restore 时,恢复图模式为 None。

6.3.1 查看某个图的模式

启用鉴权时需要图读取权限(space_member 或该图的所有者)。

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/mode
Response Status
1200
Response Body
1{
2    "mode": "NONE"
3}

合法的图模式包括:NONE,RESTORING,MERGING,LOADING

6.3.2 设置某个图的模式

启用鉴权时需要图空间管理权限(space)或该图所有者权限;管理员可按权限继承规则满足。

Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/mode
Request Body
1"RESTORING"

合法的图模式包括:NONE,RESTORING,MERGING,LOADING

存在活跃的 loading owner 时,此枚举 PUT 会拒绝所有模式修改,包括 "LOADING"。请先停止导入 worker,再释放其 owner。

Response Status
1200
Response Body
1{
2    "mode": "RESTORING"
3}

6.3.3 查看某个图的读模式

启用鉴权时需要图读取权限(space_member 或该图的所有者)。

Params
  • name: 图的名称
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph_read_mode
Response Status
1200
Response Body
1{
2    "graph_read_mode": "ALL"
3}

6.3.4 设置某个图的读模式

启用鉴权时需要图空间管理权限(space);管理员可按权限继承规则满足。

Params
  • name: 图的名称
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/graph_read_mode
Request Body
1"OLTP_ONLY"

合法的读模式包括:ALL,OLTP_ONLY。传入 OLAP_ONLY 时接口会报错 Graph-read-mode could be ALL or OLTP_ONLY。

Response Status
1200
Response Body
1{
2    "graph_read_mode": "OLTP_ONLY"
3}

6.3.5 LOADING owner 管理

自 HugeGraph 1.8.0 起提供 owner 协议 1 接口(需配合返回 protocol: 1 的新版 Server 与对应 Loader;当前 master 分支暂未包含该协议); Loader 需使用配套的 1.8.0 及以上版本客户端。旧版本发行包、早期 1.8 构建以及当前 master 分支均不包含该协议;仅支持 LOADING 枚举不能说明支持这些接口。 启用鉴权时,两个接口沿用模式设置接口的权限要求,即图空间管理权限(space)或该图所有者权限,并校验 STATUS 写权限。 Server 将句柄绑定到实际鉴权用户;token 本身不赋予权限。申请、释放和重试必须保持相同身份。

1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/mode/owners

200 能力响应包含图实例 UUID、当前非负 epoch 及状态 revision:

1{
2    "protocol": 1,
3    "instance": "<instance UUID>",
4    "epoch": 0,
5    "revision": 0
6}

每轮导入生成一个新的小写连字符 UUID(lowercase hyphenated UUID)作为 token,保留返回的 instance 和 epoch,通过以下请求申请,并设置 Content-Type: application/json:

1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/mode/owners
1{
2    "action": "acquire",
3    "instance": "<instance UUID>",
4    "epoch": 0,
5    "token": "<import UUID>"
6}

只有响应中包含 state: "active" 时才表示申请成功;此时返回 200 并回显 protocol、instance、epoch、token 以及 mode: "LOADING"。 若返回 200 但 state: "released",说明该句柄已失效或已被提前取消,此时并未获得 owner 保护;必须先停止并排空该次导入尝试,然后再通过 GET 获取新的 instance 和 epoch 并使用新 token 重新发起尝试。 释放时将 action 设置为 release,句柄保持不变;响应中包含 state: "released" 和当前实际模式。未申请前直接调用释放会被记录,并导致后续使用该句柄的申请直接返回 released。 重试保留同一句柄;Server 校验其鉴权身份、instance 和 epoch。已释放句柄不能再次申请。

当异常中断(如 kill -9)导致句柄残留时,管理员可发起强制恢复请求:

1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/mode/owners
1{
2    "action": "recover",
3    "instance": "<instance UUID>",
4    "epoch": 0,
5    "revision": 0,
6    "confirm": "I'm sure all imports have stopped"
7}

管理员恢复需要全局管理员权限(admin)。调用方必须传入从 GET /mode/owners 获取的当前 revision、instance 和 epoch, 以及确认文案 confirm: "I'm sure all imports have stopped"。 若传入的 revision 与服务端当前状态不一致,请求将被拒绝并返回 HTTP 409 Conflict。 恢复成功后服务端清除所有残留 owner,将图模式重置为 NONE 并递增 epoch,返回 HTTP 200(含 state: "recovered" 和 mode: "NONE")。

首个 owner 要求 NONE;其他 owner 共享由 owner 管理的 LOADING,最后一个释放后恢复 NONE。 手动设置的 LOADING、RESTORING 和 MERGING 不会被接管;owner 活跃时,旧枚举 PUT 会拒绝模式修改。

该协议保护同一 Server 上实际运行的图实例中的普通导入,句柄绑定到实际鉴权身份、instance 和 epoch。 它不提供跨 Server 协调、数据写入隔离或自动过期。请使用固定的 Server 直连地址,在导入停止后释放。 升级后的 Loader 仅在 owner 探测返回接口路由不受支持的 404 时回退到旧行为;其他错误仍失败。 图数据源和恢复导入保留原有枚举模式行为,参见 Loader 兼容与恢复说明。

6.4 Snapshot

6.4.1 创建快照

启用鉴权时需要图空间管理权限(space)或该图所有者权限;管理员可按权限继承规则满足。

Params
  • name: 图的名称
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/snapshot_create
Response Status
1200
Response Body
1{
2    "hugegraph": "snapshot_created"
3}

6.4.2 快照恢复

启用鉴权时需要图空间管理权限(space)或该图所有者权限;管理员可按权限继承规则满足。

Params
  • name: 图的名称
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/snapshot_resume
Response Status
1200
Response Body
1{
2    "hugegraph": "snapshot_resumed"
3}

6.5 Compact

6.5.1 手动压缩图

启用鉴权时需要图空间管理权限(space);管理员可按权限继承规则满足。

Params
  • name: 图的名称
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/compact
Response Status
1200
Response Body
1{
2    "nodes": 1,
3    "cluster_id": "local",
4    "servers": {
5        "local": "OK"
6    }
7}

6.6 Raft

以下接口只在图运行于 raft 模式时可用,参见 配置项 中的 raft.mode。未开启 raft 模式的图会返回 400 和 Allowed <operation> operation only when working on raft mode。

启用鉴权时需要图空间成员权限(space_member);管理员可按权限继承规则满足。

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

请求参数说明:

  • group: raft 组名称,默认为 default
  • endpoint: 节点地址,形如 host:port。transfer_leader、set_leader、add_peer 和 remove_peer 必填。

6.6.1 查看 raft 组的成员列表

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/raft/list_peers
Response Status
1200
Response Body

返回对象的 key 是 raft 组名称。

1{
2  "default": [
3    "127.0.0.1:8281",
4    "127.0.0.1:8282",
5    "127.0.0.1:8283"
6  ]
7}

6.6.2 查看 raft 组的 leader

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/raft/get_leader
Response Status
1200
Response Body
1{
2  "default": "127.0.0.1:8281"
3}

6.6.3 转移 raft 组的 leader

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/raft/transfer_leader?endpoint=127.0.0.1:8282
Response Status
1200
Response Body
1{
2  "default": "127.0.0.1:8282"
3}

6.6.4 指定 raft 组的 leader

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/raft/set_leader?endpoint=127.0.0.1:8282
Response Status
1200
Response Body
1{
2  "default": "127.0.0.1:8282"
3}

6.6.5 向 raft 组添加成员

该操作会创建一个异步任务,参见 Task API。

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/raft/add_peer?endpoint=127.0.0.1:8284
Response Status
1200
Response Body
1{
2  "task_id": 1
3}

6.6.6 从 raft 组移除成员

该操作会创建一个异步任务,参见 Task API。

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/raft/remove_peer?endpoint=127.0.0.1:8284
Response Status
1200
Response Body
1{
2  "task_id": 2
3}

5.1.14 - Task API

Task(任务管理)REST 接口:查询和管理异步任务的执行状态,如索引重建、图遍历等长时任务。

7.1 Task

轮询到 task_status 为终态后再读取 task_result;running 不表示任务已经完成。 Hubble 客户端传输超时与 Server 执行超时是不同限制,仅调整其中一个不会移除另一个。 不要把 Hubble 封装的任务 ID(可能映射为负数)直接传给 Server 原生 /tasks/{id}。

7.1.1 列出某个图中全部的异步任务

Params
  • status: 异步任务的状态,取值为 NEW、SCHEDULING、SCHEDULED、QUEUED、RESTORING、RUNNING、SUCCESS、CANCELLING、CANCELLED、FAILED、HANGING、DELETING 之一,不区分大小写
  • ids: 需要查询的任务 id,可以重复传多个。不能与 status 或 page 同时使用,并且会忽略 limit
  • limit:返回异步任务数目上限,默认为 100
  • page: 分页的页标记,传该参数时响应中会带上下一页的 page 字段
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks?status=success
Response Status
1200
Response Body
 1{
 2	"tasks": [{
 3		"task_name": "hugegraph.traversal().V()",
 4		"task_progress": 0,
 5		"task_create": 1532943976585,
 6		"task_status": "success",
 7		"task_update": 1532943976736,
 8		"task_result": "0",
 9		"task_retries": 0,
10		"id": 2,
11		"task_type": "gremlin",
12		"task_callable": "org.apache.hugegraph.api.job.GremlinAPI$GremlinJob",
13		"task_input": "{\"gremlin\":\"hugegraph.traversal().V()\",\"bindings\":{},\"language\":\"gremlin-groovy\",\"aliases\":{\"hugegraph\":\"graph\"}}"
14	}]
15}

7.1.2 查看某个异步任务的信息

Params
  • with_result: 是否加载任务的结果,默认为 true
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2
Response Status
1200
Response Body
 1{
 2	"task_name": "hugegraph.traversal().V()",
 3	"task_progress": 0,
 4	"task_create": 1532943976585,
 5	"task_status": "success",
 6	"task_update": 1532943976736,
 7	"task_result": "0",
 8	"task_retries": 0,
 9	"id": 2,
10	"task_type": "gremlin",
11	"task_callable": "org.apache.hugegraph.api.job.GremlinAPI$GremlinJob",
12	"task_input": "{\"gremlin\":\"hugegraph.traversal().V()\",\"bindings\":{},\"language\":\"gremlin-groovy\",\"aliases\":{\"hugegraph\":\"graph\"}}"
13}

7.1.3 删除某个异步任务信息,不删除异步任务本身

Params
  • force: 任务仍在运行时是否强制删除,默认为 false

任务记录删除与删图是不同操作。图维护须遵守图 API中的停写和任务清理要求。

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2
Response Status
1204

7.1.4 取消某个异步任务,该异步任务必须具有处理中断的能力

假设已经通过Gremlin API创建了一个异步任务如下:

1"for (int i = 0; i < 10; i++) {" +
2    "hugegraph.addVertex(T.label, 'man');" +
3    "hugegraph.tx().commit();" +
4    "try {" +
5        "sleep(1000);" +
6    "} catch (InterruptedException e) {" +
7        "break;" +
8    "}" +
9"}"
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2?action=cancel

请保证在 10 秒内发送该请求,如果超过 10 秒发送,任务可能已经执行完成,无法取消。

Response Status
1202

对已经完成或者正在取消中的任务发起取消会返回 400。

Response Body

返回整个任务对象,其中 task_status 为 cancelling 或 cancelled:

 1{
 2	"task_name": "for (int i = 0; i < 10; i++) {...}",
 3	"task_progress": 0,
 4	"task_create": 1532943976585,
 5	"task_status": "cancelling",
 6	"task_update": 1532943977001,
 7	"task_retries": 0,
 8	"id": 2,
 9	"task_type": "gremlin",
10	"task_callable": "org.apache.hugegraph.api.job.GremlinAPI$GremlinJob"
11}

此时查询 label 为 man 的顶点数目,一定是小于 10 的。

7.2 Algorithm Job

在服务内部以异步任务的方式调度一个 OLAP 算法,返回的 task id 可以用上面的 Task API 跟踪。

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
  • name: 算法名称,已注册的算法有 count_vertex、count_edge、degree_centrality、stress_centrality、betweenness_centrality、closeness_centrality、eigenvector_centrality、triangle_count、cluster_coefficient、lpa、louvain、weak_connected_component、fusiform_similarity、rings、k_core、page_rank 和 subgraph_stat。名称不存在时返回 404。
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/algorithm/page_rank
Request Body

请求体是算法的参数集合,每个算法各自校验自己的参数。传 {} 表示全部使用默认值。

1{
2    "alpha": 0.15,
3    "times": 10
4}
Response Status
1201
Response Body
1{
2    "task_id": 1
3}

7.3 Computer Job

以异步任务的方式调度一个 HugeGraph-Computer 作业。该作业在服务外部执行,参见 HugeGraph-Computer。

Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
  • name: 算法名称,已注册的有 page_rank、weak_connected_component、lpa、triangle_count 和 louvain。名称不存在时返回 404。
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/computer/page_rank
Request Body

请求体是作业的参数集合,传 {} 表示全部使用默认值。

1{}
Response Status
1201
Response Body
1{
2    "task_id": 2
3}

Python 调用方:异步全图任务使用 client.olap(),立即返回的 OLTP 查询使用 client.traverser() 或 client.rank(), 详见 Python 客户端指南。

5.1.15 - Gremlin API

Gremlin(图查询语言)REST 接口:通过 HTTP 接口执行 Gremlin 图遍历查询语言脚本。

8.1 Gremlin

说明

Gremlin 遍历语法、特性支持与升级说明请查阅 图查询语言 - Gremlin。

警告

生产环境下安全使用原生查询接口

图查询语言 (如 Gremlin/Cypher) 本身的灵活性会带来一些潜在的安全隐患。为了保障核心安全,请避免直接在公网环境暴露任何相关的原生查询接口。 生产环境必须开启 鉴权体系 (Auth)、启用并维护 IP 白名单,并按最小权限控制用户可执行的操作。Server 标准配置会把鉴权代理的授权记录写入 audit-*.log;必须保留并限制其读取权限。auth.audit_log_rate 只限制每用户日志输出速率,不是审计日志的启停开关。

8.1.1 向 HugeGraphServer 发送 gremlin 语句(GET),同步执行

Params
  • gremlin: 要发送给HugeGraphServer执行的gremlin语句
  • bindings: 用来绑定参数,key 是字符串,value 是绑定的值(只能是字符串或者数字),功能类似于 MySQL 的 Prepared Statement,用于加速语句执行
  • language: 发送语句的语言类型,默认为gremlin-groovy
  • aliases: 为存在于图空间的已有变量添加别名

此 REST 代理的 GET 查询不能可靠地传递含 JSON 花括号的 aliases 参数;当前图绑定名带连字符,也不能直接作为 Groovy 变量。以下用简单表达式示范 GET。需要选择图执行遍历时,请使用下方带 aliases 的 POST 示例。

Method & Url
1curl --compressed --get \
2  --data-urlencode "gremlin=1+1" \
3  http://127.0.0.1:8080/gremlin
Response Status
1200
Response Body
1{
2	"requestId": "<request_id>",
3	"status": {"message": "", "code": 200, "attributes": {}},
4	"result": {"data": [2], "meta": {}}
5}

8.1.2 向 HugeGraphServer 发送 gremlin 语句(POST),同步执行

查询顶点数

可执行请求命令
1curl --compressed -sS -X POST http://127.0.0.1:8080/gremlin \
2  -H 'Content-Type: application/json' \
3  --data-binary '{"gremlin":"g.V().count()","aliases":{"g":"__g_DEFAULT-hugegraph"}}'

/gremlin 是顶层接口。图空间 DEFAULT 中图 hugegraph 对应的 traversal source 名为 __g_DEFAULT-hugegraph,请求通过 aliases 映射为脚本中的 g。若使用不同图空间或图名,应按 Server 绑定名调整 alias。批量结果可能以 gzip 返回,curl 使用 --compressed 可自动解压。

绑定名区分大小写:<space>-<graph> 是图,__g_<space>-<graph> 是遍历源。多图 Server 没有隐含的全局 g。 bindings 用于查询变量,不能注册图;alias 目标也不能写成 graph.traversal() 表达式。 没有 GraphSpace 的旧版独立图使用 <graph> 与 __g_<graph>。Server 启用鉴权时,补充配置要求的 HTTP 凭据,例如 -u "$HG_USER:$HG_PASSWORD"。

同步 Gremlin 默认执行上限为 30000 毫秒,由 gremlin-server.yaml 的 evaluationTimeout 配置。 全图计数与按标签过滤计数可能走不同执行路径,不能用 g.V().count() 的耗时推断标签扫描耗时。 可能超过同步限制的查询应提交 Server 异步任务(见下文 8.1.3 节)。 轮询到 task_status 为终态后再读取 task_result;running 不表示计数已经完成。 Hubble 客户端传输超时与 Server 执行超时是不同限制,仅调整其中一个不会移除另一个。

Response Status
1200
Response Body
1{
2	"requestId": "<request_id>",
3	"status": {"message": "", "code": 200, "attributes": {}},
4	"result": {"data": [6], "meta": {}}
5}

顶点数取决于当前图中的数据;上面的 6 仅为示例结果。

响应体的结构与其他 Vertex 或 Edge 的 RESTful API 的结构有区别,用户可能需要自行解析。

查询边

Request Body
1{
2	"gremlin": "g.E().hasLabel('created').limit(1)",
3	"bindings": {},
4	"language": "gremlin-groovy",
5	"aliases": {
6		"g": "__g_DEFAULT-hugegraph"
7	}
8}
Response Status
1200
Response Body
 1{
 2	"requestId": "<request_id>",
 3	"status": {
 4		"message": "",
 5		"code": 200,
 6		"attributes": {}
 7	},
 8	"result": {
 9		"data": [{
10			"id": "<edge_id>",
11			"label": "created",
12			"type": "edge",
13			"outVLabel": "person",
14			"inVLabel": "software",
15			"outV": "<source_vertex_id>",
16			"inV": "<target_vertex_id>",
17			"properties": {
18				"weight": 0.4,
19				"date": "<date>"
20			}
21		}],
22		"meta": {}
23	}
24}

边 ID、端点和属性值取决于当前图中的数据。

8.1.3 向 HugeGraphServer 发送 gremlin 语句(POST),异步执行

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/gremlin

查询顶点

Request Body
1{
2	"gremlin": "g.V('1:marko')",
3	"bindings": {},
4	"language": "gremlin-groovy",
5	"aliases": {}
6}

注意:

异步请求不能自行传入 aliases 字段;Server 会自动绑定 graph(当前图对象)和 g(当前遍历源),并把 URL 中的图名作为 graph 的别名。因此脚本可以使用 graph 或 g,也可以使用当前请求路径中的图名。

Response Status
1201
Response Body
1{
2	"task_id": 1
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1(其中"1"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

查询边

Request Body
1{
2	"gremlin": "g.E().hasLabel('created').limit(1)",
3	"bindings": {},
4	"language": "gremlin-groovy",
5	"aliases": {}
6}
Response Status
1201
Response Body
1{
2	"task_id": 2
3}

注:

可以通过GET http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2(其中"2"是 task_id)来查询异步任务的执行状态,更多异步任务 RESTful API

5.1.16 - Cypher API

Cypher(图查询语言)REST 接口:通过 HTTP 接口执行 OpenCypher 声明式图查询语言。

9.1 Cypher

说明

Cypher 语法、语句示例与转译限制请查阅 图查询语言 - Cypher 及 Cypher 兼容性矩阵。

当服务端未开启鉴权时,无需携带 Authorization 请求头且凭证不参与鉴权校验; 开启鉴权后,支持 Basic(标准 RFC 4648 Base64 编码)或 Bearer Token(未携带认证信息的请求返回 401),并沿用已验证的调用者权限执行查询。 在 1.2.0 至 1.7.0 版本中,未开启鉴权时也必须携带该头。

9.1.1 向 HugeGraphServer 发送 Cypher 语句(GET),同步执行

Method & Url
1GET /graphspaces/{graphspace}/graphs/{graph}/cypher?cypher={cypher}
Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称

请求参数说明:

  • cypher: cypher 语句
使用示例
1GET
2http://localhost:8080/graphspaces/DEFAULT/graphs/hugecypher1/cypher?cypher=match(n:person) return n.name as name order by n.name limit 1
Response Status
1200
Response Body
 1{
 2    "requestId": "766b9f48-2f10-40d9-951a-3027d0748ab7",
 3    "status": {
 4        "message": "",
 5        "code": 200,
 6        "attributes": {
 7        }
 8    },
 9    "result": {
10        "data": [
11            {
12                "name": "hello"
13            }
14        ],
15        "meta": {
16        }
17    }
18}

9.1.2 向 HugeGraphServer 发送 Cypher 语句(POST 原始文本),同步执行

Method & Url
1POST /graphspaces/{graphspace}/graphs/{graph}/cypher
Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
Body

{cypher}

  • cypher: cypher 语句

注意:

请求体包含原始 Cypher 纯文本语句(也支持传入 JSON 对象体,详见 9.1.3)。但服务端接口使用 @Consumes(APPLICATION_JSON) 约束,POST 请求必须显式声明 -H "Content-Type: application/json" 请求头;若使用 text/plain 会被拒绝并返回 HTTP 415。

使用示例
1curl -X POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugecypher1/cypher \
2  -H "Authorization: Bearer $TOKEN" \
3  -H "Content-Type: application/json" \
4  -d 'match(n:person) return n.name as name order by n.name limit 1'
Response Status
1200
Response Body
 1{
 2    "requestId": "f096bee0-e249-498f-b5a3-ea684fc84f57",
 3    "status": {
 4        "message": "",
 5        "code": 200,
 6        "attributes": {
 7        }
 8    },
 9    "result": {
10        "data": [
11            {
12                "name": "hello"
13            }
14        ],
15        "meta": {
16        }
17    }
18}

9.1.3 向 HugeGraphServer 发送参数化 Cypher 语句(POST JSON,推荐),同步执行

Method & Url
1POST /graphspaces/{graphspace}/graphs/{graph}/cypher
Params

路径参数说明:

  • graphspace: 图空间名称
  • graph: 图名称
Body
1{
2    "cypher": "match(n:person) where n.name = $name return n.name as name order by n.name limit 1",
3    "parameters": {
4        "name": "hello"
5    }
6}
  • cypher: Cypher 查询语句(引用绑定参数使用 $param 形式)
  • parameters: 参数映射表(JSON 对象,顶层最多支持 16 个键;更多属性可放入嵌套 Map 中)
使用示例
1curl -X POST http://localhost:8080/graphspaces/DEFAULT/graphs/hugecypher1/cypher \
2  -H "Content-Type: application/json" \
3  -d '{"cypher":"match(n:person) where n.name = $name return n.name as name order by n.name limit 1","parameters":{"name":"hello"}}'
Response Status
1200
Response Body
 1{
 2    "requestId": "f096bee0-e249-498f-b5a3-ea684fc84f57",
 3    "status": {
 4        "message": "",
 5        "code": 200,
 6        "attributes": {
 7        }
 8    },
 9    "result": {
10        "data": [
11            {
12                "name": "hello"
13            }
14        ],
15        "meta": {
16        }
17    }
18}

9.1.4 Cypher 结构化错误响应与错误码

当 Cypher 语句解析、转译或执行失败时,HugeGraphServer 返回兼容 Gremlin 规范的响应体,HTTP 状态码保持为 200,status.code 为 400。 结构化的错误详情挂载在 status.attributes.errors 数组中。

说明

HTTP 层错误(如鉴权失败 401 或不支持的媒体类型 415)属于独立处理路径,不使用此响应封套。 客户端应检查响应体中的 status.code,而非单纯依赖 HTTP 状态码。响应中不包含顶层 errors 字段。

错误响应结构

status.attributes.errors 中的每个元素包含以下字段:

  • code: 稳定的错误代码字符串。
  • message: 来自转译器或执行引擎的详细错误信息(具体文字描述不作为强约束契约)。
  • hint: 明确的操作指引与排错建议(无具体指引时为空字符串)。
 1{
 2  "requestId": "example-request-id",
 3  "status": {
 4    "message": "Expected exactly one statement per query but got: 2",
 5    "code": 400,
 6    "attributes": {
 7      "errors": [
 8        {
 9          "code": "HugeGraph.Cypher.SyntaxError",
10          "message": "Expected exactly one statement per query but got: 2",
11          "hint": "Submit exactly one Cypher statement per request"
12        }
13      ]
14    }
15  },
16  "result": {
17    "data": null,
18    "meta": {}
19  }
20}
错误码列表
错误码识别的失败类型提示信息(Hint)
HugeGraph.Cypher.SyntaxError语法解析错误、未知函数、多条语句或未定义变量提示语法规则(如单语句、在 MATCH/WITH 声明变量)
HugeGraph.Cypher.ExecutionError顶点/边类型、属性或索引未定义;未识别错误兜底建议通过 Schema API 创建元数据;兜底为空字符串
HugeGraph.Cypher.UnsupportedFeature不支持的子句、match/create 模式或函数谓词建议查阅 Cypher 兼容性指南确认受支持语法
  • SyntaxError: 语法解析错误、不支持的内置函数、带行列位置的语义错误、单次请求包含多条语句,或未在 MATCH、UNWIND、WITH 中声明即引用的变量。
  • ExecutionError: 顶点类型、边类型、属性或索引未定义错误。该错误码同时作为未分类转译错误及底层运行时异常的统一兜底分类,并不意味着图遍历已开始执行。
  • UnsupportedFeature: 当前 Cypher 转译器不支持的子句、匹配/创建模式、属性类型或自定义谓词。

5.1.17 - Authentication API

Authentication(认证鉴权)REST 接口:管理用户、角色、权限和访问控制,实现细粒度的图数据安全机制。

版本说明:本页介绍当前 master 的接口。历史用法请切换到对应多版本页面: 1.7 版认证 API 或 1.5 版认证 API。

用户、图空间用户组、资源、关联和赋权接口使用 /graphspaces/{graphspace}/auth/...。登录、登出和 token 校验仍使用 /auth/login、/auth/logout、/auth/verify;图空间默认角色接口位于 /graphspaces/{graphspace}/role。源码保留顶层 /auth/groups,本页组接口示例使用图空间范围接口。

下文 {group_id}、{target_id}、{another_target_id}、{belong_id} 和 {access_id} 均为占位符,使用前须替换为对应响应中的 id。将 ID 放入 URL 路径时,还须按 URL 路径组件规则编码。

10.1 用户认证与权限控制

开启权限及相关配置请先参考 权限配置 文档

用户认证与权限控制概述:

HugeGraph 支持多用户认证、以及细粒度的权限访问控制,采用基于“用户 - 用户组 - 操作 - 资源”的 4 层设计,灵活控制用户角色与权限。 资源描述了图数据库中的数据,比如符合某一类条件的顶点,每一个资源包括 type、label、properties 三个要素,共有 18 种 type、 任意 label、任意 properties 的组合形成的资源,一个资源的内部条件是且关系,多个资源之间的条件是或关系。用户可以属于一个或多个用户组,每个用户组可以拥有对任意个资源的操作权限,操作类型包括:读、写、删除、执行等种类。HugeGraph 支持动态创建用户、用户组、资源, 支持动态分配或取消权限。初始化数据库时超级管理员用户被创建,后续可通过超级管理员创建各类角色用户,新创建的用户如果被分配足够权限后,可以由其创建或管理更多的用户。

举例说明:

user(name=boss) -belong-> group(name=all) -access(read)-> target(graph=graph1, resource={label: person, city: Beijing})
描述:用户’boss’拥有对’graph1’图中北京人的读权限。

接口说明:

用户认证与权限控制的核心接口包括 5 类核心接口与配套管理 API:

10.2 用户(User)API

用户接口包括:创建用户,删除用户,修改用户,和查询用户相关信息接口。

10.2.1 创建用户

Params
  • user_name: 用户名称
  • user_password: 用户密码
  • user_nickname: 用户昵称
  • user_phone: 用户手机号
  • user_email: 用户邮箱
  • user_avatar: 用户头像地址
  • user_description: 用户描述

其中 user_name 和 user_password 为必填,其余为选填。

Request Body
1{
2    "user_name": "boss",
3    "user_password": "******",
4    "user_phone": "182****9088",
5    "user_email": "123@xx.com"
6}
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/auth/users
Response Status
1201 
Response Body

返回报文中,密码为加密后的密文

 1{
 2    "user_password": "******",
 3    "user_email": "123@xx.com",
 4    "user_update": "2020-11-17 14:31:07.833",
 5    "user_name": "boss",
 6    "user_creator": "admin",
 7    "user_phone": "182****9088",
 8    "id": "boss",
 9    "user_create": "2020-11-17 14:31:07.833"
10}

10.2.2 删除用户

Params
  • id: 需要删除的用户 Id
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/auth/users/test
Response Status
1204

10.2.3 修改用户

Params
  • id: 需要修改的用户 Id
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/users/test
Request Body

修改 user_password 和 user_phone。user_name 不可修改,传了也必须与已有名称一致。

1{
2    "user_name": "test",
3    "user_password": "******",
4    "user_phone": "183****9266"
5}
Response Status
1200
Response Body

返回结果是包含修改过的内容在内的整个用户对象

1{
2    "user_password": "******",
3    "user_update": "2020-11-12 10:29:30.455",
4    "user_name": "test",
5    "user_creator": "admin",
6    "user_phone": "183****9266",
7    "id": "test",
8    "user_create": "2020-11-12 10:27:13.601"
9}

10.2.4 查询用户列表

Params
  • name: 只返回该名称的用户,传该参数时返回的是单个用户对象而不是列表,用户不存在时返回 404
  • limit: 返回结果条数的上限,默认为 100
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/users
Response Status
1200
Response Body
 1{
 2    "users": [
 3        {
 4            "user_password": "******",
 5            "user_update": "2020-11-11 11:41:12.254",
 6            "user_name": "admin",
 7            "user_creator": "system",
 8          "id": "admin",
 9            "user_create": "2020-11-11 11:41:12.254"
10        }
11    ]
12}

10.2.5 查询某个用户

Params
  • id: 需要查询的用户 Id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/users/admin
Response Status
1200
Response Body
1{
2    "user_password": "******",
3    "user_update": "2020-11-11 11:41:12.254",
4    "user_name": "admin",
5    "user_creator": "system",
6    "id": "admin",
7    "user_create": "2020-11-11 11:41:12.254"
8}

10.2.6 查询某个用户的角色

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/users/boss/role
Response Status
1200
Response Body
 1{
 2    "roles": {
 3        "hugegraph": {
 4            "READ": [
 5                {
 6                    "type": "ALL",
 7                    "label": "*",
 8                    "properties": null
 9                }
10            ]
11        }
12    }
13}

10.3 用户组(Group)API

用户组会赋予相应的资源权限,用户会被分配不同的用户组,即可拥有不同的资源权限。
用户组接口包括:创建用户组,删除用户组,修改用户组,和查询用户组相关信息接口。

GraphSpace 用户组名由服务端生成,格式为 ~hubble_role:v1: + GraphSpace 名称的 base64url 编码 + : + 32 个十六进制字符。 例如,DEFAULT 的名称和 ID 都是 ~hubble_role:v1:REVGQVVMVA:<32 hex>。请求中的 group_name 只是客户端标签;后续请求请用创建响应返回的 ID。

10.3.1 创建用户组

Params
  • group_name: 必填的客户端标签;持久化名称由服务端生成
  • group_description: 用户组描述
Request Body
1{
2    "group_name": "all",
3    "group_description": "group can do anything"
4}

group_name 为必填字段;图空间范围的用户组持久化名称由服务端生成,不能用此字段自定义。请从创建响应中复制 id,用于后续关联、授权、查询、更新或删除。

Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/auth/groups
Response Status
1201 
Response Body
1{
2    "group_creator": "admin",
3    "group_name": "<服务端生成的图空间范围名称>",
4    "group_create": "2020-11-11 15:46:08.791",
5    "group_update": "2020-11-11 15:46:08.791",
6    "id": "{group_id}",
7    "group_description": "group can do anything"
8}

10.3.2 删除用户组

Params
  • id: 需要删除的用户组 Id
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/auth/groups/{group_id}
Response Status
1204

10.3.3 修改用户组

Params
  • id: 需要修改的用户组 Id
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/groups/{group_id}
Request Body

修改 group_description。GraphSpace 形式下这里的 group_name 应当省略,或等于服务端生成的名称,传入其他值会被拒绝并提示 “The name of group can’t be updated”。

1{
2    "group_description": "grant"
3}
Response Status
1200
Response Body

返回结果是包含修改过的内容在内的整个用户组对象

1{
2    "group_creator": "admin",
3    "group_name": "<服务端生成的图空间范围名称>",
4    "group_create": "2020-11-12 09:50:58.458",
5    "group_update": "2020-11-12 09:57:58.155",
6    "id": "{group_id}",
7    "group_description": "grant"
8}

10.3.4 查询用户组列表

Params
  • limit: 返回结果条数的上限
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/groups
Response Status
1200
Response Body
 1{
 2    "groups": [
 3        {
 4            "group_creator": "admin",
 5            "group_name": "<服务端生成的图空间范围名称>",
 6            "group_create": "2020-11-11 15:46:08.791",
 7            "group_update": "2020-11-11 15:46:08.791",
 8            "id": "{group_id}",
 9            "group_description": "group can do anything"
10        }
11    ]
12}

10.3.5 查询某个用户组

Params
  • id: 需要查询的用户组 Id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/groups/{group_id}
Response Status
1200
Response Body
1{
2    "group_creator": "admin",
3    "group_name": "<服务端生成的图空间范围名称>",
4    "group_create": "2020-11-11 15:46:08.791",
5    "group_update": "2020-11-11 15:46:08.791",
6    "id": "{group_id}",
7    "group_description": "group can do anything"
8}

10.4 资源(Target)API

资源描述了图数据库中的数据,比如符合某一类条件的顶点,每一个资源包括 type、label、properties 三个要素,共有 18 种 type、 任意 label、任意 properties 的组合形成的资源,一个资源的内部条件是且关系,多个资源之间的条件是或关系。
资源接口包括:资源的创建、删除、修改和查询。

10.4.1 创建资源

Params
  • target_name: 资源名称
  • target_graph: 资源图
  • target_url: 资源地址
  • target_resources: 资源定义 (列表)

target_resources 可以包括多个 target_resource,以列表的形式存储。
每个 target_resource 包含:

  • type:可选值 VERTEX, EDGE 等,可填 ALL,则表示可以是顶点或边;
  • label:可选值,⼀个顶点或边类型的名称,可填*,则表示任意类型;
  • properties:map 类型,可包含多个属性的键值对,必须匹配所有属性值,属性值⽀持填条件范围(age: P.gte(18)),properties 如果为 null 表示任意属性均可,如果属性名和属性值均为‘*ʼ也表示任意属性均可。

如精细资源:“target_resources”: [{“type”:“VERTEX”,“label”:“person”,“properties”:{“city”:“Beijing”,“age”:“P.gte(20)”}}]**
资源定义含义:类型是’person’的顶点,且城市属性是’Beijing’,年龄属性大于等于 20。

Request Body
 1{
 2    "target_name": "all",
 3    "target_graph": "hugegraph",
 4    "target_url": "127.0.0.1:8080",
 5    "target_resources": [
 6        {
 7            "type": "ALL"
 8        }
 9    ]
10}
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/auth/targets
Response Status
1201 
Response Body
 1{
 2    "target_creator": "admin",
 3    "target_name": "all",
 4    "target_url": "127.0.0.1:8080",
 5    "target_graph": "hugegraph",
 6    "target_create": "2020-11-11 15:32:01.192",
 7    "target_resources": [
 8        {
 9            "type": "ALL",
10            "label": "*",
11            "properties": null
12        }
13    ],
14    "id": "{target_id}",
15    "target_update": "2020-11-11 15:32:01.192"
16}

10.4.2 删除资源

Params
  • id: 需要删除的资源 Id
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/auth/targets/{target_id}
Response Status
1204

10.4.3 修改资源

Params
  • id: 需要修改的资源 Id
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/targets/{target_id}
Request Body

修改资源定义中的 type

1{
2    "target_resources": [
3        {
4            "type": "NONE"
5        }
6    ]
7}
Response Status
1200
Response Body

返回结果是包含修改过的内容在内的整个用户组对象

 1{
 2    "target_creator": "admin",
 3    "target_name": "all",
 4    "target_url": "127.0.0.1:8080",
 5    "target_graph": "hugegraph",
 6    "target_create": "2020-11-12 09:34:13.848",
 7    "target_resources": [
 8        {
 9            "type": "NONE",
10            "label": "*",
11            "properties": null
12        }
13    ],
14    "id": "{target_id}",
15    "target_update": "2020-11-12 09:37:12.780"
16}

10.4.4 查询资源列表

Params
  • limit: 返回结果条数的上限
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/targets
Response Status
1200
Response Body
 1{
 2    "targets": [
 3        {
 4            "target_creator": "admin",
 5            "target_name": "all",
 6            "target_url": "127.0.0.1:8080",
 7            "target_graph": "hugegraph",
 8            "target_create": "2020-11-11 15:32:01.192",
 9            "target_resources": [
10                {
11                    "type": "ALL",
12                    "label": "*",
13                    "properties": null
14                }
15            ],
16            "id": "{target_id}",
17            "target_update": "2020-11-11 15:32:01.192"
18        },
19        {
20            "target_creator": "admin",
21            "target_name": "grant",
22            "target_url": "127.0.0.1:8080",
23            "target_graph": "hugegraph",
24            "target_create": "2020-11-11 15:43:24.841",
25            "target_resources": [
26                {
27                    "type": "GRANT",
28                    "label": "*",
29                    "properties": null
30                }
31            ],
32            "id": "{another_target_id}",
33            "target_update": "2020-11-11 15:43:24.841"
34        }
35    ]
36}

10.4.5 查询某个资源

Params
  • id: 需要查询的资源 Id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/targets/{target_id}
Response Status
1200
Response Body
 1{
 2    "target_creator": "admin",
 3    "target_name": "all",
 4    "target_url": "127.0.0.1:8080",
 5    "target_graph": "hugegraph",
 6    "target_create": "2020-11-11 15:32:01.192",
 7    "target_resources": [
 8        {
 9            "type": "ALL",
10            "label": "*",
11            "properties": null
12        }
13    ],
14    "id": "{target_id}",
15    "target_update": "2020-11-11 15:32:01.192"
16}

10.5 关联角色(Belong)API

关联用户和用户组的关系,一个用户可以关联一个或者多个用户组。用户组拥有相关资源的权限,不同用户组的资源权限可以理解为不同的角色。即给用户关联角色。
关联角色接口包括:用户关联角色的创建、删除、修改和查询。

下例沿用 10.3 的用户组 ID。实际调用时请换成自己创建响应中的 ID。后续操作使用 Belong 创建响应里的 id,并将 URL 路径中的 > 编码为 %3E。

10.5.1 创建用户的关联角色

Params
  • user: 用户 Id
  • group: 用户组 Id
  • belong_description: 描述
Request Body
1{
2  "user": "boss",
3    "group": "{group_id}"
4}
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/auth/belongs
Response Status
1201 
Response Body
1{
2    "belong_create": "2020-11-11 16:19:35.422",
3    "belong_creator": "admin",
4    "belong_update": "2020-11-11 16:19:35.422",
5  "id": "{belong_id}",
6  "user": "boss",
7    "group": "{group_id}"
8}

10.5.2 删除关联角色

Params
  • id: 需要删除的关联角色 Id
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/auth/belongs/{belong_id}
Response Status
1204

10.5.3 修改关联角色

关联角色只能修改描述,不能修改 user 和 group 属性,如果需要修改关联角色,需要删除原来关联关系,新增关联角色。

Params
  • id: 需要修改的关联角色 Id
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/belongs/{belong_id}
Request Body

修改 belong_description

1{
2    "belong_description": "update test"
3}
Response Status
1200
Response Body

返回结果是包含修改过的内容在内的整个用户组对象

1{
2    "belong_description": "update test",
3    "belong_create": "2020-11-12 10:40:21.720",
4    "belong_creator": "admin",
5    "belong_update": "2020-11-12 10:42:47.265",
6  "id": "{belong_id}",
7  "user": "boss",
8    "group": "{group_id}"
9}

10.5.4 查询关联角色列表

Params
  • user: 只返回该用户的关联关系
  • group: 只返回该角色的关联关系
  • limit: 返回结果条数的上限,默认为 100

user 和 group 不能同时使用。

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/belongs
Response Status
1200
Response Body
 1{
 2    "belongs": [
 3        {
 4            "belong_create": "2020-11-11 16:19:35.422",
 5            "belong_creator": "admin",
 6            "belong_update": "2020-11-11 16:19:35.422",
 7          "id": "{belong_id}",
 8          "user": "boss",
 9            "group": "{group_id}"
10        }
11    ]
12}

10.5.5 查看某个关联角色

Params
  • id: 需要查询的关联角色 Id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/belongs/{belong_id}
Response Status
1200
Response Body
1{
2    "belong_create": "2020-11-11 16:19:35.422",
3    "belong_creator": "admin",
4    "belong_update": "2020-11-11 16:19:35.422",
5  "id": "{belong_id}",
6  "user": "boss",
7    "group": "{group_id}"
8}

10.6 赋权(Access)API

给用户组赋予资源的权限,主要包含:读操作 (READ)、写操作 (WRITE)、删除操作 (DELETE)、执行操作 (EXECUTE) 等。
赋权接口包括:赋权的创建、删除、修改和查询。

下例使用 10.3 和 10.4 返回的用户组 ID、资源 ID。实际调用时请换成自己的响应值。后续操作使用 Access 创建响应里的 id,并将 URL 路径中的 > 编码为 %3E。

10.6.1 创建赋权 (用户组赋予资源的权限)

Params
  • group: 用户组 Id
  • target: 资源 Id
  • access_permission: 权限许可
  • access_description: 赋权描述

access_permission:

  • READ:读操作,所有的查询,包括查询 Schema、查顶点/边,查询顶点和边的数量 VERTEX_AGGR/EDGE_AGGR,也包括读图的状态 STATUS、变量 VAR、任务 TASK 等;
  • WRITE:写操作,所有的创建、更新操作,包括给 Schema 增加 property key,给顶点增加或更新属性等;
  • DELETE:删除操作,包括删除元数据、删除顶点/边;
  • EXECUTE:执⾏操作,包括执⾏ Gremlin 语句、执⾏ Task、执⾏ metadata 函数;
Request Body
1{
2    "group": "{group_id}",
3    "target": "{target_id}",
4    "access_permission": "READ"
5}
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/auth/accesses
Response Status
1201 
Response Body
1{
2    "access_permission": "READ",
3    "access_create": "2020-11-11 15:54:54.008",
4    "id": "{access_id}",
5    "access_update": "2020-11-11 15:54:54.008",
6    "access_creator": "admin",
7    "group": "{group_id}",
8    "target": "{target_id}"
9}

10.6.2 删除赋权

Params
  • id: 需要删除的赋权 Id
Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/auth/accesses/{access_id}
Response Status
1204

10.6.3 修改赋权

赋权只能修改描述,不能修改用户组、资源和权限许可,如果需要修改赋权的关系,可以删除原来的赋权关系,新增赋权。

Params
  • id: 需要修改的赋权 Id
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/accesses/{access_id}
Request Body

修改 access_description

1{
2    "access_description": "test"
3}
Response Status
1200
Response Body

返回结果是包含修改过的内容在内的整个用户组对象

 1{
 2    "access_description": "test",
 3    "access_permission": "READ",
 4    "access_create": "2020-11-12 10:12:03.074",
 5    "id": "{access_id}",
 6    "access_update": "2020-11-12 10:16:18.637",
 7    "access_creator": "admin",
 8    "group": "{group_id}",
 9    "target": "{target_id}"
10}

10.6.4 查询赋权列表

Params
  • group: 只返回该角色的赋权记录
  • target: 只返回该资源上的赋权记录
  • limit: 返回结果条数的上限,默认为 100

group 和 target 不能同时使用。

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/accesses
Response Status
1200
Response Body
 1{
 2    "accesses": [
 3        {
 4            "access_permission": "READ",
 5            "access_create": "2020-11-11 15:54:54.008",
 6            "id": "{access_id}",
 7            "access_update": "2020-11-11 15:54:54.008",
 8            "access_creator": "admin",
 9            "group": "{group_id}",
10            "target": "{target_id}"
11        }
12    ]
13}

10.6.5 查询某个赋权

Params
  • id: 需要查询的赋权 Id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/accesses/{access_id}
Response Status
1200
Response Body
1{
2    "access_permission": "READ",
3    "access_create": "2020-11-11 15:54:54.008",
4    "id": "{access_id}",
5    "access_update": "2020-11-11 15:54:54.008",
6    "access_creator": "admin",
7    "group": "{group_id}",
8    "target": "{target_id}"
9}

10.7 图空间管理员(Manager)API

重要提示:在使用以下 API 之前,需要先创建图空间(graphspace)。请参考 Graphspace API 创建名为 gs1 的图空间。文档中的示例均假设已存在名为 gs1 的图空间

重要提示:管理员相关接口只在 PD 模式下可用,单机模式下会返回 400 和 GraphSpace management is not supported in standalone mode 错误信息。

  1. 图空间管理员 API 用于在 graphspace 维度给用户授予/回收管理员角色,并查询当前用户或其他用户在该 graphspace 下的角色信息。角色类型可取 SPACE、SPACE_MEMBER、ADMIN 。

10.7.1 检查当前登录用户是否拥有某个角色

Params
  • type: 需要校验的角色类型,必填,取值为 SPACE、SPACE_MEMBER、ADMIN 之一
Method & Url
1GET http://localhost:8080/graphspaces/gs1/auth/managers/check?type=SPACE_MEMBER
Response Status
1200
Response Body
1{
2  "check": true
3}

10.7.2 查询图空间管理员列表

Params
  • type: 角色类型,必填,取值为 SPACE、SPACE_MEMBER、ADMIN 之一。SPACE 返回图空间管理员,SPACE_MEMBER 返回图空间成员,ADMIN 返回整个集群的管理员
Method & Url
1GET http://localhost:8080/graphspaces/gs1/auth/managers?type=SPACE
Response Status
1200
Response Body
1{
2  "admins": [
3    "admin"
4  ]
5}

10.7.3 授权/创建图空间管理员

  • 下面在 gs1 下,将用户 boss 授权为 SPACE_MEMBER 角色
Params
  • user: 用户或角色名称,必填
  • type: 角色类型,必填,取值为 SPACE、SPACE_MEMBER、ADMIN 之一

把已经是图空间成员的用户授权为 SPACE 时会先回收其成员角色,反之同理。只有管理员可以授予 ADMIN。

Request Body
1{
2  "user": "boss",
3  "type": "SPACE_MEMBER"
4}
Method & Url
1POST http://localhost:8080/graphspaces/gs1/auth/managers
Response Status
1201
Response Body
1{
2  "user": "boss",
3  "type": "SPACE_MEMBER",
4  "graphspace": "gs1"
5}

10.7.4 取消图空间管理员权限

  • 下面在 gs1 下,将用户 boss 的 SPACE_MEMBER 角色删除
Params
  • user: 需要删除的用户名称,内置的 admin 用户不能从 ADMIN 中移除
  • type: 需要删除的角色类型,取值为 SPACE、SPACE_MEMBER、ADMIN 之一
Method & Url
1DELETE http://localhost:8080/graphspaces/gs1/auth/managers?user=boss&type=SPACE_MEMBER
Response Status
1204

10.7.5 查询指定用户在图空间中的角色

Params
  • user: 用户名称
Method & Url
1GET http://localhost:8080/graphspaces/gs1/auth/managers/role?user=boss
Response Status
1200
Response Body

返回的角色取自 ADMIN、SPACE、SPACE_MEMBER;用户在该图空间下不具备其中任何角色时返回 NONE。

1{
2  "user": "boss",
3  "graphspace": "gs1",
4  "roles": [
5    "SPACE_MEMBER"
6  ]
7}

10.7.6 检查当前登录用户是否拥有某个默认角色

默认角色是图空间的内置角色,参见 Graphspace API。role 的合法取值为 space、space_member、analyst 和 observer;graph 只在 role=observer 时生效。

Params
  • role: 默认角色名称,必填
  • graph: 图名称,选填,只在 role=observer 时使用
Method & Url
1GET http://localhost:8080/graphspaces/gs1/auth/managers/default?role=analyst
Response Status
1200
Response Body
1{
2  "check": true
3}

10.8 登录(Login)API

除了 HTTP Basic 认证之外,服务还可以签发 JWT token,之后通过 Authorization: Bearer <token> 请求头携带。登录相关接口不带图空间前缀。

token 使用 auth.token_secret 配置项签名,有效期为 auth.token_expire 秒(默认 86400)。该密钥的默认值在启动时随机生成,因此当 token 需要在重启后继续有效、或者需要被多个服务节点接受时,必须显式配置该项。

10.8.1 登录并获取 token

Params
  • user_name: 用户名称,必填
  • user_password: 用户密码,必填
  • token_expire: token 有效期(秒),选填
Request Body
1{
2    "user_name": "test",
3    "user_password": "******"
4}
Method & Url
1POST http://localhost:8080/auth/login
Response Status
1200

用户名或密码错误时返回 401。

Response Body
1{
2    "token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX25hbWUiOiJ0ZXN0IiwidXNlcl9pZCI6InRlc3QiLCJleHAiOjE3MTIxMjM0NTZ9.PBs0iBt0PtqvLDpJvKrPHkyIzT1TICz9zJmMy8FvXVo"
3}

10.8.2 登出并使 token 失效

需要失效的 token 从请求头中获取,无需请求体。

Params

请求头说明:

  • Authorization: Bearer <token>,必填。只接受 Bearer 方式,其他方式返回 400。
Method & Url
1DELETE http://localhost:8080/auth/logout
Response Status
1204

token 非法或已过期时返回 401。

10.8.3 校验 token

Params

请求头说明:

  • Authorization: Bearer <token>,必填
Method & Url
1GET http://localhost:8080/auth/verify
Response Status
1200

token 非法或已过期时返回 401。

Response Body
1{
2    "user_name": "test",
3    "user_id": "test"
4}

10.9 项目(Project)API

项目把一组图和一个管理员角色、一个操作员角色绑定在一起,从而可以一次性对这组图授权。创建项目时会同时生成它的 project_target、project_admin_group 和 project_op_group,这些字段会在响应中返回,但不能由客户端设置。

10.9.1 创建项目

Params
  • project_name: 项目名称,必填
  • project_description: 项目描述,选填

创建时不能传 project_graphs,请使用下面的 add_graph 操作。

Request Body
1{
2    "project_name": "test_project",
3    "project_description": "this is a good project"
4}
Method & Url
1POST http://localhost:8080/graphspaces/DEFAULT/auth/projects
Response Status
1201
Response Body
 1{
 2    "project_name": "test_project",
 3    "project_description": "this is a good project",
 4    "project_target": "project_test_project",
 5    "project_admin_group": "project_test_project_admin",
 6    "project_op_group": "project_test_project_op",
 7    "project_create": "2024-01-10 09:30:00.000",
 8    "project_update": "2024-01-10 09:30:00.000",
 9    "project_creator": "admin",
10    "id": "test_project"
11}

10.9.2 向项目中添加或移除图

Params
  • id: 项目 Id
  • action: add_graph 表示添加,remove_graph 表示移除
Request Body
1{
2    "project_graphs": [
3        "hugegraph"
4    ]
5}
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/projects/test_project?action=add_graph
Response Status
1200
Response Body

返回整个项目对象,其中包含更新后的图列表。

10.9.3 修改项目描述

Params
  • id: 项目 Id

不传 action 时表示修改描述,此时请求体中不能带 project_graphs。

Request Body
1{
2    "project_description": "update desc"
3}
Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/auth/projects/test_project
Response Status
1200

10.9.4 查询项目列表

Params
  • limit: 返回结果条数的上限,默认为 100
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/projects
Response Status
1200
Response Body
 1{
 2    "projects": [
 3        {
 4            "project_name": "test_project",
 5            "project_description": "this is a good project",
 6            "project_target": "project_test_project",
 7            "project_admin_group": "project_test_project_admin",
 8            "project_op_group": "project_test_project_op",
 9            "project_create": "2024-01-10 09:30:00.000",
10            "project_update": "2024-01-10 09:30:00.000",
11            "project_creator": "admin",
12            "id": "test_project"
13        }
14    ]
15}

10.9.5 查询某个项目

Params
  • id: 项目 Id
Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/auth/projects/test_project
Response Status
1200

10.9.6 删除项目

Params
  • id: 项目 Id

删除前需要先把项目中的图全部移除。

Method & Url
1DELETE http://localhost:8080/graphspaces/DEFAULT/auth/projects/test_project
Response Status
1204

5.1.18 - Metrics API

Metrics(监控指标)REST 接口:获取系统运行时的性能指标、统计信息和健康状态数据。

HugeGraph 提供了获取监控信息的 Metrics 接口,比如各个 Gremlin 执行时间的统计、缓存的占用大小等。Metrics 接口包括如下几类:基础指标、统计指标、系统指标、后端存储指标。

1. 基础指标

1.1 获取所有基础指标

Params
  • type:如果传值为json,则以 json 格式返回,否则以 Promethaus 格式返回。
1.1.1 Method & Url
1http://localhost:8080/metrics/?type=json
Response Status
1200
Response Body
  1{
  2  "gauges": {
  3    "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.capacity": {
  4      "value": 1000000
  5    },
  6    "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.expire": {
  7      "value": 600000
  8    },
  9    "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.hits": {
 10      "value": 0
 11    },
 12    "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.miss": {
 13      "value": 0
 14    },
 15    "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.size": {
 16      "value": 0
 17    },
 18    "org.apache.hugegraph.backend.cache.Cache.instances": {
 19      "value": 7
 20    },
 21    "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.capacity": {
 22      "value": 10000
 23    },
 24    "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.expire": {
 25      "value": 0
 26    },
 27    "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.hits": {
 28      "value": 0
 29    },
 30    "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.miss": {
 31      "value": 0
 32    },
 33    "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.size": {
 34      "value": 17
 35    },
 36    "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.capacity": {
 37      "value": 10000
 38    },
 39    "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.expire": {
 40      "value": 0
 41    },
 42    "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.hits": {
 43      "value": 0
 44    },
 45    "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.miss": {
 46      "value": 0
 47    },
 48    "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.size": {
 49      "value": 17
 50    },
 51    "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.capacity": {
 52      "value": 10240
 53    },
 54    "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.expire": {
 55      "value": 600000
 56    },
 57    "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.hits": {
 58      "value": 0
 59    },
 60    "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.miss": {
 61      "value": 0
 62    },
 63    "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.size": {
 64      "value": 0
 65    },
 66    "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.capacity": {
 67      "value": 10240
 68    },
 69    "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.expire": {
 70      "value": 600000
 71    },
 72    "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.hits": {
 73      "value": 0
 74    },
 75    "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.miss": {
 76      "value": 0
 77    },
 78    "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.size": {
 79      "value": 0
 80    },
 81    "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.capacity": {
 82      "value": 10240
 83    },
 84    "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.expire": {
 85      "value": 600000
 86    },
 87    "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.hits": {
 88      "value": 0
 89    },
 90    "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.miss": {
 91      "value": 0
 92    },
 93    "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.size": {
 94      "value": 0
 95    },
 96    "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.capacity": {
 97      "value": 10000000
 98    },
 99    "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.expire": {
100      "value": 600000
101    },
102    "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.hits": {
103      "value": 0
104    },
105    "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.miss": {
106      "value": 0
107    },
108    "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.size": {
109      "value": 0
110    },
111    "org.apache.hugegraph.server.RestServer.max-write-threads": {
112      "value": 0
113    },
114    "org.apache.hugegraph.task.TaskManager.pending-tasks": {
115      "value": 0
116    },
117    "org.apache.hugegraph.task.TaskManager.workers": {
118      "value": 4
119    },
120    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.average-load-penalty": {
121      "value": 922769200
122    },
123    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.estimated-size": {
124      "value": 2
125    },
126    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.eviction-count": {
127      "value": 0
128    },
129    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.eviction-weight": {
130      "value": 0
131    },
132    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.hit-count": {
133      "value": 0
134    },
135    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.hit-rate": {
136      "value": 0
137    },
138    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-count": {
139      "value": 2
140    },
141    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-failure-count": {
142      "value": 0
143    },
144    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-failure-rate": {
145      "value": 0
146    },
147    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-success-count": {
148      "value": 2
149    },
150    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.long-run-compilation-count": {
151      "value": 0
152    },
153    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.miss-count": {
154      "value": 2
155    },
156    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.miss-rate": {
157      "value": 1
158    },
159    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.request-count": {
160      "value": 2
161    },
162    "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.total-load-time": {
163      "value": 1845538400
164    },
165    "org.apache.tinkerpop.gremlin.server.GremlinServer.sessions": {
166      "value": 0
167    }
168  },
169  "counters": {
170    "favicon.ico/GET/FAILED_COUNTER": {
171      "count": 1
172    },
173    "favicon.ico/GET/TOTAL_COUNTER": {
174      "count": 1
175    },
176    "metrics/POST/FAILED_COUNTER": {
177      "count": 1
178    },
179    "metrics/POST/TOTAL_COUNTER": {
180      "count": 1
181    },
182    "metrics/backend/GET/SUCCESS_COUNTER": {
183      "count": 2
184    },
185    "metrics/backend/GET/TOTAL_COUNTER": {
186      "count": 2
187    },
188    "metrics/gauges/GET/SUCCESS_COUNTER": {
189      "count": 1
190    },
191    "metrics/gauges/GET/TOTAL_COUNTER": {
192      "count": 1
193    },
194    "metrics/system/GET/SUCCESS_COUNTER": {
195      "count": 2
196    },
197    "metrics/system/GET/TOTAL_COUNTER": {
198      "count": 2
199    },
200    "system/GET/FAILED_COUNTER": {
201      "count": 1
202    },
203    "system/GET/TOTAL_COUNTER": {
204      "count": 1
205    }
206  },
207  "histograms": {
208    "favicon.ico/GET/RESPONSE_TIME_HISTOGRAM": {
209      "count": 1,
210      "min": 1,
211      "mean": 1,
212      "max": 1,
213      "stddev": 0,
214      "p50": 1,
215      "p75": 1,
216      "p95": 1,
217      "p98": 1,
218      "p99": 1,
219      "p999": 1
220    },
221    "metrics/POST/RESPONSE_TIME_HISTOGRAM": {
222      "count": 1,
223      "min": 21,
224      "mean": 21,
225      "max": 21,
226      "stddev": 0,
227      "p50": 21,
228      "p75": 21,
229      "p95": 21,
230      "p98": 21,
231      "p99": 21,
232      "p999": 21
233    },
234    "metrics/backend/GET/RESPONSE_TIME_HISTOGRAM": {
235      "count": 2,
236      "min": 6,
237      "mean": 12.6852124529148,
238      "max": 20,
239      "stddev": 6.992918475157571,
240      "p50": 6,
241      "p75": 20,
242      "p95": 20,
243      "p98": 20,
244      "p99": 20,
245      "p999": 20
246    },
247    "metrics/gauges/GET/RESPONSE_TIME_HISTOGRAM": {
248      "count": 1,
249      "min": 7,
250      "mean": 7,
251      "max": 7,
252      "stddev": 0,
253      "p50": 7,
254      "p75": 7,
255      "p95": 7,
256      "p98": 7,
257      "p99": 7,
258      "p999": 7
259    },
260    "metrics/system/GET/RESPONSE_TIME_HISTOGRAM": {
261      "count": 2,
262      "min": 0,
263      "mean": 8.942674506664073,
264      "max": 40,
265      "stddev": 16.665399873223066,
266      "p50": 0,
267      "p75": 0,
268      "p95": 40,
269      "p98": 40,
270      "p99": 40,
271      "p999": 40
272    },
273    "system/GET/RESPONSE_TIME_HISTOGRAM": {
274      "count": 1,
275      "min": 2,
276      "mean": 2,
277      "max": 2,
278      "stddev": 0,
279      "p50": 2,
280      "p75": 2,
281      "p95": 2,
282      "p98": 2,
283      "p99": 2,
284      "p999": 2
285    }
286  },
287  "meters": {
288    "org.apache.hugegraph.api.API.commit-succeed": {
289      "count": 0,
290      "mean_rate": 0,
291      "m15_rate": 0,
292      "m5_rate": 0,
293      "m1_rate": 0,
294      "rate_unit": "events/second"
295    },
296    "org.apache.hugegraph.api.API.expected-error": {
297      "count": 0,
298      "mean_rate": 0,
299      "m15_rate": 0,
300      "m5_rate": 0,
301      "m1_rate": 0,
302      "rate_unit": "events/second"
303    },
304    "org.apache.hugegraph.api.API.illegal-arg": {
305      "count": 0,
306      "mean_rate": 0,
307      "m15_rate": 0,
308      "m5_rate": 0,
309      "m1_rate": 0,
310      "rate_unit": "events/second"
311    },
312    "org.apache.hugegraph.api.API.unknown-error": {
313      "count": 0,
314      "mean_rate": 0,
315      "m15_rate": 0,
316      "m5_rate": 0,
317      "m1_rate": 0,
318      "rate_unit": "events/second"
319    },
320    "org.apache.tinkerpop.gremlin.server.GremlinServer.errors": {
321      "count": 0,
322      "mean_rate": 0,
323      "m15_rate": 0,
324      "m5_rate": 0,
325      "m1_rate": 0,
326      "rate_unit": "events/second"
327    }
328  },
329  "timers": {
330    "org.apache.hugegraph.api.auth.AccessAPI.create": {
331      "count": 0,
332      "min": 0,
333      "mean": 0,
334      "max": 0,
335      "stddev": 0,
336      "p50": 0,
337      "p75": 0,
338      "p95": 0,
339      "p98": 0,
340      "p99": 0,
341      "p999": 0,
342      "duration_unit": "milliseconds",
343      "mean_rate": 0,
344      "m15_rate": 0,
345      "m5_rate": 0,
346      "m1_rate": 0,
347      "rate_unit": "calls/second"
348    },
349    "org.apache.hugegraph.api.auth.AccessAPI.delete": {
350      "count": 0,
351      "min": 0,
352      "mean": 0,
353      "max": 0,
354      "stddev": 0,
355      "p50": 0,
356      "p75": 0,
357      "p95": 0,
358      "p98": 0,
359      "p99": 0,
360      "p999": 0,
361      "duration_unit": "milliseconds",
362      "mean_rate": 0,
363      "m15_rate": 0,
364      "m5_rate": 0,
365      "m1_rate": 0,
366      "rate_unit": "calls/second"
367    },
368    "org.apache.hugegraph.api.auth.AccessAPI.get": {
369      "count": 0,
370      "min": 0,
371      "mean": 0,
372      "max": 0,
373      "stddev": 0,
374      "p50": 0,
375      "p75": 0,
376      "p95": 0,
377      "p98": 0,
378      "p99": 0,
379      "p999": 0,
380      "duration_unit": "milliseconds",
381      "mean_rate": 0,
382      "m15_rate": 0,
383      "m5_rate": 0,
384      "m1_rate": 0,
385      "rate_unit": "calls/second"
386    },
387    "org.apache.hugegraph.api.auth.AccessAPI.list": {
388      "count": 0,
389      "min": 0,
390      "mean": 0,
391      "max": 0,
392      "stddev": 0,
393      "p50": 0,
394      "p75": 0,
395      "p95": 0,
396      "p98": 0,
397      "p99": 0,
398      "p999": 0,
399      "duration_unit": "milliseconds",
400      "mean_rate": 0,
401      "m15_rate": 0,
402      "m5_rate": 0,
403      "m1_rate": 0,
404      "rate_unit": "calls/second"
405    },
406    ...
407  }
408}
1.1.2 Method & Url
1http://localhost:8080/metrics/
Response Status
1200
Response Body
 1# HELP hugegraph_info
 2# TYPE hugegraph_info untyped
 3hugegraph_info{version="0.69",
 4} 1.0
 5# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_capacity
 6# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_capacity gauge
 7org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_capacity 1000000
 8# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_expire
 9# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_expire gauge
10org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_expire 600000
11# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_hits
12# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_hits gauge
13org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_hits 0
14# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_miss
15# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_miss gauge
16org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_miss 0
17# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_size
18# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_size gauge
19org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_size 0
20# HELP org_apache_hugegraph_backend_cache_Cache_instances
21# TYPE org_apache_hugegraph_backend_cache_Cache_instances gauge
22org_apache_hugegraph_backend_cache_Cache_instances 7
23# HELP org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_capacity
24# TYPE org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_capacity gauge
25org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_capacity 10000
26# HELP org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_expire
27# TYPE org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_expire gauge
28org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_expire 0
29# HELP org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_hits
30# TYPE org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_hits gauge
31org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_hits 0
32# HELP org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_miss
33# TYPE org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_miss gauge
34org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_miss 0
35# HELP org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_size
36# TYPE org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_size gauge
37org_apache_hugegraph_backend_cache_Cache_schema_id_hugegraph_size 17
38# HELP org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_capacity
39# TYPE org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_capacity gauge
40org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_capacity 10000
41# HELP org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_expire
42# TYPE org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_expire gauge
43org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_expire 0
44# HELP org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_hits
45# TYPE org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_hits gauge
46org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_hits 0
47# HELP org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_miss
48# TYPE org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_miss gauge
49org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_miss 0
50# HELP org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_size
51# TYPE org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_size gauge
52org_apache_hugegraph_backend_cache_Cache_schema_name_hugegraph_size 17
53...

1.2 获取 Gauges 指标

Method & Url
1http://localhost:8080/metrics/gauges
Response Status
1200
Response Body
  1{
  2  "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.capacity": {
  3    "value": 1000000
  4  },
  5  "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.expire": {
  6    "value": 600000
  7  },
  8  "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.hits": {
  9    "value": 0
 10  },
 11  "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.miss": {
 12    "value": 0
 13  },
 14  "org.apache.hugegraph.backend.cache.Cache.edge-hugegraph.size": {
 15    "value": 0
 16  },
 17  "org.apache.hugegraph.backend.cache.Cache.instances": {
 18    "value": 7
 19  },
 20  "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.capacity": {
 21    "value": 10000
 22  },
 23  "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.expire": {
 24    "value": 0
 25  },
 26  "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.hits": {
 27    "value": 0
 28  },
 29  "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.miss": {
 30    "value": 0
 31  },
 32  "org.apache.hugegraph.backend.cache.Cache.schema-id-hugegraph.size": {
 33    "value": 17
 34  },
 35  "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.capacity": {
 36    "value": 10000
 37  },
 38  "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.expire": {
 39    "value": 0
 40  },
 41  "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.hits": {
 42    "value": 0
 43  },
 44  "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.miss": {
 45    "value": 0
 46  },
 47  "org.apache.hugegraph.backend.cache.Cache.schema-name-hugegraph.size": {
 48    "value": 17
 49  },
 50  "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.capacity": {
 51    "value": 10240
 52  },
 53  "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.expire": {
 54    "value": 600000
 55  },
 56  "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.hits": {
 57    "value": 0
 58  },
 59  "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.miss": {
 60    "value": 0
 61  },
 62  "org.apache.hugegraph.backend.cache.Cache.token-hugegraph.size": {
 63    "value": 0
 64  },
 65  "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.capacity": {
 66    "value": 10240
 67  },
 68  "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.expire": {
 69    "value": 600000
 70  },
 71  "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.hits": {
 72    "value": 0
 73  },
 74  "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.miss": {
 75    "value": 0
 76  },
 77  "org.apache.hugegraph.backend.cache.Cache.users-hugegraph.size": {
 78    "value": 0
 79  },
 80  "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.capacity": {
 81    "value": 10240
 82  },
 83  "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.expire": {
 84    "value": 600000
 85  },
 86  "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.hits": {
 87    "value": 0
 88  },
 89  "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.miss": {
 90    "value": 0
 91  },
 92  "org.apache.hugegraph.backend.cache.Cache.users_pwd-hugegraph.size": {
 93    "value": 0
 94  },
 95  "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.capacity": {
 96    "value": 10000000
 97  },
 98  "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.expire": {
 99    "value": 600000
100  },
101  "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.hits": {
102    "value": 0
103  },
104  "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.miss": {
105    "value": 0
106  },
107  "org.apache.hugegraph.backend.cache.Cache.vertex-hugegraph.size": {
108    "value": 0
109  },
110  "org.apache.hugegraph.server.RestServer.max-write-threads": {
111    "value": 0
112  },
113  "org.apache.hugegraph.task.TaskManager.pending-tasks": {
114    "value": 0
115  },
116  "org.apache.hugegraph.task.TaskManager.workers": {
117    "value": 4
118  },
119  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.average-load-penalty": {
120    "value": 9.227692E8
121  },
122  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.estimated-size": {
123    "value": 2
124  },
125  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.eviction-count": {
126    "value": 0
127  },
128  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.eviction-weight": {
129    "value": 0
130  },
131  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.hit-count": {
132    "value": 0
133  },
134  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.hit-rate": {
135    "value": 0.0
136  },
137  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-count": {
138    "value": 2
139  },
140  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-failure-count": {
141    "value": 0
142  },
143  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-failure-rate": {
144    "value": 0.0
145  },
146  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.load-success-count": {
147    "value": 2
148  },
149  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.long-run-compilation-count": {
150    "value": 0
151  },
152  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.miss-count": {
153    "value": 2
154  },
155  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.miss-rate": {
156    "value": 1.0
157  },
158  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.request-count": {
159    "value": 2
160  },
161  "org.apache.tinkerpop.gremlin.server.GremlinServer.gremlin-groovy.sessionless.class-cache.total-load-time": {
162    "value": 1845538400
163  },
164  "org.apache.tinkerpop.gremlin.server.GremlinServer.sessions": {
165    "value": 0
166  }
167}

1.3 获取 Counters 指标

Method & Url
1GET http://localhost:8080/metrics/counters
Response Status
1200
Response Body
 1{
 2  "favicon.ico/GET/FAILED_COUNTER": {
 3    "count": 1
 4  },
 5  "favicon.ico/GET/TOTAL_COUNTER": {
 6    "count": 1
 7  },
 8  "metrics//GET/SUCCESS_COUNTER": {
 9    "count": 2
10  },
11  "metrics//GET/TOTAL_COUNTER": {
12    "count": 2
13  },
14  "metrics/POST/FAILED_COUNTER": {
15    "count": 1
16  },
17  "metrics/POST/TOTAL_COUNTER": {
18    "count": 1
19  },
20  "metrics/backend/GET/SUCCESS_COUNTER": {
21    "count": 2
22  },
23  "metrics/backend/GET/TOTAL_COUNTER": {
24    "count": 2
25  },
26  "metrics/gauges/GET/SUCCESS_COUNTER": {
27    "count": 1
28  },
29  "metrics/gauges/GET/TOTAL_COUNTER": {
30    "count": 1
31  },
32  "metrics/statistics/GET/SUCCESS_COUNTER": {
33    "count": 2
34  },
35  "metrics/statistics/GET/TOTAL_COUNTER": {
36    "count": 2
37  },
38  "metrics/system/GET/SUCCESS_COUNTER": {
39    "count": 2
40  },
41  "metrics/system/GET/TOTAL_COUNTER": {
42    "count": 2
43  },
44  "metrics/timers/GET/SUCCESS_COUNTER": {
45    "count": 1
46  },
47  "metrics/timers/GET/TOTAL_COUNTER": {
48    "count": 1
49  },
50  "system/GET/FAILED_COUNTER": {
51    "count": 1
52  },
53  "system/GET/TOTAL_COUNTER": {
54    "count": 1
55  }
56}

1.4 获取 histograms 指标

Method & Url
1GET http://localhost:8080/metrics/gauges
Response Status
1200
Response Body
  1{
  2  "favicon.ico/GET/RESPONSE_TIME_HISTOGRAM": {
  3    "count": 1,
  4    "min": 1,
  5    "mean": 1.0,
  6    "max": 1,
  7    "stddev": 0.0,
  8    "p50": 1.0,
  9    "p75": 1.0,
 10    "p95": 1.0,
 11    "p98": 1.0,
 12    "p99": 1.0,
 13    "p999": 1.0
 14  },
 15  "metrics//GET/RESPONSE_TIME_HISTOGRAM": {
 16    "count": 2,
 17    "min": 10,
 18    "mean": 10.0,
 19    "max": 10,
 20    "stddev": 0.0,
 21    "p50": 10.0,
 22    "p75": 10.0,
 23    "p95": 10.0,
 24    "p98": 10.0,
 25    "p99": 10.0,
 26    "p999": 10.0
 27  },
 28  "metrics/POST/RESPONSE_TIME_HISTOGRAM": {
 29    "count": 1,
 30    "min": 21,
 31    "mean": 21.0,
 32    "max": 21,
 33    "stddev": 0.0,
 34    "p50": 21.0,
 35    "p75": 21.0,
 36    "p95": 21.0,
 37    "p98": 21.0,
 38    "p99": 21.0,
 39    "p999": 21.0
 40  },
 41  "metrics/backend/GET/RESPONSE_TIME_HISTOGRAM": {
 42    "count": 2,
 43    "min": 6,
 44    "mean": 12.6852124529148,
 45    "max": 20,
 46    "stddev": 6.992918475157571,
 47    "p50": 6.0,
 48    "p75": 20.0,
 49    "p95": 20.0,
 50    "p98": 20.0,
 51    "p99": 20.0,
 52    "p999": 20.0
 53  },
 54  "metrics/gauges/GET/RESPONSE_TIME_HISTOGRAM": {
 55    "count": 1,
 56    "min": 7,
 57    "mean": 7.0,
 58    "max": 7,
 59    "stddev": 0.0,
 60    "p50": 7.0,
 61    "p75": 7.0,
 62    "p95": 7.0,
 63    "p98": 7.0,
 64    "p99": 7.0,
 65    "p999": 7.0
 66  },
 67  "metrics/statistics/GET/RESPONSE_TIME_HISTOGRAM": {
 68    "count": 2,
 69    "min": 1,
 70    "mean": 1.4551211076264199,
 71    "max": 2,
 72    "stddev": 0.49798181193626,
 73    "p50": 1.0,
 74    "p75": 2.0,
 75    "p95": 2.0,
 76    "p98": 2.0,
 77    "p99": 2.0,
 78    "p999": 2.0
 79  },
 80  "metrics/system/GET/RESPONSE_TIME_HISTOGRAM": {
 81    "count": 2,
 82    "min": 0,
 83    "mean": 8.942674506664073,
 84    "max": 40,
 85    "stddev": 16.665399873223066,
 86    "p50": 0.0,
 87    "p75": 0.0,
 88    "p95": 40.0,
 89    "p98": 40.0,
 90    "p99": 40.0,
 91    "p999": 40.0
 92  },
 93  "metrics/timers/GET/RESPONSE_TIME_HISTOGRAM": {
 94    "count": 1,
 95    "min": 3,
 96    "mean": 3.0,
 97    "max": 3,
 98    "stddev": 0.0,
 99    "p50": 3.0,
100    "p75": 3.0,
101    "p95": 3.0,
102    "p98": 3.0,
103    "p99": 3.0,
104    "p999": 3.0
105  },
106  "system/GET/RESPONSE_TIME_HISTOGRAM": {
107    "count": 1,
108    "min": 2,
109    "mean": 2.0,
110    "max": 2,
111    "stddev": 0.0,
112    "p50": 2.0,
113    "p75": 2.0,
114    "p95": 2.0,
115    "p98": 2.0,
116    "p99": 2.0,
117    "p999": 2.0
118  }
119}

1.5 获取 meters 指标

Method & Url
1GET http://localhost:8080/metrics/meters
Response Status
1200
Response Body
 1{
 2  "org.apache.hugegraph.api.API.commit-succeed": {
 3    "count": 0,
 4    "mean_rate": 0.0,
 5    "m15_rate": 0.0,
 6    "m5_rate": 0.0,
 7    "m1_rate": 0.0,
 8    "rate_unit": "events/second"
 9  },
10  "org.apache.hugegraph.api.API.expected-error": {
11    "count": 0,
12    "mean_rate": 0.0,
13    "m15_rate": 0.0,
14    "m5_rate": 0.0,
15    "m1_rate": 0.0,
16    "rate_unit": "events/second"
17  },
18  "org.apache.hugegraph.api.API.illegal-arg": {
19    "count": 0,
20    "mean_rate": 0.0,
21    "m15_rate": 0.0,
22    "m5_rate": 0.0,
23    "m1_rate": 0.0,
24    "rate_unit": "events/second"
25  },
26  "org.apache.hugegraph.api.API.unknown-error": {
27    "count": 0,
28    "mean_rate": 0.0,
29    "m15_rate": 0.0,
30    "m5_rate": 0.0,
31    "m1_rate": 0.0,
32    "rate_unit": "events/second"
33  },
34  "org.apache.tinkerpop.gremlin.server.GremlinServer.errors": {
35    "count": 0,
36    "mean_rate": 0.0,
37    "m15_rate": 0.0,
38    "m5_rate": 0.0,
39    "m1_rate": 0.0,
40    "rate_unit": "events/second"
41  }
42}

1.6 获取 timers 指标

Method & Url
1GET http://localhost:8080/metrics/timers
Response Status
1200
Response Body
 1{
 2  "org.apache.hugegraph.api.auth.AccessAPI.create": {
 3    "count": 0,
 4    "min": 0.0,
 5    "mean": 0.0,
 6    "max": 0.0,
 7    "stddev": 0.0,
 8    "p50": 0.0,
 9    "p75": 0.0,
10    "p95": 0.0,
11    "p98": 0.0,
12    "p99": 0.0,
13    "p999": 0.0,
14    "duration_unit": "milliseconds",
15    "mean_rate": 0.0,
16    "m15_rate": 0.0,
17    "m5_rate": 0.0,
18    "m1_rate": 0.0,
19    "rate_unit": "calls/second"
20  },
21  "org.apache.hugegraph.api.auth.AccessAPI.delete": {
22    "count": 0,
23    "min": 0.0,
24    "mean": 0.0,
25    "max": 0.0,
26    "stddev": 0.0,
27    "p50": 0.0,
28    "p75": 0.0,
29    "p95": 0.0,
30    "p98": 0.0,
31    "p99": 0.0,
32    "p999": 0.0,
33    "duration_unit": "milliseconds",
34    "mean_rate": 0.0,
35    "m15_rate": 0.0,
36    "m5_rate": 0.0,
37    "m1_rate": 0.0,
38    "rate_unit": "calls/second"
39  },
40  ...
41}

2.统计指标

Params
  • type:如果传值为 json,则以 json 格式返回,否则以 Promethaus 格式返回。
2.1 Method & Url
1GET http://localhost:8080/metrics/statistics
Response Status
 1# HELP hugegraph_info
 2# TYPE hugegraph_info untyped
 3hugegraph_info{version="0.69",
 4} 1.0
 5# HELP metrics_POST
 6# TYPE metrics_POST gauge
 7metrics_POST{name=FAILED_REQUEST,} 1
 8metrics_POST{name=MEAN_RESPONSE_TIME,} 21.0
 9metrics_POST{
10name=MAX_RESPONSE_TIME,
11} 21
12metrics_POST{name=SUCCESS_REQUEST,
13} 0
14metrics_POST{
15name=TOTAL_REQUEST,
16} 1
17# HELP metrics_backend_GET
18# TYPE metrics_backend_GET gauge
19metrics_backend_GET{name=FAILED_REQUEST,
20} 0
21metrics_backend_GET{
22name=MEAN_RESPONSE_TIME,
23} 12.6852124529148
24metrics_backend_GET{
25name=MAX_RESPONSE_TIME,
26} 20
27metrics_backend_GET{
28name=SUCCESS_REQUEST,
29} 2
30metrics_backend_GET{name=TOTAL_REQUEST,} 2
31# HELP system_GET
32# TYPE system_GET gauge
33system_GET{name=FAILED_REQUEST,} 1
34system_GET{name=MEAN_RESPONSE_TIME,} 2.0
35system_GET{name=MAX_RESPONSE_TIME,} 2
36system_GET{
37name=SUCCESS_REQUEST,
38} 0
39system_GET{name=TOTAL_REQUEST,
40} 1
41# HELP metrics_gauges_GET
42# TYPE metrics_gauges_GET gauge
43metrics_gauges_GET{name=FAILED_REQUEST,} 0
44metrics_gauges_GET{name=MEAN_RESPONSE_TIME,
45} 7.0
46metrics_gauges_GET{
47name=MAX_RESPONSE_TIME,
48} 7
49metrics_gauges_GET{
50name=SUCCESS_REQUEST,
51} 1
52metrics_gauges_GET{
53name=TOTAL_REQUEST,
54} 1
55# HELP favicon.ico_GET
56# TYPE favicon.ico_GET gauge
57favicon.ico_GET{name=FAILED_REQUEST,
58} 1
59favicon.ico_GET{
60name=MEAN_RESPONSE_TIME,
61} 1.0
62favicon.ico_GET{name=MAX_RESPONSE_TIME,} 1
63favicon.ico_GET{name=SUCCESS_REQUEST,} 0
64favicon.ico_GET{
65name=TOTAL_REQUEST,
66} 1
67# HELP metrics__GET
68# TYPE metrics__GET gauge
69metrics__GET{name=FAILED_REQUEST,} 0
70metrics__GET{name=MEAN_RESPONSE_TIME,} 10.0
71metrics__GET{name=MAX_RESPONSE_TIME,
72} 10
73metrics__GET{
74name=SUCCESS_REQUEST,
75} 2
76metrics__GET{
77name=TOTAL_REQUEST,
78} 2
79# HELP metrics_system_GET
80# TYPE metrics_system_GET gauge
81metrics_system_GET{name=FAILED_REQUEST,} 0
82metrics_system_GET{name=MEAN_RESPONSE_TIME,
83} 8.942674506664073
84metrics_system_GET{
85name=MAX_RESPONSE_TIME,
86} 40
87metrics_system_GET{name=SUCCESS_REQUEST,} 2
88metrics_system_GET{name=TOTAL_REQUEST,
89} 2
Response Body
1200
2.2 Method & Url
1GET http://localhost:8080/metrics/statistics?type=json
Response Status
1200
Response Body
 1{
 2  "metrics/POST": {
 3    "FAILED_REQUEST": 1,
 4    "MEAN_RESPONSE_TIME": 21,
 5    "MAX_RESPONSE_TIME": 21,
 6    "SUCCESS_REQUEST": 0,
 7    "TOTAL_REQUEST": 1
 8  },
 9  "metrics/backend/GET": {
10    "FAILED_REQUEST": 0,
11    "MEAN_RESPONSE_TIME": 12.6852124529148,
12    "MAX_RESPONSE_TIME": 20,
13    "SUCCESS_REQUEST": 2,
14    "TOTAL_REQUEST": 2
15  },
16  "system/GET": {
17    "FAILED_REQUEST": 1,
18    "MEAN_RESPONSE_TIME": 2,
19    "MAX_RESPONSE_TIME": 2,
20    "SUCCESS_REQUEST": 0,
21    "TOTAL_REQUEST": 1
22  },
23  "metrics/gauges/GET": {
24    "FAILED_REQUEST": 0,
25    "MEAN_RESPONSE_TIME": 7,
26    "MAX_RESPONSE_TIME": 7,
27    "SUCCESS_REQUEST": 1,
28    "TOTAL_REQUEST": 1
29  },
30  "favicon.ico/GET": {
31    "FAILED_REQUEST": 1,
32    "MEAN_RESPONSE_TIME": 1,
33    "MAX_RESPONSE_TIME": 1,
34    "SUCCESS_REQUEST": 0,
35    "TOTAL_REQUEST": 1
36  },
37  "metrics//GET": {
38    "FAILED_REQUEST": 0,
39    "MEAN_RESPONSE_TIME": 10,
40    "MAX_RESPONSE_TIME": 10,
41    "SUCCESS_REQUEST": 2,
42    "TOTAL_REQUEST": 2
43  },
44  "metrics/system/GET": {
45    "FAILED_REQUEST": 0,
46    "MEAN_RESPONSE_TIME": 8.942674506664073,
47    "MAX_RESPONSE_TIME": 40,
48    "SUCCESS_REQUEST": 2,
49    "TOTAL_REQUEST": 2
50  }
51}

3.系统指标

系统指标主要返回机器运行指标,如内存、线程等信息。

Method & Url
1GET http://localhost:8080/metrics/system
Response Status
1200
Response Body
 1{
 2  "basic": {
 3    "mem": 1010,
 4    "mem_total": 911,
 5    "mem_used": 239,
 6    "mem_free": 671,
 7    "mem_unit": "MB",
 8    "processors": 20,
 9    "uptime": 137503,
10    "systemload_average": -1.0
11  },
12  "heap": {
13    "committed": 911,
14    "init": 254,
15    "used": 239,
16    "max": 3596
17  },
18  "nonheap": {
19    "committed": 98,
20    "init": 2,
21    "used": 95,
22    "max": 0
23  },
24  "thread": {
25    "peak": 82,
26    "daemon": 34,
27    "total_started": 108,
28    "count": 82
29  },
30  "class_loading": {
31    "count": 11495,
32    "loaded": 11495,
33    "unloaded": 0
34  },
35  "garbage_collector": {
36    "ps_scavenge_count": 16,
37    "ps_scavenge_time": 155,
38    "ps_marksweep_count": 3,
39    "ps_marksweep_time": 494,
40    "time_unit": "ms"
41  }
42}

4.后端指标

hugeGraph 支持多种后端存储,后端指标包括内存、磁盘等信息。

Method & Url
1GET http://localhost:8080/metrics/backend
Response Status
1200
Response Body
 1{
 2  "hugegraph": {
 3    "backend": "rocksdb",
 4    "nodes": 1,
 5    "cluster_id": "local",
 6    "servers": {
 7      "local": {
 8        "mem_unit": "MB",
 9        "disk_unit": "GB",
10        "mem_used": 0.1,
11        "mem_used_readable": "103.53 KB",
12        "disk_usage": 0.03,
13        "disk_usage_readable": "29.03 KB",
14        "block_cache_usage": 0.00359344482421875,
15        "block_cache_pinned_usage": 0.00359344482421875,
16        "block_cache_capacity": 304.0,
17        "estimate_table_readers_mem": 0.019697189331054688,
18        "size_all_mem_tables": 0.07421875,
19        "cur_size_all_mem_tables": 0.07421875,
20        "estimate_live_data_size": 5.536526441574097E-5,
21        "total_sst_files_size": 5.536526441574097E-5,
22        "live_sst_files_size": 5.536526441574097E-5,
23        "estimate_pending_compaction_bytes": 0.0,
24        "estimate_num_keys": 0,
25        "num_entries_active_mem_table": 0,
26        "num_entries_imm_mem_tables": 0,
27        "num_deletes_active_mem_table": 0,
28        "num_deletes_imm_mem_tables": 0,
29        "num_running_flushes": 0,
30        "mem_table_flush_pending": 0,
31        "num_running_compactions": 0,
32        "compaction_pending": 0,
33        "num_immutable_mem_table": 0,
34        "num_snapshots": 0,
35        "oldest_snapshot_time": 0,
36        "num_live_versions": 38,
37        "current_super_version_number": 38
38      }
39    }
40  }
41}

5.1.19 - Other API

Other(其他接口)REST 接口:提供版本查询、API 列表、异常堆栈开关、IP 白名单和 Arthas 诊断代理等辅助功能。

11.1 Other

11.1.1 查看HugeGraph的版本信息

Method & Url
1GET http://localhost:8080/versions
Response Status
1200
Response Body
1{
2    "versions": {
3        "version": "v1",
4        "core": "1.7.0",
5        "gremlin": "3.5.1",
6        "api": "0.72.0.0"
7    }
8}

11.1.2 查看服务的概要信息

返回服务名、内核版本、文档地址以及当前节点注册的 API 分组。

Method & Url
1GET http://localhost:8080/
Response Status
1200
Response Body

swagger_ui 由 restserver.url 拼接得到,apis 是当前节点注册的 API 分组,按名称排序。

 1{
 2    "service": "hugegraph",
 3    "version": "1.7.0",
 4    "doc": "https://hugegraph.apache.org/docs/",
 5    "api_doc": "https://hugegraph.apache.org/docs/clients/",
 6    "swagger_ui": "http://127.0.0.1:8080/swagger-ui/index.html",
 7    "apis": [
 8        "arthas",
 9        "auth",
10        "cypher",
11        "filter",
12        "graph",
13        "gremlin",
14        "job",
15        "metrics",
16        "profile",
17        "raft",
18        "schema",
19        "space",
20        "traversers",
21        "variables"
22    ]
23}

11.1.3 列出服务的全部 API

按 API 分组和资源类列出所有已注册的接口方法,每条记录包含 url、HTTP 方法,以及查询参数的类型和默认值。

Method & Url
1GET http://localhost:8080/apis
Response Status
1200
Response Body

返回内容较长,下面的片段展示了它的结构:

 1{
 2    "apis": {
 3        "schema": {
 4            "PropertyKeyAPI": [
 5                {
 6                    "url": "graphspaces/{graphspace}/graphs/{graph}/schema/propertykeys",
 7                    "method": "GET",
 8                    "parameters": [
 9                        {
10                            "name": "names",
11                            "type": "java.util.List<java.lang.String>",
12                            "default_value": null
13                        }
14                    ]
15                }
16            ]
17        }
18    }
19}

11.1.4 查看和切换异常堆栈开关

服务返回的错误信息中是否带上 exception 和 cause 等异常堆栈字段,由 exception.allow_trace 配置项(默认 true)决定。下面的接口是一个节点级别的运行期覆盖开关:打开时无论配置项取值如何都会带上堆栈。GET 返回的是该覆盖开关的状态,初始为 false。

Method & Url
1GET http://localhost:8080/exception/trace
Response Status
1200
Response Body
1{
2    "trace": false
3}
Method & Url
1PUT http://localhost:8080/exception/trace
Request Body
1true
Response Status
1200
Response Body
1{
2    "trace": true
3}

11.1.5 管理 IP 白名单,该操作需要管理员权限

白名单只在开关打开时生效,参见 white_ip.status 配置项(默认 disable)。

查看白名单
Method & Url
1GET http://localhost:8080/whiteiplist
Response Status
1200
Response Body
1{
2    "whiteIpList": [
3        "127.0.0.1"
4    ]
5}
向白名单添加或删除 IP
Params
  • ips: IPv4 地址列表
  • action: load 表示添加,remove 表示删除
Method & Url
1POST http://localhost:8080/whiteiplist
Request Body
1{
2    "ips": [
3        "10.0.0.1",
4        "10.0.0.2"
5    ],
6    "action": "load"
7}
Response Status
1202
Response Body

existed_ips 是已经在白名单中的地址,added_ips 是新增的地址,illegal_ips 只在存在非法 IPv4 地址时返回。action=remove 时返回的是 removed_ips 和 non_existed_ips。

1{
2    "existed_ips": [],
3    "added_ips": [
4        "10.0.0.1",
5        "10.0.0.2"
6    ]
7}
启用或关闭白名单
Params
  • status: true 表示启用,false 表示关闭
Method & Url
1PUT http://localhost:8080/whiteiplist?status=true
Response Status
1200
Response Body
1{
2    "WhiteIpListOpen": true
3}

11.1.6 启动 Arthas 诊断代理

自 HugeGraph 1.8.0 起,Server 与 Store 发行包统一内置 Arthas 4.1.5(PD 未内置)。 可通过本地脚本或管理员 HTTP 接口挂载到正在运行的 JVM 进行在线诊断。

重要

安全与访问控制说明

  • 默认本地监听:Arthas 默认仅监听 127.0.0.1。若绑定通配地址(如 0.0.0.0),请务必收紧网络防火墙并开启认证。
  • 管理员权限限制:HTTP API 激活(PUT /arthas)仅限已开启鉴权的管理员调用;未开启鉴权时直接返回 403。
  • Store 端点禁用:Store 服务的 GET /v1/arthasstart 已禁用并返回 403,统一推荐使用 bin/arthas.sh。
  • 免重启与自动清理:推荐在宿主机以服务属主身份直接运行 bin/arthas.sh,无需重启服务; 交互会话退出时脚本会自动卸载代理。
部署方式推荐激活方式权限与访问说明
Server(已开启认证)管理员调用 PUT /arthas 或运行 bin/arthas.sh仅管理员账号可调用 HTTP 接口;本地脚本需服务 OS 用户权限
Server(未开启认证)本地脚本 bin/arthas.shHTTP 接口直接返回 403(包括 loopback 与代理请求)
Store本地脚本 bin/arthas.shGET /v1/arthasstart 已禁用并返回 403
激活与使用方式
本地免重启诊断 (推荐)
1# 以服务进程所属的 OS 用户执行(离线使用内置代理,无需重启)
2bin/arthas.sh
3
4# 官方容器镜像内置 JDK 17,可在容器内直接运行
5docker exec -it <container> bin/arthas.sh
常用诊断参数
1# 指定目标 JVM PID 及自定义 telnet 端口(同机多实例场景)
2bin/arthas.sh --pid <PID> --telnet-port 3659
3
4# 指定远程监听地址与原生认证凭据
5bin/arthas.sh --target-ip 0.0.0.0 --username admin --password '<password>'
6
7# 非交互模式执行单条命令并退出
8bin/arthas.sh --command version
管理员 HTTP API 激活
1# 1. 管理员调用 REST API 挂载诊断代理(默认端口 8562/8561,监听 127.0.0.1)
2curl -u admin:pa -X PUT http://127.0.0.1:8080/arthas
3
4# 2. 使用本地脚本连接已有代理
5bin/arthas.sh --telnet-port 8562
运维说明与安全配置
  • 会话退出与清理:本地脚本会在退出时(输入 quit、stop 或 --command 执行完成)自动停止 Arthas 代理并释放端口, 服务 JVM 保持运行。若仅通过 HTTP API 激活,会话结束后需显式执行 stop 彻底卸载代理。
  • 用户认证与安全:对外暴露诊断端口前强烈建议启用原生认证。可通过脚本参数 --username/--password 传递凭据, 或在服务 JVM 参数中设置 -Darthas.username 与 -Darthas.password。 详细认证机制及安全配置请参考 Arthas 官方用户认证文档。
  • 禁用高危命令:Server 可在 rest-server.properties 中通过 arthas.disabled_commands 配置禁用命令列表 (以逗号分隔,如 jad,mc)。请勿禁用 session 与 stop,以便工具管理生命周期。 各命令详情请参见 Arthas 官方命令列表。
HTTP 响应体示例

成功激活后返回 HTTP 200 及生效配置:

1{
2    "arthas.telnetPort": "8562",
3    "arthas.httpPort": "8561",
4    "arthas.ip": "127.0.0.1",
5    "arthas.disabledCommands": ""
6}
说明

配置项 采用规范的 snake_case 命名:arthas.telnet_port、arthas.http_port、 arthas.ip 与 arthas.disabled_commands。旧版 camelCase 命名仍作为兼容回退;显式配置的 snake_case 选项优先 (参见配置指南升级说明)。 响应内容保持 Arthas 代理的原始键名以便兼容现有客户端。

5.2 - 客户端/SDK

HugeGraph 官方多语言客户端 SDK(Java、Python、Go 等)概览与接入指引。

HugeGraph 提供多语言客户端 SDK,方便在不同语言与技术栈中连接 HugeGraph Server,进行 Schema 管理、顶点与边数据读写、Gremlin 遍历及高级分析。

支持的客户端

  • HugeGraph Java Client

    官方核心 Java SDK,提供与 Gremlin 语法相近的 API 风格,支持完整的 Schema 管理、CRUD、Gremlin 查询及 Traverser 算法,并支持 GraphSpace 隔离。

  • HugeGraph Python Client

    官方 Python SDK(pyhugegraph),位于 HugeGraph-AI 仓库,支持管理 Schema、读写图数据及提交 Gremlin 查询,深度集成 HugeGraph-LLM 与 HugeGraph-ML。

  • HugeGraph Go Client

    官方 Go SDK,支持版本查询、Schema 定义(PropertyKey/VertexLabel/EdgeLabel)、顶点操作与 Gremlin 查询。

选择建议

  • 生产级 Java/Scala 服务:推荐使用 HugeGraph Java Client,功能最完备,覆盖所有底层能力与连接池管理。
  • AI/LLM/算法与数据科学应用:推荐使用 HugeGraph Python Client(pyhugegraph),深度适配 HugeGraph-LLM、HugeGraph-ML 及 Python 数据科学分析工作流。
  • 微服务与云原生工具构建:推荐使用 HugeGraph Go Client 或直接调用 RESTful API。
  • 终端离线调试或临时查询:推荐使用 Gremlin Console。

5.2.1 - HugeGraph Java Client

1 HugeGraph-Client 概述

HugeGraph Java Client 将 Java API 转换为 HugeGraph Server 的 REST 请求,支持管理 Schema 和图数据、执行 Gremlin 及调用 Traverser API。本文涵盖 Java 项目的快速接入示例与全量核心 API 参考。

其他语言可使用 Go Client 或 Python Client。

2 环境要求

  • JDK 17,用于本文示例及从 Toolchain master 构建 Client 1.8.0
  • Maven 3.6.3+

3 使用流程

按下面的顺序接入 HugeGraph-Client。

  1. 使用 IntelliJ IDEA 或 Eclipse 新建 Maven 工程。
  2. 在 pom.xml 中添加 HugeGraph-Client 依赖。
  3. 创建客户端、调用 API,并在使用后关闭客户端。

详细操作见下面的完整示例。

4 完整示例

4.1 新建 Maven 工程

使用 Eclipse 或 IntelliJ IDEA 创建 Maven 工程。

4.2 添加 hugegraph-client 依赖

在 pom.xml 中添加依赖。

1
2<dependencies>
3    <dependency>
4        <groupId>org.apache.hugegraph</groupId>
5        <artifactId>hugegraph-client</artifactId>
6        <!-- 以下完整示例可使用已发布的 1.7.0 -->
7        <version>1.7.0</version>
8    </dependency>
9</dependencies>

先根据用途选择客户端版本。

用途客户端版本Java 编译目标
运行下方完整示例已发布的 1.7.0,使用上面的依赖即可发布版 POM 为 Java 8;本文统一使用 JDK 17
使用能力探测等 master 新接口Toolchain master(以 1.8 为基线)Java 17

示例使用的 Schema、Graph、Gremlin 和资源关闭接口在 Client 1.7.0 中可用,也与 Toolchain master 兼容。 发布版的 Java 编译目标不代表所有传递依赖的运行环境要求。

若需要使用 master 分支未发布的新接口,可从源码编译安装 Client(需配合 Toolchain 源码,详见 Tools 源码构建指引):

1java -version
2mvn -version
3mvn -Dmaven.repo.local="${candidate_dir:?Run the candidate SDK setup first}/m2" \
4  -Dsdk.validation.mode=candidate \
5  install -pl hugegraph-client -am -DskipTests -Dmaven.javadoc.skip=true -ntp

两条版本检查都应显示 JDK 17。使用 master 分支 Client 的项目运行 Maven 命令时,也需添加 -Dmaven.repo.local="$candidate_dir/m2"。 Client 与 Server 的版本不必相同;升级前核对所需 API 及兼容范围。

4.3 Example

选择单条操作或批量操作示例,将完整代码保存为 Maven 工程中的 src/main/java/SingleExample.java 或 src/main/java/BatchExample.java。复制按钮会包含已折叠的代码行。

4.3.1 SingleExample
  1import java.io.IOException;
  2import java.util.Iterator;
  3import java.util.List;
  4
  5import org.apache.hugegraph.driver.GraphManager;
  6import org.apache.hugegraph.driver.GremlinManager;
  7import org.apache.hugegraph.driver.HugeClient;
  8import org.apache.hugegraph.driver.SchemaManager;
  9import org.apache.hugegraph.structure.constant.T;
 10import org.apache.hugegraph.structure.graph.Edge;
 11import org.apache.hugegraph.structure.graph.Path;
 12import org.apache.hugegraph.structure.graph.Vertex;
 13import org.apache.hugegraph.structure.gremlin.Result;
 14import org.apache.hugegraph.structure.gremlin.ResultSet;
 15
 16public class SingleExample {
 17
 18    public static void main(String[] args) throws IOException {
 19        // If connect failed will throw a exception.
 20        HugeClient hugeClient = HugeClient.builder("http://localhost:8080",
 21                                                   "DEFAULT",
 22                                                   "hugegraph")
 23                                          .configUser("username", "password")
 24                                          // 这是示例,生产环境需要使用安全的凭证
 25                                          .build();
 26
 27        SchemaManager schema = hugeClient.schema();
 28
 29        schema.propertyKey("name").asText().ifNotExist().create();
 30        schema.propertyKey("age").asInt().ifNotExist().create();
 31        schema.propertyKey("city").asText().ifNotExist().create();
 32        schema.propertyKey("weight").asDouble().ifNotExist().create();
 33        schema.propertyKey("lang").asText().ifNotExist().create();
 34        schema.propertyKey("date").asDate().ifNotExist().create();
 35        schema.propertyKey("price").asInt().ifNotExist().create();
 36
 37        schema.vertexLabel("person")
 38              .properties("name", "age", "city")
 39              .primaryKeys("name")
 40              .ifNotExist()
 41              .create();
 42
 43        schema.vertexLabel("software")
 44              .properties("name", "lang", "price")
 45              .primaryKeys("name")
 46              .ifNotExist()
 47              .create();
 48
 49        schema.indexLabel("personByCity")
 50              .onV("person")
 51              .by("city")
 52              .secondary()
 53              .ifNotExist()
 54              .create();
 55
 56        schema.indexLabel("personByAgeAndCity")
 57              .onV("person")
 58              .by("age", "city")
 59              .secondary()
 60              .ifNotExist()
 61              .create();
 62
 63        schema.indexLabel("softwareByPrice")
 64              .onV("software")
 65              .by("price")
 66              .range()
 67              .ifNotExist()
 68              .create();
 69
 70        schema.edgeLabel("knows")
 71              .sourceLabel("person")
 72              .targetLabel("person")
 73              .properties("date", "weight")
 74              .ifNotExist()
 75              .create();
 76
 77        schema.edgeLabel("created")
 78              .sourceLabel("person").targetLabel("software")
 79              .properties("date", "weight")
 80              .ifNotExist()
 81              .create();
 82
 83        schema.indexLabel("createdByDate")
 84              .onE("created")
 85              .by("date")
 86              .secondary()
 87              .ifNotExist()
 88              .create();
 89
 90        schema.indexLabel("createdByWeight")
 91              .onE("created")
 92              .by("weight")
 93              .range()
 94              .ifNotExist()
 95              .create();
 96
 97        schema.indexLabel("knowsByWeight")
 98              .onE("knows")
 99              .by("weight")
100              .range()
101              .ifNotExist()
102              .create();
103
104        GraphManager graph = hugeClient.graph();
105        Vertex marko = graph.addVertex(T.LABEL, "person", "name", "marko",
106                                       "age", 29, "city", "Beijing");
107        Vertex vadas = graph.addVertex(T.LABEL, "person", "name", "vadas",
108                                       "age", 27, "city", "Hongkong");
109        Vertex lop = graph.addVertex(T.LABEL, "software", "name", "lop",
110                                     "lang", "java", "price", 328);
111        Vertex josh = graph.addVertex(T.LABEL, "person", "name", "josh",
112                                      "age", 32, "city", "Beijing");
113        Vertex ripple = graph.addVertex(T.LABEL, "software", "name", "ripple",
114                                        "lang", "java", "price", 199);
115        Vertex peter = graph.addVertex(T.LABEL, "person", "name", "peter",
116                                       "age", 35, "city", "Shanghai");
117
118        marko.addEdge("knows", vadas, "date", "2016-01-10", "weight", 0.5);
119        marko.addEdge("knows", josh, "date", "2013-02-20", "weight", 1.0);
120        marko.addEdge("created", lop, "date", "2017-12-10", "weight", 0.4);
121        josh.addEdge("created", lop, "date", "2009-11-11", "weight", 0.4);
122        josh.addEdge("created", ripple, "date", "2017-12-10", "weight", 1.0);
123        peter.addEdge("created", lop, "date", "2017-03-24", "weight", 0.2);
124
125        GremlinManager gremlin = hugeClient.gremlin();
126        System.out.println("==== Path ====");
127        ResultSet resultSet = gremlin.gremlin("g.V().outE().path()").execute();
128        Iterator<Result> results = resultSet.iterator();
129        results.forEachRemaining(result -> {
130            System.out.println(result.getObject().getClass());
131            Object object = result.getObject();
132            if (object instanceof Vertex) {
133                System.out.println(((Vertex) object).id());
134            } else if (object instanceof Edge) {
135                System.out.println(((Edge) object).id());
136            } else if (object instanceof Path) {
137                List<Object> elements = ((Path) object).objects();
138                elements.forEach(element -> {
139                    System.out.println(element.getClass());
140                    System.out.println(element);
141                });
142            } else {
143                System.out.println(object);
144            }
145        });
146
147        hugeClient.close();
148    }
149}
4.3.2 BatchExample
  1import java.util.ArrayList;
  2import java.util.List;
  3
  4import org.apache.hugegraph.driver.GraphManager;
  5import org.apache.hugegraph.driver.HugeClient;
  6import org.apache.hugegraph.driver.SchemaManager;
  7import org.apache.hugegraph.structure.graph.Edge;
  8import org.apache.hugegraph.structure.graph.Vertex;
  9
 10public class BatchExample {
 11
 12    public static void main(String[] args) {
 13        // If connect failed will throw a exception.
 14        HugeClient hugeClient = HugeClient.builder("http://localhost:8080",
 15                                                "DEFAULT",
 16                                                "hugegraph")
 17                                          .configUser("username", "password")
 18                                          // 这是示例,生产环境需要使用安全的凭证
 19                                          .build();
 20
 21        SchemaManager schema = hugeClient.schema();
 22
 23        schema.propertyKey("name").asText().ifNotExist().create();
 24        schema.propertyKey("age").asInt().ifNotExist().create();
 25        schema.propertyKey("lang").asText().ifNotExist().create();
 26        schema.propertyKey("date").asDate().ifNotExist().create();
 27        schema.propertyKey("price").asInt().ifNotExist().create();
 28
 29        schema.vertexLabel("person")
 30              .properties("name", "age")
 31              .primaryKeys("name")
 32              .ifNotExist()
 33              .create();
 34
 35        schema.vertexLabel("person")
 36              .properties("price")
 37              .nullableKeys("price")
 38              .append();
 39
 40        schema.vertexLabel("software")
 41              .properties("name", "lang", "price")
 42              .primaryKeys("name")
 43              .ifNotExist()
 44              .create();
 45
 46        schema.indexLabel("softwareByPrice")
 47              .onV("software").by("price")
 48              .range()
 49              .ifNotExist()
 50              .create();
 51
 52        schema.edgeLabel("knows")
 53              .link("person", "person")
 54              .properties("date")
 55              .ifNotExist()
 56              .create();
 57
 58        schema.edgeLabel("created")
 59              .link("person", "software")
 60              .properties("date")
 61              .ifNotExist()
 62              .create();
 63
 64        schema.indexLabel("createdByDate")
 65              .onE("created").by("date")
 66              .secondary()
 67              .ifNotExist()
 68              .create();
 69
 70        // get schema object by name
 71        System.out.println(schema.getPropertyKey("name"));
 72        System.out.println(schema.getVertexLabel("person"));
 73        System.out.println(schema.getEdgeLabel("knows"));
 74        System.out.println(schema.getIndexLabel("createdByDate"));
 75
 76        // list all schema objects
 77        System.out.println(schema.getPropertyKeys());
 78        System.out.println(schema.getVertexLabels());
 79        System.out.println(schema.getEdgeLabels());
 80        System.out.println(schema.getIndexLabels());
 81
 82        GraphManager graph = hugeClient.graph();
 83
 84        Vertex marko = new Vertex("person").property("name", "marko")
 85                                           .property("age", 29);
 86        Vertex vadas = new Vertex("person").property("name", "vadas")
 87                                           .property("age", 27);
 88        Vertex lop = new Vertex("software").property("name", "lop")
 89                                           .property("lang", "java")
 90                                           .property("price", 328);
 91        Vertex josh = new Vertex("person").property("name", "josh")
 92                                          .property("age", 32);
 93        Vertex ripple = new Vertex("software").property("name", "ripple")
 94                                              .property("lang", "java")
 95                                              .property("price", 199);
 96        Vertex peter = new Vertex("person").property("name", "peter")
 97                                           .property("age", 35);
 98
 99        Edge markoKnowsVadas = new Edge("knows").source(marko).target(vadas)
100                                                .property("date", "2016-01-10");
101        Edge markoKnowsJosh = new Edge("knows").source(marko).target(josh)
102                                               .property("date", "2013-02-20");
103        Edge markoCreateLop = new Edge("created").source(marko).target(lop)
104                                                 .property("date",
105                                                           "2017-12-10");
106        Edge joshCreateRipple = new Edge("created").source(josh).target(ripple)
107                                                   .property("date",
108                                                             "2017-12-10");
109        Edge joshCreateLop = new Edge("created").source(josh).target(lop)
110                                                .property("date", "2009-11-11");
111        Edge peterCreateLop = new Edge("created").source(peter).target(lop)
112                                                 .property("date",
113                                                           "2017-03-24");
114
115        List<Vertex> vertices = new ArrayList<>();
116        vertices.add(marko);
117        vertices.add(vadas);
118        vertices.add(lop);
119        vertices.add(josh);
120        vertices.add(ripple);
121        vertices.add(peter);
122
123        List<Edge> edges = new ArrayList<>();
124        edges.add(markoKnowsVadas);
125        edges.add(markoKnowsJosh);
126        edges.add(markoCreateLop);
127        edges.add(joshCreateRipple);
128        edges.add(joshCreateLop);
129        edges.add(peterCreateLop);
130
131        vertices = graph.addVertices(vertices);
132        vertices.forEach(vertex -> System.out.println(vertex));
133
134        edges = graph.addEdges(edges, false);
135        edges.forEach(edge -> System.out.println(edge));
136
137        hugeClient.close();
138    }
139}

4.4 运行 Example

  1. 启动 HugeGraph Server,在图空间 DEFAULT 中准备名为 hugegraph 的测试图。
  2. 将 Maven 工程的 JDK 设为 17,把所选示例中 HugeClient.builder(...) 和 configUser(...) 的 Server 地址、图空间、图名和凭据改为实际配置。 Server 未开启鉴权时,省略 configUser(...)。
  3. 在 IDE 中运行 SingleExample.main() 或 BatchExample.main()。两个示例都会创建 Schema 和图数据、打印结果并关闭客户端。 请使用测试图,已有 Schema 或数据可能影响重复运行。

本文的代码都是java语言写的,但其风格与gremlin(groovy)是非常类似的。用户只需要把代码中的变量声明替换成def或直接去掉, 就能将java代码转变为groovy;另外就是每一行语句最后可以不加分号,groovy认为一行就是一条语句。

用户在HugeGraph-Hubble中编写的gremlin(groovy)可以参考本文的java代码,下面会举出几个例子。

本文以 Toolchain master(Client 1.8.0)为准。请先按上方快速入门准备对应依赖; 能力探测等新增接口不能直接用于旧版 Client。

5 HugeClient 构造与操作入口

HugeGraph-Client 是操作 graph 的总入口,用户必须先创建出 HugeGraph-Client 对象,与 HugeGraph-Server 建立连接(伪连接)后,才能获取到 schema、graph 以及 gremlin 的操作入口对象。

HugeGraph-Client 连接服务端已有的图。构造器支持传入 GraphSpace;使用双参数构造器或传入空值时,GraphSpace 默认为 DEFAULT。

1// HugeGraphServer 地址:"http://localhost:8080"
2// 图的名称:"hugegraph"
3HugeClient hugeClient = HugeClient.builder("http://localhost:8080", "hugegraph")
4                                //.builder("http://localhost:8080", "graphSpaceName", "hugegraph")
5                                  .configTimeout(20) // 默认 20s 超时
6                                  // .configUser("username", "password") // 服务端启用认证时配置
7                                  .build();

上述创建 HugeClient 的过程如果失败会抛出异常,用户需要 try-catch。如果成功则继续获取 schema、graph 以及 gremlin 的 manager。

在HugeGraph - Hubble中通过gremlin来操作时,不需要使用HugeClient,可以忽略。

5.1 构造器选项

构造器支持下列选项。所有超时参数的单位都是秒,内部会转换为毫秒。

interfacedescriptiondefault
configUrl(String url)服务端地址,通常已经通过 builder(...) 传入必填
configGraph(String graph)图名称,通常已经通过 builder(...) 传入必填
configGraphSpace(String graphSpace)GraphSpace 名称,传入 null 或空值时回退为 DEFAULTDEFAULT
configUser(String username, String password)服务端用户名和密码,传入 null 时按空字符串处理空,不开启认证
configToken(String token)使用 Token 代替用户名和密码空
configTimeout(int seconds)请求超时,建议使用正数秒值20
configConnectTimeout(Integer seconds)连接超时,不设置时沿用 configTimeout未设置
configReadTimeout(Integer seconds)读取超时,不设置时沿用 configTimeout未设置
configPool(int maxConns, int maxConnsPerRoute)连接池大小,任意一项传入 0 时恢复其默认值4 x CPU 数,2 x CPU 数
configIdleTime(int seconds)空闲连接保持时间,必须大于 030
configSSL(String trustStoreFile, String trustStorePassword)HTTPS 连接使用的信任库空
configHttpBuilder(Consumer<OkHttpClient.Builder> consumer)回调,用于进一步定制底层的 OkHttp 客户端无
graphRequired(boolean graphRequired)build() 是否拒绝空的 url 或图名称true

当前 master 的 configTimeout(0) 存在单位换算缺陷,会得到 20,000 秒而非默认的 20 秒。 保持默认值时省略该调用,或显式使用 configTimeout(20);不要用 0 恢复默认值。

调用 build() 时,客户端会读取服务端的 API 版本,超出 [0.38, 0.81) 范围时报错。

5.2 操作入口

除 schema、graph 和 gremlin 外,HugeClient 还提供下列入口。图级别的入口只有在指定了图名称时才可用;如果创建客户端时图名称为空,这些入口会返回 null,直到调用 assignGraph(graphSpace, graph) 为止。

interfacereturnsscopedescription
schema()SchemaManagergraph管理 PropertyKey、VertexLabel、EdgeLabel 和 IndexLabel
graph()GraphManagergraph单条或批量地增删改查顶点和边
gremlin()GremlinManagergraph同步执行 Gremlin 语句,或作为异步任务提交
cypher()CypherManagergraph同步执行 Cypher 语句,或作为异步任务提交
traverser()TraverserManagergraphRESTful 遍历,如最短路径、k-out、k-neighbor、交叉点等
variables()VariablesManagergraph获取、设置、列出和删除图变量
job()JobManagergraph重建 VertexLabel、EdgeLabel 或 IndexLabel 的索引
task()TaskManagergraph列出、获取、取消、删除异步任务,或等待其完成
computer()ComputerManagergraph创建、取消、列出和获取 computer 任务
graphs()GraphsManagergraphspace创建、克隆、列出、重载、清空和删除图,读取和设置图的模式
graphSpace()GraphSpaceManagerserver管理 GraphSpace,详见第 8 节
auth()AuthManagerserver管理 user、group、target、belong 和 access
metrics()MetricsManagerserver读取后端、系统和统计指标
versionManager()VersionManagerserver读取服务端的 core、gremlin 和 API 版本

客户端还会报告所连服务端支持的能力,调用方可以据此判断,而不必解析版本号:supportsGraphSpace()、supportsCypher()、supportsGraphCreate()、supportsDefaultRole() 和 isServerAuthEnabled()。

6 元数据管理 (SchemaManager)

6.1 SchemaManager

SchemaManager 用于管理 HugeGraph 中的四种元数据,分别是 PropertyKey(属性类型)、VertexLabel(顶点类型)、EdgeLabel(边类型)和 IndexLabel(索引标签)。在定义元数据信息之前必须先创建 SchemaManager 对象。

用户可使用如下方法获得 SchemaManager 对象:

1SchemaManager schema = hugeClient.schema()

在HugeGraph-Hubble中通过gremlin创建schema对象:

1schema = graph.schema()

下面分别介绍四种元数据的定义过程。

6.2 PropertyKey

6.2.1 接口及参数介绍

PropertyKey 用来规范顶点和边的属性的约束,暂不支持定义属性的属性。

PropertyKey 允许定义的约束信息包括:name、datatype、cardinality、aggregateType、writeType、userdata,下面逐一介绍。

  • name: 属性的名字,用来区分不同的 PropertyKey,不允许有同名的属性;
interfaceparammust set
propertyKey(String name)namey
  • datatype:属性值类型,必须从下表中选择符合具体业务场景的一项显式设置;
interfaceJava Class
asText()String
asInt()Integer
asDate()Date
asUUID()UUID
asBoolean()Boolean
asByte()Byte
asBlob()Byte[]
asDouble()Double
asFloat()Float
asLong()Long
  • cardinality:属性值是单值还是多值,多值的情况下又分为允许有重复值和不允许有重复值,该项默认为 single,如有必要可从下表中选择一项设置;
interfacecardinalitydescription
valueSingle()singlesingle value
valueList()listmulti-values that allow duplicate value
valueSet()setmulti-values that not allow duplicate value
  • aggregateType:同一属性被重复写入时的合并方式,默认为 none,即保留最后写入的值。数值类的选项要求属性为数字类型;
interfaceaggregateTypedescription
calcSum()sum对写入的值累加
calcMax()max保留最大值
calcMin()min保留最小值
calcOld()old保留首次写入的值,忽略后续更新

aggregateType(AggregateType type) 可以直接设置该项,传入 AggregateType.NONE 即恢复默认。

  • writeType:属性属于 OLTP 图数据还是 OLAP 计算结果,对于 OLAP 还区分是否带索引,默认为 oltp;
writeTypedescription
OLTP普通图属性
OLAP_COMMON不带索引的 OLAP 属性
OLAP_SECONDARY带二级索引的 OLAP 属性
OLAP_RANGE带范围索引的 OLAP 属性
interfacedescription
writeType(WriteType writeType)使用枚举值设置写入类型
writeType(String name)使用枚举名设置写入类型
  • userdata:用户可以自己添加一些约束或额外信息,然后自行检查传入的属性是否满足约束,或者必要的时候提取出额外信息
interfacedescription
userdata(String key, Object value)The same key, the latter will cover the former
6.2.2 创建 PropertyKey
1schema.propertyKey("name").asText().valueSet().ifNotExist().create()

在HugeGraph-Hubble中通过gremlin创建上述PropertyKey对象的语法完全一致,如果用户没有定义出schema变量,应该这样写:

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

以下的示例中,gremlin与java的语法完全一致,不再赘述。

  • ifNotExist():为 create 添加判断机制,若当前 PropertyKey 已经存在则不再创建,否则创建该属性。若不添加判断,在 properkey 已存在的情况下会抛出异常信息,下同,不再赘述。
6.2.3 删除 PropertyKey
1schema.propertyKey("name").remove()
6.2.4 查询 PropertyKey
1// 获取 PropertyKey 对象
2schema.getPropertyKey("name")
3
4// 获取 PropertyKey 属性
5schema.getPropertyKey("name").cardinality()
6schema.getPropertyKey("name").dataType()
7schema.getPropertyKey("name").name()
8schema.getPropertyKey("name").userdata()

6.3 VertexLabel

6.3.1 接口及参数介绍

VertexLabel 用来定义顶点类型,描述顶点的约束信息:

VertexLabel 允许定义的约束信息包括:name、idStrategy、properties、primaryKeys、nullableKeys 和 ttl,下面逐一介绍。

  • name: 属性的名字,用来区分不同的 VertexLabel,不允许有同名的属性;
interfaceparammust set
vertexLabel(String name)namey
  • idStrategy: 每一个 VertexLabel 都可以选择自己的 Id 策略,目前有三种策略供选择,即 Automatic(自动生成)、Customize(用户传入)和 PrimaryKey(主属性键)。其中 Automatic 使用 Snowflake 算法生成 Id,Customize 需要用户自行传入字符串或数字类型的 Id,PrimaryKey 则允许用户从 VertexLabel 的属性中选择若干主属性作为区分的依据,HugeGraph 内部会根据主属性的值拼接生成 Id。idStrategy 默认使用 Automatic 的,但如果用户没有显式设置 idStrategy 又调用了 primaryKeys(…) 方法设置了主属性,则 idStrategy 将自动使用 PrimaryKey;
interfaceidStrategydescription
useAutomaticIdAUTOMATICgenerate id automatically by Snowflake algorithm
useCustomizeStringIdCUSTOMIZE_STRINGpassed id by user, must be string type
useCustomizeNumberIdCUSTOMIZE_NUMBERpassed id by user, must be number type
useCustomizeUuidIdCUSTOMIZE_UUIDpassed id by user, must be UUID type
usePrimaryKeyIdPRIMARY_KEYchoose some important prop as primary key to splice id
  • properties: 定义顶点的属性,传入的参数是 PropertyKey 的 name
interfacedescription
properties(String… properties)allow to pass multi props
  • primaryKeys: 当用户选择了 PrimaryKey 的 Id 策略时,需要从 VertexLabel 的属性中选择若干主属性作为区分的依据;
interfacedescription
primaryKeys(String… keys)allow to choose multi prop as primaryKeys

需要注意的是,Id 策略的选择与 primaryKeys 的设置有一些相互约束,不能随意调用,约束关系见下表:

useAutomaticIduseCustomizeStringIduseCustomizeNumberIdusePrimaryKeyId
unset primaryKeysAUTOMATICCUSTOMIZE_STRINGCUSTOMIZE_NUMBERERROR
set primaryKeysERRORERRORERRORPRIMARY_KEY

客户端自身只校验 Id 策略是否被重复设置,因此在同一个构造器上调用两个上述方法会在本地报错。上表中的组合由服务端校验。

  • nullableKeys: 对于通过 properties(…) 方法设置过的属性,默认全都是不可为空的,也就是在创建顶点时该属性必须赋值,这样可能对用户数据提出了太过严格的完整性要求。为避免这样的强约束,用户可以通过 本方法设置若干属性为可空的,这样添加顶点时该属性可以不赋值。
interfacedescription
nullableKeys(String… properties)allow to pass multi props

注意:primaryKeys 和 nullableKeys 不能有交集,因为一个属性不能既作为主属性,又是可空的。

  • ttl:该类型顶点的存活时间,默认为 0,即永不过期。客户端会拒绝负值。默认从顶点写入的时刻开始计时;设置 ttlStartTime 后,改为从该 label 的某个日期属性开始计时。
interfacedescription
ttl(long ttl)设置存活时间,0 表示不过期
ttlStartTime(String property)指定计时起点所用的日期属性
  • enableLabelIndex:用户可以指定是否需要为 label 创建索引。不创建则无法全局搜索指定 label 的顶点和边,创建则可以全局搜索,做类似于g.V().hasLabel('person'), g.E().has('label', 'person')这样的查询, 但是插入数据时性能上会更加慢,并且需要占用更多的存储空间。此项默认为 true。
interfacedescription
enableLabelIndex(boolean enable)Whether to create a label index
  • userdata:用户可以自己添加一些约束或额外信息,然后自行检查传入的属性是否满足约束,或者必要的时候提取出额外信息
interfacedescription
userdata(String key, Object value)The same key, the latter will cover the former
6.3.2 创建 VertexLabel
 1// 使用 Automatic 的 Id 策略
 2schema.vertexLabel("person").properties("name", "age").ifNotExist().create();
 3schema.vertexLabel("person").useAutomaticId().properties("name", "age").ifNotExist().create();
 4
 5// 使用 Customize_String 的 Id 策略
 6schema.vertexLabel("person").useCustomizeStringId().properties("name", "age").ifNotExist().create();
 7// 使用 Customize_Number 的 Id 策略
 8schema.vertexLabel("person").useCustomizeNumberId().properties("name", "age").ifNotExist().create();
 9// 使用 Customize_Uuid 的 Id 策略
10schema.vertexLabel("person").useCustomizeUuidId().properties("name", "age").ifNotExist().create();
11
12// 使用 PrimaryKey 的 Id 策略
13schema.vertexLabel("person").properties("name", "age").primaryKeys("name").ifNotExist().create();
14schema.vertexLabel("person").usePrimaryKeyId().properties("name", "age").primaryKeys("name").ifNotExist().create();
6.3.3 追加 VertexLabel

VertexLabel 是可以追加约束的,不过仅限 properties 和 nullableKeys,而且追加的属性也必须添加到 nullableKeys 集合中。

1schema.vertexLabel("person").properties("price").nullableKeys("price").append();
6.3.4 删除 VertexLabel
1schema.vertexLabel("person").remove();
6.3.5 查询 VertexLabel
 1// 获取 VertexLabel 对象
 2schema.getVertexLabel("name")
 3
 4// 获取 property key 属性
 5schema.getVertexLabel("person").idStrategy()
 6schema.getVertexLabel("person").primaryKeys()
 7schema.getVertexLabel("person").name()
 8schema.getVertexLabel("person").properties()
 9schema.getVertexLabel("person").nullableKeys()
10schema.getVertexLabel("person").userdata()
11schema.getVertexLabel("person").ttl()
12schema.getVertexLabel("person").ttlStartTime()

6.4 EdgeLabel

6.4.1 接口及参数介绍

EdgeLabel 用来定义边类型,描述边的约束信息。

EdgeLabel 允许定义的约束信息包括:name、sourceLabel、targetLabel、frequency、properties、sortKeys、nullableKeys 和 ttl,下面逐一介绍。

  • name: 属性的名字,用来区分不同的 EdgeLabel,不允许有同名的属性;
interfaceparammust set
edgeLabel(String name)namey
  • sourceLabel 和 targetLabel: 边连接的源顶点类型名和目标顶点类型名,两者都设置等同于声明一组连接。

  • link: EdgeLabel 内部保存的是一组源顶点和目标顶点的组合,因此 link(...) 可以多次调用,让同一种边连接多组顶点类型。一旦通过这种方式添加过组合,sourceLabel(...) 和 targetLabel(...) 就会被拒绝;同时 sourceLabel() 和 targetLabel() 这两个取值方法只在恰好有一组组合时可用,需要读取全部组合时请使用 links()。

interfaceparammust set
link(String sourceLabel, String targetLabel)sourceLabel, targetLabely,或设置下面两项
sourceLabel(String label)labely,除非已使用 link()
targetLabel(String label)labely,除非已使用 link()
  • frequency: 字面意思是频率,表示在两个具体的顶点间某个关系出现的次数,可以是单次(single)或多次(frequency),默认为 single;
interfacefrequencydescription
singleTime()singlea relationship can only occur once
multiTimes()multiplea relationship can occur many times
  • properties: 定义边的属性
interfacedescription
properties(String… properties)allow to pass multi props
  • sortKeys: 当 EdgeLabel 的 frequency 为 multiple 时,需要某些属性来区分这多次的关系,故引入了 sortKeys(排序键);
interfacedescription
sortKeys(String… keys)allow to choose multi prop as sortKeys
  • nullableKeys: 与顶点中的 nullableKeys 概念一致,不再赘述

注意:sortKeys 和 nullableKeys 也不能有交集。

  • ttl:与顶点中的 ttl 概念一致,同样提供 ttl(long ttl) 和 ttlStartTime(String property) 方法,默认值同样为 0。

  • edge label type:EdgeLabel 默认为普通类型,也可以声明为一族边类型的父类型、某个父类型的子类型,或者通用类型:

interfaceedgeLabelTypedescription
asBase()PARENT将该 label 声明为父类型
withBase(String parentLabel)SUB将该 label 声明为 parentLabel 的子类型
asGeneral()GENERAL将该 label 声明为通用类型
  • enableLabelIndex:与顶点中的 enableLabelIndex 概念一致,不再赘述

  • userdata:用户可以自己添加一些约束或额外信息,然后自行检查传入的属性是否满足约束,或者必要的时候提取出额外信息

interfacedescription
userdata(String key, Object value)The same key, the latter will cover the former
6.4.2 创建 EdgeLabel
1schema.edgeLabel("knows").link("person", "person").properties("date").ifNotExist().create();
2schema.edgeLabel("created").multiTimes().link("person", "software").properties("date").sortKeys("date").ifNotExist().create();
6.4.3 追加 EdgeLabel
1schema.edgeLabel("knows").properties("price").nullableKeys("price").append();
6.4.4 删除 EdgeLabel
1schema.edgeLabel("knows").remove();
6.4.5 查询 EdgeLabel
 1// 获取 EdgeLabel 对象
 2schema.getEdgeLabel("knows")
 3
 4// 获取 property key 属性
 5schema.getEdgeLabel("knows").frequency()
 6schema.getEdgeLabel("knows").sourceLabel()
 7schema.getEdgeLabel("knows").targetLabel()
 8schema.getEdgeLabel("knows").sortKeys()
 9schema.getEdgeLabel("knows").name()
10schema.getEdgeLabel("knows").properties()
11schema.getEdgeLabel("knows").nullableKeys()
12schema.getEdgeLabel("knows").userdata()
13schema.getEdgeLabel("knows").ttl()
14schema.getEdgeLabel("knows").ttlStartTime()
15schema.getEdgeLabel("knows").edgeLabelType()
16// 全部的源顶点和目标顶点组合,存在多组时也可安全调用
17schema.getEdgeLabel("knows").links()

6.5 IndexLabel

6.5.1 接口及参数介绍

IndexLabel 用来定义索引类型,描述索引的约束信息,主要是为了方便查询。

IndexLabel 允许定义的约束信息包括:name、baseType、baseValue、indexFields、indexType,下面逐一介绍。

  • name: 属性的名字,用来区分不同的 IndexLabel,不允许有同名的属性;
interfaceparammust set
indexLabel(String name)namey
  • baseType: 表示要为 VertexLabel 还是 EdgeLabel 建立索引, 与下面的 baseValue 配合使用;

  • baseValue: 指定要建立索引的 VertexLabel 或 EdgeLabel 的名称;

interfaceparamdescription
onV(String baseValue)baseValuebuild index for VertexLabel: ‘baseValue’
onE(String baseValue)baseValuebuild index for EdgeLabel: ‘baseValue’
  • indexFields: 要在哪些属性上建立索引,可以是为多列建立联合索引;
interfaceparamdescription
by(String… fields)filesallow to build index for multi fields for secondary index
  • indexType: 建立的索引类型,目前支持五种,即 Secondary、Range、Search、Shard 和 Unique。
    • Secondary 支持精确匹配的二级索引,允许建立联合索引,联合索引支持索引前缀搜索
      • 单个属性,支持相等查询,比如:person 顶点的 city 属性的二级索引,可以用g.V().has("city", "北京") 查询"city 属性值是北京"的全部顶点
      • 联合索引,支持前缀查询和相等查询,比如:person 顶点的 city 和 street 属性的联合索引,可以用g.V().has ("city", "北京").has('street', '中关村街道') 查询"city属性值是北京且street属性值是中关村"的全部顶点,或者g.V() .has("city", "北京")查询"city 属性值是北京"的全部顶点

      secondary index 的查询都是基于"是"或者"相等"的查询条件,不支持"部分匹配"

    • Range 支持数值类型的范围查询
      • 必须是单个数字或者日期属性,比如:person 顶点的 age 属性的范围索引,可以用g.V().has("age", P.gt(18)) 查询"age属性值大于18"的顶点。除了P.gt()以外,还支持P.gte(), P.lte(), P.lt(), P.eq(), P.between(), P.inside()和P.outside()等
    • Search 支持全文检索的索引
      • 必须是单个文本属性,比如:person 顶点的 address 属性的全文索引,可以用g.V().has("address", Text .contains('大厦')查询"address 属性中包含大厦"的全部顶点

      search index 的查询是基于"是"或者"包含"的查询条件

    • Shard 支持前缀匹配 + 数字范围查询的索引
      • N 个属性的分片索引,支持前缀相等情况下的范围查询,比如:person 顶点的 city 和 age 属性的分片索引,可以用g.V().has ("city", "北京").has("age", P.between(18, 30)) 查询"city 属性是北京且年龄大于等于 18 小于 30"的全部顶点
      • shard index N 个属性全是文本属性时,等价于 secondary index
      • shard index 只有单个数字或者日期属性时,等价于 range index

      shard index 可以有任意数字或者日期属性,但是查询时最多只能提供一个范围查找条件,且该范围查找条件的属性的前缀属性都是相等查询条件

    • Unique 支持属性值唯一性约束,即可以限定属性的值不重复,允许联合索引,但不支持查询
      • 单个或者多个属性的唯一性索引,不可用来查询,只可对属性的值进行限定,当出现重复值时将报错
interfaceindexTypedescription
secondary()Secondarysupport prefix search
range()Rangesupport range(numeric or date type) search
search()Searchsupport full text search
shard()Shardsupport prefix + range(numeric or date type) search
unique()Uniquesupport unique props value, not support search
6.5.2 创建 IndexLabel

以下示例假定已创建带 name、age 的 person 顶点类型,以及带 date 的 created 边类型。 先补充索引所需属性;id 是业务属性,与顶点的内部 ID 不同。

 1schema.propertyKey("lived").asText().ifNotExist().create();
 2schema.propertyKey("city").asText().ifNotExist().create();
 3schema.propertyKey("id").asInt().ifNotExist().create();
 4schema.vertexLabel("person").properties("lived", "city", "id")
 5      .nullableKeys("lived", "city", "id").append();
 6
 7schema.indexLabel("personByAge").onV("person").by("age").range().ifNotExist().create();
 8schema.indexLabel("createdByDate").onE("created").by("date").secondary().ifNotExist().create();
 9schema.indexLabel("personByLived").onV("person").by("lived").search().ifNotExist().create();
10schema.indexLabel("personByCityAndAge").onV("person").by("city", "age").shard().ifNotExist().create();
11schema.indexLabel("personById").onV("person").by("id").unique().ifNotExist().create();
6.5.3 删除 IndexLabel
1schema.indexLabel("personByAge").remove()
6.5.4 查询 IndexLabel
1// 获取 IndexLabel 对象
2schema.getIndexLabel("personByAge")
3
4// 获取 property key 属性
5schema.getIndexLabel("personByAge").baseType()
6schema.getIndexLabel("personByAge").baseValue()
7schema.getIndexLabel("personByAge").indexFields()
8schema.getIndexLabel("personByAge").indexType()
9schema.getIndexLabel("personByAge").name()

7 图数据操作 (GraphManager)

7.1 Vertex

顶点是构成图的最基本元素,一个图中可以有非常多的顶点。下面给出一个添加顶点的例子:

1Vertex marko = graph.addVertex(T.LABEL, "person", "name", "marko", "age", 29);
2Vertex lop = graph.addVertex(T.LABEL, "software", "name", "lop", "lang", "java", "price", 328);
  • 添加顶点的关键是顶点属性,添加顶点函数的参数个数必须为偶数,且满足key1 -> val1, key2 -> val2 ···的顺序排列,键值对之间的顺序是自由的。
  • 参数中必须包含一对特殊的键值对,就是T.LABEL -> "val",用来定义该顶点的类别,以便于程序从缓存或后端获取到该 VertexLabel 的 schema 定义,然后做后续的约束检查。例子中的 label 定义为 person。T.LABEL 就是常量 "label",直接传入该字符串效果相同。
  • 如果顶点类型的 Id 策略为 AUTOMATIC,则不允许用户传入 id 键值对。
  • 如果顶点类型的 Id 策略为 CUSTOMIZE_STRING,则用户需要自己传入 String 类型 id 的值,键值对形如:T.ID, "123456"。
  • 如果顶点类型的 Id 策略为 CUSTOMIZE_NUMBER,则用户需要自己传入 Number 类型 id 的值,键值对形如:T.ID, 123456。
  • 如果顶点类型的 Id 策略为 PRIMARY_KEY,参数还必须全部包含该primaryKeys对应属性的名和值,如果不设置会抛出异常。比如之前person的primaryKeys是name,例子中就设置了name的值为marko。
  • 对于非 nullableKeys 的属性,必须要赋值。
  • 剩下的参数就是顶点其他属性的设置,但并非必须。
  • 调用addVertex方法后,顶点会立刻被插入到后端存储系统中。

7.2 Edge

有了点,还需要边才能构成完整的图。下面给出一个添加边的例子:

1Edge knows1 = marko.addEdge("knows", vadas, "city", "Beijing");
  • 由(源)顶点来调用添加边的函数,函数第一个参数为边的 label,第二个参数是目标顶点,这两个参数的位置和顺序是固定的。后续的参数就是key1 -> val1, key2 -> val2 ···的顺序排列,设置边的属性,键值对顺序自由。
  • 源顶点和目标顶点必须符合 EdgeLabel 中 source-label 和 target-label 的定义,不能随意添加。
  • 对于非 nullableKeys 的属性,必须要赋值。

注意:当 frequency 为 multiple 时必须要设置 sortKeys 对应属性类型的值。

8 图空间管理 (GraphSpace)

Client 支持管理一个物理部署中的多个 GraphSpace,每个 GraphSpace 可以包含多个图。不指定 GraphSpace 时使用 DEFAULT。

GraphSpace 需要服务端 core 版本不低于 1.7.0。连接更早的服务端时,客户端会退回到 legacy 模式,此时 hugeClient.supportsGraphSpace() 返回 false。

8.1 创建GraphSpace

 1GraphSpaceManager spaceManager = hugeClient.graphSpace();
 2
 3// 定义 GraphSpace 配置
 4GraphSpace graphSpace = new GraphSpace();
 5graphSpace.setName("myGraphSpace");
 6graphSpace.setDescription("Business data graph space");
 7graphSpace.setMaxGraphNumber(10);  // 最大图数量
 8graphSpace.setMaxRoleNumber(100);  // 最大角色数量
 9
10// 创建 GraphSpace
11spaceManager.createGraphSpace(graphSpace);

8.2 GraphSpace 接口汇总

类别接口描述
Manager - 查询listGraphSpace()获取所有 GraphSpace 名称
listProfile() / listProfile(String prefix)获取 GraphSpace 概要
getGraphSpace(String name)获取指定 GraphSpace
getDefault()获取默认 GraphSpace
Manager - 创建/更新createGraphSpace(GraphSpace)创建 GraphSpace
updateGraphSpace(GraphSpace)更新配置
setDefault(String name)设置默认 GraphSpace
Manager - 删除deleteGraphSpace(String name)删除指定 GraphSpace
Manager - 默认角色setDefaultRole(String name, String user, String role)授予默认角色,可用第四个参数限定到某个图
checkDefaultRole(String name, String user, String role)检查默认角色,可用第四个参数限定到某个图
deleteDefaultRole(String name, String user, String role)撤销默认角色,可用第四个参数限定到某个图
GraphSpace - 属性getName() / getNickname() / getDescription()获取名称/昵称/描述
getGraphNumberUsed() / getRoleNumberUsed()获取已使用的图数量/角色数量
getCpuUsed() / getMemoryUsed() / getStorageUsed()获取已使用的资源
getCreateTime() / getUpdateTime()获取创建时间/更新时间
GraphSpace - 配置setDescription(String) / setNickname(String)设置描述/昵称
setMaxGraphNumber(int) / setMaxRoleNumber(int)设置最大图数量/角色数量
setCpuLimit(int) / setMemoryLimit(int) / setStorageLimit(int)设置资源配额
setConfigs(Map<String, Object>)设置额外的配置项

5.2.2 - HugeGraph Python 客户端快速上手

hugegraph-python-client 是 Apache HugeGraph 的 Python SDK。它支持管理 Schema、读写图数据、执行 Gremlin 查询、进行 OLTP 实时图遍历以及 提交异步 OLAP 全图计算任务。HugeGraph-LLM 和 HugeGraph-ML 也依赖该客户端进行图数据库交互。

客户端源码位于 hugegraph-ai 仓库的 hugegraph-python-client/ 目录下,导入包名为 pyhugegraph。

环境要求

  • Python >= 3.12(支持 Python 3.12–3.14)。
  • HugeGraph Server 1.5.0 或更高版本(Server 1.7+ 推荐开启 GraphSpace 模式;1.5/1.6 使用传统路由)。
  • pip 或 uv 包管理器。

运行时依赖包括 decorator、requests、urllib3 和 rich。

安装

客户端提供两种安装方式,具体取决于使用的是 PyPI 稳定发行版还是 master 分支最新的开发功能。

说明

版本与功能边界说明: 已发布的 PyPI 发行包(hugegraph-python 1.7.x)为稳定基础版本,以 CamelCase 命名风格为主(带旧版 snake_case 别名)。 本文档演示的现代特性——包括原生 snake_case API、client.olap() 全图计算算法、client.task().wait() 任务轮询等待、 client.close() 连接生命周期管理以及更新后的遍历器签名——均对齐 master 分支最新实现。 如需体验或测试这些新特性,请通过源码方式安装客户端。

PyPI 稳定版 (1.7.x)
1pip install hugegraph-python
2# 或使用 uv:
3# uv pip install hugegraph-python
源码安装 (Master)
1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai/hugegraph-python-client
3pip install -e .
Workspace 同步 (uv)
1git clone https://github.com/apache/hugegraph-ai.git
2cd hugegraph-ai
3uv sync --extra python-client
4source .venv/bin/activate

连接与数据写入

 1from pyhugegraph.client import PyHugeClient
 2
 3client = PyHugeClient(
 4    url="http://127.0.0.1:8080",
 5    graph="hugegraph",
 6    user="admin",
 7    pwd="admin",
 8    graphspace=None,
 9)
10
11schema = client.schema()
12schema.property_key("name").as_text().if_not_exist().create()
13schema.property_key("birthDate").as_text().if_not_exist().create()
14schema.vertex_label("Person").properties("name", "birthDate") \
15      .use_primary_key_id().primary_keys("name").if_not_exist().create()
16schema.vertex_label("Movie").properties("name") \
17      .use_primary_key_id().primary_keys("name").if_not_exist().create()
18schema.edge_label("ActedIn").source_label("Person").target_label("Movie") \
19      .if_not_exist().create()
20
21graph = client.graph()
22person = graph.add_vertex(
23    "Person", {"name": "Al Pacino", "birthDate": "1940-04-25"}
24)
25movie = graph.add_vertex("Movie", {"name": "The Godfather"})
26edge = graph.add_edge("ActedIn", person.id, movie.id, {})
27
28print(graph.get_vertex_by_id(person.id))
29print(graph.get_edge_by_id(edge.id))
30
31client.close()

客户端初始化参数

PyHugeClient(url, graph, user, pwd, graphspace=None, timeout=None, *, token=None)

参数类型默认值说明
urlstr必填HugeGraph Server 基础地址。若未携带协议前缀,会自动补齐 http://(例如 127.0.0.1:8080)。
graphstr必填目标图实例名称,为第二个位置参数。
userstr必填用户名,用于 HTTP Basic Auth 认证。
pwdstr必填密码,用于 HTTP Basic Auth 认证。
graphspacestr 或 NoneNoneGraphSpace 名称。为 None 时通过版本探测自动决定路由。
timeoutfloat、tuple[float, float] 或 NoneNone(connect, read) 超时秒数,或统一指定单个浮点数。默认值为 (0.5, 15.0)。
tokenstr 或 NoneNone显式指定 Bearer Token;提供时优先覆盖 Basic Auth 认证。

对于幂等请求,在收到 500、502、504 错误响应时最多重试 3 次(退避系数为 0.1)。异步任务轮询等待期间会自动管理截止时间预算,不额外触发重定向或 HTTP 重试。

服务端版本与 GraphSpace 路由

客户端在初始化阶段自动解析 GraphSpace 路由:

  • 显式传入非空 graphspace 时,直接启用对应的 GraphSpace 路由模式。
  • graphspace=None 时,客户端向 GET {url}/versions 发起探测以获取服务端内核版本。
  • HugeGraph Server 1.7+ 默认启用 GraphSpace 并分配至 DEFAULT。
  • HugeGraph Server 1.5 / 1.6 保持传统无 GraphSpace 路由。
  • 低于 1.5.0 的版本不支持,初始化时会抛出 RuntimeError。
  • 若版本探测失败且未显式指定 GraphSpace,客户端初始化将直接抛出异常,避免错误猜测服务端路由结构。

路由模式决定了服务端请求路径前缀:开启 GraphSpace 时为 /graphspaces/<graphspace>/graphs/<graph>/...,关闭时为 /graphs/<graph>/...。

客户端入口概览

PyHugeClient 实例维护全局共享的 HTTP Session。所有管理器均采用延迟加载并缓存复用:

访问入口管理器类功能范围
client.schema()SchemaManager属性类型、顶点类型、边类型、索引类型管理
client.graph()GraphManager顶点与边增删改查、批量写入、条件分页查询
client.gremlin()GremlinManager执行 Gremlin 查询语句
client.traverser()TraverserManager实时图遍历与路径查询(OLTP)
client.rank()RankManager实时个性化推荐排序(OLTP)
client.olap()OlapManager异步全图计算算法作业(OLAP)
client.task()TaskManager异步任务状态查询、结果轮询等待、任务取消与删除
client.graphs()GraphsManager图元数据查看、配置导出、图列表、清空全图数据
client.graphspaces()GraphspaceManager多图空间(GraphSpace)生命周期管理
client.schema_templates()SchemaTemplateManager可复用 Schema 模板管理
client.auth()AuthManager用户、用户组、目标资源、所属关系与权限管理
client.variable()VariableManager图级别持久化键值变量
client.metrics()MetricsManager服务端监控指标数据采集
client.version()VersionManager服务端及各组件版本信息
client.rest()RestClient底层 REST API 直接调用及扩展端点

常用操作

定义 Schema

Schema 构造器采用链式调用。调用 create() 执行创建,或使用 append()、eliminate()、remove() 修改已有定义:

 1schema = client.schema()
 2
 3# 属性类型:as_text / as_int / as_long / as_float / as_double / as_bool / as_date
 4# 基数模式:value_single / value_list / value_set
 5schema.property_key("age").as_int().value_single().if_not_exist().create()
 6
 7# 顶点类型:use_automatic_id / use_customize_string_id / use_primary_key_id
 8schema.vertex_label("person").properties("name", "age", "city") \
 9      .primary_keys("name").nullable_keys("city").if_not_exist().create()
10
11# 边类型:link() 快捷指定起点与终点顶点类型
12schema.edge_label("knows").link("person", "person").multi_times() \
13      .properties("date", "city").sort_keys("date").nullable_keys("city") \
14      .if_not_exist().create()
15
16# 索引类型:on_v / on_e,支持 secondary / range / search / shard / unique
17schema.index_label("personByCity").on_v("person").by("city") \
18      .secondary().if_not_exist().create()

查询 Schema

 1schema = client.schema()
 2print(schema.get_schema())            # 获取全图 Schema 结构字典
 3print(schema.get_property_keys())
 4print(schema.get_vertex_labels())
 5print(schema.get_edge_labels())
 6print(schema.get_index_labels())
 7
 8# 查询单个 Schema 定义
 9print(schema.get_property_key("name"))
10print(schema.get_vertex_label("person"))
11print(schema.get_edge_label("knows"))
12print(schema.get_index_label("personByCity"))
13
14# 边关联关系概览,格式形如 "Person--ActedIn-->Movie"
15print(schema.get_relations())

增删改查图数据

图数据 API 直接接收 Python 属性字典:

1graph = client.graph()
2graph.append_vertex(person.id, {"birthDate": "1940-04-25"})    # 追加属性
3graph.eliminate_vertex(person.id, {"birthDate": "1940-04-25"}) # 移除属性
4graph.append_edge(edge.id, {"city": "Beijing"})
5graph.eliminate_edge(edge.id, {"city": "Beijing"})
6graph.remove_edge_by_id(edge.id)
7graph.remove_vertex_by_id(person.id)

add_vertex 返回包含 id、label、type 与 properties 的 VertexData 实例。 add_edge 返回包含 id、label、type、outV、outVLabel、inV、inVLabel 与 properties 的 EdgeData 实例。

传入客户端的顶点 ID 可以是字符串、整数或 uuid.UUID 对象。布尔类型会被拦截拒绝,整数必须位于 Java 64 位有符号整型范围内。

批量导入数据

add_vertices 接收 (label, properties) 元组列表,add_edges 接收 (label, out_id, in_id, out_label, in_label, properties) 元组列表:

1graph = client.graph()
2vertices = graph.add_vertices([
3    ("person", {"name": "Alice", "age": 20}),
4    ("person", {"name": "Bob", "age": 23}),
5])
6edges = graph.add_edges([
7    ("knows", vertices[0].id, vertices[1].id, "person", "person", {"date": "2012-01-10"}),
8])

分页与条件查询

 1graph = client.graph()
 2
 3# 分页迭代查询:传入上一页返回的 next_page token 即可继续拉取下一页
 4vertices, next_page = graph.get_vertex_by_page("person", limit=10)
 5vertices, next_page = graph.get_vertex_by_page("person", limit=10, page=next_page)
 6
 7# 服务端属性条件过滤
 8older = graph.get_vertex_by_condition("person", properties={"age": "P.gt(29)"})
 9
10# 边分页查询(指定 vertex_id 时必须同时指定 direction 方向)
11edges, next_page = graph.get_edge_by_page(label="knows", limit=10)
12edges, next_page = graph.get_edge_by_page(vertex_id=person.id, direction="OUT", limit=10)
13
14# 根据 ID 列表批量查询顶点与边
15graph.get_vertices_by_id([v1.id, v2.id])
16graph.get_edges_by_id([e1.id, e2.id])

执行 Gremlin 查询

1gremlin = client.gremlin()
2result = gremlin.exec("g.V().limit(5)")
3print(result)

exec() 会根据图实例名称及解析出的 GraphSpace 自动绑定 graph 与 g 别名,并解析返回服务端响应中的 result 数据内容。

实时图遍历(OLTP)

client.traverser() 封装了服务端实时图遍历接口,支持多跳邻居、最短路径、共同邻居与相似度计算:

 1traverser = client.traverser()
 2
 3traverser.k_out(marko_id, 2)
 4traverser.k_neighbor(marko_id, 2)
 5traverser.same_neighbors(marko_id, josh_id)
 6traverser.jaccard_similarity(marko_id, josh_id)
 7traverser.shortest_path(marko_id, ripple_id, 3)
 8traverser.all_shortest_paths(marko_id, ripple_id, 3)
 9traverser.weighted_shortest_path(marko_id, ripple_id, "weight", 3)
10traverser.single_source_shortest_path(marko_id, 2)
11traverser.multi_node_shortest_path([marko_id, josh_id], max_depth=2)
12traverser.paths(marko_id, josh_id, 2)
13traverser.crosspoints(marko_id, josh_id, 2)
14traverser.rings(marko_id, 3)
15traverser.rays(marko_id, 2)
16traverser.vertices(marko_id)
17traverser.edges(edge_id)

POST 方式的遍历接口支持复杂请求体:advanced_paths、customized_paths、template_paths、customized_crosspoints 以及 fusiform_similarity。

OLAP 全图计算任务

对于全图级别的重型计算算法(如 PageRank、Louvain 社区发现、中心度计算等),请使用 client.olap()。这些作业在服务端以异步任务方式运行并通过 Task ID 进行跟踪管理:

 1# 1. 提交异步计算任务
 2receipt = client.olap().count_vertex()
 3task_id = receipt["task_id"]
 4
 5# 2. 轮询等待任务完成并获取计算结果
 6task = client.task().wait(task_id, timeout=300, poll_interval=1)
 7result = client.task().result(task)
 8print(result)
 9
10# 也可以直接使用 run() 一步完成提交、等待与结果解析:
11result = client.olap().run("count_vertex", timeout=60)

支持的 OLAP 算法

服务端提供了 17 个唯一的全图计算算法名称:

算法类别具体算法名称
图统计count_edge、count_vertex、subgraph_stat、triangle_count、rings
中心度betweenness_centrality、closeness_centrality、degree_centrality、eigenvector_centrality、stress_centrality
社区与聚类cluster_coefficient、k_core、louvain、lpa、weak_connected_component
排序与相似度page_rank、fusiform_similarity
提示

类似 page_rank 的算法会将计算出的权重属性回写到图中。在要求显式 Schema 声明的环境中,执行 PageRank 前需在参与计算的顶点类型上提前声明名为 r_rank 的可空 DOUBLE 属性。

任务生命周期管理

TaskManager 提供了对异步任务的完整管控能力:

 1task = client.task()
 2
 3# 查询任务历史列表
 4task.list_tasks(status="success", limit=10)
 5
 6# 轮询等待指定任务完成
 7record = task.wait(task_id, timeout=300, poll_interval=1)
 8
 9# 解码任务执行结果(只对序列化 JSON 解析一次)
10result = task.result(record)
11
12# 取消或删除任务
13task.cancel_task(task_id)
14task.delete_task(task_id, force=False)
  • wait(id, timeout=300, poll_interval=1) 轮询期间仅查询任务状态而不拉取大体积结果,完成后再统一获取最终产出。
  • TaskTimeoutError 仅代表客户端轮询等待超时,服务端后台运行的任务作业不会被终止。
  • 如需强行终止服务端任务,请显式调用 cancel_task(id)。

图变量、监控与元数据

 1# 图变量管理
 2variable = client.variable()
 3variable.set("owner", "mary")
 4print(variable.get("owner"))
 5print(variable.all())
 6variable.remove("owner")
 7
 8# 监控指标数据
 9metrics = client.metrics()
10metrics.get_all_basic_metrics()
11metrics.get_system_metrics()
12metrics.get_backend_metrics()
13
14# 图管理与版本
15graphs = client.graphs()
16print(graphs.list())
17print(client.version().version())

认证与权限控制

PyHugeClient 同时支持 HTTP Basic Auth 与 Bearer Token 认证:

1# 将会话切换为 Bearer Token 认证
2client.use_token("your-jwt-token")
3
4# 恢复为初始化配置的 HTTP Basic Auth 凭据
5client.use_token(None)

AuthManager 支持在 GraphSpace 隔离下管理用户、用户组、目标资源、所属关系以及操作权限:

 1auth = client.auth()
 2
 3user = auth.create_user("test_user", "password")
 4auth.modify_user(user["id"], user_email="hugegraph@apache.org")
 5auth.get_user(user["id"])
 6auth.list_users(limit=10)
 7
 8group = auth.create_group("test_group", "read only")
 9auth.modify_group(group["id"], group_description="updated")
10auth.list_groups()
11
12target = auth.create_target("target1", "hugegraph", "127.0.0.1:8080", [])
13auth.update_target(target["id"], "target1", "hugegraph", "127.0.0.1:8080", [])
14auth.list_targets()
15
16belong = auth.create_belong(user["id"], group["id"])
17auth.update_belong(belong["id"], "description")
18auth.list_belongs()
19
20access = auth.grant_accesses(group["id"], target["id"], "READ")
21auth.modify_accesses(access["id"], "description")
22auth.list_accesses()
23
24# 按照依赖反向顺序清理资源
25auth.revoke_accesses(access["id"])
26auth.delete_belong(belong["id"])
27auth.delete_target(target["id"])
28auth.delete_group(group["id"])
29auth.delete_user(user["id"])

方法命名规范与迁移说明

  • 推荐规范:新代码请统一使用 snake_case 方法名(如 add_vertex、property_key 等)。
  • 兼容保证:现有的公开 CamelCase 方法(如 addVertex、propertyKey 等)作为直接别名持续得到兼容支持。
  • 客户端生命周期:结束调用后请统一通过 client.close() 释放连接池会话资源,无需单独关闭单个 manager。
  • 返回契约:
    • 传统快捷接口 get_all_graphs()、get_version() 和 get_graph_info() 保持返回 JSON 字符串以维护向前兼容。
    • 标准现代接口 client.graphs().list()、client.version().version() 和 client.graphs().get(graph_name) 直接返回已解析的 Python 字典。
    • 带权最短路径与单源最短路径方法不再支持 max_depth 参数(服务端接口不支持);请使用 capacity、max_degree 和 skip_degree 参数进行限制。

底层 REST API 直接调用

对于批量原生接口调用或高级管理器尚未封装的扩展接口,可通过 client.rest() 直接访问完整 REST 接口面:

1rest = client.rest()
2print(rest.vertex.list(label="person", offset=0, limit=20))
3print(rest.task.list(status="success", page="", limit=20))

下表列出与服务端完全对齐的 194 个底层 REST 端点:

Python REST entryMethodPathQuery parameters
rest.access.create()POST/graphspaces/{graphspace}/auth/accesses—
rest.access.delete()DELETE/graphspaces/{graphspace}/auth/accesses/{id}—
rest.access.get()GET/graphspaces/{graphspace}/auth/accesses/{id}—
rest.access.list()GET/graphspaces/{graphspace}/auth/accessesgroup, target, limit
rest.access.update()PUT/graphspaces/{graphspace}/auth/accesses/{id}—
rest.adamic_adar.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/adamicadarvertex, other, direction, label, max_degree, limit
rest.algorithm.post()POST/graphspaces/{graphspace}/graphs/{graph}/jobs/algorithm/{name}—
rest.all_shortest_paths.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/allshortestpathssource, target, direction, label, max_depth, max_degree, skip_degree, with_vertex, with_edge, capacity
rest.arthas.start_arthas()PUT/arthas—
rest.belong.create()POST/graphspaces/{graphspace}/auth/belongs—
rest.belong.delete()DELETE/graphspaces/{graphspace}/auth/belongs/{id}—
rest.belong.get()GET/graphspaces/{graphspace}/auth/belongs/{id}—
rest.belong.list()GET/graphspaces/{graphspace}/auth/belongsuser, group, limit
rest.belong.update()PUT/graphspaces/{graphspace}/auth/belongs/{id}—
rest.computer.post()POST/graphspaces/{graphspace}/graphs/{graph}/jobs/computer/{name}—
rest.count.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/count—
rest.crosspoints.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/crosspointssource, target, direction, label, max_depth, max_degree, capacity, limit
rest.customized_crosspoints.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/customizedcrosspoints—
rest.customized_paths.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/customizedpaths—
rest.cypher.post()POST/graphspaces/{graphspace}/graphs/{graph}/cypher—
rest.cypher.query()GET/graphspaces/{graphspace}/graphs/{graph}/cyphercypher
rest.edge.create()POST/graphspaces/{graphspace}/graphs/{graph}/graph/edges—
rest.edge.create_batch()POST/graphspaces/{graphspace}/graphs/{graph}/graph/edges/batchcheck_vertex
rest.edge.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/graph/edges/{id}label
rest.edge.get()GET/graphspaces/{graphspace}/graphs/{graph}/graph/edges/{id}—
rest.edge.list()GET/graphspaces/{graphspace}/graphs/{graph}/graph/edgesvertex_id, direction, label, properties, keep_start_p, offset, page, limit
rest.edge.update_batch()PUT/graphspaces/{graphspace}/graphs/{graph}/graph/edges/batch—
rest.edge.update_by_id()PUT/graphspaces/{graphspace}/graphs/{graph}/graph/edges/{id}action
rest.edge_existence.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/edgeexistsource, target, label, sort_values, limit
rest.edge_label.create()POST/graphspaces/{graphspace}/graphs/{graph}/schema/edgelabels—
rest.edge_label.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/schema/edgelabels/{name}—
rest.edge_label.get()GET/graphspaces/{graphspace}/graphs/{graph}/schema/edgelabels/{name}—
rest.edge_label.list()GET/graphspaces/{graphspace}/graphs/{graph}/schema/edgelabelsnames
rest.edge_label.update()PUT/graphspaces/{graphspace}/graphs/{graph}/schema/edgelabels/{name}action
rest.edges.list()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/edgesids
rest.edges.scan()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/edges/scanstart, end, page, page_limit
rest.edges.shards()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/edges/shardssplit_size
rest.exception_trace.get()GET/exception/trace—
rest.exception_trace.trace()PUT/exception/trace—
rest.fusiform_similarity.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/fusiformsimilarity—
rest.graph_space.check_default_role()GET/graphspaces/{graphspace}/roleuser, role, graph
rest.graph_space.create()POST/graphspaces—
rest.graph_space.delete()DELETE/graphspaces/{name}—
rest.graph_space.delete_default_role()DELETE/graphspaces/{graphspace}/roleuser, role, graph
rest.graph_space.get()GET/graphspaces/{graphspace}—
rest.graph_space.list()GET/graphspaces—
rest.graph_space.list_profile()GET/graphspaces/profileprefix
rest.graph_space.manage()PUT/graphspaces/{name}—
rest.graph_space.set_default_role()POST/graphspaces/{graphspace}/role—
rest.graph_space_group.create()POST/graphspaces/{graphspace}/auth/groups—
rest.graph_space_group.delete()DELETE/graphspaces/{graphspace}/auth/groups/{id}—
rest.graph_space_group.get()GET/graphspaces/{graphspace}/auth/groups/{id}—
rest.graph_space_group.list()GET/graphspaces/{graphspace}/auth/groupslimit
rest.graph_space_group.update()PUT/graphspaces/{graphspace}/auth/groups/{id}—
rest.graphs.clear()DELETE/graphspaces/{graphspace}/graphs/{name}/clearconfirm_message
rest.graphs.clone_schema()POST/graphspaces/{graphspace}/graphs/{name}/schema-clonesource
rest.graphs.compact()PUT/graphspaces/{graphspace}/graphs/{name}/compact—
rest.graphs.create()POST/graphspaces/{graphspace}/graphs/{name}clone_graph_name
rest.graphs.create_by_text()POST/graphspaces/{graphspace}/graphs/{name}clone_graph_name
rest.graphs.create_snapshot()PUT/graphspaces/{graphspace}/graphs/{name}/snapshot_create—
rest.graphs.drop()DELETE/graphspaces/{graphspace}/graphs/{name}confirm_message
rest.graphs.get()GET/graphspaces/{graphspace}/graphs/{name}—
rest.graphs.get_conf()GET/graphspaces/{graphspace}/graphs/{name}/conf—
rest.graphs.get_default()GET/graphspaces/{graphspace}/graphs/default—
rest.graphs.graph_read_mode_get()GET/graphspaces/{graphspace}/graphs/{name}/graph_read_mode—
rest.graphs.graph_read_mode_set()PUT/graphspaces/{graphspace}/graphs/{name}/graph_read_mode—
rest.graphs.list()GET/graphspaces/{graphspace}/graphs—
rest.graphs.list_profile()GET/graphspaces/{graphspace}/graphs/profileprefix
rest.graphs.loading_mode_get()GET/graphspaces/{graphspace}/graphs/{name}/mode/owners—
rest.graphs.loading_mode_set()PUT/graphspaces/{graphspace}/graphs/{name}/mode/owners—
rest.graphs.manage()PUT/graphspaces/{graphspace}/graphs/{name}—
rest.graphs.mode_get()GET/graphspaces/{graphspace}/graphs/{name}/mode—
rest.graphs.mode_set()PUT/graphspaces/{graphspace}/graphs/{name}/mode—
rest.graphs.reload()PUT/graphspaces/{graphspace}/graphs/manage—
rest.graphs.resume_snapshot()PUT/graphspaces/{graphspace}/graphs/{name}/snapshot_resume—
rest.graphs.set_default()POST/graphspaces/{graphspace}/graphs/{name}/default—
rest.graphs.unset_default()DELETE/graphspaces/{graphspace}/graphs/{name}/default—
rest.gremlin.get()GET/gremlingremlin, language; additional query map
rest.gremlin.post()POST/gremlin—
rest.gremlin_job.post()POST/graphspaces/{graphspace}/graphs/{graph}/jobs/gremlin—
rest.group.create()POST/auth/groups—
rest.group.delete()DELETE/auth/groups/{id}—
rest.group.get()GET/auth/groups/{id}—
rest.group.list()GET/auth/groupslimit
rest.group.update()PUT/auth/groups/{id}—
rest.index_label.create()POST/graphspaces/{graphspace}/graphs/{graph}/schema/indexlabels—
rest.index_label.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/schema/indexlabels/{name}—
rest.index_label.get()GET/graphspaces/{graphspace}/graphs/{graph}/schema/indexlabels/{name}—
rest.index_label.list()GET/graphspaces/{graphspace}/graphs/{graph}/schema/indexlabelsnames
rest.index_label.update()PUT/graphspaces/{graphspace}/graphs/{graph}/schema/indexlabels/{name}action
rest.jaccard_similarity.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/jaccardsimilarityvertex, other, direction, label, max_degree
rest.jaccard_similarity.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/jaccardsimilarity—
rest.kneighbor.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/kneighborsource, direction, label, max_depth, count_only, max_degree, limit
rest.kneighbor.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/kneighbor—
rest.kout.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/koutsource, direction, label, max_depth, nearest, count_only, max_degree, capacity, limit
rest.kout.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/kout—
rest.login.login()POST/auth/login—
rest.login.logout()DELETE/auth/logout—
rest.login.verify_token()GET/auth/verify—
rest.manager.check_default_role()GET/graphspaces/{graphspace}/auth/managers/defaultrole, graph
rest.manager.check_role()GET/graphspaces/{graphspace}/auth/managers/checktype
rest.manager.create_manager()POST/graphspaces/{graphspace}/auth/managers—
rest.manager.delete()DELETE/graphspaces/{graphspace}/auth/managersuser, type
rest.manager.get_roles_in_gs()GET/graphspaces/{graphspace}/auth/managers/roleuser
rest.manager.list()GET/graphspaces/{graphspace}/auth/managerstype
rest.metrics.all()GET/metricstype
rest.metrics.backend()GET/metrics/backend—
rest.metrics.counters()GET/metrics/counters—
rest.metrics.gauges()GET/metrics/gauges—
rest.metrics.histograms()GET/metrics/histograms—
rest.metrics.meters()GET/metrics/meters—
rest.metrics.statistics()GET/metrics/statisticstype
rest.metrics.system()GET/metrics/system—
rest.metrics.timers()GET/metrics/timers—
rest.multi_node_shortest_path.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/multinodeshortestpath—
rest.neighbor_rank.neighbor_rank()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/neighborrank—
rest.paths.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/pathssource, target, direction, label, max_depth, max_degree, capacity, limit
rest.paths.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/paths—
rest.personal_rank.personal_rank()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/personalrank—
rest.profile.get_profile()GET/—
rest.profile.show_all_apis()GET/apis—
rest.project.create()POST/graphspaces/{graphspace}/auth/projects—
rest.project.delete()DELETE/graphspaces/{graphspace}/auth/projects/{id}—
rest.project.get()GET/graphspaces/{graphspace}/auth/projects/{id}—
rest.project.list()GET/graphspaces/{graphspace}/auth/projectslimit
rest.project.update()PUT/graphspaces/{graphspace}/auth/projects/{id}action
rest.property_key.create()POST/graphspaces/{graphspace}/graphs/{graph}/schema/propertykeys—
rest.property_key.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/schema/propertykeys/{name}—
rest.property_key.get()GET/graphspaces/{graphspace}/graphs/{graph}/schema/propertykeys/{name}—
rest.property_key.list()GET/graphspaces/{graphspace}/graphs/{graph}/schema/propertykeysnames
rest.property_key.update()PUT/graphspaces/{graphspace}/graphs/{graph}/schema/propertykeys/{name}action
rest.raft.add_peer()POST/graphspaces/{graphspace}/graphs/{graph}/raft/add_peergroup, endpoint
rest.raft.get_leader()GET/graphspaces/{graphspace}/graphs/{graph}/raft/get_leadergroup
rest.raft.list_peers()GET/graphspaces/{graphspace}/graphs/{graph}/raft/list_peersgroup
rest.raft.remove_peer()POST/graphspaces/{graphspace}/graphs/{graph}/raft/remove_peergroup, endpoint
rest.raft.set_leader()POST/graphspaces/{graphspace}/graphs/{graph}/raft/set_leadergroup, endpoint
rest.raft.transfer_leader()POST/graphspaces/{graphspace}/graphs/{graph}/raft/transfer_leadergroup, endpoint
rest.rays.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/rayssource, direction, label, max_depth, max_degree, capacity, limit, with_vertex, with_edge
rest.rebuild.edge_label_rebuild()PUT/graphspaces/{graphspace}/graphs/{graph}/jobs/rebuild/edgelabels/{name}—
rest.rebuild.index_label_rebuild()PUT/graphspaces/{graphspace}/graphs/{graph}/jobs/rebuild/indexlabels/{name}—
rest.rebuild.vertex_label_rebuild()PUT/graphspaces/{graphspace}/graphs/{graph}/jobs/rebuild/vertexlabels/{name}—
rest.resource_allocation.create()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/resourceallocationvertex, other, direction, label, max_degree, limit
rest.rings.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/ringssource, direction, label, max_depth, source_in_ring, max_degree, capacity, limit, with_vertex, with_edge
rest.same_neighbors.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/sameneighborsvertex, other, direction, label, max_degree, limit
rest.same_neighbors.same_neighbors()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/sameneighbors—
rest.same_neighbors_batch.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/sameneighborsbatch—
rest.schema.list()GET/graphspaces/{graphspace}/graphs/{graph}/schema—
rest.schema_template.create()POST/graphspaces/{graphspace}/schematemplates—
rest.schema_template.delete()DELETE/graphspaces/{graphspace}/schematemplates/{name}—
rest.schema_template.get()GET/graphspaces/{graphspace}/schematemplates/{name}—
rest.schema_template.list()GET/graphspaces/{graphspace}/schematemplates—
rest.schema_template.update()PUT/graphspaces/{graphspace}/schematemplates/{name}—
rest.shortest_path.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/shortestpathsource, target, direction, label, max_depth, max_degree, skip_degree, with_vertex, with_edge, capacity
rest.single_source_shortest_path.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/singlesourceshortestpathsource, direction, label, weight, max_degree, skip_degree, with_vertex, with_edge, capacity, limit
rest.target.create()POST/graphspaces/{graphspace}/auth/targets—
rest.target.delete()DELETE/graphspaces/{graphspace}/auth/targets/{id}—
rest.target.get()GET/graphspaces/{graphspace}/auth/targets/{id}—
rest.target.list()GET/graphspaces/{graphspace}/auth/targetslimit
rest.target.update()PUT/graphspaces/{graphspace}/auth/targets/{id}—
rest.task.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/tasks/{id}force
rest.task.get()GET/graphspaces/{graphspace}/graphs/{graph}/tasks/{id}with_result
rest.task.list()GET/graphspaces/{graphspace}/graphs/{graph}/tasksstatus, ids, limit, page
rest.task.update()PUT/graphspaces/{graphspace}/graphs/{graph}/tasks/{id}action
rest.template_paths.post()POST/graphspaces/{graphspace}/graphs/{graph}/traversers/templatepaths—
rest.user.create()POST/graphspaces/{graphspace}/auth/users—
rest.user.delete()DELETE/graphspaces/{graphspace}/auth/users/{id}—
rest.user.get()GET/graphspaces/{graphspace}/auth/users/{id}—
rest.user.list()GET/graphspaces/{graphspace}/auth/usersname, limit
rest.user.role()GET/graphspaces/{graphspace}/auth/users/{id}/role—
rest.user.update()PUT/graphspaces/{graphspace}/auth/users/{id}—
rest.variables.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/variables/{key}—
rest.variables.get()GET/graphspaces/{graphspace}/graphs/{graph}/variables/{key}—
rest.variables.list()GET/graphspaces/{graphspace}/graphs/{graph}/variables—
rest.variables.update()PUT/graphspaces/{graphspace}/graphs/{graph}/variables/{key}—
rest.version.list()GET/versions—
rest.vertex.create()POST/graphspaces/{graphspace}/graphs/{graph}/graph/vertices—
rest.vertex.create_batch()POST/graphspaces/{graphspace}/graphs/{graph}/graph/vertices/batch—
rest.vertex.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/graph/vertices/{id}label
rest.vertex.get()GET/graphspaces/{graphspace}/graphs/{graph}/graph/vertices/{id}—
rest.vertex.list()GET/graphspaces/{graphspace}/graphs/{graph}/graph/verticeslabel, properties, keep_start_p, offset, page, limit
rest.vertex.update_batch()PUT/graphspaces/{graphspace}/graphs/{graph}/graph/vertices/batch—
rest.vertex.update_by_id()PUT/graphspaces/{graphspace}/graphs/{graph}/graph/vertices/{id}action
rest.vertex_label.create()POST/graphspaces/{graphspace}/graphs/{graph}/schema/vertexlabels—
rest.vertex_label.delete()DELETE/graphspaces/{graphspace}/graphs/{graph}/schema/vertexlabels/{name}—
rest.vertex_label.get()GET/graphspaces/{graphspace}/graphs/{graph}/schema/vertexlabels/{name}—
rest.vertex_label.list()GET/graphspaces/{graphspace}/graphs/{graph}/schema/vertexlabelsnames
rest.vertex_label.update()PUT/graphspaces/{graphspace}/graphs/{graph}/schema/vertexlabels/{name}action
rest.vertices.list()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/verticesids
rest.vertices.scan()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/vertices/scanstart, end, page, page_limit
rest.vertices.shards()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/vertices/shardssplit_size
rest.weighted_shortest_path.get()GET/graphspaces/{graphspace}/graphs/{graph}/traversers/weightedshortestpathsource, target, direction, label, weight, max_degree, skip_degree, with_vertex, with_edge, capacity
rest.white_ip_list.list()GET/whiteiplist—
rest.white_ip_list.update_status()PUT/whiteipliststatus
rest.white_ip_list.update_white_ips()POST/whiteiplist—

异常处理

常见异常定义位于 pyhugegraph.utils.exceptions:

异常类型触发场景
NotAuthorizedError服务端返回 HTTP 401 未认证
NotFoundError服务端返回 HTTP 404 资源未找到
ServerError服务端返回非 2xx 响应(附带服务端错误详情)
ResponseParseError响应内容无法反序列化为预期格式
ServiceUnavailableError服务端暂时不可用
InvalidParameterError, CreateError, RemoveError, UpdateError, DataFormatError客户端本地参数或格式校验失败

敏感参数(密码、Token、密钥等)在日志输出中会自动脱敏处理。

1from pyhugegraph.utils.exceptions import NotFoundError
2
3try:
4    graph.get_vertex_by_id("missing-id")
5except NotFoundError:
6    print("未找到指定顶点")

开发与测试验证

在 HugeGraph-AI 仓库根目录下执行代码规范与测试套件:

  1. 代码格式化与静态检查:

    1uv run --extra dev ruff format --check .
    2uv run --extra dev ruff check .
    3uv run --extra dev ty check hugegraph-python-client/src/pyhugegraph
  2. 运行单元测试与契约测试:

    1uv run pytest hugegraph-python-client/src/tests -m "unit or contract"
  3. 针对正在运行的 HugeGraph Server 执行集成测试:

    1HUGEGRAPH_URL=http://127.0.0.1:8080 \
    2HUGEGRAPH_GRAPH=hugegraph \
    3HUGEGRAPH_USER=admin \
    4HUGEGRAPH_PASSWORD=admin \
    5uv run pytest hugegraph-python-client/src/tests -m "integration and hugegraph"

主线 CI 默认使用 hugegraph/hugegraph:latest 镜像进行集成验证,并对 1.7.0 执行兼容回归。源码与测试位于 hugegraph-python-client/src/pyhugegraph/ 和 hugegraph-python-client/src/tests/。

5.2.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 项目中执行:

1go get github.com/apache/hugegraph-toolchain/hugegraph-client-go

初始化客户端

NewCommonClient 要求 Host 是 IP 地址,Port 在 1 到 65535 之间;客户端始终使用明文 HTTP 连接。未启用认证时,用户名和密码留空;只有两者都设置时才会发送 Basic Auth。

GraphSpace 非空时,Vertex 和 Schema API(Schema()、Propertykey、VertexLabel、EdgeLabel)使用 /graphspaces/{space}/graphs/{graph}/... 路径;留空时使用旧版 /graphs/{graph}/... 路径。默认图空间填写 DEFAULT。 Gremlin 默认 aliases 也使用 GraphSpace,空值按 DEFAULT 处理。Version() 始终请求 /versions,不依赖图空间。

 1package main
 2
 3import (
 4	"fmt"
 5	"log"
 6
 7	hugegraph "github.com/apache/hugegraph-toolchain/hugegraph-client-go"
 8)
 9
10func main() {
11	client, err := hugegraph.NewCommonClient(hugegraph.Config{
12		Host:       "127.0.0.1",
13		Port:       8080,
14		GraphSpace: "DEFAULT",
15		Graph:      "hugegraph",
16		Username:   "",
17		Password:   "",
18	})
19	if err != nil {
20		log.Fatal(err)
21	}
22
23	response, err := client.Version()
24	if err != nil {
25		log.Fatal(err)
26	}
27	defer response.Body.Close()
28
29	fmt.Println(response.Versions.Version)
30}

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
GraphSpacestringVertex、Schema API 和 Gremlin 默认 aliases 使用的图空间;默认空间填写 DEFAULT
GraphstringServer 上配置的图名
UsernamestringServer 用户名,未启用认证时填空字符串
PasswordstringServer 密码,未启用认证时填空字符串
Transporthttp.RoundTripper自定义 HTTP transport,为 nil 时使用 http.DefaultTransport
Loggerhgtransport.Logger请求/响应日志,为 nil 时不记录日志

hgtransport 包提供四种 logger:TextLogger(纯文本)、ColorLogger(终端彩色)、CurlLogger(可执行的 curl 命令)和 JSONLogger(JSON 行)。它们的字段相同:Output(io.Writer)、EnableRequestBody 和 EnableResponseBody。

 1import (
 2	"os"
 3
 4	hugegraph "github.com/apache/hugegraph-toolchain/hugegraph-client-go"
 5	"github.com/apache/hugegraph-toolchain/hugegraph-client-go/hgtransport"
 6)
 7
 8client, err := hugegraph.NewCommonClient(hugegraph.Config{
 9	Host:  "127.0.0.1",
10	Port:  8080,
11	Graph: "hugegraph",
12	Logger: &hgtransport.ColorLogger{
13		Output:             os.Stdout,
14		EnableRequestBody:  true,
15		EnableResponseBody: true,
16	},
17})

已实现的入口

CommonClient 当前公开以下入口:

入口用途
Version()查询服务端版本
Schema()查询完整 Schema
PropertykeyCreate、GetAll、GetByName、UpdateUserdata、DeleteByName
VertexLabelCreate、GetAll、GetByName、UpdateUserdata、DeleteByName
EdgeLabelCreate、GetAll、DeleteByName
VertexCreate、BatchCreate、UpdateProperties(通过 WithAction 指定 append 或 eliminate)
GremlinGet 和 Post。Post 默认 language 为 gremlin-groovy,根据 GraphSpace 和 Graph 自动填充 graph/g aliases,并在 Data 中返回解析后的结果;Get 只返回状态码,并把原始响应打印到 stdout。

每个操作都通过挂在操作本身上的 With... 函数式选项传参,例如 client.Gremlin.Post.WithGremlin(...) 或 client.Propertykey.GetByName.WithName(...)。

EdgeLabel.Create 的请求数据允许 Properties: nil 或空切片 []string{},用于创建无属性的边标签。

类型化 API 返回的 err 表示参数校验、传输、响应读取或 JSON 解码错误。 HTTP 4xx/5xx 仍可能返回 err == nil,例如创建顶点时指定不存在的 label 会返回 HTTP 400。 读取结果数据前,请检查 response.StatusCode 是否属于 2xx。调用 Gremlin.Post 时,还需检查 response.Data.Status.Code 是否为成功的 Gremlin 协议状态码(2xx)。

 1resp, err := client.Gremlin.Post(
 2	client.Gremlin.Post.WithGremlin("g.V().limit(3)"),
 3)
 4if err != nil {
 5	log.Fatal(err)
 6}
 7defer resp.Body.Close()
 8if resp.StatusCode < 200 || resp.StatusCode >= 300 {
 9	log.Fatalf("HugeGraph returned HTTP %d", resp.StatusCode)
10}
11if resp.Data.Status.Code < 200 || resp.Data.Status.Code >= 300 {
12	log.Fatalf("Gremlin returned status %d: %s", resp.Data.Status.Code, resp.Data.Status.Message)
13}
14fmt.Println(resp.Data.Result.Data)

Vertex 相关操作的入参是 internal/model 包中的 model.Vertex[any]。Go 不允许从其他 module 导入 internal 包,因此目前 Vertex API 只能在客户端 module 内部调用;其测试文件也已全部注释。

完整调用方式可参考各 API 目录中的测试,例如 version_test.go、gemlin_test.go 和 vertexlabel_test.go。

5.3 - Gremlin-Console

Gremlin-Console 是 TinkerPop 的交互式客户端,支持离线操作图,也可以连接 Server 提交查询。常用 Gremlin 遍历语法与示例请参阅 Gremlin 查询语言。主要包含两种工作模式:

说明

Gremlin-Console 适合快速体验、原型探索与排查调试,不推荐直接用于高并发或高吞吐的生产环境。生产环境建议使用相应语言的客户端(如 HugeGraph-Client)。

1 单机离线调用模式

Server 发行包内的 Console 已包含 HugeGraph-Core JAR 和插件,可以直接执行 Groovy 脚本操作图,无需启动 Server。

先在 hugegraph.properties 中配置 Memory 后端。其他后端可能需要额外初始化。

1backend=memory
2serializer=text

然后运行示例脚本。

 1> ./bin/gremlin-console.sh -- -i scripts/example.groovy
 2
 3         \,,,/
 4         (o o)
 5-----oOOo-(3)-oOOo-----
 6plugin activated: HugeGraph
 7plugin activated: tinkerpop.server
 8plugin activated: tinkerpop.utilities
 9plugin activated: tinkerpop.tinkergraph
10main dict load finished, time elapsed 644 ms
11model load finished, time elapsed 35 ms.
12>>>> query all vertices: size=6
13>>>> query all edges: size=6
14gremlin> 

这里的 -- 会被 getopts 解析为最后一个 option,这样后面的 options 就可以传入 Gremlin-Console 进行处理了。-i 代表 Execute the specified script and leave the console open on completion,更多选项请参考 TinkerPop Gremlin Console 官方文档。

其中 example.groovy 是 scripts 目录下的一个示例脚本,该脚本插入了一些数据,并在最后查询图中顶点和边的数量。

脚本执行后,可以继续输入 Gremlin 语句。

 1gremlin> g.V()
 2==>v[2:lop]
 3==>v[1:josh]
 4==>v[1:marko]
 5==>v[1:peter]
 6==>v[1:vadas]
 7==>v[2:ripple]
 8gremlin> g.E()
 9==>e[S1:josh>2>>S2:lop][1:josh-created->2:lop]
10==>e[S1:josh>2>>S2:ripple][1:josh-created->2:ripple]
11==>e[S1:marko>1>>S1:josh][1:marko-knows->1:josh]
12==>e[S1:marko>1>>S1:vadas][1:marko-knows->1:vadas]
13==>e[S1:marko>2>>S2:lop][1:marko-created->2:lop]
14==>e[S1:peter>2>>S2:lop][1:peter-created->2:lop]
15gremlin> 

更多的 Gremlin 语句请参考 Tinkerpop 官网。

2 Client/Server 请求模式

Gremlin-Console 通过 WebSocket 连接 HugeGraph-Server。使用与 Server 同版本发行包中的 Console 和 conf/remote.yaml, 保留文件中的序列化器配置,只修改地址,以及启用鉴权时需要的凭据。旧版配置可能引用已经不存在的序列化器类。

  1. 准备连接配置并启动 Server。

    检查 conf/gremlin-server.yaml 中的 host、port。默认的 WsAndHttpChannelizer 同时处理 WebSocket 和 HTTP 请求,无需修改。 conf/remote.yaml 中的 hosts 应填写 Console 能访问的 Server 地址,port 应与 Gremlin 端口一致(默认为 8182,不是 REST 端口 8080)。 按照快速上手启动 Server。

    当前 master 配置使用 GraphBinary V1 和 HugeGraph 类型注册器。

    1hosts: [localhost]
    2port: 8182
    3serializer:
    4  className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1
    5  config:
    6    serializeResultToString: false
    7    builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder
    8    ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]

    如果 Server 开启了鉴权,在同一个文件中填写实际凭据。

    1username: admin
    2password: "replace-with-your-password"

    随包的 remote-objects.yaml 和 gremlin-driver-settings.yaml 使用相同的序列化器配置;使用这些文件时也要保持一致。

  2. 从 Server 发行包目录启动 Console,并创建带 traversal 别名的客户端。

    1./bin/gremlin-console.sh

    Server 端将默认图空间下的图绑定为 DEFAULT-hugegraph,其 traversal source 绑定为 __g_DEFAULT-hugegraph。 由于连字符 - 在 Groovy 中不能直接用作变量名,通过 Java Driver 连接时,使用 .alias(['g': '__g_DEFAULT-hugegraph']) 将其映射为 g。

    1import org.apache.tinkerpop.gremlin.driver.Cluster
    2cluster = Cluster.open('conf/remote.yaml')
    3client = cluster.connect().alias(['g': '__g_DEFAULT-hugegraph'])
  3. 通过客户端提交查询。

    1client.submit('g.V().count()').all().get()[0].object
    2client.submit('g.V().toList().size()').all().get()[0].object

    若启动 Server 时预加载了示例图,两条查询均返回 6(其他图返回其实际顶点数)。 通过 Driver 的 client.submit() 提交脚本时,无需在语句前加 :> 前缀。

  4. 使用结束后关闭客户端和集群连接。

    1client.close()
    2cluster.close()

此外,也可以使用 Gremlin Console 内置的 :remote 命令连接:

1:remote connect tinkerpop.server conf/remote.yaml
2// 通过 Console 远程连接提交脚本时,前缀使用 :>
3:remote close

使用 :remote 连接时,以 :> 开头的语句会被发送至远端 Server 执行,普通语句则在 Console 本地执行。

更多用法见 TinkerPop Gremlin Console 参考。

6 - 使用指南

本节说明 HugeGraph 的架构、设计、备份恢复、插件开发、安全设置和常见问题。

6.1 - HugeGraph 架构概览

全栈组件

HugeGraph 生态由职责不同的图数据库、图计算、图 AI 和工具链组件组成。HugeGraph Server 提供 OLTP 图数据库服务;HugeGraph-Computer 与 Vermeer 是独立的 OLAP 图计算引擎;HugeGraph-AI 提供图 AI 能力。Toolchain 中的客户端、数据导入、可视化和运维工具为应用及运维人员提供配套入口。

HugeGraph 架构总览图:展示 Toolchain、AI、Computer、Vermeer 与 Server、PD、Store 的关系

图:Server 以 HStore 后端为例;RocksDB、HBase 等独立后端见下方 Mermaid。Vermeer 和 HugeGraph-Computer 是独立的 OLAP 引擎,虚线表示可选接入。

生态接入

flowchart TB
  Apps["应用 / 运维"] --> Toolchain["Toolchain"] --> Server["Server REST API"]
  AI["AI"] -. REST .-> Server
  Computer["Computer"] -. REST .-> Server
  Vermeer["Vermeer"] -. PD .-> PD["PD"]
  Vermeer -. 扫描 .-> Store["Store"]
  Vermeer -. 写回 .-> Server

虚线表示可选的 HugeGraph 接入,不代表所有 AI、Computer 或 Vermeer 任务都必须连接 Server、PD 或 Store。Computer 和 AI 通过 Server REST API 读写图数据。Vermeer 的 HugeGraph 输入模式向 PD 查询分区元数据,并直接向 Store 扫描 HStore 分区;选择 HugeGraph 结果输出时,再通过 Server REST API 写回结果。

Server 内部结构

flowchart TB
  API["REST API / Gremlin"] --> Core["Core"] --> Adapter["后端适配"]
  Adapter --> RocksDB["RocksDB"]
  Adapter --> HBase["HBase"]
  Adapter --> HStore["HStore"]
  HStore --> PD["PD"]
  HStore --> Store["Store"]

Server 的 REST API 和 Gremlin 接口把请求交给 Core,再由存储后端适配器执行读写。RocksDB 和 HBase 是独立后端;HStore 适配器从 PD 获取集群元数据和分区信息,并向 Store 节点发送图数据操作。PD 管理集群元数据与分区,不承载图数据读写路径。

当前 Server 提供 RocksDB、HBase、HStore 和内存后端实现。内存后端主要用于测试或临时使用,不属于正式持久化部署选项;生产部署方式见 Server 快速上手。

Toolchain 的主要组件如下:

  • Hubble — Web 交互式图可视化与一站式管理工作台。
  • Loader — 支持多源、断点续传的高性能批量图数据导入工具。
  • Tools — 提供集群部署运维、元数据检查与备份恢复能力的 CLI 工具。
  • Client — 官方多语言客户端 SDK,支持 Java、Python 与 Go。

独立图计算引擎

  • Vermeer — 基于 Go 实现的高性能内存级图计算引擎,内置 15+ OLAP 核心算法。
  • HugeGraph-Computer — 基于 BSP/Pregel 模型的 Java 分布式大规模图计算框架。

历史架构图

下图保留作历史参考,其中 Server 同时承担 OLTP 与 OLAP、以及多种旧后端的标注不代表 当前主线实现。

展开旧版架构图
旧版 HugeGraph 架构图,仅用于历史参考

相关专题

  • HugeGraph Plugin

    介绍 HugeGraph Plugin 扩展机制、SPI 接口注册与自定义插件生命周期。

  • 设计理念(legacy)

    早期属性图模型设计背景、分区方案与历史实现考量。

6.1.1 - HugeGraph Plugin 机制及插件扩展流程

插件接入计划用于 1.8.0 的共享基础模块 API 时,请按Java/SPI 迁移指南调整并使用配套 artifacts 重新编译。 下方示例描述 1.7.0 API。

背景

  1. HugeGraph 不仅开源开放,而且要做到简单易用,一般用户无需更改源码也能轻松增加插件扩展功能。
  2. HugeGraph 支持多种内置存储后端,也允许用户无需更改现有源码的情况下扩展自定义后端。
  3. HugeGraph 支持全文检索,全文检索功能涉及到各语言分词,目前已内置 7 种分词器(ansj、hanlp、smartcn、jieba、jcseg、mmseg4j、ikanalyzer),也允许用户无需更改现有源码的情况下扩展自定义分词器。

可扩展维度

目前插件方式提供如下几个维度的扩展项:

  • 后端存储
  • 序列化器
  • 自定义配置项
  • 分词器

插件实现机制

  1. 提供 SPI 接口:HugeGraph 提供核心插件接口 HugeGraphPlugin,通过标准 Java SPI 机制支持运行时插件化发现。
  2. 静态注册入口:HugeGraphPlugin 提供了 4 个扩展项注册静态函数:registerOptions()、registerBackend()、registerSerializer()、registerAnalyzer()。
  3. 实现扩展接口:插件开发者实现相应的 OptionHolder、BackendStoreProvider、AbstractSerializer 或 Analyzer 等核心接口。
  4. 插件注册并打包:实现 HugeGraphPlugin 的 register() 方法完成类注册,配置 META-INF/services/ 描述文件并打成 JAR 包。
  5. 部署生效:将编译出的 JAR 包放置在 HugeGraph Server 安装目录的 plugins/ 路径下,修改对应配置项后重启服务即可生效。

插件实现流程实例

1 新建一个 maven 项目

1.1 项目名称取名:hugegraph-plugin-demo
1.2 添加hugegraph-core Jar 包依赖

maven pom.xml 详细内容如下。hugegraph.version 应与要兼容的 Server 版本一致;此处以当前主线版本 1.7.0 为例:

 1<?xml version="1.0" encoding="UTF-8"?>
 2
 3<project xmlns="http://maven.apache.org/POM/4.0.0"
 4         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 6
 7    <modelVersion>4.0.0</modelVersion>
 8    <groupId>org.apache.hugegraph</groupId>
 9    <artifactId>hugegraph-plugin-demo</artifactId>
10    <version>1.0.0</version>
11    <packaging>jar</packaging>
12
13    <name>hugegraph-plugin-demo</name>
14
15    <properties>
16        <hugegraph.version>1.7.0</hugegraph.version>
17    </properties>
18
19    <dependencies>
20        <dependency>
21            <groupId>org.apache.hugegraph</groupId>
22            <artifactId>hugegraph-core</artifactId>
23            <version>${hugegraph.version}</version>
24        </dependency>
25    </dependencies>
26</project>

2 实现扩展功能

2.1 扩展自定义后端
2.1.1 实现接口 BackendStoreProvider
  • 可实现接口:org.apache.hugegraph.backend.store.BackendStoreProvider
  • 或者继承抽象类:org.apache.hugegraph.backend.store.AbstractBackendStoreProvider

以 RocksDB 后端 RocksDBStoreProvider 为例:

 1public class RocksDBStoreProvider extends AbstractBackendStoreProvider {
 2
 3    protected String database() {
 4        return this.graph().toLowerCase();
 5    }
 6
 7    @Override
 8    protected BackendStore newSchemaStore(HugeConfig config, String store) {
 9        return new RocksDBStore.RocksDBSchemaStore(this, this.database(), store);
10    }
11
12    @Override
13    protected BackendStore newGraphStore(HugeConfig config, String store) {
14        return new RocksDBStore.RocksDBGraphStore(this, this.database(), store);
15    }
16
17    @Override
18    protected BackendStore newSystemStore(HugeConfig config, String store) {
19        return new RocksDBStore.RocksDBSystemStore(this, this.database(), store);
20    }
21
22    @Override
23    public String type() {
24        return "rocksdb";
25    }
26
27    @Override
28    public String driverVersion() {
29        return "1.11";
30    }
31}
2.1.2 实现接口 BackendStore

BackendStore 的核心抽象方法如下(接口默认辅助方法略):

 1public interface BackendStore {
 2    // Store name
 3    String store();
 4
 5    // Stored version
 6    String storedVersion();
 7
 8    // Database name
 9    String database();
10
11    // Get the parent provider
12    BackendStoreProvider provider();
13
14    // Get the system schema store
15    SystemSchemaStore systemSchemaStore();
16
17    // Whether it is the storage of schema
18    boolean isSchemaStore();
19
20    // Open/close database
21    void open(HugeConfig config);
22    void close();
23    boolean opened();
24
25    // Initialize/clear database
26    void init();
27    void clear(boolean clearSpace);
28    boolean initialized();
29
30    // Delete all data of database (keep table structure)
31    void truncate();
32
33    // Add/delete data
34    void mutate(BackendMutation mutation);
35
36    // Query data
37    Iterator<BackendEntry> query(Query query);
38    Iterator<Iterator<BackendEntry>> query(Iterator<Query> queries,
39                                           Function<Query, Query> queryWriter,
40                                           HugeGraph hugeGraph);
41    Number queryNumber(Query query);
42
43    // Transaction
44    void beginTx();
45    void commitTx();
46    void rollbackTx();
47
48    // Get metadata by key
49    <R> R metadata(HugeType type, String meta, Object[] args);
50
51    // Backend features
52    BackendFeatures features();
53
54    // Increase next id for specific type
55    void increaseCounter(HugeType type, long increment);
56
57    // Get current counter for a specific type
58    long getCounter(HugeType type);
59}
2.1.3 扩展自定义序列化器

序列化器必须继承抽象类:org.apache.hugegraph.backend.serializer.AbstractSerializer(implements GraphSerializer, SchemaSerializer) 主要接口的定义如下:

 1public interface GraphSerializer {
 2    BackendEntry writeVertex(HugeVertex vertex);
 3    BackendEntry writeOlapVertex(HugeVertex vertex);
 4    BackendEntry writeVertexProperty(HugeVertexProperty<?> prop);
 5    HugeVertex readVertex(HugeGraph graph, BackendEntry entry);
 6    BackendEntry writeEdge(HugeEdge edge);
 7    BackendEntry writeEdgeProperty(HugeEdgeProperty<?> prop);
 8    HugeEdge readEdge(HugeGraph graph, BackendEntry entry);
 9    CIter<Edge> readEdges(HugeGraph graph, BackendEntry bytesEntry);
10    BackendEntry writeIndex(HugeIndex index);
11    HugeIndex readIndex(HugeGraph graph, ConditionQuery query, BackendEntry entry);
12    BackendEntry writeId(HugeType type, Id id);
13    Query writeQuery(Query query);
14}
15
16public interface SchemaSerializer {
17    BackendEntry writeVertexLabel(VertexLabel vertexLabel);
18    VertexLabel readVertexLabel(HugeGraph graph, BackendEntry entry);
19    BackendEntry writeEdgeLabel(EdgeLabel edgeLabel);
20    EdgeLabel readEdgeLabel(HugeGraph graph, BackendEntry entry);
21    BackendEntry writePropertyKey(PropertyKey propertyKey);
22    PropertyKey readPropertyKey(HugeGraph graph, BackendEntry entry);
23    BackendEntry writeIndexLabel(IndexLabel indexLabel);
24    IndexLabel readIndexLabel(HugeGraph graph, BackendEntry entry);
25}
2.1.4 扩展自定义配置项

增加自定义后端时,可能需要增加新的配置项,实现流程主要包括:

  • 增加配置项容器类,并实现接口org.apache.hugegraph.config.OptionHolder
  • 提供单例方法public static OptionHolder instance(),并在对象初始化时调用方法OptionHolder.registerOptions()
  • 增加配置项声明,单值配置项类型为ConfigOption、多值配置项类型为ConfigListOption

以 RocksDB 配置项定义为例:

 1public class RocksDBOptions extends OptionHolder {
 2
 3    private RocksDBOptions() {
 4        super();
 5    }
 6
 7    private static volatile RocksDBOptions instance;
 8
 9    public static synchronized RocksDBOptions instance() {
10        if (instance == null) {
11            instance = new RocksDBOptions();
12            instance.registerOptions();
13        }
14        return instance;
15    }
16
17    public static final ConfigOption<String> DATA_PATH =
18            new ConfigOption<>(
19                    "rocksdb.data_path",
20                    "The path for storing data of RocksDB.",
21                    disallowEmpty(),
22                    "rocksdb-data/data"
23            );
24
25    public static final ConfigOption<String> WAL_PATH =
26            new ConfigOption<>(
27                    "rocksdb.wal_path",
28                    "The path for storing WAL of RocksDB.",
29                    disallowEmpty(),
30                    "rocksdb-data/wal"
31            );
32
33    public static final ConfigListOption<String> DATA_DISKS =
34            new ConfigListOption<>(
35                    "rocksdb.data_disks",
36                    false,
37                    "The optimized disks for storing data of RocksDB. " +
38                    "The format of each element: `STORE/TABLE: /path/disk`." +
39                    "Allowed keys are [g/vertex, g/edge_out, g/edge_in, " +
40                    "g/vertex_label_index, g/edge_label_index, " +
41                    "g/range_int_index, g/range_float_index, " +
42                    "g/range_long_index, g/range_double_index, " +
43                    "g/secondary_index, g/search_index, g/shard_index, " +
44                    "g/unique_index, g/olap]",
45                    null,
46                    String.class,
47                    ImmutableList.of()
48            );
49}
2.2 扩展自定义分词器

分词器需要实现接口org.apache.hugegraph.analyzer.Analyzer,以实现一个 SpaceAnalyzer 空格分词器为例。

 1package org.apache.hugegraph.plugin;
 2
 3import java.util.Arrays;
 4import java.util.HashSet;
 5import java.util.Set;
 6
 7import org.apache.hugegraph.analyzer.Analyzer;
 8
 9public class SpaceAnalyzer implements Analyzer {
10
11    @Override
12    public Set<String> segment(String text) {
13        return new HashSet<>(Arrays.asList(text.split(" ")));
14    }
15}

3. 实现插件接口,并进行注册

插件注册入口为HugeGraphPlugin.register(),自定义插件必须实现该接口方法,在其内部注册上述定义好的扩展项。接口org.apache.hugegraph.plugin.HugeGraphPlugin定义如下:

 1public interface HugeGraphPlugin {
 2
 3    String name();
 4
 5    void register();
 6
 7    String supportsMinVersion();
 8
 9    String supportsMaxVersion();
10}

并且 HugeGraphPlugin 提供了 4 个静态方法用于注册扩展项:

  • registerOptions(String name, String classPath):注册配置项
  • registerBackend(String name, String classPath):注册后端(BackendStoreProvider)
  • registerSerializer(String name, String classPath):注册序列化器
  • registerAnalyzer(String name, String classPath):注册分词器

下面以注册 SpaceAnalyzer 分词器为例:

 1package org.apache.hugegraph.plugin;
 2
 3public class DemoPlugin implements HugeGraphPlugin {
 4
 5    @Override
 6    public String name() {
 7        return "demo";
 8    }
 9
10    @Override
11    public void register() {
12        HugeGraphPlugin.registerAnalyzer("demo", SpaceAnalyzer.class.getName());
13    }
14
15    @Override
16    public String supportsMinVersion() {
17        return "1.7.0";
18    }
19
20    @Override
21    public String supportsMaxVersion() {
22        return "1.8.0";
23    }
24}

4. 配置 SPI 入口

  1. 确保 services 目录存在:hugegraph-plugin-demo/resources/META-INF/services
  2. 在 services 目录下建立文本文件:org.apache.hugegraph.plugin.HugeGraphPlugin
  3. 文件内容如下:org.apache.hugegraph.plugin.DemoPlugin

5. 打 Jar 包

通过 maven 打包,在项目目录下执行命令mvn package,在 target 目录下会生成 Jar 包文件。使用时将该 Jar 包拷到plugins目录,重启服务即可生效。

6.1.2 - HugeGraph 设计理念

1. 属性图模型

版本说明:本页保留早期设计内容。属性图模型和顶点 ID 策略仍与 当前主线源码相符;图示、分区结论及事务实现描述按各节注明的范围阅读,不能直接当作当前部署或存储实现说明。

常见的图数据表示模型有两种,分别是RDF(Resource Description Framework)模型和属性图模型。 RDF和Property Graph都是最基础、最有名的图表示模式,都能够表示各种图的实体关系建模。 RDF是W3C标准,而Property Graph是工业标准,受到广大图数据库厂商的广泛支持。HugeGraph目前采用Property Graph。

HugeGraph采用属性图模型。下图以人物和图书为例,展示顶点与有向边各自的标签和属性;这是逻辑模型示意,不描述 当前主线的内部数据布局。

属性图逻辑模型示意:人物顶点经“阅读”有向边连接图书顶点,顶点与边均有各自的标签和属性

图:顶点和边分别携带自己的标签与属性。

在HugeGraph内部,每个顶点 / 边由唯一的 VertexId / EdgeId 标识,属性存储在对应点 / 边内部。而顶点与顶点之间的关系 / 映射则是通过边来存储的。

顶点属性值通过边指针方式存储时,如果要更新一个顶点特定的属性值直接通过覆盖写入即可,其弊端是冗余存储了VertexId;如果要更新关系的属性需要通过read-and-modify方式,先读取所有属性,修改部分属性,然后再写入存储系统,更新效率较低。 从经验来看顶点属性的修改需求较多,而边的属性修改需求较少,例如PageRank和Graph Cluster等计算都需要频繁修改顶点的属性值。

2. 图分区方案

版本说明:Edge Cut 与 Vertex Cut 的比较属于历史设计背景。当前主线的 PD 与 Store 源码没有把“HugeGraph 采用 Edge Cut”定义为实现契约,因此下文该结论不适用于描述 当前主线的实际分区与副本机制;当前分布式部署请参考 HStore 快速上手。

对于分布式图数据库而言,图的分区存储方式有两种:分别是边分割存储(Edge Cut)和点分割存储(Vertex Cut),如下图所示。使用Edge Cut方式存储图时,任何一个顶点只会出现在一台机器上,而边可能分布在不同机器上,这种存储方式有可能导致边多次存储。 使用Vertex Cut方式存储图时,任何一条边只会出现在一台机器上,而每相同的一个点可能分布到不同机器上,这种存储方式可能会导致顶点多次存储。

image

采用EdgeCut分区方案可以支持高性能的插入和更新操作,而VertexCut分区方案更适合静态图查询分析,因此EdgeCut适合OLTP图查询,VertexCut更适合OLAP的图查询。早期设计资料曾记载 HugeGraph 采用 Edge Cut。此处保留该历史结论,不将其视为当前分区实现说明。

3. VertexId 策略

HugeGraph的Vertex支持四种ID策略,在同一个图数据库中不同的VertexLabel可以使用不同的Id策略,目前HugeGraph支持的Id策略分别是:

  • 自动生成(AUTOMATIC):使用Snowflake算法自动生成全局唯一Id,Long类型;
  • 主键(PRIMARY_KEY):通过VertexLabel+PrimaryKeyValues生成Id,String类型;
  • 自定义(CUSTOMIZE_STRING|CUSTOMIZE_NUMBER):用户自定义Id,分为String和Long类型两种,需自己保证Id的唯一性;
  • 自定义UUID(CUSTOMIZE_UUID):用户自定义UUID形式的Id,需自己保证Id的唯一性;

默认的Id策略是AUTOMATIC,如果用户调用primaryKeys()方法并设置了正确的PrimaryKeys,则自动启用PRIMARY_KEY策略。启用PRIMARY_KEY策略后HugeGraph能根据PrimaryKeys实现数据去重。

  1. AUTOMATIC ID策略
1schema.vertexLabel("person")
2     .useAutomaticId()
3     .properties("name", "age", "city")
4     .create();
5graph.addVertex(T.label, "person","name", "marko", "age", 18, "city", "Beijing");
  1. PRIMARY_KEY ID策略
1schema.vertexLabel("person")
2     .usePrimaryKeyId()
3     .properties("name", "age", "city")
4     .primaryKeys("name", "age")
5     .create();
6graph.addVertex(T.label, "person","name", "marko", "age", 18, "city", "Beijing");
  1. CUSTOMIZE_STRING ID策略
1schema.vertexLabel("person")
2     .useCustomizeStringId()
3     .properties("name", "age", "city")
4     .create();
5graph.addVertex(T.label, "person", T.id, "123456", "name", "marko","age", 18, "city", "Beijing");
  1. CUSTOMIZE_NUMBER ID策略
1schema.vertexLabel("person")
2     .useCustomizeNumberId()
3     .properties("name", "age", "city")
4     .create();
5graph.addVertex(T.label, "person", T.id, 123456, "name", "marko","age", 18, "city", "Beijing");
  1. CUSTOMIZE_UUID ID策略
1schema.vertexLabel("person")
2     .useCustomizeUuidId()
3     .properties("name", "age", "city")
4     .create();
5graph.addVertex(T.label, "person", T.id, UUID.randomUUID(), "name", "marko","age", 18, "city", "Beijing");

如果用户需要Vertex去重,有三种方案分别是:

  1. 采用PRIMARY_KEY策略,自动覆盖,适合大数据量批量插入,用户无法知道是否发生了覆盖行为
  2. 采用AUTOMATIC策略,read-and-modify,适合小数据量插入,用户可以明确知道是否发生覆盖
  3. 采用CUSTOMIZE_STRING或CUSTOMIZE_NUMBER策略,用户自己保证唯一

4. EdgeId 策略

当前实现提示:本节的四项组合是历史简化描述。当前 EdgeId 还区分边方向及父、子边标签;其实际字段见 Server 源码中的 EdgeId 实现。需要依赖 ID 格式或持久化键时,应以对应版本源码为准。

HugeGraph的EdgeId是由srcVertexId+edgeLabel+sortKey+tgtVertexId四部分组合而成。其中sortKey是HugeGraph的一个重要概念。在Edge中加入sortKey作为Edge的唯一标识的原因有两个:

  1. 如果两个顶点之间存在多条相同Label的边可通过sortKey来区分
  2. 对于SuperNode的节点,可以通过sortKey来排序截断。

由于EdgeId是由srcVertexId+edgeLabel+sortKey+tgtVertexId四部分组合,多次插入相同的Edge时HugeGraph会自动覆盖以实现去重。需要注意的是如果批量插入模式下Edge的属性也将会覆盖。

另外由于HugeGraph的EdgeId采用自动去重策略,对于self-loop(一个顶点存在一条指向自身的边)的情况下HugeGraph认为仅有一条边,对于采用AUTOMATIC策略的图数据库(例如TitianDB )则会认为该图存在两条边。

HugeGraph的边仅支持有向边,无向边可以创建Out和In两条边来实现。

5. HugeGraph 事务概览

版本范围:下文关于 HugeGraph 隔离级别、线程绑定和后端原子性的描述保留为历史实现说明。各后端的事务隔离与失败回滚边界应以对应实现为准,不应将下述历史描述当作跨后端保证。

TinkerPop事务概述

TinkerPop 事务是对数据库执行操作的工作单元,一个事务内的一组操作要么执行成功,要么全部失败。详细介绍请参考TinkerPop官方文档:http://tinkerpop.apache.org/docs/current/reference/#transactions

TinkerPop事务操作接口
  • open 打开事务
  • commit 提交事务
  • rollback 回滚事务
  • close 关闭事务
TinkerPop事务规范
  • 事务必须显式提交后才可生效(未提交时修改操作只有本事务内查询可看到)
  • 事务必须打开之后才可提交或回滚
  • 如果事务设置自动打开则无需显式打开(默认方式),如果设置手动打开则必须显式打开
  • 可设置事务关闭时:自动提交、自动回滚(默认方式)、手动(禁止显式关闭)等3种模式
  • 事务在提交或回滚后必须是关闭状态
  • 事务在查询后必须是打开状态
  • 事务(非threaded tx)必须线程隔离,多线程操作同一事务互不影响

更多事务规范用例见:Transaction Test

HugeGraph事务实现
  • 一个事务中所有的操作要么成功要么失败
  • 一个事务只能读取到另外一个事务已提交的内容(Read committed)
  • 所有未提交的操作均能在本事务中查询出来,包括:
    • 增加顶点能够查询出该顶点
    • 删除顶点能够过滤掉该顶点
    • 删除顶点能够过滤掉该顶点相关边
    • 增加边能够查询出该边
    • 删除边能够过滤掉该边
    • 增加/修改(顶点、边)属性能够在查询时生效
    • 删除(顶点、边)属性能够在查询时生效
  • 所有未提交的操作在事务回滚后均失效,包括:
    • 顶点、边的增加、删除
    • 属性的增加/修改、删除

示例:一个事务无法读取另一个事务未提交的内容

 1    static void testUncommittedTx(final HugeGraph graph) throws InterruptedException {
 2
 3        final CountDownLatch latchUncommit = new CountDownLatch(1);
 4        final CountDownLatch latchRollback = new CountDownLatch(1);
 5
 6        Thread thread = new Thread(() -> {
 7            // this is a new transaction in the new thread
 8            graph.tx().open();
 9
10            System.out.println("current transaction operations");
11
12            Vertex james = graph.addVertex(T.label, "author",
13                                           "id", 1, "name", "James Gosling",
14                                           "age", 62, "lived", "Canadian");
15            Vertex java = graph.addVertex(T.label, "language", "name", "java",
16                                          "versions", Arrays.asList(6, 7, 8));
17            james.addEdge("created", java);
18
19            // we can query the uncommitted records in the current transaction
20            System.out.println("current transaction assert");
21            assert graph.vertices().hasNext() == true;
22            assert graph.edges().hasNext() == true;
23
24            latchUncommit.countDown();
25
26            try {
27                latchRollback.await();
28            } catch (InterruptedException e) {
29                throw new RuntimeException(e);
30            }
31
32            System.out.println("current transaction rollback");
33            graph.tx().rollback();
34        });
35
36        thread.start();
37
38        // query none result in other transaction when not commit()
39        latchUncommit.await();
40        System.out.println("other transaction assert for uncommitted");
41        assert !graph.vertices().hasNext();
42        assert !graph.edges().hasNext();
43
44        latchRollback.countDown();
45        thread.join();
46
47        // query none result in other transaction after rollback()
48        System.out.println("other transaction assert for rollback");
49        assert !graph.vertices().hasNext();
50        assert !graph.edges().hasNext();
51    }
事务实现原理
  • 服务端内部通过将事务与线程绑定实现隔离(ThreadLocal)
  • 本事务未提交的内容按照时间顺序覆盖老数据以供本事务查询最新版本数据
  • 底层依赖后端数据库保证事务原子性操作(如RocksDB的batch接口保证原子性)
注意

REST API 未提供独立的事务生命周期接口;写操作接口会在服务端调用相应的事务提交逻辑。

TinkerPop API允许打开事务,请求完成时会自动关闭(Gremlin Server强制关闭)

6.2 - 开发测试

HugeGraph 开发者测试与环境集成指南,包含 Toolchain 本地测试与开发版存储引擎集成。

本节汇总 HugeGraph 开发者在本地进行测试与环境集成的操作指南。

模块指引

  • Toolchain 本地测试

    指导开发者在本地搭建 HugeGraph Server 并运行 Toolchain 全量组件的单元测试与功能测试。

  • ToplingDB (开发版)

    介绍从开发源码构建并启用可选 ToplingDB 运行时的配置与测试方法。

6.2.1 - HugeGraph工具链本地测试指南

本指南帮助开发者在本地运行 HugeGraph 工具链测试。

1. 核心概念

1.1 核心依赖:HugeGraph Server

工具链的集成测试和功能测试都依赖 HugeGraph Server,包括 Client、Loader、Hubble、Spark Connector、Tools 等组件。

1.2 测试类型

  • 单元测试 (Unit Tests):测试单个函数/方法,不依赖外部服务
  • API 测试 (ApiTestSuite):测试 API 接口,需要运行中的 HugeGraph Server
  • 功能测试 (FuncTestSuite):端到端测试,需要完整的系统环境

2. 环境准备

2.1 系统要求

  • 操作系统:Linux / macOS(Windows 使用 WSL2)
  • JDK:>= 11,配置好 JAVA_HOME
  • Maven:>= 3.6
  • Python:>= 3.11(仅 Hubble 测试需要)

2.2 克隆代码

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

3. 部署测试环境

方式选择

  • 脚本部署:指定 Server Commit,可复现 CI 使用的服务端版本
  • Docker 部署:适合快速检查;测试失败时应先核对镜像与 Toolchain 的兼容性

详细安装说明参考 社区文档

3.1 脚本部署

参数说明

  • $COMMIT_ID:指定 Server 源码的 Git Commit ID
  • $DB_DATABASE / $DB_PASS:Loader JDBC 测试用的 MySQL 数据库名和密码

部署步骤

1. 安装 HugeGraph Server

1# 设置 Server 基线;需要可复现结果时请使用完整 commit SHA
2export COMMIT_ID="master"
3
4# 执行安装(脚本位于 /assembly/travis/ 目录)
5hugegraph-client/assembly/travis/install-hugegraph-from-source.sh $COMMIT_ID
  • 脚本会启动 HTTP 8080 和 HTTPS 8443 两个实例,并配置 admin/pa 认证。
  • 执行前确认两个端口未被占用。

2. 安装可选依赖

1# Hadoop (仅 Loader HDFS 测试需要)
2hugegraph-loader/assembly/travis/install-hadoop.sh
3
4# MySQL (仅 Loader JDBC 测试需要)
5hugegraph-loader/assembly/travis/install-mysql.sh $DB_DATABASE $DB_PASS

3. 健康检查

1curl -u admin:pa http://localhost:8080/graphspaces/DEFAULT/graphs
2# 返回 {"graphs":["hugegraph"]} 表示成功

3.2 Docker 部署

注意:Docker 镜像可能版本滞后,如遇兼容性问题请使用脚本部署

快速启动

1docker network create hugegraph-net
2docker run -itd --name=server -p 8080:8080 --network hugegraph-net hugegraph/hugegraph:latest

docker-compose 配置(可选)

完整配置示例,包含 Server、MySQL、Hadoop 服务(需要 Docker Compose V2):

 1version: '3.8'
 2
 3services:
 4  hugegraph-server:
 5    image: hugegraph/hugegraph:latest  # 可以替换为特定版本,或构建自己的镜像
 6    container_name: hugegraph-server
 7    ports:
 8      - "8080:8080"  # HugeGraph Server HTTP 端口
 9    environment:
10      # 根据需要配置HugeGraph Server的参数,例如后端存储
11      - HUGEGRAPH_SERVER_OPTIONS="-Dstore.backend=rocksdb"
12    volumes:
13      # 如果需要持久化数据或挂载配置文件,可以在这里添加卷
14      # - ./hugegraph-data:/opt/hugegraph/data
15    healthcheck:
16      test: ["CMD-SHELL", "curl -f http://localhost:8080/graphspaces/DEFAULT/graphs || exit 1"]
17      interval: 5s
18      timeout: 3s
19      retries: 5
20    networks:
21      - hugegraph-net
22  
23  # 如果需要hugegraph-loader的JDBC测试,可以添加以下服务
24  #   mysql:
25  #     image: mysql:5.7
26  #     container_name: mysql-db
27  #     environment:
28  #       MYSQL_ROOT_PASSWORD: ${DB_PASS:-your_mysql_root_password} # 从环境变量读取,或使用默认值
29  #       MYSQL_DATABASE: ${DB_DATABASE:-hugegraph_test_db} # 从环境变量读取,或使用默认值
30  #     ports:
31  #       - "3306:3306"
32  #     volumes:
33  #       - ./mysql-data:/var/lib/mysql # 数据持久化
34  #     healthcheck:
35  #       test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p${DB_PASS:-your_mysql_root_password}"]
36  #       interval: 5s
37  #       timeout: 3s
38  #       retries: 5
39  #     networks:
40  #       - hugegraph-net
41
42  # 如果需要hugegraph-loader的Hadoop/HDFS测试,可以添加以下服务
43  #   namenode:
44  #     image: johannestang/hadoop-namenode:2.0.0-hadoop2.8.5-java8
45  #     container_name: namenode
46  #     ports:
47  #       - "0.0.0.0:9870:9870"
48  #       - "0.0.0.0:8020:8020"
49  #     environment:
50  #       - CLUSTER_NAME=test-cluster
51  #       - HDFS_NAMENODE_USER=root
52  #       - HADOOP_CONF_DIR=/hadoop/etc/hadoop
53  #     volumes:
54  #       - ./config/core-site.xml:/hadoop/etc/hadoop/core-site.xml
55  #       - ./config/hdfs-site.xml:/hadoop/etc/hadoop/hdfs-site.xml
56  #       - namenode_data:/hadoop/dfs/name
57  #     command: bash -c "if [ ! -d /hadoop/dfs/name/current ]; then hdfs namenode -format; fi && /entrypoint.sh"
58  #     healthcheck:
59  #       test: ["CMD", "hdfs", "dfsadmin", "-report"]
60  #       interval: 5s
61  #       timeout: 3s
62  #       retries: 5
63  #     networks:
64  #       - hugegraph-net
65
66  #   datanode:
67  #     image: johannestang/hadoop-datanode:2.0.0-hadoop2.8.5-java8
68  #     container_name: datanode
69  #     depends_on:
70  #       - namenode
71  #     environment:
72  #       - CLUSTER_NAME=test-cluster
73  #       - HDFS_DATANODE_USER=root
74  #       - HADOOP_CONF_DIR=/hadoop/etc/hadoop
75  #     volumes:
76  #       - ./config/core-site.xml:/hadoop/etc/hadoop/core-site.xml
77  #       - ./config/hdfs-site.xml:/hadoop/etc/hadoop/hdfs-site.xml
78  #       - datanode_data:/hadoop/dfs/data
79  #     healthcheck:
80  #       test: ["CMD", "hdfs", "dfsadmin", "-report"]
81  #       interval: 5s
82  #       timeout: 3s
83  #       retries: 5
84  #     networks:
85  #       - hugegraph-net
86
87networks:
88  hugegraph-net:
89    driver: bridge
90volumes:
91  namenode_data:
92  datanode_data:

Hadoop 配置挂载

在与 docker-compose.yml 相同的目录下创建 ./config 文件夹用于挂载 Hadoop 配置文件。如果不需要 HDFS 测试,可以跳过此步骤。

📁 ./config/core-site.xml 内容:

1<configuration>
2    <property>
3        <name>fs.defaultFS</name>
4        <value>hdfs://namenode:8020</value>
5    </property>
6</configuration>

📁 ./config/hdfs-site.xml 内容:

 1<configuration>
 2    <property>
 3        <name>dfs.namenode.name.dir</name>
 4        <value>/hadoop/hdfs/name</value>
 5    </property>
 6    <property>
 7        <name>dfs.datanode.data.dir</name>
 8        <value>/hadoop/hdfs/data</value>
 9    </property>
10    <property>
11        <name>dfs.permissions.superusergroup</name>
12        <value>hadoop</value>
13    </property>
14    <property>
15        <name>dfs.support.append</name>
16        <value>true</value>
17    </property>
18</configuration>

Docker 操作

 1# 启动服务
 2docker compose up -d
 3
 4# 检查状态
 5docker compose ps
 6lsof -i:8080  # Server
 7lsof -i:8020  # Hadoop
 8lsof -i:3306  # MySQL
 9
10# 停止服务
11docker compose down

4. 运行测试

各工具的测试流程:

HugeGraph工具链测试流程图

4.1 hugegraph-client

编译

1mvn -e compile -pl hugegraph-client -Dmaven.javadoc.skip=true -ntp

依赖服务

启动 HugeGraph Server(参考 第3节)

Server 鉴权配置

ApiTest 需要认证。使用 3.1 节的脚本安装时无需重复配置;自行部署 Server 时,认证配置和测试凭证必须与测试代码一致。

 1# 1. 修改鉴权模式
 2cp conf/rest-server.properties conf/rest-server.properties.backup
 3sed -i 's|#auth.authenticator=.*|auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator|' conf/rest-server.properties
 4grep auth.authenticator conf/rest-server.properties
 5sed -i 's|gremlin.graph=org.apache.hugegraph.HugeFactory|gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy|' conf/graphs/hugegraph.properties
 6
 7# 2. 设置密码
 8# 注:测试代码中默认使用 "pa" 作为密码,设置时需与测试保持一致
 9bin/stop-hugegraph.sh
10export PASSWORD="pa"  # 设置为测试默认密码
11echo -e "${PASSWORD}" | bin/init-store.sh
12bin/start-hugegraph.sh

运行测试

1# 检查环境
2curl -u admin:pa http://localhost:8080/graphspaces/DEFAULT/graphs
3
4# 运行测试
5cd hugegraph-client
6mvn test -Dtest=UnitTestSuite -ntp      # 单元测试
7mvn test -Dtest=ApiTestSuite -ntp       # API测试(需 Server)
8mvn test -Dtest=FuncTestSuite -ntp      # 功能测试(需 Server)

测试失败时检查 Server 日志:logs/hugegraph-server.log

4.2 hugegraph-loader

编译

1mvn install -pl hugegraph-client,hugegraph-loader -am -Dmaven.javadoc.skip=true -DskipTests -ntp

依赖服务

  • 必需:HugeGraph Server
  • 可选:Hadoop (HDFS 测试)、MySQL (JDBC 测试);Kafka 测试通过 Testcontainers 启动 Kafka 容器,因此还需要可用的 Docker daemon

运行测试

1cd hugegraph-loader
2mvn test -P unit -ntp   # 单元测试
3mvn test -P file -ntp   # 文件测试(需 Server)
4mvn test -P hdfs -ntp   # HDFS测试(需 Server + Hadoop)
5mvn test -P jdbc -ntp   # JDBC测试(需 Server + MySQL)
6mvn test -P kafka -ntp  # Kafka 测试(需 Server + Docker daemon;测试会启动 Kafka 容器)

4.3 hugegraph-hubble

编译

1mvn install -pl hugegraph-client,hugegraph-loader -am -Dmaven.javadoc.skip=true -DskipTests -ntp
2cd hugegraph-hubble
3mvn -e compile -Dmaven.javadoc.skip=true -ntp

依赖服务

1. 启动 Server(参考 第3节)

2. Python 环境

1python -m venv venv
2source venv/bin/activate  # Windows: venv\Scripts\activate
3python -m pip install -r hubble-dist/assembly/travis/requirements.txt

3. 构建并验证

1mvn package -Dmaven.test.skip=true
2# 可选:启动验证
3cd apache-hugegraph-hubble*/bin
4./start-hubble.sh -d && sleep 10
5curl http://localhost:8088/actuator/health
6./stop-hubble.sh

运行测试

 1# 单元测试
 2mvn test -P unit-test -pl hugegraph-hubble/hubble-be -ntp
 3
 4# 旧版 Python API 测试(需 Server;脚本会安装并启动 Hubble)
 5curl -u admin:pa http://localhost:8080/graphspaces/DEFAULT/graphs  # 检查 Server
 6cd hugegraph-hubble
 7./hubble-dist/assembly/travis/run-api-test.sh
 8
 9# 当前 CI 的完整验收入口(需先生成 Hubble tar 包)
10HUBBLE_TARBALL="$(ls target/apache-hugegraph-hubble-*.tar.gz | head -n 1)"
11hubble-dist/assembly/travis/verify-hubble-issue-694.sh \
12  "$HUBBLE_TARBALL" http://127.0.0.1:8080

4.4 hugegraph-spark-connector

编译

1mvn install -pl hugegraph-client,hugegraph-spark-connector -am -Dmaven.javadoc.skip=true -DskipTests -ntp

运行测试

1cd hugegraph-spark-connector
2mvn test -ntp  # 需 Server 运行

4.5 hugegraph-tools

编译

1mvn install -pl hugegraph-client,hugegraph-tools -am -Dmaven.javadoc.skip=true -DskipTests -ntp

运行测试

1cd hugegraph-tools
2mvn test -Dtest=FuncTestSuite -ntp  # 需 Server 运行

5. 常见问题

服务连接问题

无法连接 Server、MySQL 或 Hadoop 时:

  • 确认服务已启动(Server 必须在 8080 端口)
  • 检查端口占用:lsof -i:8080
  • Docker 检查:docker compose ps 和 docker compose logs

配置问题

找不到文件或参数错误时:

  • 检查环境变量:echo $COMMIT_ID
  • 脚本权限:chmod +x hugegraph-*/assembly/travis/*.sh

HDFS 测试失败

  • 确认 NameNode/DataNode 运行正常
  • 检查 Hadoop 日志
  • 验证 HDFS 连接:hdfs dfsadmin -report

JDBC 测试失败

  • 确认 MySQL 运行正常
  • 验证数据库连接:mysql -u root -p$DB_PASS
  • 检查 MySQL 日志

6. 参考资料

6.2.2 - ToplingDB 开发版集成

从开发源码构建可选 ToplingDB 运行时,隔离数据目录,并了解启动与恢复边界。

开发版接口:本文适用于开启可选 ToplingDB 运行时的开发构建版本。 已有发行版和镜像标签不代表支持本文接口,采用前须完成运行时验证。

确认数据库所属组件

HugeGraph 默认使用标准 RocksDB。对持有本地存储的每个进程分别启用 Topling:

组件业务 provider 配置启动命令
独立 RocksDB Server每个选用的 graph properties 文件中设置 rocksdb.provider=toplingbin/start-hugegraph.sh
PDconf/application.yml 的 rocksdb 下设置 provider: toplingbin/start-hugegraph-pd.sh
Storeconf/application-pd.yml 的 rocksdb 下设置 provider: toplingbin/start-hugegraph-store.sh

独立 Server 保持 backend=rocksdb;HStore Server 使用 backend=hstore,不需要本地 Topling 运行时。 同一 Server 进程中的本地 RocksDB 图必须使用相同 provider。业务配置必须与启动脚本选择的运行时一致。

构建并准备标准发行包

在源码仓库根目录,使用 Java 17 和 Maven 3.6.3 或更新版本构建普通发行包:

1mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true

从可信制品渠道取得 Topling Easy Migrate JNI JAR 及其 SHA-256。准备环境需要 Java 17 JDK、Linux x86_64、sha256sum、unzip、od、ldd 和 GNU mv。 还须满足所选 JAR 的 native 依赖,包括其要求的 glibc 和 libaio。

先停止组件,解压一份新的标准发行包,再从该组件目录执行:

1export TOPLING_JNI_JAR=/absolute/path/to/rocksdbjni-topling.jar
2export TOPLING_JNI_SHA256='<trusted-64-character-sha256>'
3bash bin/prepare-topling.sh

脚本校验复制后的 JAR 哈希、Topling Java 标识、唯一的 Linux x86_64 JNI 条目、ELF 架构及 native 依赖。 安装前还会用所选 JNI 打开临时数据库,确认 EasyMigrate 配置实际改变了持久化的写缓冲区大小;类标识和哈希匹配但不支持该配置入口的构建会被拒绝。 此探针不代表已有数据兼容性或所有生产配置均已验证。校验记录绑定已测试的 JAR 和 native 库,启动时拒绝缺失或失效的记录;从旧准备脚本升级时请重新准备一份新发行包。 默认/标准模式启动时会拒绝继承的 RocksDB JNI 预载库,Topling 模式则拒绝与所选 JNI 竞争的预载库;其他预载库继续保留。 它将 topling/rocksdbjni.jar、对应 native 库和可选网页资源放在 lib 之外。已有 topling 目录时会拒绝准备;更换运行时请使用另一份已停止的新发行包。 按实际部署需要,为 Server、PD 和 Store 分别执行准备步骤。

将持久数据放在发行包之外

更换 provider 不会转换已有数据库。为 Topling 使用独立、初始为空的目录,并保留标准 provider 的数据。 预先创建服务账号可写的持久目录,将其放在源码检出、构建输出和解压后的发行包目录之外。注意:每个图必须使用互不相同的独立数据与 WAL 目录,避免目录冲突:

组件配置文件及配置项持久路径示例
Server 数据Graph properties:rocksdb.data_path/srv/hugegraph/topling/server/<graph>/data
Server WALGraph properties:rocksdb.wal_path/srv/hugegraph/topling/server/<graph>/wal
PDconf/application.yml:pd.data-path/srv/hugegraph/topling/pd
Store 数据conf/application.yml:app.data-path/srv/hugegraph/topling/store/data
Store Raftconf/application.yml:app.raft-path/srv/hugegraph/topling/store/raft

独立 Server 的每个选用图配置都需修改,例如 conf/graphs/hugegraph.properties(若配置多个图,请将路径中的 hugegraph 替换为对应图名):

1backend=rocksdb
2rocksdb.provider=topling
3rocksdb.data_path=/srv/hugegraph/topling/server/hugegraph/data
4rocksdb.wal_path=/srv/hugegraph/topling/server/hugegraph/wal

Server 的数据和 WAL 路径都要设置,且不同图之间不能共享同一路径。若 WAL 仍使用发行包内的默认路径,重新构建或替换发行包时可能丢失该目录。 运行时或发行包更新时,保留外部数据、WAL 和 Raft 根目录。

PD 和 Store 应在上表对应的 provider 配置文件中修改已有 rocksdb 映射,保留其余选项:

1rocksdb:
2  provider: topling

持久路径另在 conf/application.yml 中配置,同时保留正常的网络地址和集群配置。

准备完成后的 runtime 目录权限为 0755,普通资源文件为 0644,因此使用另一个服务账号也能读取 JNI。该账号还需要组件上级目录的遍历权限;prepare 不会修改上级目录权限。

选择运行时并启动验证

在每个持有 Topling 数据库的组件启动终端中,显式选择运行时:

1export TOPLINGDB_ROCKSDB_PROVIDER=topling
2# 执行第一张表中该组件对应的启动命令。

启动脚本默认使用该组件的 conf/toplingdb.yaml,也可用 TOPLINGDB_EASY_MIGRATE_CONF=/absolute/path/config.yaml 显式覆盖。 发行包中的 native 配置关闭 HTTP 服务,并保留 Java 写入路径要求的 memtable_as_log_index=false。 请按机器条件调整该文件;它与业务 provider、数据目录配置分别生效。

独立 Server 使用全新图时,首次启动前先初始化一次存储:

1bash bin/init-store.sh
2bash bin/start-hugegraph.sh

bin/init-store.sh、bin/dump-store.sh 与 bin/start-hugegraph.sh 使用同一显式运行时选择。 HStore 按 PD、Store、Server 的顺序启动。在同一 shell 中启动 HStore Server 前,执行 unset TOPLINGDB_ROCKSDB_PROVIDER (或 export TOPLINGDB_ROCKSDB_PROVIDER=rocksdb);不要在该 Server 上启用本地 Topling。 业务 provider 与实际运行时不一致时,组件会在开库前拒绝启动。

采用前须确认实际 RocksDB Java 类和进程加载的 JNI 库来自准备好的运行时。在专用数据目录中验证真实写入、读取、正常停止和重启; HStore 还需通过 Server 执行图操作,覆盖 PD 和 Store 链路。仅构建成功、启动成功或通过标准 JNI 单元测试,不能证明 Topling 运行时已验收。

停止或切回标准 RocksDB

先停止新业务,再使用正常停止脚本。HStore 依次执行 Server 的 bin/stop-hugegraph.sh、Store 的 bin/stop-hugegraph-store.sh、 PD 的 bin/stop-hugegraph-pd.sh,等待前一个进程退出后再停止其依赖。强制终止进程不能作为正常 native 资源清理的证明。

切回标准 RocksDB 前先停止组件,取消 TOPLINGDB_ROCKSDB_PROVIDER,并把业务 provider 改回 rocksdb。 使用对应的标准 provider 数据和 WAL 路径,不要指向已被 Topling 修改的数据库。

专用 Topling 发行包、Docker/Compose 打包、通用生命周期改造及可重试快照恢复分别后续交付。 本文覆盖普通发行包的启动脚本;自定义 IDE 和嵌入式入口需要自行准备运行时并完成验证。

6.3 - 备份与恢复

描述

Backup 将一张图的 Schema、顶点和边导出为 JSON 数据,Restore 将这些数据导入目标图。 它们是 HugeGraph-Tools 的命令,适合图迁移、升级后的恢复及图合并。

Backup

备份可在任意图模式下执行。建议在导出前暂停源图的写入操作,以确保 Schema、顶点和边的数据一致性(分批读取不提供全局事务快照)。 注意:backup -t all 仅导出图的 Schema 和图数据,不包含系统配置文件与用户权限。

Restore

恢复数据前,需先根据目标图的状态切换恢复模式。日常读写处于 NONE 模式;注意:LOADING 模式不能用于 restore。

目标模式Schema ID顶点和边 ID
恢复到没有 Schema 和数据的新图RESTORING使用备份中的 ID使用备份中的 ID
合并到已有图MERGING使用目标图的 Schema ID,必要时新建部分 ID 随目标 Schema 重算,见下文

MERGING 中,PRIMARY_KEY 顶点 ID 按目标 label ID 重新生成,关联边的端点与 ID 随之调整。 AUTOMATIC 和自定义顶点 ID 保留。合并会复用同名 Schema,先检查双方的定义是否兼容,以及保留的顶点 ID 是否冲突。 它不提供任意 Schema 冲突或数据冲突的自动解决策略。先在独立目标图验证,再合并正式数据。

使用方法

准备与 Server 版本匹配的 HugeGraph-Tools,在 Tools 根目录执行以下命令。 本例从 8080 的源图恢复到 8081 的空目标图。两个 Server 和目标图应已创建并启动;可将变量改成实际地址及图名。

1SOURCE_URL=http://127.0.0.1:8080
2TARGET_URL=http://127.0.0.1:8081
3SOURCE_GRAPH=hugegraph
4TARGET_GRAPH=hugegraph
5BACKUP_DIR="$PWD/data/hugegraph-backup"

启用认证时,在每条 Tools 命令的子命令前加入 --user <user> --password <password>,并使用具备对应图读写和模式管理权限的账号。 详细参数及凭据使用方式见 Tools 参考。

Backup

暂停源图写入后,备份全部 Schema、顶点和边。

1bin/hugegraph --url "$SOURCE_URL" --graph "$SOURCE_GRAPH" \
2  backup -t all -d "$BACKUP_DIR"

显式指定的 -d 就是备份目录,不会自动附加图名。为每次备份使用独立目录,避免混入旧文件。 保留完整目录,包括压缩文件;Restore 可读取 Tools 支持的 JSON 备份格式。

Restore

以下流程使用 RESTORING。合并时改为 MERGING,并先完成上面的兼容性检查。 操作期间暂停目标图业务写入。

  1. 查看并记录原模式,再切换。

    1bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" graph-mode-get
    2ORIGINAL_MODE=NONE
    3bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" \
    4  graph-mode-set -m RESTORING

    正常业务图应处于 NONE。将查询返回的值填入 ORIGINAL_MODE,例如下方的 NONE。若另一项维护正在使用 RESTORING、MERGING 或 LOADING,先协调该任务,不要覆盖其模式。

  2. 恢复数据。

    1bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" \
    2  restore -t all -d "$BACKUP_DIR"

    检查命令输出与各类型的导入结果。若发生错误,请先保留备份目录与日志,并检查目标图的数据状态。 Restore 不会自动回滚已写入的数据,切勿在部分恢复的图上盲目重跑。

  3. 还原原模式。

    使用第一步记录的 ORIGINAL_MODE 还原模式。

    1bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" graph-mode-set -m "$ORIGINAL_MODE"
    2bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" graph-mode-get

    无论恢复成功还是失败,最后都必须将图模式还原为原有模式(通常为 NONE)。 若恢复失败,先保留现场并排查日志,待重新准备目标图后再恢复业务写入。

还原模式后,对比两端的顶点数和边数。

1bin/hugegraph --url "$SOURCE_URL" --graph "$SOURCE_GRAPH" gremlin-execute --script 'g.V().count()'
2bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" gremlin-execute --script 'g.V().count()'
3bin/hugegraph --url "$SOURCE_URL" --graph "$SOURCE_GRAPH" gremlin-execute --script 'g.E().count()'
4bin/hugegraph --url "$TARGET_URL" --graph "$TARGET_GRAPH" gremlin-execute --script 'g.E().count()'

两组计数结果应保持完全一致。建议进一步通过 Schema API 核对元数据定义, 并抽样检查顶点和边的属性与端点关联,确保业务数据的完整性。

帮助

更多关于压缩、并发和分类型备份的参数说明,见 Tools 参考。 在跨大版本恢复前,建议先在测试环境中验证备份文件的兼容性。

Backup/Restore使用和实现的API说明

Backup

Backup 使用 Schema、顶点和边的列表 GET API 导出数据。

Restore

Restore 使用 Schema、顶点和边的创建 API 导入数据。模式对应的 ID 行为见前面的选择表。 RESTORING 允许指定 Schema ID;MERGING 不允许指定 Schema ID。两种模式均允许保留 AUTOMATIC 顶点 ID。 普通 NONE 模式不接受这些恢复操作所需的 ID 设置。

查看某个图的模式

启用鉴权时需要图读取权限(space_member 或该图的所有者)。

Method & Url
1GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/mode
Response Status
1200
Response Body
1{
2    "mode": "NONE"
3}

合法图模式为 NONE、RESTORING、MERGING 和 LOADING。

设置某个图的模式

启用鉴权时需要图空间管理权限(space);管理员可按权限继承规则满足。

Method & Url
1PUT http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/mode
Request Body
1"RESTORING"

合法图模式为 NONE、RESTORING、MERGING 和 LOADING。

Response Status
1200
Response Body
1{
2    "mode": "RESTORING"
3}

6.4 - HugeGraph Docker 集群部署指南

概述

HugeGraph 通过 Docker-Compose 可快速运行完整的分布式集群版(PD + Store + Server)。该方式适用于 Linux 和 Mac。

前置条件

  • Docker Engine 20.10+ 或 Docker Desktop 4.x+
  • Docker Compose v2
  • Mac 运行 3 节点集群时,建议分配至少 12 GB 内存(设置 → 资源 → 内存)。[其他平台根据实际情况调整]

已测试环境:Linux(原生 Docker)和 macOS(Docker Desktop with ARM M4)

Compose 文件

在 HugeGraph 主仓库 docker/ 目录下提供了四个 compose 文件:

文件服务适用场景
docker-compose.yml1 个 RocksDB Server + 1 个 Hubble默认的单机快速启动,推荐从这里开始
docker-compose-hstore.yml1 PD + 1 Store + 1 Server + 1 Hubble分布式本地开发
docker-compose-3pd-3store-3server.yml3 PD + 3 Store + 3 Server + 1 HubbleHA 参考与评估
docker-compose.dev.yml(仅覆盖文件)最小 HStore 拓扑的源码构建覆盖,始终与 docker-compose-hstore.yml 一起使用

单机拓扑使用 hugegraph/hugegraph:${HUGEGRAPH_VERSION:-latest};HStore 拓扑使用对应的 hugegraph/pd、hugegraph/store 和 hugegraph/server tag。Hubble 由 ${HUBBLE_IMAGE:-hugegraph/hubble:latest} 单独选择。

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

本页的 HStore 与 HA Compose 操作按当前主线文件编写,必须使用从同一主线源码构建的 PD、Store 和 Server 镜像;不要把这些 Compose 文件与 1.7.0 标签的 HStore 组件镜像混用。单机示例单独固定 hugegraph/hugegraph:1.7.0 镜像标签。

鉴权环境

以下 .env 模板对应当前主线 Compose。尖括号内容和 replace-with-your-password 都是占位,必须替换为真实值后才能载入或启动;可参考主线 docker/README.md 的鉴权环境步骤生成 .env,并先替换其中的管理员密码占位:

1HUGEGRAPH_ADMIN_PASSWORD='replace-with-your-password'
2HUGEGRAPH_AUTH_TOKEN_SECRET='<32 字节随机值,例如 openssl rand -hex 32>'
3HG_PD_AUTH_SECRET_KEY='<24 字节随机值,例如 openssl rand -hex 24>'

在主线 HStore 和 HA 拓扑中,HG_PD_AUTH_SECRET_KEY 是 PD REST Basic 鉴权密码,所有 PD 节点、Server 和 Hubble 都必须使用同一个值。当前主线 PD Docker 镜像要求设置该密钥。Hubble 不会直接读取 .env,启动前还要用该值生成拓扑对应的本地配置文件,见下文。不要提交 .env 或生成的 .local.properties。

HUGEGRAPH_ADMIN_PASSWORD 非空时会以 PASSWORD 启用 Server 鉴权,Hubble 通过 Server API 自动识别该模式;该密码只在首次初始化内置 admin 账号。不设置或设为空值则关闭鉴权,这只适用于可信的本地环境。

当前主线 Compose 会把 HUGEGRAPH_AUTH_TOKEN_SECRET 传给 HG_SERVER_AUTH_TOKEN_SECRET。同一密钥可让主线多 Server 副本验证相同 token,并在容器重建后继续验证已签发 token;HA Compose 还要求显式提供该密钥。hugegraph/hugegraph:1.7.0 单机镜像的 Docker 入口脚本只根据 PASSWORD 开启鉴权,不读取 HG_SERVER_AUTH_TOKEN_SECRET,因此不要把 .env 中该变量视为该镜像的固定 JWT 配置。若在 1.7.0 中需要固定 JWT secret,请在其认证图配置 conf/graphs/hugegraph.properties 中显式设置 auth.token_secret,并确保该配置随容器替换保留;认证图路径及密钥生成说明见鉴权配置指南。

之后修改 HUGEGRAPH_ADMIN_PASSWORD 不会轮换已有密码,请使用用户 API 修改。

警告

生产环境的组件访问控制

生产环境必须按 Server 认证与授权配置 为图 API 启用 Server Auth,启用并维护 Server IP 白名单、按最小权限授权,并保留、限制读取 Server audit-*.log。PD 的 REST 凭据与 PD/Store 的 gRPC、Raft、REST 网络边界独立配置;Server Auth 不会保护这些端口。仅向集群节点和受信运维入口开放 PD/Store 端口。

单节点快速启动

本节固定使用 hugegraph/hugegraph:1.7.0 单机镜像标签;HStore/HA 示例使用当前主线构建镜像,不能照搬本节的版本号。

1cd "$(git rev-parse --show-toplevel)/docker"
2# 单机 RocksDB Server 镜像示例
3HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose.yml up -d --wait

验证:

1curl -fsS http://localhost:8080/versions
2curl -fsS http://localhost:8088/about        # Hubble

Hubble 默认只发布在宿主机回环地址(127.0.0.1:8088)。只有在 HTTPS 反向代理和可信网络管控之后才应设置 HUBBLE_PUBLISH_HOST。

最小 HStore 快速启动(当前主线镜像)

从 HugeGraph Server 主线仓库根目录构建 PD、Store 和 HStore Server 镜像:

1cd "$(git rev-parse --show-toplevel)"
2docker build -f hugegraph-pd/Dockerfile -t hugegraph/pd:local .
3docker build -f hugegraph-store/Dockerfile -t hugegraph/store:local .
4docker build -f hugegraph-server/Dockerfile-hstore -t hugegraph/server:local .

从仓库根目录执行以下命令进入 docker/,载入 .env 并生成最小拓扑所需的 Hubble 配置。缺少 hstore.local.properties 时,Compose 不会为只读 bind mount 自动创建有效配置;先生成文件再启动:

1cd "$(git rev-parse --show-toplevel)/docker"
2set -a; . ./.env; set +a
3./set-hubble-pd-password.sh hstore
4HUGEGRAPH_VERSION=local HUGEGRAPH_PULL_POLICY=never \
5  docker compose -f docker-compose-hstore.yml up -d --wait

验证:

1set -a; . ./.env; set +a
2curl -fsS http://localhost:8620/v1/health    # PD
3curl -fsS http://localhost:8520/v1/health    # Store
4curl -fsS http://localhost:8080/versions     # Server
5curl -fsS http://localhost:8088/about        # Hubble
6curl -fsS -u "hg:${HG_PD_AUTH_SECRET_KEY:?请先载入 .env}" \
7  http://localhost:8620/v1/stores       # PD REST 认证后查看 Store 注册状态

若要从本地源码构建该拓扑而不是拉取镜像,可加上开发覆盖文件,并在后续所有生命周期命令中同时带上这两个文件:

1cd "$(git rev-parse --show-toplevel)/docker"
2set -a; . ./.env; set +a
3./set-hubble-pd-password.sh hstore
4docker compose -f docker-compose-hstore.yml -f docker-compose.dev.yml up -d --build --wait

覆盖文件为本地构建生成 dev 标签的镜像;如果已经按上文构建 local 标签镜像,则使用基础 Compose 文件和 HUGEGRAPH_VERSION=local 启动,不要同时混用两个版本标签。

3 节点集群快速启动(当前主线镜像)

HA Compose 文件不包含源码构建覆盖层。先按最小 HStore 一节从同一主线源码构建 hugegraph/pd:local、hugegraph/store:local 和 hugegraph/server:local,然后在 docker/ 目录载入 .env,生成 HA Hubble 配置并启动:

1cd "$(git rev-parse --show-toplevel)/docker"
2set -a; . ./.env; set +a
3./set-hubble-pd-password.sh hstore-ha
4HUGEGRAPH_VERSION=local \
5  docker compose -f docker-compose-3pd-3store-3server.yml up -d --wait

HA Hubble bind-mount conf/hubble/hstore-ha.local.properties;必须在启动前生成。该文件与最小 HStore 使用的 hstore.local.properties 分开生成,但两者从同一 .env 读取同一个 HG_PD_AUTH_SECRET_KEY。

默认内置的启动顺序:

  1. PD (节点)最先启动,且必须通过 /v1/health 健康检查
  2. Store (节点)在所有 PD 健康后再启动
  3. Server (节点)在所有 Store + PD 健康后最后启动

验证集群正常:PD 的 /v1/health 和 /v1/ready 是无需认证的探针;查询 Store 注册和分区数据属于受保护的 PD REST 管理接口,需用用户名 hg 和 .env 中的 HG_PD_AUTH_SECRET_KEY 进行 Basic 认证。

 1set -a; . ./.env; set +a
 2curl -fsS http://localhost:8620/v1/health      # PD 健康检查
 3curl -fsS http://localhost:8520/v1/health      # Store 健康检查
 4curl -fsS http://localhost:8080/versions        # Server
 5for port in 8620 8621 8622; do
 6  curl -fsS "http://localhost:${port}/v1/ready" | grep -q '"ready":true' || exit 1
 7done
 8curl -fsS -u "hg:${HG_PD_AUTH_SECRET_KEY:?请先载入 .env}" \
 9  http://localhost:8620/v1/stores          # 认证后查看已注册的 Store
10curl -fsS -u "hg:${HG_PD_AUTH_SECRET_KEY:?请先载入 .env}" \
11  http://localhost:8620/v1/partitions      # 认证后查看分区分配
12curl -fsS http://localhost:8088/about           # Hubble

开启鉴权后,图列表接口应拒绝匿名请求并接受管理员:

1set -a; . ./.env; set +a
2curl -o /dev/null -w '%{http_code}\n' \
3  http://localhost:8080/graphspaces/DEFAULT/graphs                      # 期望 401
4curl -o /dev/null -w '%{http_code}\n' -u "admin:${HUGEGRAPH_ADMIN_PASSWORD}" \
5  http://localhost:8080/graphspaces/DEFAULT/graphs                      # 期望 200

另外两个 Server 分别在 8081 和 8082 上提供服务,其余 PD 和 Store 节点分别在 8621/8622 和 8521/8522。

环境变量参考

以下 PD、Store、Server 和 Compose 变量表描述当前主线镜像入口及 Compose 文件,不是 hugegraph/hugegraph:1.7.0 单机镜像的环境变量契约。PD 和 Store 的入口脚本会把各自的变量拼成 SPRING_APPLICATION_JSON,并在启动时打印部分非敏感配置摘要;PD 密钥不会打印在该摘要中。docker logs 可用于核对日志列出的配置项,但不要以日志中未显示密钥来判断是否生效。Server 的入口脚本则直接改写 conf/graphs/hugegraph.properties 和 conf/rest-server.properties 中的键。

PD 变量

变量必填默认值映射配置
HG_PD_GRPC_HOST是(无)grpc.host
HG_PD_RAFT_ADDRESS是(无)raft.address
HG_PD_RAFT_PEERS_LIST是(无)raft.peers-list
HG_PD_INITIAL_STORE_LIST是(无)pd.initial-store-list
HG_PD_GRPC_PORT否8686grpc.port
HG_PD_REST_PORT否8620server.port
HG_PD_DATA_PATH否/hugegraph-pd/pd_datapd.data-path
HG_PD_INITIAL_STORE_COUNT否1pd.initial-store-count
HG_PD_AUTH_SECRET_KEY是(当前主线 Docker)无auth.secret-key;PD REST Basic 密码,也供 Server 与 Hubble 使用

已弃用的别名:GRPC_HOST → HG_PD_GRPC_HOST、RAFT_ADDRESS → HG_PD_RAFT_ADDRESS、RAFT_PEERS → HG_PD_RAFT_PEERS_LIST、PD_INITIAL_STORE_LIST → HG_PD_INITIAL_STORE_LIST。只有当新名称未设置时才会把旧名称映射过去,并打印一条警告日志。任一必填变量缺失时,入口脚本以退出码 2 退出。

Store 变量

变量必填默认值映射配置
HG_STORE_PD_ADDRESS是(无)pdserver.address
HG_STORE_GRPC_HOST是(无)grpc.host
HG_STORE_RAFT_ADDRESS是(无)raft.address
HG_STORE_GRPC_PORT否8500grpc.port
HG_STORE_REST_PORT否8520server.port
HG_STORE_DATA_PATH否/hugegraph-store/storageapp.data-path
HG_STORE_ROCKSDB_TOTAL_MEMORY_SIZE否无rocksdb.total_memory_size,auto 或字节数

已弃用的别名:PD_ADDRESS → HG_STORE_PD_ADDRESS、GRPC_HOST → HG_STORE_GRPC_HOST、RAFT_ADDRESS → HG_STORE_RAFT_ADDRESS

RocksDB 缓存使用堆外内存。未设置 HG_STORE_ROCKSDB_TOTAL_MEMORY_SIZE 时,系统将优先根据容器内存限制(cgroup)自动计算;未配置容器限制时则按宿主机内存推导。 由于默认 Docker Compose 未限制容器内存,各 Store 均会以宿主机整机容量估算;若单机部署多个 Store,建议显式配置容器内存限制,或直接为该变量指定字节数。 此外,Store 启动脚本默认会根据系统空闲内存分配 JVM 堆与直接内存(上限各 2 GiB)。建议结合容器规格,通过 JAVA_OPTS 显式约束 JVM 内存(例如容器为 4 GiB 时配置 JAVA_OPTS="-Xmx1g -XX:MaxDirectMemorySize=512m")。详细推导公式见 HStore 配置参考。

Server 变量

与 PD、Store 不同,Server 入口脚本没有必填变量:只有实际设置了的变量才会被写入配置文件。但分布式部署至少需要 HG_SERVER_BACKEND 和 HG_SERVER_PD_PEERS。

变量默认值映射配置
HG_SERVER_BACKEND模板取值(rocksdb,在 hugegraph/server 镜像中为 hstore)conf/graphs/hugegraph.properties 中的 backend
HG_SERVER_PD_PEERS(无)hugegraph.properties 和 rest-server.properties 中的 pd.peers
HG_SERVER_USE_PDfalserest-server.properties 中的 usePD
HG_SERVER_CLUSTERhg-testrest-server.properties 中的 cluster
HG_SERVER_REST_URLhttp://0.0.0.0:8080(镜像中已设置)restserver.url
HG_SERVER_URLS_TO_PDhttp://0.0.0.0:8080server.urls_to_pd:本 Server 注册到 PD 的地址列表(逗号分隔),代替 restserver.url;仅在 server.deploy_in_k8s 为 true 时生效;每个地址都要自带 http:// 前缀,系统只会给第一个地址补上;其中的空白字符会被去除
HG_SERVER_DEPLOY_IN_K8Sfalserest-server.properties 中的 server.deploy_in_k8s
HG_SERVER_MIN_FREE_MEMORY64(MB)restserver.min_free_memory
HG_SERVER_INIT_STORE_ENABLEDtrueinit_store.enabled;元数据由存储侧管理的 PD/HStore 部署应设为 false
HG_SERVER_AUTH_TOKEN_SECRET设置了 PASSWORD 时自动生成两个配置文件中的 auth.token_secret,至少 32 字节
HG_SERVER_REQUIRE_AUTH_TOKEN_SECRETfalse为 true 时,只设置 PASSWORD 而未设置 HG_SERVER_AUTH_TOKEN_SECRET 则拒绝启动
PASSWORD(无)auth.admin_pa,并执行 bin/enable-auth.sh 开启鉴权模式
PRELOAD(无)为 true 时从 scripts/example.groovy 预加载示例图
JAVA_OPTS镜像中已设置传给 bin/start-hugegraph.sh -j
HG_SERVER_STARTUP_TIMEOUT_S120(秒)传给 bin/start-hugegraph.sh -t,允许范围为 1–86400;详见下文的 Server 启动等待超时
STORE_RESTstore:8520wait-partition.sh 轮询的 Store REST 地址,仅 hstore 后端使用
HG_SERVER_PD_REST_ENDPOINT由 pd.peers 把 :8686 改写为 :8620 得到wait-storage.sh 轮询的 PD REST 地址
PD_AUTH_USERstorewait-storage.sh 访问 PD REST API 的 Basic 用户名
PD_AUTH_PASSWORD空PD REST Basic 密码;启用 PD REST 鉴权时须与 HG_PD_AUTH_SECRET_KEY 相同
WAIT_PARTITION_TIMEOUT_S120分区轮询超时;包含下文修复的构建还会限制最终诊断

包含鉴权属性修复的 master 镜像会保留显式签名密钥中的空格、反斜杠和 Unicode,各 Server 副本应使用同一密钥。 如果旧镜像曾错误读取这类密钥,升级时应重新显式提供原本想使用的 HG_SERVER_AUTH_TOKEN_SECRET;仅复用旧配置仍会保留错误读取后的密钥。 若实际生效的密钥改变,须重新登录获取 token。上文所述 1.7.0 镜像限制仍适用。

旧镜像在初始化程序继承 C locale 时,可能错误初始化 Unicode 管理员密码。升级或再次设置 PASSWORD 不会修复已有账号存储的密码, 须由仍可登录的管理员通过用户 API修改。若已无可用管理员身份,本修复不提供自动恢复;应保留现有数据,安排账号恢复后再升级。

已弃用的别名:BACKEND → HG_SERVER_BACKEND、PD_PEERS → HG_SERVER_PD_PEERS

wait-storage.sh 最多等待 300 秒直到出现状态为 Up 的 Store。该时长写死在脚本中,无法通过环境变量调整。

在当前 master Server 构建中,HStore 启动时,分区轮询和最终 /v1/partitions 诊断分别使用独立的 WAIT_PARTITION_TIMEOUT_S 预算。旧构建仅限制轮询时间,最终诊断请求没有超时。 使用默认配置时,最终响应停滞会在 120 秒后超时;设为 0 会禁用 GNU timeout 的时限。 入口脚本在等待 Java 进程前会先等待 wait-partition.sh。若 Java 进程在分区轮询阶段提前退出,轮询仍可能消耗完整超时预算后入口脚本才感知到退出; 若轮询成功,后续的最终诊断也可能再次消耗完整的超时预算。信号触发的关闭仍可正常中断检查。

HG_SERVER_INIT_STORE_ENABLED 和 HG_SERVER_DEPLOY_IN_K8S 只接受 HugeConfig 能识别的写法(忽略大小写):y、t、yes、on、true、n、f、no、off、false。其他取值(包括 0 和 1)都会让入口脚本终止。

入口脚本在初始化成功后写入 docker/init_complete,后续启动会跳过重新初始化,但仍会再执行一次 bin/init-store.sh,以便关闭状态下每次启动都重新校验配置。

Compose 变量

以下变量由 Compose 文件读取,而非入口脚本:

变量默认值用途
HUGEGRAPH_VERSIONlatestServer、PD 和 Store 的镜像 tag
HUGEGRAPH_PULL_POLICYmissing上述镜像的 pull_policy,使用 never 可保留本地构建的镜像
HUBBLE_IMAGEhugegraph/hubble:latestHubble 镜像,与 HUGEGRAPH_VERSION 独立选择
HUBBLE_PULL_POLICYmissingHubble 镜像的 pull_policy
HUBBLE_PUBLISH_HOST127.0.0.1Hubble 8088 端口发布到的宿主机网卡
HUGEGRAPH_ADMIN_PASSWORD(无)以 PASSWORD 传给 Server
HUGEGRAPH_AUTH_TOKEN_SECRET(无)当前主线 Compose 以 HG_SERVER_AUTH_TOKEN_SECRET 传给 Server;1.7.0 镜像不读取该变量
HG_PD_AUTH_SECRET_KEY(无)HStore 拓扑 PD REST Basic 密码;由 Compose 传给 PD 和 Server,并用于生成 Hubble 本地配置

端口参考

3 节点集群发布的端口:

服务宿主机端口容器端口用途
pd086208620REST API
pd086868686gRPC
pd186218620REST API
pd186878686gRPC
pd286228620REST API
pd286888686gRPC
store085008500gRPC
store085108510Raft
store085208520REST API
store185018500gRPC
store185118510Raft
store185218520REST API
store285028500gRPC
store285128510Raft
store285228520REST API
server080808080Graph API
server180818080Graph API
server280828080Graph API
hubble80888088Hubble 界面,默认绑定 127.0.0.1

单机拓扑只发布 8080 和 8088;最小 HStore 拓扑发布 8620(PD REST)、8520(Store REST)、8080 和 8088。PD Raft 使用网络内的 8610,所有拓扑都不对外发布。

故障排查

  1. 容器 OOM 退出(exit code 137):将 Docker Desktop 内存增加到 12 GB 以上 (或调整被 kill 的启动 jvm 内存设置)

  2. Raft 选举超时:检查所有 PD 节点的 HG_PD_RAFT_PEERS_LIST 是否一致。验证连通性:docker exec hg-pd0 ping pd1

  3. 分区分配未完成:在 docker/ 目录先载入 .env,再用 PD REST Basic 认证检查 Store:

    1set -a; . ./.env; set +a
    2curl -fsS -u "hg:${HG_PD_AUTH_SECRET_KEY:?请先载入 .env}" http://localhost:8620/v1/stores

    3 个 Store 都显示 "state":"Up" 后,PD 才能为集群完成分区分配。

  4. 连接被拒:确保 HG_* 环境变量使用容器主机名(pd0、store0),而非 127.0.0.1

  5. 数据在意料之外地保留了下来:docker compose down 会保留命名卷。要同时删除该拓扑的数据,请使用 docker compose down -v

  6. 升级到 master 构建的镜像后出现 Permission denied:基于当前 master 构建的 PD、Store 和 Server 镜像以非 root 用户 hugegraph(UID/GID 10001)运行。 旧镜像以 root 运行,写入的卷仍归 root 所有。先执行 docker compose down(不要用 down -v),对每个数据卷执行一次属主变更,再重新启动:

    1docker run --rm -u 0 --entrypoint chown -v <volume>:/data <new-image> -R 10001:10001 /data

    不要对运行中的容器直接执行 up -d 升级:Compose 会重新挂载保存旧镜像应用目录(归 root 所有)的匿名卷。请先执行 down,或使用 up -d --renew-anon-volumes。 作为 bind mount 的宿主机目录必须对 UID 10001 可写;旧镜像写入过的目录需要执行 sudo chown -R 10001:10001 <dir>,因为其中的文件仍归 root 所有。在 Kubernetes 上,Pod 安全上下文需要 fsGroup: 10001,Helm Chart 已为 PD 和 Store 设置,参见 Helm 升级和验证。

查看运行时日志:使用 docker logs <container-name>(如 docker logs hg-pd0)可直接查看日志,无需进入容器。基于当前 master 构建的 PD、Store 以及两个 Server 镜像(hugegraph/hugegraph 和 HStore 的 hugegraph/server)都设置了 STDOUT_MODE=true,服务日志会输出到容器 stdout。对 Server 而言,Hadoop、ZooKeeper、SOFA、Netty 和 Commons 的 WARN 及以上日志也会输出到 stdout;Hadoop、Netty 和 Commons 的 INFO 日志以及审计日志、慢查询日志仍只写入文件,ZooKeeper 和 SOFA 不输出 WARN 以下的日志。/hugegraph-server/logs 中包含 hugegraph-server.log、JVM 崩溃日志(hs_err_pid*.log)和内存溢出时的堆转储(heapdump_*/java_pid*.hprof,每次启动一个目录,Server 及其启动的 JVM 分别写入各自的文件,除非某个 JVM 复用了同一次启动中先前的 PID;如果无法创建该目录,转储会直接写入 /hugegraph-server/logs)。两个镜像都声明了 VOLUME /hugegraph-server,因此 docker restart 和 Compose 重新创建容器都会保留这些文件;docker compose down 会留下这个匿名卷,下一次 up 不会再挂载它,之后执行 down -v 也不会删除它(请在 down 之前用 docker inspect 记下卷名,再用 docker volume rm <name> 删除;docker volume prune 会同时删除 Docker 主机上所有其他未使用的匿名卷),所以请使用具名卷或绑定挂载来保留这些文件。Kubernetes 每次重启都会新建容器,因此需要在 /hugegraph-server/logs 挂载 emptyDir 或 PersistentVolumeClaim。请为每个 Pod 使用单独的卷,或在共享 PVC 上为每个 Pod 使用单独的目录(subPathExpr: $(POD_NAME),并通过 Downward API 从 metadata.name 传入 POD_NAME;Helm Chart 两者都没有设置):崩溃文件的名字各不相同,但日志文件本身的名字是固定的。只有当存储支持多个节点同时读写挂载(通常是 ReadWriteMany)时,不同节点上的 Pod 才能共享同一个 PVC;ReadWriteOnce 的 PVC 只能被一个节点读写挂载,否则请为每个 Pod 使用单独的 PVC。Helm Chart 目前还不会挂载日志卷。堆转储可能和 JVM 堆一样大,而且每次启动都会使用新目录,因此反复内存溢出的 Server 会把卷写满;请按需要保留的转储数量规划卷大小,并确保不超过 ephemeral-storage 限制或 emptyDir 的 sizeLimit(被驱逐时 emptyDir 会连同转储一起删除),也不要使用 medium: Memory。存活探针失败后,容器最早可能在转储开始后约 (failureThreshold - 1) × periodSeconds + timeoutSeconds 被重启,kubelet 最多再等待 terminationGracePeriodSeconds 就会终止它;请让这段时间长于写入一次堆转储所需的时间,否则在写转储的过程中重启会留下不完整的文件。启动脚本从不删除转储或 heapdump_* 目录,因为 computer 任务的 JVM 可能在 Server 退出后仍在使用它;每次启动到 Java 阶段都会留下一个目录,除非发生内存溢出否则为空。在该次启动的 HugeGraph JVM 都已退出后可以删除旧目录,但不要动正在运行的 Server 最新的那个目录。要对所有 JVM 关闭堆转储,请在容器的环境变量中设置 JAVA_TOOL_OPTIONS=-XX:-HeapDumpOnOutOfMemoryError(可以使用 docker run -e,或在 Compose 中 Server 服务的 environment: 里添加,自带的 Compose 文件没有设置它,或在 Kubernetes 中使用 env;只在宿主机 shell 中导出不会生效),这样会保留镜像默认的 JAVA_OPTS;把该参数加到 JAVA_OPTS 中只对 Server 自身的 JVM 生效,而且会替换镜像默认值(-XX:+UseContainerSupport -XX:MaxRAMPercentage=50 ...),需要把这些参数一并写上。

版本范围:上文描述的是基于当前 master 构建的镜像。1.7.0 及更早的镜像都没有设置 STDOUT_MODE,包括上文使用的单机镜像 hugegraph/hugegraph:1.7.0:docker logs 只能看到入口脚本的输出,服务日志仍在容器内的 logs/ 中(Server 为 logs/hugegraph-server.log)。

容器监控与健康检查

版本说明:本节描述当前主线 Docker 镜像的行为,不包含在 1.7.0 镜像中。可使用上文从主线构建并标记为 local 的镜像,或包含这些改动的 latest 镜像。

进程监控模型

此前,三个 Docker 入口脚本均以 tail -f /dev/null 结尾,即使 Java 进程崩溃,容器仍会保持运行状态。由于容器从未退出,Docker 的 restart: unless-stopped 策略也不会触发。

现在,入口脚本直接监控 Java 进程:

  • PD 和 Store 容器:入口脚本向启动脚本传入 -d false 参数,启动脚本通过 exec 直接替换为 Java 进程。容器进程即为 Java 进程,当 Java 退出(崩溃或正常关闭)时,容器立即退出,Docker 的重启策略随即触发。
  • Server 容器:入口脚本持有前台 launcher 并等待 Java。服务就绪后保留 Java 的实际退出码,包括 0、42 和 SIGKILL 对应的 137。 SIGTERM 和 SIGINT 请求协作关闭、回收持有的就绪/分区检查进程,并在关闭后分别返回 143 和 130。
  • 所有镜像中的 PID 1 均为 dumb-init,负责将 Docker 信号转发给入口脚本进程。

Server 启动等待超时

HG_SERVER_STARTUP_TIMEOUT_S 设置 Docker 入口脚本等待 REST 就绪的期限,未设置时默认 120 秒。取值必须是不带前导零的十进制整数,范围为 1–86400 秒。空字符串、0、负数、小数和超出范围的值都会使入口脚本记录错误并以退出码 1 退出。

入口脚本也通过 bin/start-hugegraph.sh -t 传入该值;前台 launcher 本身等待 Java,不轮询 REST。 启动期限失败、或 Java 在就绪前以 0 退出时,入口脚本返回 1;提前以非零码退出则保留该退出码。 此时长不包括此前的存储初始化或等待后端就绪的时间。关闭时可以中断就绪和分区检查;启动期限失败会请求终止 Java 并返回,不增加无限等待。 未响应终止请求的 Java 进程仍依靠容器终止完成最终清理。

例如,在 HugeGraph 仓库的 docker/ 目录下,将单机 Server 的启动等待时间增加到 300 秒(Compose 文件会将该变量传入容器):

1HG_SERVER_STARTUP_TIMEOUT_S=300 HUGEGRAPH_VERSION=latest \
2  docker compose -f docker-compose.yml up -d --wait

该设置与 Docker 健康检查的 start_period、interval、timeout 和 retries 相互独立。健康检查参数决定何时将容器标记为 unhealthy;仅增加健康检查的等待时间,不会延长 Server 启动脚本的等待期限。调整此变量也不会自动修改健康检查参数,启动较慢时应分别检查这两组设置。

健康检查端点

所有四个 Docker 镜像现已内置 HEALTHCHECK 指令。docker ps 将显示真实的健康状态。在 90 秒的启动期内,检查失败不计入统计;此后,连续三次失败将把容器标记为 unhealthy。

镜像健康检查端点端口参数
hugegraph/hugegraph(单机 RocksDB Server)GET /versions8080--interval=15s --timeout=10s --start-period=90s --retries=3
hugegraph/server(HStore Server)GET /versions8080同上
hugegraph/pdGET /v1/health8620同上
hugegraph/storeGET /v1/health8520同上

Compose 文件在此之上还定义了自己的健康检查,因此 --wait 和 depends_on: condition: service_healthy 不依赖镜像内置的检查。Compose 中的检查使用更短的启动期(视服务和拓扑为 30 到 120 秒)和更多的重试次数。

注意:start-hugegraph.sh 中的 -m true 标志(基于 cron 的监控)仅适用于虚拟机/裸机部署,Docker 镜像中未安装也不使用该功能。Docker 用户应依赖内置的 HEALTHCHECK 和 Docker 重启策略。

6.5 - FAQ

部署与启动

如何选择 RocksDB 或 HStore

开发测试或中小规模单机部署推荐选择 Server + RocksDB,部署轻便且性能优异。当数据规模较大(如 TB/PB 级)、需要水平扩容或多副本高可用时,推荐部署 HStore 分布式集群(PD + Store + Server)。

1.7.0 支持 RocksDB、HStore、HBase 和 Memory。Cassandra、ScyllaDB、MySQL、PostgreSQL 等旧后端需使用低于 1.7.0 的版本。 部署步骤见 Server 快速开始。

启动时出现 core dumped 怎么查

先执行 java -version 确认 JDK 版本:HugeGraph master 分支(以 1.8 为基线)要求 Java 17,1.7.0 要求 Java 11(已不再支持 Java 8)。 若 JDK 版本正确,进一步查看 Server 日志及 JVM 崩溃日志(hs_err_pid*.log),排查是否由于系统架构不匹配、依赖的动态库(如 RocksDB JNI)缺失或系统内存不足引起。

哪些后端需要 init-store

使用 RocksDB 或 HBase 等本地持久化后端时,首次启动前必须执行 bin/init-store.sh 进行初始化。Memory(内存后端)和 HStore(分布式后端)无需执行此脚本,HStore 的存储由 PD 和 Store 统一管理。

注意:backend 与 serializer 必须配套使用(例如 RocksDB 配套 binary),不可随意替换。若服务启动后提示无法连接后端,请优先检查是否完成初始化以及后端存储配置是否正确。

init-store 报 GLIBCXX 版本缺失怎么办

出现以下报错表示当前系统的 libstdc++ 版本过低,缺少 RocksDB JNI 本地库所需的符号:

1java.lang.UnsatisfiedLinkError: .../librocksdbjni....so:
2.../libstdc++.so.6: version `GLIBCXX_3.4.10' not found

解决方法:核对发行包支持的系统架构,升级系统的 libstdc++(或安装较新的 GCC 运行库),或者直接使用官方提供的 Docker 镜像运行。

应该使用哪个 Server 启动脚本

当前发行包统一使用 bin/start-hugegraph.sh,GremlinServer 与 REST Server 会在同一个进程中启动。旧版本文档中的 start-restserver.sh 和 start-gremlinserver.sh 已废弃。

启动脚本会加载哪些图

脚本名称与加载的图无关。Server 默认会扫描并加载 conf/graphs 目录下的所有图配置(可在 conf/rest-server.properties 中的 graphs 修改该目录)。每张本地图使用独立的配置文件,修改配置后需重启 Server。

注:graph.load_from_local_config 默认为 false(控制构造阶段预加载),不能用来禁止启动时加载本地图。详见服务端配置说明。

连接与查询

curl 返回乱码怎么办

批量顶点和边接口默认会返回 gzip 压缩数据。使用 curl 请求时加上 --compressed 参数即可自动解压:

1curl --compressed \
2  'http://127.0.0.1:8080/graphspaces/DEFAULT/graphs/hugegraph/graph/vertices?limit=10'

若开启了认证,需同时传入凭据。若返回内容仍不符合预期,请检查 HTTP 状态码、Content-Type 与 Content-Encoding,不要把 JSON 报错直接管道传给 gunzip。

按顶点 ID 查询却找不到顶点

先从已有查询结果中确认 id 的实际格式和类型:字符串 ID 需要 JSON 双引号,数值 ID 不需要。例如字符串 ID 1:marko 的 JSON 格式应为 "1:marko"。

在把 ID 放入 URL 路径时,必须对包含双引号在内的完整字符串进行 URL 编码。若 ID 含有特殊字符,不能仅补双引号而遗漏编码:

字符URL 编码
+%2B
空格%20
/%2F
?%3F
%%25
#%23
&%26
=%3D
"%22

按类型查询顶点或边时超时

当某个标签下的数据量很大时,全量扫描很容易耗尽资源导致超时。建议优化方式:

  1. 加上 limit() 限制返回记录数;
  2. 使用分页机制分批读取;
  3. 配合具体属性过滤,并确保对应属性已建立索引,避免全表扫描。

REST 请求正常,Gremlin 返回 500

REST 接口正常仅说明 HTTP 入口可用,Gremlin 执行返回 500 通常有以下原因:

  1. Gremlin Server 连接异常:检查 conf/rest-server.properties 中的 gremlinserver.url 是否指向可达的 Gremlin 端口(默认 8182,对应 conf/gremlin-server.yaml);
  2. 语句语法或逻辑错误:例如未加索引导致遍历被拦截;
  3. 认证凭据缺失或过期。

建议查看 logs/hugegraph-server.log 中的异常堆栈定位具体报错。

REST 请求返回 HTTP 415

发送带请求体的 POST/PUT 请求时,需在请求头中指定 Content-Type: application/json,并确保请求体是合法的 JSON 格式。

导入与数据维护

Loader 出现 Socket Timeout

导入超时通常由于单批次写入过大或并发压力过高导致。建议:

  1. 适当调小 --batch-size(如由 500 降为 200);
  2. 适当降低并发线程数;
  3. 调大 --timeout 并配置重试机制。参数说明见 Loader 指南。

如何清空一张图

管理员可调用以下接口清空指定图的 Schema、顶点、边和索引(执行前请务必确认目标图并做好备份):

1DELETE /graphspaces/{graphspace}/graphs/{graph}/clear

请求需携带 confirm_message 查询参数,值必须严格等于 I'm sure to delete all data(需进行 URL 编码)。完整调用方式见 Graph API。

清理底层存储后,为什么仍提示 Schema 已存在

Server 在内存中维护了 Schema 缓存。如果直接绕过 Server 清理底层存储(如清空 RocksDB 目录或 HBase 表),Server 缓存与实际存储将出现不一致。 若已手动清理底层,必须重启 Server。日常清理建议使用官方提供的 Clear 图 API。

建模与 ID

顶点或边 ID 超过长度限制

为保证底层存储与索引性能,HugeGraph 对 ID 长度作了如下限制(按编码后的字节数计算):

  • 顶点 ID:最长 16384 字节(16 KB);
  • 边 ID:最长 65536 字节(64 KB)。

建议使用简洁的业务唯一标识作为主键,避免在 ID 中拼接大段文本。注:属性索引值超过 32 字节时会自动转为哈希存储,不会报错超长。

是否支持嵌套属性

目前不支持嵌套属性(复杂对象或嵌套 Map)。如果需要表达多层级关系,建议将嵌套对象拆分成独立的顶点,通过边与主体顶点相连。

支持。创建 EdgeLabel 时,对每一组起点和终点类型分别调用一次 link(sourceLabel, targetLabel) 即可。 例如“投资”关系可以同时连接“个人 → 企业”和“企业 → 企业”。旧版 sourceLabel() 与 targetLabel() 只支持单一配对,现已废弃。

其他问题可搜索 Server issues 或 Toolchain issues。

6.6 - 报告安全问题

报告 Apache HugeGraph 的安全问题

警告

生产环境安全要求

HugeGraph 默认不启用用户认证。生产环境必须启用认证与授权、将 white_ip.status 设为 enable 并启用和维护 IP 白名单,同时按最小权限为账号授权;不得将 Gremlin、Cypher 等查询接口直接暴露到公网。白名单管理方式见 IP 白名单 API。生产部署还必须隔离 Server 进程,可使用 Docker 或 Kubernetes 等容器环境。

Server 标准配置将鉴权代理的审计记录写入 audit-*.log。部署时必须保留并限制这些日志的读取权限。auth.audit_log_rate 只控制每用户的最大日志输出速率,不是审计日志的启停开关。

警告

漏洞报告范围

近期社区已收到较多关于图查询语言灵活性的安全反馈。在 HugeGraph 安全体系整体重构完成前,对于在不启用或跳过 Auth 系统/避开授权身份的前提下执行 DSL 查询的情况,此类已知风险将不再单独视为新漏洞进行处理。

如果在已开启 Auth 系统的环境中仍能以匿名或未授权身份访问并利用漏洞,或者成功绕过 IP 白名单 / 逃逸容器造成严重越权或底层系统破坏,仍属于高危安全漏洞,欢迎向社区报告。

遵循 ASF 的规范,HugeGraph 社区对解决修复项目中的安全问题保持非常积极和开放的态度。

我们强烈建议用户首先向我们的独立安全邮件列表报告此类问题,相关详细的流程规范请参考 ASF SEC 守则。

请注意,安全邮件组适用于报告未公开的安全漏洞并跟进漏洞处理的过程。常规的软件 Bug/Error 报告应该使用 Github Issue/Discussion 或是 HugeGraph-Dev 邮箱组。发送到安全邮件组但与安全问题无关的邮件将被忽略。

独立的安全邮件 (组) 地址为: security@hugegraph.apache.org

安全漏洞处理大体流程如下:

  • 报告人私下向 Apache HugeGraph SEC 邮件组报告漏洞 (尽可能包括复现的版本/相关说明/复现方式/影响范围等)
  • HugeGraph 项目安全团队与报告人私下合作/商讨漏洞解决方案 (初步确认后可申请 CVE 编号予以登记)
  • 项目创建一个新版本的受漏洞影响的软件包,以提供修复程序
  • 合适的时间可公开漏洞的大体问题 & 描述如何应用修复程序 (遵循 ASF 规范,公告中不应携带复现细节等敏感信息)
  • 正式的 CVE 发布及相关流程同 ASF-SEC 页面

已发现的安全漏洞 (CVEs)

HugeGraph 主仓库 (Server/PD/Store)

HugeGraph-Toolchain 仓库 (Hubble/Loader/Client/Tools/..)

6.7 - 1.8.0 共享基础模块迁移指南

调整 Java import 和插件实现,并准备 1.8.0 共享基础模块迁移所需的 Server、PD、Store 同步升级。

1.8.0 共享基础模块迁移会改变 Java import 和扩展接口的签名,Server、PD、Store 也需要一起升级。 先根据集成方式找出受影响代码,再重新构建应用,并在部署前检查已有数据。

先确定需要调整的部分

你的集成方式需要准备什么
Java 代码使用 Server 的 ID、schema 元数据、查询或索引调整 import 和受影响签名,使用配套的 1.8.0 依赖包重新编译。
自定义序列化器、HugeGraph 实现或元素子类按下方说明修改 SPI 契约和共享元素状态的适配。
自定义 Gremlin import 或脚本替换旧 IdGenerator 类名,并验证发行包中的 Gremlin 服务启动。
Hubble、Java client 或 Computer 集成配套依赖包可用后,应用对应的异常类调整。
HStore 部署对齐 PD 命名空间,检查旧的 Store 重建索引,同步升级所有写入端。
Loader 或其他仅通过 REST 调用的集成保留独立 client DTO,按实际使用情况迁移受影响的 Java 调用。

该共享基础模块重构面向 1.8.0 目标版本。 升级时请使用配套的 Server、PD、Store 发行包及下游依赖。 Java 映射和兼容性样本见源码迁移指南。

共享代码现在由谁维护

此前 Server core 和 struct 分别维护了部分 ID、schema 类型、查询、元素和编解码实现。 迁移后,这些共享类型统一由一个模块维护,Server 和 Store 使用同一份实现。 hugegraph-core 继续运行图引擎,hugegraph-struct 提供共享模型和编解码,hugegraph-common 提供通用工具。

迁移前 core 和 struct 分别维护共享实现,迁移后 core 与 Store 使用 struct,struct 使用 common,PD 使用 common

Core 保留图执行和适配器,Store 保留存储和 schema 生命周期,struct、common 统一维护共享实现。 箭头描述共享职责,不包含完整依赖树。

维护模块职责
structID、schema 元数据、类型码、查询、基础元素、属性和字节编解码、索引构建及分词器
core事务、遍历、任务、schema 修改、后端适配器及索引更新编排
Store通过 SchemaGraph/SchemaDriver 管理基于 PD 的 schema 访问、监听器和缓存生命周期
commonJWT 签名与校验、共享认证常量和 RPC 配置接口

Server 的 HStore 适配器仍需要 PD、Store 客户端,Store 保留网络、PD 客户端及存储库。 PD、Store 不应依赖 core,struct 不应依赖 core 或 PD 客户端。

Core、Store 实现 HugeGraphSupplier,提供 schema、配置和时钟访问能力。 共享基础元素持有状态和邻接关系,HugeVertex、HugeEdge 保留引擎行为及基于同一状态的包装对象身份。 属性修改、克隆、删除、过期和加载状态都应通过这份共享状态传递。 Core 序列化器保留后端适配逻辑,委托共享代码完成编解码。 共享索引和 OLAP 选择接收调用方提供的 schema 候选及结果接收器,事务写入和后端能力检查仍由 core 执行。

调整 Java 源码和 SPI 实现

先检查代码实际使用的类型。以下 ID 构造调用保留相同的字符串值,只需要迁移 import。

调整前,使用 1.7.0 core API

1import org.apache.hugegraph.backend.id.Id;
2import org.apache.hugegraph.backend.id.IdGenerator;
3
4Id vertexId = IdGenerator.of("vertex-1");

调整后,使用共享 API

1import org.apache.hugegraph.id.Id;
2import org.apache.hugegraph.id.IdGenerator;
3
4Id vertexId = IdGenerator.of("vertex-1");

调整源码后,重新编译应用和插件。迁移后的类型同时改变了方法描述符,仅修改 import 不能让旧的已编译 jar 具备二进制兼容性。 被移除的 core 类没有通用兼容包。插件示例仍描述 1.7.0 API,接入迁移后的 API 时按下表调整。

原 Java 入口迁移后的入口
org.apache.hugegraph.backend.id 中下方列出的共享类型org.apache.hugegraph.id.*
org.apache.hugegraph.schema.* 元数据org.apache.hugegraph.struct.schema.*
org.apache.hugegraph.backend.query 中下方列出的共享类型org.apache.hugegraph.query.*
org.apache.hugegraph.backend.query.serializer.*org.apache.hugegraph.query.serializer.*
org.apache.hugegraph.backend.store.Shardorg.apache.hugegraph.backend.Shard
org.apache.hugegraph.backend.store.BackendEntry.BackendColumnorg.apache.hugegraph.backend.BackendColumn
org.apache.hugegraph.structure.HugeIndexorg.apache.hugegraph.structure.Index
后端序列化器中的共享字节与编码逻辑org.apache.hugegraph.serializer.*
Core HugeExceptionorg.apache.hugegraph.exception.HugeException
org.apache.hugegraph.SchemaGraph/SchemaDriverorg.apache.hugegraph.store.schema.*

ID 包只迁移 Id、IdGenerator、EdgeId、IdUtil、SplicingIdGenerator。 SnowflakeIdGenerator 保留在 core 的 org.apache.hugegraph.backend.id,继续使用原 import。 查询包迁移 Query、ConditionQuery、Condition、IdQuery、IdPrefixQuery、IdRangeQuery、BatchConditionQuery、Aggregate。 QueryResults、ConditionQueryFlatten、EdgesQueryIterator、QueryBatch、QueryResultContext 保留在 core 的 org.apache.hugegraph.backend.query,继续使用原 import。

SchemaManager、Schema 修改 builder 和后端专用序列化器仍在 core,需按实际受影响类型应用表中的映射。 客户端 REST DTO 保持独立,包括 Toolchain 的 org.apache.hugegraph.structure.graph.Shard。

扩展点实现需要怎样调整
HugeGraph.sameAs(HugeGraph)Override 改为 sameAs(org.apache.hugegraph.HugeGraphSupplier),没有旧签名的重载。
GraphSerializer.writeIndex/readIndex接收或返回共享 org.apache.hugegraph.structure.Index,并调整调用方。
自定义 HugeElement 子类通过 element() 提供共享 BaseElement,通过 wrapProperty 适配属性。

元素适配器继续使用共享状态,不要恢复已移除的引擎状态字段,也不要新增一套邻接集合。 Gremlin classImports 和脚本需将 org.apache.hugegraph.backend.id.IdGenerator 改为 org.apache.hugegraph.id.IdGenerator。 启动发行包中的 Gremlin 服务,验证仅存在于配置中的类名引用;Java 编译不会检查这些引用。

RPC 接口 org.apache.hugegraph.rpc.RpcServiceConfig4Client 和 RpcServiceConfig4Server 统一由 common 维护。 类名和签名保持不变,无需因这项迁移调整 RPC import 或配置。 org.apache.hugegraph.auth.TokenGenerator 也由 common 维护,调用方提供签名密钥,并将 JWT 失败转换为各服务的响应。 Common 的 JWT 依赖为 optional,直接使用 JWT 的模块需声明所需库。

使用配套依赖包时调整下游异常

原下游入口替换为
Hubble org.apache.hugegraph.exception.HugeExceptionorg.apache.hugegraph.exception.HubbleException
Java client org.apache.hugegraph.exception.NotSupportExceptionorg.apache.hugegraph.exception.ClientNotSupportException
Hubble 自带的 org.apache.hugegraph.license.MachineInfo保留 import,使用 common 的实现。

与 import 一起修改构造调用和 catch。HubbleException 保留 RuntimeException 父类和字符串构造器。 ClientNotSupportException 保留 ClientException 父类及 message/cause、message/arguments 构造器。 Computer 的 HgkvDirImpl 是受影响的 client 异常调用方。Struct 中名称相近的异常具有不同契约。 Loader 的 REST 边界和独立 client DTO 无需整体改为 struct。

Toolchain、Computer 调整仍是未发布的下游交接内容,需要配套发布、构建和发行包类路径检查。 检查构建后的 jar 以及源码,排除残留或传递依赖引入的同名类副本。

准备同步升级服务

将 Server、PD、Store 一起升级到配套发行包,本次迁移不支持混合版本滚动升级。 以下步骤适用于配套发行包已可用的部署。

迁移流程包括备份和索引检查、修改 Java 代码、同步升级 Server PD Store、验证服务和数据,OLAP key 改为属性加顶点

先备份数据和配置、检查受影响索引,再修改 import、SPI 并重新编译,随后同步升级配套服务、对齐 PD 命名空间。 最后验证发行包服务及图数据读写。OLAP 从每个顶点一行改为每个属性和顶点一行;匹配的旧行仍可读取,覆盖丢失的值不能恢复,不支持混合版本滚动升级。

  1. 按已有备份恢复流程备份图数据,并保留部署配置。
  2. 准备配套的 Server、PD、Store 发行包,以及重新构建的插件和实际需要的下游集成。
  3. 按下方配置对齐元数据命名空间,保留既有底层图名称。
  4. 在验证环境演练,启动发行包中的服务,读取历史数据,执行受影响查询和写入。
  5. 暂停写入后同步升级部署。所有 Server、Store 写入端使用配套发行包且检查通过后,再恢复写入。

本次整合不会自动重写图数据、重建索引或恢复历史项。演练时需检查下方兼容性场景。

对齐 PD 元数据命名空间

Store 的 pd.cluster 默认值为 hg,在 Store application.yml 中按以下方式设置。

1pd:
2  cluster: hg

对应环境变量为 PD_CLUSTER。

Server 模式必须与 Store pd.cluster 一致的配置
usePD=trueServer 的 cluster
usePD=false图配置的 pd.cluster

命名空间用于 schema、图配置、缓存监听和 TTL 清理器元数据。 同一个 Server 进程内的所有 HStore 图必须使用同一元数据命名空间。 usePD=false 时,首先打开的 HStore 图会用自身的 pd.cluster 绑定进程级 MetaManager。 后续图显式配置的冲突 pd.cluster 会记录警告并被忽略,不会建立独立命名空间。 同一个 Store 进程不能在冲突命名空间之间共享 schema driver。 保留 backend graphspace/store/table 名称,例如 DEFAULT/hugegraph/g;REST 标识 DEFAULT-hugegraph 不是元数据 key。

检查数据兼容性

数据或行为保留或调整的行为
已存储的 ID 和属性保留既有类型码、ID 与属性字节,以及配置默认值。
字符串 ID 比较统一采用 Java UTF-16 顺序,包括从 UTF-8 字节加载的 ID;存储字节不变。
查询 JSON 和受支持的 Kryo 数据类型迁移后仍需兼容解码历史 Java 类名。
Schema map保留 wire 字段和 ID 身份;主键及 edge sort-key 列表保留顺序和重复项。
Schema 端点可读取匹配的冗余元数据和旧版仅含端点字段的 map;拒绝冲突或格式错误的端点。
普通 schema 索引Server 创建的 key 保留 key/name-TTL 布局。
带正过期时间的 Store SYSTEM-label 索引保留稳定 key 和旧版 13 字节 value 封装,label 读取端识别这个有明确边界的封装。

Core SYSTEM-label 写入端保留原有字节。这次迁移不为这些 key 添加 TTL 后缀,也不改变前缀删除行为。 原本不支持的仅凭索引重建元素功能仍不支持。

元素分类通过 BaseVertex.TypeContext 保留生产方上下文。

上下文既有系统顶点分类
STORAGE~variables 是任务数据。
ENGINE~server、~role_data 是服务端数据,~variables 是普通顶点数据。
两者~task、~taskresult 都是任务数据。

引擎 wrapper 选择 ENGINE,独立 storage 元素保留 STORAGE,使表路由沿用既有行为。

重建受影响的旧长文本索引

旧 Store IndexBuilder 将长文本值截短为 20 个字符,Server 查询使用完整值及其 hash。 共享 builder 现在采用 Server 契约。旧的截短索引行仍可解码,但不会自动匹配完整值查询。

若部署曾通过 Store 重建索引,应找出受影响索引,必要时从图数据重新构建。 本次迁移不自动重建索引,也不能恢复缺失的历史项。普通 Server 创建的索引 key 沿用原有契约。

验证 HStore OLAP 读取和删除

新 OLAP 行使用 [property ID][vertex ID] key,让同一顶点的多个 OLAP 属性可以共存。 旧行只以 vertex ID 作为 key,其 value 无需重写仍可读取。

操作组合 key 与旧 key 的处理方式
读取某个属性优先读取其组合 key;旧 vertex-only 行的 value 包含请求的 property ID 时,才回退读取。
删除某个属性移除其组合行和匹配的旧行,保留其他属性。
读取旧写入端已经覆盖丢失的属性本次修复无法恢复丢失的值。

恢复写入前,升级全部 Server、Store 写入端。旧写入端可能更新旧行,新读取端仍优先读取已经存在的组合行。 混合版本 OLAP 写入不在支持的升级契约内。

验证发行包服务和集成

运行受影响的 Java/SPI 测试,再检查 RocksDB、HStore 查询、认证、Store schema 与过滤行为,以及共享元素状态传播。 覆盖历史 ID、schema、属性和索引样本、分页、TTL、OLAP 场景。 核查解析后的依赖和发行 jar,排除禁止的模块依赖或重复 HugeGraph 类,并启动实际发行包中的服务,不依赖类路径顺序规避冲突。 构建和依赖清单的前置条件见贡献指南。

实现、网站文档和下游依赖包仍需配套发布。 根据配套发行包、依赖包和运行结果决定采用迁移的时间;只编译源码或跳过测试的构建不足以确认可用性。

6.8 - HugeGraph 1.8.0 Gremlin 迁移与兼容性指南

详细说明 HugeGraph 1.8.0 从 TinkerPop 3.5 升级到 3.8 带来的核心语法兼容性变化、常用改写方案、配置调整及全量细则速查表。

HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升级至 TinkerPop 3.8.1,运行环境统一要求 Java 17(服务端与构建),并将脚本引擎升级至 Groovy 4.0.25。

此次升级引入了部分语言层面的破坏性变更(Breaking Changes)。下文优先列出最常用且行为发生变化的核心语法与改写方案,以便快速排查和迁移;次常用选项及底层协议等边缘细节整理在文末的全量细则速查表。

说明
  • 本指南适用于从 1.7.0(或更早版本)升级至 1.8.0 的用户。
  • 1.8.0 依然保留了 Groovy 脚本引擎支持,既有的多行脚本、变量定义及 Java 闭包等大多数逻辑仍可正常运行。

最常用的 5 大语法与行为变化

以下 5 项改动在已有业务查询中最为高频。前 3 项若不改写,在 HugeGraph 1.8 中会直接抛出异常;后 2 项不报错,但会静默改变返回结果(自动剔除缺失属性的元素或放行未匹配分支),需重点排查。

1. has(key, traversal) 重载删除(高危:查询执行报错)

  • 影响说明: 在 TinkerPop 3.8.0 中,has(String, Traversal) 和 has(T, Traversal) 重载被彻底移除。 在 Groovy 脚本引擎下,旧写法会退化命中 has(String, Object) 重载。在 HugeGraph 1.8 中,由于图引擎将 has() 谓词下推至后端存储检索,并通过 TraversalUtil.validPropertyValue() 对属性值进行强类型校验,会直接抛出类型不匹配异常:
    • 属性过滤如 g.V().has('age', __.is(gt(30))) 抛出: IllegalArgumentException: Invalid data type of query value '[IsStep(gt(30))]', expect INT for 'age', actual got class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal
    • 标签过滤如 g.V().has(T.label, __.is('person')) 抛出: HugeException: The label type must be number or string, but got 'class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal' (注:仅在纯内存 TinkerGraph 上会静默返回空数组 [],而在 HugeGraph 1.8 上会严格报错)。
  • 典型旧写法:
    1// 错误!在 HugeGraph 1.8 下执行将抛出 Invalid data type 异常
    2g.V().has('age', __.is(gt(30)))
    3g.V().has(T.label, __.is('person'))
  • 推荐改写方案:
    1// 简单标量/谓词判断,直接传值或 P 谓词
    2g.V().has('age', gt(30))
    3g.V().hasLabel('person')
    4g.V().hasId('v-1')
    5
    6// 若需要把属性值传给复杂子遍历计算后再过滤,改用 filter()
    7g.V().filter(__.values('age').is(gt(30)))

2. store() 彻底删除 & aggregate() Scope 重载移除

  • 影响说明:
    • 旧版中用于惰性边走边收集副作用的 store('x') 步骤已被完全删除,在 3.8.1 中直接报错 MissingMethodException: No signature of method: ...store()。
    • aggregate(Scope, 'x') 的带 Scope 重载也被删除(包括 aggregate(local, 'x') 和 aggregate(global, 'x'))。
  • 典型旧写法:
    1// 错误!store 步骤已被移除
    2g.V().store('x').by('age').cap('x')
    3
    4// 错误!aggregate 的 scope 重载已被移除
    5g.V().aggregate(local, 'x')
    6g.V().aggregate(global, 'x')
  • 推荐改写方案:
    1// 1. 全局贪心收集(原 global 聚合):直接使用 aggregate('x')
    2g.V().aggregate('x').by('age').cap('x')
    3
    4// 2. 局部/惰性逐个对象收集(原 store 或 local 聚合):使用 local(__.aggregate('x'))
    5g.V().local(__.aggregate('x').by('age')).cap('x')

3. 丢弃输入步骤 none() 更名为 discard()

  • 影响说明: 在 TinkerPop 3.5.1 中,none() 为 traversal 步骤,用于丢弃流中输入(如 g.V().hasLabel('person').none() 返回 [])。 3.8.1 中该操作更名为 discard()。 同时 3.8 引入了新的集合谓词步骤 none(P)(用于检查集合是否没有元素满足条件)。若在 3.8.1 中直接调用无参 none(),会立即抛出异常: IllegalArgumentException: Input predicate to none step can't be null.
  • 推荐改写方案:
     1// 旧写法(3.5.1 下执行返回 []):
     2g.V().hasLabel('person').none()
     3
     4// 新写法:统一使用 discard()
     5g.V().hasLabel('person').discard()
     6
     7// 在 choose() 或分支中丢弃未匹配元素与属性缺失元素:
     8g.V().choose(__.values('age'))
     9  .option(gt(30), __.values('name'))
    10  .option(Pick.none, __.discard())
    11  .option(Pick.unproductive, __.discard())

4. by() 属性缺失行为变严(可能导致排序丢点、投影丢字段、路径丢失)

  • 影响说明: TinkerPop 3.6+ 统一了 by() 调制器的缺失值处理(去除了原先部分默认补 null 的策略)。在 3.8.1 中,当 by() 依赖的属性不存在时:
    1. 排序 order().by('age'):缺少 age 属性的顶点直接被过滤掉(旧版可能保留在开头或末尾)。
    2. 投影 project('name', 'age').by('name').by('age'):若某个顶点缺少 age,返回的 Map 中将直接不包含 age 键(旧版会返回 age: null)。
    3. 路径 path().by('age'):路径上若有任一节点缺少该属性,整条路径将被直接丢弃。
  • 推荐改写方案: 如果业务要求在属性缺失时仍保留元素并填入默认值(如 null 或默认占位值),需在 by() 中使用 coalesce() 显式保底:
    1// 保证缺 age 时依然保留该字段,且值为 null
    2g.V().project('name', 'age')
    3  .by('name')
    4  .by(__.coalesce(__.values('age'), __.constant(null)))
    5
    6// 排序时为缺失属性指定统一后置的默认值(需保持数据类型一致)
    7g.V().order().by(__.coalesce(__.values('age'), __.constant(-1)), desc)

5. 分支条件 choose() 语义收敛

  • 影响说明:
    • 缺失属性处理:当选择子遍历依赖的属性缺失时,TinkerPop 3.5.1 会直接抛出异常: IllegalArgumentException: The provided traverser does not map to a value: v[3]->[PropertiesStep([age],value)]。 在 3.8.1 中,缺少对应属性的元素不再报错,而是默认原样放行穿透。
    • 单分支执行:当多个 option() 条件同时命中时,旧版可能会把多个匹配分支全部执行;新版只执行第一个命中的分支。
    • 默认放行机制:如果没有任何一个 option() 匹配,新版默认将输入元素原样向下游放行(3.5.1 则会过滤掉)。
  • 推荐改写方案:
    • 如需在多个条件同时命中时全部执行,请使用 union() 配合 filter()。
    • 如需在无匹配或属性缺失时将元素过滤抛弃,需显式声明 Pick.none 与 Pick.unproductive 分支:
    1// 显式丢弃无匹配项以及缺少 age 属性的项
    2g.V().choose(__.values('age'))
    3  .option(gt(30), __.values('name'))
    4  .option(Pick.none, __.discard())
    5  .option(Pick.unproductive, __.discard())

1.8 新增步骤与内置函数(TinkerPop 3.8)

TinkerPop 3.8 引入了原生日期操作函数与步骤,这些能力在 3.5.1(HugeGraph 1.7.0)中并不存在:

日期步骤(datetime()、dateAdd()、dateDiff())

  • datetime():构造日期时间对象或取得服务器当前时间。在 3.8 中返回 java.time.OffsetDateTime(如 datetime('2026-10-19T00:00:00Z'))。
  • dateAdd():对日期进行加减运算。
  • dateDiff():计算两个日期的差值,返回差值的毫秒数(例如相隔 1 天的结果为 86400000 ms)。
  • 代码示例:
    1// 获取当前时间 OffsetDateTime
    2g.inject(datetime())
    3
    4// 计算日期毫秒差并转换为秒
    5g.inject(datetime('2026-10-19T00:00:00Z')).dateDiff(datetime('2026-10-18T00:00:00Z'))
    6  .math('_ / 1000').asNumber(GType.LONG)

服务端配置与客户端连接兼容

1. conf/gremlin-server.yaml 序列化器配置

在 TinkerPop 3.8 中,序列化器从 gremlin-driver(org.apache.tinkerpop.gremlin.driver.ser.*)包迁移到了 gremlin-util(org.apache.tinkerpop.gremlin.util.ser.*)包。

重要

请勿直接复制 1.7.0 的 gremlin-server.yaml 并仅替换类名! 推荐直接使用 HugeGraph 1.8.0 发行包自带的 conf/gremlin-server.yaml,再将自定义端口、认证等配置合并进去。 HugeGraph 需要专用的 Builder 与 Registry:GraphBinary 必须配置 builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder 才能序列化 HugeGraph 的 Id、Schema、Blob 与枚举类型(否则会抛出 IOException: Serializer for type ... not found); 无类型 GraphSON V1 需要添加 org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry。

旧配置类名 (driver.ser.*)1.8.0 对应类名 (util.ser.*)所需 Builder / Registry说明
GraphBinaryMessageSerializerV1org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder
ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]
推荐,默认高效二进制协议
GraphSONMessageSerializerV1d0org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry, org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry]保持无类型 GraphSON V1
GraphSONMessageSerializerV2d0org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]标准 Typed GraphSON V2
GraphSONMessageSerializerV3d0org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]标准 Typed GraphSON V3
(1.8 新增)org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]无类型 GraphSON V2 (types=false)
(1.8 新增)org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]无类型 GraphSON V3 (types=false)

2. HugeGraph Client 1.5.0 能否平滑使用?

  • 结论:基础数据 CRUD 与 Schema 操作可以继续使用;Gremlin 查询与鉴权管理需要升级或适配。
  • 服务端在 1.8.0 中增加了向前兼容层,使用 hugegraph-client:1.5.0 进行常规顶点/边 CRUD 和 Schema 操作均可正常连通。
  • 限制说明:
    • Gremlin 查询别名:Client 1.5.0 的 gremlin().execute() 发送旧版图别名(graph=<graph> 与 g=__g_<graph>),而 1.8.0 服务端仅绑定了 GraphSpace 命名空间的别名(DEFAULT-<graph> 与 __g_DEFAULT-<graph>),且服务端 /gremlin 会原样透传请求体,因此 1.5.0 客户端的 Gremlin 查询会因别名未识别而失败。如需在 1.8.0 下执行 Gremlin 查询,请升级客户端或改用 HTTP 接口显式传递正确的 aliases。
    • Auth 鉴权路径:1.8.0 将用户与鉴权体系重构至 GraphSpace 维度(graphspaces/{graphspace}/auth/users),Client 1.5.0 的 graphs/{graph}/auth/... 路径并不包含在此重定向范围内,鉴权管理操作需升级 Client。
    • Gremlin 脚本语法:客户端所发送的 Gremlin 脚本字符串均在服务端的 3.8.1 引擎中执行,必须按上述规则适配 3.8 语法。

全量细则速查表

除上述高频变化外,TinkerPop 3.5.1 → 3.8.1 还包含若干深层优化与边缘语义调整。如遇特定场景异常,请查阅下表对应项:

附录 1:写入与 Upsert(mergeV / mergeE)

在 HugeGraph 1.8.0(自 TinkerPop 3.6.0 起引入)中可使用标准的 mergeV() 与 mergeE() 执行图数据 Upsert 操作:

  • M01: onCreate 的属性 Map 严格继承主匹配 Map,不允许用冲突值覆盖主匹配条件(如匹配条件是 name: 'A',onCreate 不能设 name: 'B')。
  • M02: mergeE 不再隐式拿上游顶点填补端点,必须在 Map 中指明 (Direction.OUT) 与 (Direction.IN),或使用 option(Merge.outV, ...) 显式绑定。
  • M03: 静态 onCreate Map 与 match 检索匹配条件发生键值冲突时,在构造阶段就会被严格校验,而非等到运行时才报错。
  • M04: onMatch 子遍历在 3.8 中接收的是当前已匹配到的 Element 对象,而非最开始输入的 Map。若需引用外部输入参数,请在 merge 前通过 .as('input') 保存引用,内部通过 select('input') 取值。

附录 2:遍历内部高级步骤与集合行为

  • B07 (local() 拆 bulk):带 bulk 计数的 Traverser 经过 local() 子遍历时会被展开为单个对象处理。若需统计频次,建议使用 groupCount()。
  • B09 (range(local) 集合解包):对列表截取单元素(如 limit(local, 1)),新版始终返回 Collection 包装(如 [1]),若业务必须获取标量,请在后续追加 .unfold()。
  • B11 (sum() 返回类型):整数流的 sum() 结果可能直接返回 Integer 而不是 Long(若无溢出),建议 Java 端统一使用 Number 接收。
  • B14 (split() 步骤):HugeGraph 1.8 新增步骤。空字符串分隔符将拆分为单字符列表(如 'abc' 拆分为 ['a','b','c'])。
  • B15 (asString() 步骤):HugeGraph 1.8 新增步骤。asString() 接收到 null 时会抛出 IllegalArgumentException,如需兼容 null 请配合 choose() 显式处理。

附录 3:多语言客户端差异(GLV)

  • Python:步骤名避免与 Python 关键字冲突,全面使用下划线后缀(如 filter_()、id_()、range_()、max_() 等),推荐使用 snake_case(如 has_label)。
  • JavaScript:返回的集合从 Array 转为真正的 ECMAScript Set(通过 .size、.has() 操作);移除废弃的 connectOnStartup 选项,需使用 await connection.open()。
  • .NET:byte 类型严格按有符号整数(sbyte)序列化。
  • Go:BigDecimal/BigInt 解析对齐,必须始终检查 Next() 的 error 返回。

附录 4:底层协议与序列化边界

  • C03 (OLTP 元素属性携带):远程查询返回的 Vertex/Edge 默认携带属性,不再仅是轻量引用的 id/label。若只关注特定业务字段,建议显式通过 project() 或 valueMap() 投影,避免网络负载膨胀。
  • C06 (GraphSON 载荷安全限制):新增数字长度(默认 10,000)、字符串长度(默认 20,000,000)与嵌套深度(默认 1,000)反序列化上限,避免深层 JSON 导致 OOM。

附录 5:HugeGraph 适配与能力边界

  • 元属性保持不支持(Unchanged):HugeGraph 严格遵循自有 Schema 体系,历来不支持 TinkerPop 的属性元数据(属性上的属性)。 向顶点属性写入 metadata 始终会抛出 VertexProperty.Exceptions.metaPropertiesNotSupported() 或 NotSupportException("nested property"),1.8.0 行为与历史版本完全一致。
  • 图计算限制:supportsComputer() 仍为 false,依赖 GraphComputer 的步骤(如 pageRank()、peerPressure())不能在 OLTP 引擎上直接执行,建议使用 HugeGraph 的专门算法 API 或 Vermeer 组件。
  • 统一列表特性:supportsUniformListValues() 现返回 false;图中的 List 属性依然由 HugeGraph 内部 Schema (valueList()) 提供完整支持。

7 - 图查询语言

HugeGraph 支持两种主流图查询语言:Gremlin(命令式遍历语言)与 Cypher(声明式模式匹配语言)。

  • Gremlin:Apache TinkerPop 的核心图遍历语言,语法灵活、表达力强,适合复杂拓扑路径探索与精细遍历控制。
  • Cypher:openCypher 标准化的声明式语言,类似 SQL 的直观模式匹配(MATCH ... WHERE ... RETURN),易读性强且便于 Neo4j 迁移。

语言指南与参考

  • HugeGraph-Gremlin

    Gremlin 遍历基础、CRUD 语法示例以及 TinkerPop 规范支持情况。

  • Cypher 查询语言

    Cypher 声明式语法支持、读取与写入示例、执行机制与使用限制。

  • Cypher 兼容性说明

    Cypher 子句与函数的覆盖矩阵、已知差异及未实现特性的规避方案。

  • 从 Neo4j 迁移到 HugeGraph

    Neo4j 与 HugeGraph 在图模型、ID 策略、多标签及查询语法上的核心差异对照与迁移步骤。

  • 经典示例数据

    经典的 TitanDB“众神图”(Graph of the Gods,包含 12 个顶点)示例数据集,供编写查询时对照参考。

周边工具与相关入口

在不同场景下执行图查询的快捷入口:

7.1 - HugeGraph Gremlin

概述

HugeGraph 原生支持 Apache TinkerPop3 的图遍历查询语言 Gremlin。 与关系型数据库使用的声明式 SQL 不同,Gremlin 是一种通用的图遍历与计算语言,能够精准控制图的拓扑路径探索,执行实体创建(Vertex 与 Edge)、属性修改、批量删除以及复杂的图分析。

HugeGraph 基于 TinkerPop 3.8.1 引擎构建。完整规范与语法参考请查阅 Apache TinkerPop 3.8.1 官方参考文档。 若习惯声明式模式匹配(类似 SQL 或 Neo4j 风格),HugeGraph 同时提供 Cypher 查询语言 支持。


TinkerPop 特性支持

HugeGraph 实现了 TinkerPop 规范核心接口,针对图存储、顶点、边以及属性数据类型的具体支持情况如下:

图级特性(Graph Features)

特性名称含义与说明支持情况
Computer是否支持基于 GraphComputer 的 OLAP 图计算引擎(HugeGraph 服务端专注实时 OLTP 遍历,大规模图计算由独立组件支持)false
Transactions是否支持事务机制(原生支持 ACID 事务提交与回滚)true
Persistence是否原生将数据持久化到磁盘介质(取决于所配置的底层存储后端,RocksDB/Cassandra/HBase 等均持久化存储)取决于后端
ThreadedTransactions是否支持通过 createThreadedTx() 在多个线程间共享同一个执行事务false
ConcurrentAccess是否支持同一底层数据实例的多连接并发访问false

顶点特性(Vertex Features)

特性名称含义与说明支持情况
UserSuppliedIds是否允许在创建顶点时由用户指定自定义标识符(HugeGraph 支持用户自定义、主键和自动生成等策略)true
NumericIds顶点内部标识符是否限定为纯数值类型false
StringIds顶点内部标识符是否支持字符串类型true
UuidIds顶点内部标识符是否原生限定为 UUID 格式false
CustomIds顶点内部标识符是否支持复合自定义对象true
AnyIds顶点内部标识符是否允许任意 Java 对象类型false
AddProperty是否支持向顶点添加或动态更新属性true
RemoveProperty是否支持从顶点移除已有属性true
AddVertices是否支持向图中添加新顶点true
MultiProperties单个顶点同一属性名下是否支持存储多个值(多值属性)true
DuplicateMultiProperties在启用多值属性时,是否允许存在相同的重复值true
MetaProperties是否支持在属性上附加元属性(属性的属性)false
RemoveVertices是否支持从图中删除指定顶点true

边特性(Edge Features)

特性名称含义与说明支持情况
UserSuppliedIds是否允许直接指定边标识符(HugeGraph 边 ID 自动由起点、标签、排序键与终点复合生成)false
NumericIds边内部标识符是否限定为纯数值类型false
StringIds边内部标识符是否支持字符串类型true
UuidIds边内部标识符是否限定为 UUID 格式false
CustomIds边内部标识符是否支持复合自定义对象true
AnyIds边内部标识符是否允许任意 Java 对象类型false
AddProperty是否支持向边添加或动态更新属性true
RemoveProperty是否支持从边移除已有属性true
AddEdges是否支持在顶点之间建立边true
RemoveEdges是否支持从图中删除指定边true

数据类型支持(Data Type Features)

特性名称含义与说明支持情况
BooleanValues布尔类型属性(boolean)true
ByteValues单字节整数(byte)true
DoubleValues双精度浮点数(double)true
FloatValues单精度浮点数(float)true
IntegerValues32 位整型(int)true
LongValues64 位长整型(long)true
MapValues是否支持直接存储嵌套 Map 键值对对象false
MixedListValues是否支持存储不同类型混合元素的列表false
BooleanArrayValues布尔数组类型(boolean[])false
ByteArrayValues二进制字节数组(byte[],常用于 Blob 或向量嵌入存储)true
DoubleArrayValues双精度浮点数组(double[])false
FloatArrayValues单精度浮点数组(float[])false
IntegerArrayValues整型数组(int[])false
LongArrayValues长整型数组(long[])false
SerializableValues是否支持直接存储任意 Java 序列化对象false
StringArrayValues字符串数组(String[])false
StringValues标准文本字符串类型(text/string)true
UniformListValues存储同类型元素的集合列表(由 Schema 中的 cardinality() 与 valueList() 机制原生支持)false(由 Schema 支持)

Gremlin 常用步骤参考

HugeGraph 支持 Gremlin 遍历规范定义的各项步骤。完整说明与高级遍历用法请参阅 TinkerPop 3.8.1 步骤参考。

步骤说明官方文档
addE在两个顶点之间添加有向边addE step
addV向图中添加新顶点addV step
and确保所有子遍历都产生有效输出and step
as为步骤输出分配变量标签的调制器as step
by与 group、order 等步骤配合使用的维度调制器by step
coalesce返回首个产生结果的子遍历coalesce step
constant生成指定常量值,常与 coalesce 配合使用constant step
count统计遍历流中元素的总数量count step
datetime构造日期时间对象或取得服务器当前时间(返回 OffsetDateTime)datetime function
dedup去除遍历流中的重复元素dedup step
discard丢弃当前流中的遍历器输出discard step
drop从图中彻底删除对应实体(顶点、边或属性)drop step
fold栅栏步骤,将流中所有项汇总折叠为一个 Listfold step
group根据指定的键与投影调制器对数据进行分组聚合group step
has属性与元素过滤,支持 hasLabel、hasId、hasNot 等变体has step
inject将外部离散值直接注入当前遍历流中inject step
is针对标量值执行布尔条件匹配与过滤is step
limit限制遍历流返回的最大项数limit step
local局部作用域执行子遍历,类似于局部子查询local step
not对子遍历匹配结果取反(必须不满足条件)not step
optional尝试执行子遍历;若有输出则返回,否则保留输入元素optional step
or确保至少有一个子遍历返回有效结果or step
order按指定字段或比较规则对元素进行排序order step
path收集并返回当前遍历所经过的历史完整路径path step
project将多个调制结果投影为结构化 Map 映射project step
properties获取指定键的 Property 实体对象properties step
range基于下标范围进行切片截取(起始索引至结束索引)range step
repeat循环执行指定的子遍历步骤repeat step
sample从当前流中进行随机抽样sample step
select从历史路径或映射投影中提取特定标签的变量值select step
mergeV按属性匹配顶点,存在则更新,不存在则创建(标准 Upsert 步骤)mergeV step
mergeE按属性与端点匹配边,存在则更新,不存在则创建(标准 Upsert 步骤)mergeE step
tree将遍历路径汇总聚合成树形层级结构tree step
unfold将集合或数组结构展开为连续的流元素unfold step
union并行执行多个子遍历并合并其输出结果union step
V顶点检索与端点跳转基础步骤:V、E、out、in、both、outE、inE 等vertex steps
where使用表达式或谓词(eq、neq、gt 等)进行条件筛选过滤where step

7.2 - HugeGraph Cypher

概述

HugeGraph 支持 Cypher —— 最初由 Neo4j 创建、并由 openCypher 标准化的声明式图查询语言。Gremlin 是命令式的遍历语言,而 Cypher 只需描述想要的图模式(MATCH、WHERE、RETURN),由引擎决定如何执行。

HugeGraph 实现了对 openCypher 9 语法子集的支持,查询语句在服务端解析并无缝对接底层 TinkerPop 图遍历引擎。因此开发者可以使用直观的模式匹配语法,快速完成图数据的检索与写入。完整支持矩阵与限制参见 Cypher 兼容性。

何时用 Cypher、何时用 Gremlin

适合用 Cypher适合用 Gremlin
正在从 Neo4j 迁移,或已熟悉 Cypher需要 HugeGraph 的完整功能面
需要声明式模式匹配(MATCH (a)-[:KNOWS]->(b))需要精细的遍历控制、自定义步骤或 lambda
查询以读模式和投影为主需要图算法、OLAP 或 Cypher 未暴露的功能

凡是 Cypher 表达不了的,等价的 Gremlin 查询 总是可用 —— 下文示例同时给出两种写法。

调用 Cypher API

Cypher 语句通过 HugeGraph Server 的 REST 端点提交:

1GET  /graphspaces/{graphspace}/graphs/{graph}/cypher?cypher={statement}
2POST /graphspaces/{graphspace}/graphs/{graph}/cypher

当服务端开启鉴权时,Cypher 请求需要携带 Authorization 请求头,支持 Authorization: Basic ...(标准 RFC 4648 Base64 编码,如 curl -u)或 Authorization: Bearer <token>(未携带认证信息的请求返回 401)。服务端未开启鉴权时无需携带此头。 完整请求/响应格式见 Cypher REST API 参考。

示例:

1curl -H "Authorization: Bearer $TOKEN" \
2  "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/cypher?cypher=MATCH%20(n:person)%20RETURN%20n.name%20LIMIT%2010"

Java 客户端使用 CypherManager(见 hugegraph-client):

1ResultSet resultSet = hugeClient.cypher().execute("MATCH (n:person) RETURN n.name LIMIT 10");

基础示例

以下示例基于包含 person(属性 name、age、city)和 knows 边的图模型。 执行前请注意:

  • 属性过滤谓词(如 WHERE n.age > 30)通常需要对应的索引覆盖(如在 person.age 上建立 RANGE 索引)。
  • 若顶点标签采用 PRIMARY_KEY 策略或定义了非空属性,创建数据时需为必填属性和主键赋值;建议先分别创建顶点再建立关联边。

查询 — MATCH / WHERE / RETURN

1// 所有名为 "marko" 的 person
2MATCH (n:person) WHERE n.name = 'marko' RETURN n
1// 投影 + 排序 + 限制条数
2MATCH (n:person)
3WHERE n.age > 30
4RETURN n.name AS name, n.age AS age
5ORDER BY age DESC
6LIMIT 10
1// 关系模式
2MATCH (a:person)-[:knows]->(b:person)
3WHERE a.name = 'marko'
4RETURN b.name AS friend

创建 — CREATE

1// 创建顶点
2CREATE (n:person {name: 'alice', age: 32, city: 'beijing'})
1// 先创建两个顶点,再创建它们之间的边(每条语句单独作为一次请求发送)
2CREATE (:person {name: 'bob'})
3CREATE (:person {name: 'carol'})
4MATCH (a:person), (b:person)
5WHERE a.name = 'bob' AND b.name = 'carol'
6CREATE (a)-[:knows]->(b)

更新 — SET / REMOVE

1MATCH (n:person) WHERE n.name = 'alice'
2SET n.age = 33
3REMOVE n.city

删除 — DELETE / DETACH DELETE

1// 删除边
2MATCH (a:person)-[r:knows]->(b:person)
3WHERE a.name = 'bob' AND b.name = 'carol'
4DELETE r
1// 删除顶点及其所有边
2MATCH (n:person) WHERE n.name = 'alice'
3DETACH DELETE n

聚合

1// 总数
2MATCH (n:person) RETURN count(n) AS total
1// 按城市分组计数
2MATCH (n:person) RETURN n.city AS city, count(*) AS cnt ORDER BY cnt DESC

等价的 Gremlin 写法

每条 Cypher 语句在内部都会被翻译为 Gremlin。当某个 Cypher 特性不受支持时,可直接编写遍历:

Cypher等价 Gremlin
MATCH (n:person) WHERE n.name='marko' RETURN ng.V().hasLabel('person').has('name','marko')
MATCH (a)-[:knows]->(b) RETURN bg.V().out('knows')
CREATE (n:person {name:'x'})g.addV('person').property('name','x')
MATCH (n) DETACH DELETE ng.V().drop()
MATCH (n:person) RETURN count(n)g.V().hasLabel('person').count()

提示:可使用 EXPLAIN MATCH (n:person) RETURN n 查看对应的底层 Gremlin 遍历语句(位于返回结果的 translation 字段中),方便对照编写等价写法。PROFILE 暂不受支持。

使用限制

  • 参数化查询规则:支持通过 JSON 请求体传递参数({"cypher": "...", "parameters": {...}},最多支持 16 个顶层参数; 更多属性可放入 Map 对象并显式引用)。引用了未声明的 $param 时会直接抛出执行错误;显式传入 null 是允许的。
  • 高级语法覆盖边界:部分高级 openCypher 语法(如 map projection、部分复杂函数)当前暂不支持,未支持的结构会在解析校验阶段报错。
  • 过程调用:HugeGraph 的图分析算法(最短路径、k-out、PersonalRank 等)通过独立的 Traverser REST API 或 Gremlin 提供,未暴露为 Cypher CALL 过程。
  • 单请求单语句:每次请求仅支持执行一条 Cypher 语句,不支持多语句复合脚本。

执行或校验失败时,服务端会在响应的 status.attributes.errors 中返回包含 code、message 与 hint 的结构化错误详情。遇到功能缺口时,等价的 Gremlin 写法是官方推荐的替代方案。

延伸阅读

7.3 - Cypher 兼容性

概述与支持范围

HugeGraph 支持 openCypher 9 声明式图查询规范,支持在 TinkerPop 引擎之上直接执行模式匹配与图数据读写。 本页汇总 Cypher 请求形式、参数绑定规则、支持的语法子集与行为边界。

接口端点为 /graphspaces/{graphspace}/graphs/{graph}/cypher。常规语法示例与 Gremlin 对照参见 HugeGraph Cypher 指南。

请求形式与参数绑定

请求形式Content-Type说明
POST(推荐)application/json请求体为 JSON 对象 {"cypher": "...", "parameters": {...}},支持参数绑定
POSTapplication/json请求体为原始 Cypher 文本字符串(用于无参数的纯文本语句)
GET—查询参数 ?cypher=<URL 编码语句>,适合简单只读查询

JSON 对象参数化请求示例:

1{
2  "cypher": "MATCH (n:person) WHERE n.name = $name RETURN n.name",
3  "parameters": {"name": "marko"}
4}

参数绑定规则

  • 参数格式:cypher 字段必须为非空字符串;parameters 若提供必须为 JSON 对象(省略表示空参数表)。
  • 参数数量:顶层 parameters 最多接受 16 个键。若需要传入更多属性,可将相关字段组织为嵌套 Map 对象,并在 Cypher 语句中显式引用字段(例如 $props.name)。
  • 未绑定变量处理:语句中引用未提供的 $param 时会直接抛出执行错误,拒绝执行(显式传入 null 是允许的)。
  • 保留标记:引擎将 " cypher.null"(前导双空格)用作内部保留哨兵标记,绑定值中禁止传入该精确字符串。
  • 错误响应:格式错误的请求体直接返回 HTTP 400 及标准错误结构;语法翻译与查询执行错误则返回 HTTP 200(响应体中包含 status.code: 400 与空 result),并在 status.attributes.errors 中提供包含 code、message 与 hint 的结构化错误详情。

语法与功能支持矩阵

分类支持特性说明
查询与模式标签扫描、等值与范围过滤、逻辑组合(AND/OR/NOT)、单跳与多跳有向关系、正则匹配(=~ 全匹配)范围过滤等条件需预先建立相应索引
结果投影节点与标量投影、别名(AS)、属性访问、嵌套结构、关系 ID、路径表达、空值(null)处理返回结果映射为标准 JSON 格式
聚合与排序count、sum、min、max、avg、DISTINCT、ORDER BY、SKIP、LIMIT分页与聚合计算由引擎自动转换为对应图遍历步骤
数据写入顶点与边 CREATE、属性 SET / REMOVE、边与顶点 DELETE / DETACH DELETE创建边前建议先为端点顶点赋值并创建,避免简写形式因非空约束或主键缺失失败

写入约束与注意事项

在包含非空属性或使用 PRIMARY_KEY 策略的 Schema 下,双顶点简写 CREATE (a)-[:knows]->(b) 会因未提供属性而触发非空属性校验失败(checkNonnullProperty)或主键缺失错误。 建议将顶点与边的创建语句分开执行,并显式为顶点填充所需属性。

暂未支持的范围

以下高级语法和特性在当前版本中尚未直接提供,建议改用 Gremlin 或相应 REST API:

  • 复杂子句:MERGE、UNION、变长路径匹配(*1..3);
  • 过程调用:CALL dbms.* / CALL algo.*(请使用 Traverser REST API);
  • 模式定义:Cypher Schema DDL(请使用 Schema REST API);
  • 协议与驱动:Bolt 协议与驱动(请使用 HTTP REST API 或 HugeGraph 客户端)。

7.4 - 从 Neo4j 迁移

概述

面向从 Neo4j 迁移或评估 HugeGraph 的开发者。HugeGraph 原生支持 openCypher 声明式查询语法, 但在图模型、Schema 规范、参数绑定和索引机制上与 Neo4j 存在差异。 具体语法与兼容性请参考 HugeGraph Cypher 与 Cypher 兼容性说明。

可以直接带过来的部分

Neo4j 概念HugeGraph 对应
属性图模型(节点/关系/属性)相同 —— 顶点标签 / 边标签 / 属性
基础 Cypher:MATCH/WHERE/RETURN/CREATE/SET/DELETE直接可用(REST /cypher 端点或 Java 客户端 CypherManager),但须遵守下文的 Schema 与索引规则
简单聚合(count/sum/min/max/avg)直接可用
依赖图遍历的查询需求Gremlin 遍历或 traverser REST API(k-out、最短路、personalrank 等)

需要改变习惯的部分

在 Neo4j 里在 HugeGraph 里
CREATE INDEX / CREATE CONSTRAINT通过 IndexLabel REST API 创建属性索引;唯一性约束对应 UNIQUE 索引;节点键对应非可空属性加复合 UNIQUE 索引;属性存在约束对应 VertexLabel / EdgeLabel 上的非可空属性。注意 primary_keys 决定顶点标识,不是约束机制,重复 CREATE 直接覆盖旧记录
隐式 schema(属性随意添加)强 schema:先定义 VertexLabel/EdgeLabel/PropertyKey,再写数据
WHERE 中的属性谓词无需索引起始顶点查找需要索引覆盖(除非对该标签全部主键做等值匹配):> / < 等范围比较需要 RANGE 类型的 IndexLabel。缺少覆盖索引时返回 HTTP 200(响应体 status.code 400 “未建索引"错误)
参数化查询 $param支持 JSON 格式参数化请求(最多支持 16 个顶层参数,更多属性可通过嵌套 Map 传递);未声明的参数会报错
CALL dbms.* / CALL algo.* 过程对应功能分散在 traverser、task 等 REST API
驱动:Neo4j Bolt driverhugegraph-client(CypherManager)或任意 HTTP 客户端
事务边界在 Cypher 语句内每次请求一个语句;图到图的数据迁移使用 Apache SeaTunnel 3.0.0(首选,见下文),基于文件的批量导入使用 HugeGraph Loader

PRIMARY_KEY 标签上 UNIQUE 索引不能包含该标签的全部主键(服务端会拒绝)。若需保留唯一性约束,请改用 CUSTOMIZE_STRING id 策略,以 Neo4j 节点 id 为键,再在业务键上建 UNIQUE 索引。

建议的迁移路径

  1. 盘点查询:对照 Cypher 兼容性说明 与 使用限制,梳理应用中的 Cypher 语句, 确认直接可用、需改写为 Gremlin 或需调用 REST API 的部分。

  2. 先建 schema:用 schema API 建好 VertexLabel/EdgeLabel/PropertyKey 和索引 —— HugeGraph 在写入前要求 schema 存在。

  3. 导入数据:首选路径是 Apache SeaTunnel 的 Neo4j Connector(Source)与 HugeGraph Connector(Sink),直接运行 Neo4j Source → HugeGraph Sink —— 无需中间文件导出。 小数据集用 REST 也没问题;基于文件的大批量导入仍可使用 HugeGraph Loader。 HugeGraph 侧的环境准备、mappings 配置与顶点/边导入示例见 通过 SeaTunnel Sink 导入图数据。

    SeaTunnel 连接器文档 说明了可依赖的能力:

    • Neo4j Source 以显式字段 schema 读取 Cypher 查询结果,支持通过 tables_configs 的多表读取。
    • HugeGraph Sink 支持多映射 —— 顶点/边请使用推荐的 mappings 配置,并遵循其 schema 创建行为。该 Sink 默认 遇到错误快速失败(batch_failure_fallback=false 与 max_insert_errors=0)。跳过失败记录为 可选配置(batch_failure_fallback=true);若开启,请在正式切换前捕获并核对跳过行,并比对数据总条数。
    • HugeGraph Source 支持 schema 自动发现与多标签并行读取,使 HugeGraph 的导出与迁移工作流成为可能。

    将 Neo4j 属性映射为 HugeGraph PropertyKey,并在导入前先定好顶点 ID 策略。Sink 对除 AUTOMATIC 之外的每种顶点策略都要求 idFields,边映射还需要分别设置 sourceConfig.idFields 与 targetConfig.idFields,因此 Neo4j 查询必须返回承载 ID 的字段:

    • idStrategy = "PRIMARY_KEY":在 idFields 中放入 Neo4j 业务键,边的端点也通过这些键字段表达。
    • idStrategy = "CUSTOMIZE_STRING":仅选择它并不能保留 Neo4j 节点 id。请让 Neo4j 查询把要保留的 id 作为单独一列返回(用 AS node_id 等别名),在 Source 的 schema.fields 中声明该字段(必须与查询返回的字段一致), 把顶点的 idFields 设为该字段,并在 sourceConfig.idFields 与 targetConfig.idFields 中映射对应的边端点字段。

    第 2 步预创建的标签必须使用同一策略——自动创建不会把已有的 PRIMARY_KEY 标签改为 CUSTOMIZE_STRING。 Sink 的 mappings 配置可以创建缺失的 PropertyKey、VertexLabel 和 EdgeLabel 定义,因此使用它时第 2 步中的这三类 定义可省略;但它不会创建 IndexLabel,查询所依赖的索引仍须单独创建(见上文“需要改变习惯的部分”表)。 若未显式指定 frequency,自动创建 EdgeLabel 时默认采用 SINGLE,相同类型且端点相同的多条平行关系(Parallel Relationships)会被覆盖合并为一条边。 若需保留 Neo4j 中的平行边,必须在边映射中显式指定 frequency = "MULTIPLE",并配置稳定的业务区分字段作为 sortKeys(HugeGraph 依赖 sortKeys 生成重边的唯一边 ID)。 先导入顶点、后导入边。建议在正式切换前,先在测试环境中使用业务数据样本完整验证导入流程。

  4. 灰度切换:Cypher 能表达的查询保持不动,暂不支持的改写为 Gremlin(等价写法见 对照表)。

使用限制速查

  • 语句与参数:不支持多语句脚本与 CALL 过程;参数绑定最多支持 16 个顶层参数(更多属性可通过嵌套 Map 传递)。
  • 未覆盖语法:兼容性矩阵中未涉及的高级 openCypher 结构属于未验证范围,可能在解析校验期报错;明确不支持的限制见前文说明。
  • 回退方案:不受支持的查询结构通常可以改写为等价的 Gremlin 遍历 —— 详见 HugeGraph Cypher 对照表; Schema DDL 与存储过程请改用对应 REST API。

7.5 - HugeGraph Examples

1 概述

本示例将TitanDB Getting Started 为模板来演示 HugeGraph 的使用方法。通过对比 HugeGraph 和 TitanDB,了解 HugeGraph 和 TitanDB 的差异。

1.1 HugeGraph 与 TitanDB 的异同

HugeGraph 和 TitanDB 都是基于Apache TinkerPop3框架的图数据库,均支持Gremlin图查询语言,在使用方法和接口方面具有很多相似的地方。然而 HugeGraph 是全新设计开发的,其代码结构清晰,功能较为丰富,接口更为友好等特点。

HugeGraph 相对于 TitanDB 而言,其主要特点如下:

  • HugeGraph 目前有 HugeGraph-API、HugeGraph-Client、HugeGraph-Loader、HugeGraph-Studio、HugeGraph-Spark 等完善的工具组件,可以完成系统集成、数据载入、图可视化查询、Spark 连接等功能;
  • HugeGraph 具有 Server 和 Client 的概念,第三方系统可以通过 jar 引用、client、api 等多种方式接入,而 TitanDB 仅支持 jar 引用方式接入。
  • HugeGraph 的 Schema 需要显式定义,所有的插入和查询均需要通过严格的 schema 校验,目前暂不支持 schema 的隐式创建。
  • HugeGraph 充分利用后端存储系统的特点来实现数据高效存取,而 TitanDB 以统一的 Kv 结构无视后端的差异性。
  • HugeGraph 的更新操作可以实现按需操作(例如:更新某个属性)性能更好。TitanDB 的更新是 read and update 方式。
  • HugeGraph 的 VertexId 和 EdgeId 均支持拼接,可实现自动去重,同时查询性能更好。TitanDB 的所有 Id 均是自动生成,查询需要经索引。

1.2 人物关系图谱

本示例通过 Property Graph Model 图数据模型来描述希腊神话中各人物角色的关系(也被成为人物关系图谱),具体关系详见下图。

image

其中,圆形节点代表实体 (Vertex),箭头代表关系(Edge),方框的内容为属性。

该关系图谱中有两类顶点,分别是人物(character)和位置(location)如下表:

名称类型属性
charactervertexname,age,type
locationvertexname

有六种关系,分别是父子(father)、母子(mother)、兄弟(brother)、战斗(battled)、居住 (lives)、拥有宠物(pet)关于关系图谱的具体信息如下:

名称类型source vertex labeltarget vertex label属性
fatheredgecharactercharacter-
motheredgecharactercharacter-
brotheredgecharactercharacter-
battlededgecharactercharactertime
petedgecharactercharacter-
livesedgecharacterlocationreason

一个 edge label 可以连接多对 source vertex label 和 target vertex label:创建时对每一对顶点标签各调用一次 link(sourceLabel, targetLabel) 即可。已废弃的 sourceLabel() 和 targetLabel() 构建方法只支持单一配对。

本例子将原TitanDB中的monster, god, human, demigod均使用相同的vertex label: character来表示, 同时增加属性type来标识人物的类型。edge label与原TitanDB保持一致。

2 Graph Schema and Data Ingest Examples

HugeGraph 需要显示创建 Schema,因此需要依次创建 PropertyKey、VertexLabel、EdgeLabel,如果有需要索引还需要创建 IndexLabel。

以下代码片段假定 Groovy 脚本已打开 HugeGraph 实例并将其绑定为 graph,同时设置遍历源 g = graph.traversal()。可从 Gremlin Console 本地模式示例开始;该页面的 scripts/example.groovy 会创建这两个变量。远程 Console 中的 g 是 Server 端遍历源别名,客户端本地没有 graph 对象;远程建模请使用本页之外的 Schema REST API。

2.1 Graph Schema

 1import org.apache.tinkerpop.gremlin.structure.T
 2import org.apache.tinkerpop.gremlin.structure.Vertex
 3
 4schema = graph.schema()
 5g = graph.traversal()
 6
 7schema.propertyKey("name").asText().ifNotExist().create()
 8schema.propertyKey("age").asInt().ifNotExist().create()
 9schema.propertyKey("time").asInt().ifNotExist().create()
10schema.propertyKey("reason").asText().ifNotExist().create()
11schema.propertyKey("type").asText().ifNotExist().create()
12
13schema.vertexLabel("character").properties("name", "age", "type").primaryKeys("name").nullableKeys("age").ifNotExist().create()
14schema.vertexLabel("location").properties("name").primaryKeys("name").ifNotExist().create()
15
16schema.edgeLabel("father").link("character", "character").ifNotExist().create()
17schema.edgeLabel("mother").link("character", "character").ifNotExist().create()
18schema.edgeLabel("battled").link("character", "character").properties("time").ifNotExist().create()
19schema.edgeLabel("lives").link("character", "location").properties("reason").nullableKeys("reason").ifNotExist().create()
20schema.edgeLabel("pet").link("character", "character").ifNotExist().create()
21schema.edgeLabel("brother").link("character", "character").ifNotExist().create()

2.2 Graph Data

 1// add vertices
 2Vertex saturn = graph.addVertex(T.label, "character", "name", "saturn", "age", 10000, "type", "titan")
 3Vertex sky = graph.addVertex(T.label, "location", "name", "sky")
 4Vertex sea = graph.addVertex(T.label, "location", "name", "sea")
 5Vertex jupiter = graph.addVertex(T.label, "character", "name", "jupiter", "age", 5000, "type", "god")
 6Vertex neptune = graph.addVertex(T.label, "character", "name", "neptune", "age", 4500, "type", "god")
 7Vertex hercules = graph.addVertex(T.label, "character", "name", "hercules", "age", 30, "type", "demigod")
 8Vertex alcmene = graph.addVertex(T.label, "character", "name", "alcmene", "age", 45, "type", "human")
 9Vertex pluto = graph.addVertex(T.label, "character", "name", "pluto", "age", 4000, "type", "god")
10Vertex nemean = graph.addVertex(T.label, "character", "name", "nemean", "type", "monster")
11Vertex hydra = graph.addVertex(T.label, "character", "name", "hydra", "type", "monster")
12Vertex cerberus = graph.addVertex(T.label, "character", "name", "cerberus", "type", "monster")
13Vertex tartarus = graph.addVertex(T.label, "location", "name", "tartarus")
14
15// add edges
16jupiter.addEdge("father", saturn)
17jupiter.addEdge("lives", sky, "reason", "loves fresh breezes")
18jupiter.addEdge("brother", neptune)
19jupiter.addEdge("brother", pluto)
20neptune.addEdge("lives", sea, "reason", "loves waves")
21neptune.addEdge("brother", jupiter)
22neptune.addEdge("brother", pluto)
23hercules.addEdge("father", jupiter)
24hercules.addEdge("mother", alcmene)
25hercules.addEdge("battled", nemean, "time", 1)
26hercules.addEdge("battled", hydra, "time", 2)
27hercules.addEdge("battled", cerberus, "time", 12)
28pluto.addEdge("brother", jupiter)
29pluto.addEdge("brother", neptune)
30pluto.addEdge("lives", tartarus, "reason", "no fear of death")
31pluto.addEdge("pet", cerberus)
32cerberus.addEdge("lives", tartarus)
33
34graph.tx().commit()

2.3 Indices

HugeGraph 默认是自动生成 Id,如果用户通过primaryKeys指定VertexLabel的primaryKeys字段列表后,VertexLabel的 Id 策略将会自动切换到primaryKeys策略。启用primaryKeys策略后,HugeGraph 通过vertexLabel+primaryKeys拼接生成VertexId ,可实现自动去重,同时无需额外创建索引即可以使用primaryKeys中的属性进行快速查询。例如 “character” 和 “location” 都有primaryKeys("name")属性,因此在不额外创建索引的情况下可以通过g.V().hasLabel('character') .has('name','hercules')查询 vertex。

3 Graph Traversal Examples

3.1 Traversal Query

1. Find the grandfather of hercules

1g.V().hasLabel('character').has('name','hercules').out('father').out('father')

也可以通过repeat方式:

1g.V().hasLabel('character').has('name','hercules').repeat(__.out('father')).times(2)

2. Find the name of Hercules’s father

1g.V().hasLabel('character').has('name','hercules').out('father').value('name')

3. Find the characters with age > 100

1g.V().hasLabel('character').has('age',gt(100))

4. Find who are pluto’s cohabitants

1g.V().hasLabel('character').has('name','pluto').out('lives').in('lives').values('name')

5. Find pluto can’t be his own cohabitant

1pluto = g.V().hasLabel('character').has('name', 'pluto')
2g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name')
3
4// use 'as'
5g.V().hasLabel('character').has('name', 'pluto').as('x').out('lives').in('lives').where(neq('x')).values('name')

6. Pluto’s Brothers

1pluto = g.V().hasLabel('character').has('name', 'pluto').next()
2// where do pluto's brothers live?
3g.V(pluto).out('brother').out('lives').values('name')
4
5// which brother lives in which place?
6g.V(pluto).out('brother').as('god').out('lives').as('place').select('god','place')
7
8// what is the name of the brother and the name of the place?
9g.V(pluto).out('brother').as('god').out('lives').as('place').select('god','place').by('name')

推荐使用HugeGraph-Hubble 通过可视化的方式来执行上述代码。另外也可以通过 HugeGraph-Client、HugeApi、GremlinConsole 和 GremlinDriver 等多种方式执行上述代码。

3.2 总结

HugeGraph 目前支持 Gremlin 的语法,用户可以通过 Gremlin / REST-API 实现各种查询需求。

8 - PERFORMANCE

⚠️ 性能测试章节正在重构

当前章节中的 benchmark、API 性能和 Loader 性能报告均基于历史版本、测试方法或测试环境,旧结果不代表当前版本的实际性能,也不适合直接用于版本比较或容量规划。后续将统一更新测试方法、软硬件环境和报告,并对旧报告进行归档。

当前可查阅的 benchmark 页面:

8.1 - HugeGraph BenchMark Performance

Note:

当前的性能指标测试基于很早期的版本。最新版本在性能和功能上都有显著的改进。我们鼓励您参考最新的发布版本, 该版本具有自主分布式存储和增强的计算推下能力。或者,您可以等待社区更新相关测试数据 (也欢迎反馈共建)。

同目录下的 HugeGraph 0.4.4 历史性能测试 数据来自 2018 年,仅用于历史参考。

1 测试环境

1.1 硬件信息

CPUMemory网卡磁盘
48 Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz128G10000Mbps750GB SSD

1.2 软件信息

1.2.1 测试用例

测试使用graphdb-benchmark,一个图数据库测试集。该测试集主要包含 4 类测试:

  • Massive Insertion,批量插入顶点和边,一定数量的顶点或边一次性提交

  • Single Insertion,单条插入,每个顶点或者每条边立即提交

  • Query,主要是图数据库的基本查询操作:

    • Find Neighbors,查询所有顶点的邻居
    • Find Adjacent Nodes,查询所有边的邻接顶点
    • Find Shortest Path,查询第一个顶点到 100 个随机顶点的最短路径
  • Clustering,基于 Louvain Method 的社区发现算法

1.2.2 测试数据集

测试使用人造数据和真实数据

本测试用到的数据集规模
名称vertex 数目edge 数目文件大小
email-enron.txt36,691367,6614MB
com-youtube.ungraph.txt1,157,8062,987,62438.7MB
amazon0601.txt403,3933,387,38847.9MB
com-lj.ungraph.txt399796134681189479MB

1.3 服务配置

  • HugeGraph 版本:0.5.6,RestServer 和 Gremlin Server 和 backends 都在同一台服务器上

    • RocksDB 版本:rocksdbjni-5.8.6
  • Titan 版本:0.5.4, 使用 thrift+Cassandra 模式

    • Cassandra 版本:cassandra-3.10,commit-log 和 data 共用 SSD
  • Neo4j 版本:2.0.1

graphdb-benchmark 适配的 Titan 版本为 0.5.4

2 测试结果

2.1 Batch 插入性能

说明

以下图表和原表均为 HugeGraph 0.5.6 历史测试数据,不代表当前版本性能。硬件、软件版本和后端条件见上方测试环境。

图表使用对数坐标比较批量插入耗时(秒);点击图例可切换系列,原表保留供准确取值。

{
  "tooltip": {
    "trigger": "axis",
    "confine": true
  },
  "legend": {
    "data": [
      "HugeGraph",
      "Titan",
      "Neo4j"
    ]
  },
  "grid": {
    "left": 75,
    "right": 30,
    "top": 55,
    "bottom": 75
  },
  "xAxis": {
    "type": "category",
    "data": [
      "email-enron (30w)",
      "amazon0601 (300w)",
      "YouTube (300w)",
      "LiveJournal (3000w)"
    ],
    "axisLabel": {
      "rotate": 10
    }
  },
  "yAxis": {
    "type": "log",
    "name": "耗时 / 秒(对数)"
  },
  "series": [
    {
      "name": "HugeGraph",
      "type": "bar",
      "data": [
        0.629,
        5.711,
        5.243,
        67.033
      ]
    },
    {
      "name": "Titan",
      "type": "bar",
      "data": [
        10.15,
        108.569,
        150.266,
        1217.944
      ]
    },
    {
      "name": "Neo4j",
      "type": "bar",
      "data": [
        3.884,
        18.938,
        24.89,
        281.537
      ]
    }
  ]
}
Backendemail-enron(30w)amazon0601(300w)com-youtube.ungraph(300w)com-lj.ungraph(3000w)
HugeGraph0.6295.7115.24367.033
Titan10.15108.569150.2661217.944
Neo4j3.88418.93824.890281.537

说明

  • 表头"()“中数据是数据规模,以边为单位
  • 表中数据是批量插入的时间,单位是 s
  • 例如,HugeGraph 使用 RocksDB 插入 amazon0601 数据集的 300w 条边,花费 5.711s
结论
  • 批量插入性能 HugeGraph(RocksDB) > Neo4j > Titan(thrift+Cassandra)

2.2 遍历性能

2.2.1 术语说明
  • FN(Find Neighbor), 遍历所有 vertex, 根据 vertex 查邻接 edge, 通过 edge 和 vertex 查 other vertex
  • FA(Find Adjacent), 遍历所有 edge,根据 edge 获得 source vertex 和 target vertex
2.2.2 FN 性能
Backendemail-enron(3.6w)amazon0601(40w)com-youtube.ungraph(120w)com-lj.ungraph(400w)
HugeGraph4.07245.11866.006609.083
Titan8.08492.507184.5431099.371
Neo4j2.42410.53711.609106.919

说明

  • 表头”()“中数据是数据规模,以顶点为单位
  • 表中数据是遍历顶点花费的时间,单位是 s
  • 例如,HugeGraph 使用 RocksDB 后端遍历 amazon0601 的所有顶点,并查找邻接边和另一顶点,总共耗时 45.118s
2.2.3 FA 性能
Backendemail-enron(30w)amazon0601(300w)com-youtube.ungraph(300w)com-lj.ungraph(3000w)
HugeGraph1.54010.76411.243151.271
Titan7.36193.344169.2181085.235
Neo4j1.6734.7754.28440.507

说明

  • 表头”()“中数据是数据规模,以边为单位
  • 表中数据是遍历边花费的时间,单位是 s
  • 例如,HugeGraph 使用 RocksDB 后端遍历 amazon0601 的所有边,并查询每条边的两个顶点,总共耗时 10.764s
结论
  • 遍历性能 Neo4j > HugeGraph(RocksDB) > Titan(thrift+Cassandra)

2.3 HugeGraph-图常用分析方法性能

术语说明
  • FS(Find Shortest Path), 寻找最短路径
  • K-neighbor,从起始 vertex 出发,通过 K 跳边能够到达的所有顶点,包括 1, 2, 3…(K-1), K 跳边可达 vertex
  • K-out, 从起始 vertex 出发,恰好经过 K 跳 out 边能够到达的顶点
FS 性能
Backendemail-enron(30w)amazon0601(300w)com-youtube.ungraph(300w)com-lj.ungraph(3000w)
HugeGraph0.4940.1033.3648.155
Titan11.8180.239377.709575.678
Neo4j1.7191.8001.9568.530

说明

  • 表头”()“中数据是数据规模,以边为单位
  • 表中数据是找到从第一个顶点出发到达随机选择的 100 个顶点的最短路径的时间,单位是 s
  • 例如,HugeGraph 使用 RocksDB 后端在图 amazon0601 中查找第一个顶点到 100 个随机顶点的最短路径,总共耗时 0.103s
结论
  • 在数据规模小或者顶点关联关系少的场景下,HugeGraph 性能优于 Neo4j 和 Titan
  • 随着数据规模增大且顶点的关联度增高,HugeGraph 与 Neo4j 性能趋近,都远高于 Titan
K-neighbor 性能
顶点深度一度二度三度四度五度六度
v1时间0.031s0.033s0.048s0.500s11.27sOOM
v111时间0.027s0.034s0.1151.36sOOM–
v1111时间0.039s0.027s0.052s0.511s10.96sOOM

说明

  • HugeGraph-Server 的 JVM 内存设置为 32GB,数据量过大时会出现 OOM
K-out 性能
顶点深度一度二度三度四度五度六度
v1时间0.054s0.057s0.109s0.526s3.77sOOM
度10133245350,8301,128,688
v111时间0.032s0.042s0.136s1.25s20.62sOOM
度1021149441131502,629,970
v1111时间0.039s0.045s0.053s1.10s2.92sOOM
度101402555508251,070,230

说明

  • HugeGraph-Server 的 JVM 内存设置为 32GB,数据量过大时会出现 OOM
结论
  • FS 场景,HugeGraph 性能优于 Neo4j 和 Titan
  • K-neighbor 和 K-out 场景,HugeGraph 能够实现在 5 度范围内秒级返回结果

2.4 图综合性能测试-CW

数据库规模 1000规模 5000规模 10000规模 20000
HugeGraph(core)20.804242.099744.7801700.547
Titan45.790820.6332652.2359568.623
Neo4j5.91350.267142.354460.880

说明

  • “规模"以顶点为单位
  • 表中数据是社区发现完成需要的时间,单位是 s,例如 HugeGraph 使用 RocksDB 后端在规模 10000 的数据集,社区聚合不再变化,需要耗时 744.780s
  • CW 测试是 CRUD 的综合评估
  • 该测试中 HugeGraph 跟 Titan 一样,没有通过 client,直接对 core 操作
结论
  • 社区聚类算法性能 Neo4j > HugeGraph > Titan

8.2 - HugeGraph-API Performance

HugeGraph API性能测试主要测试HugeGraph-Server对RESTful API请求的并发处理能力,包括:

  • 顶点/边的单条插入
  • 顶点/边的批量插入
  • 顶点/边的查询

HugeGraph的每个发布版本的RESTful API的性能测试情况可以参考:

即将更新,敬请期待!

8.2.1 - v0.5.6 Stand-alone(RocksDB)

Note:

当前的性能指标测试基于很早期的版本。最新版本在性能和功能上都有显著的改进。我们鼓励您参考最新的发布版本, 该版本具有自主分布式存储和增强的计算推下能力。或者,您可以等待社区更新相关测试数据 (也欢迎反馈共建)。

1 测试环境

被压机器信息

CPUMemory网卡磁盘
48 Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz128G10000Mbps750GB SSD,2.7T HDD
  • 起压力机器信息:与被压机器同配置
  • 测试工具:apache-Jmeter-2.5.1

注:起压机器和被压机器在同一机房

2 测试说明

2.1 名词定义(时间的单位均为 ms)

  • Samples – 本次场景中一共完成了多少个线程
  • Average – 平均响应时间
  • Median – 统计意义上面的响应时间的中值
  • 90% Line – 所有线程中 90% 的线程的响应时间都小于 xx
  • Min – 最小响应时间
  • Max – 最大响应时间
  • Error – 出错率
  • Throughput – 吞吐量
  • KB/sec – 以流量做衡量的吞吐量

2.2 底层存储

后端存储使用 RocksDB,HugeGraph 与 RocksDB 都在同一机器上启动,server 相关的配置文件除主机和端口有修改外,其余均保持默认。

3 性能结果总结

  1. HugeGraph 单条插入顶点和边的速度在每秒 1w 左右
  2. 顶点和边的批量插入速度远大于单条插入速度
  3. 按 id 查询顶点和边的并发度可达到 13000 以上,且请求的平均延时小于 50ms

4 测试结果及分析

4.1 batch 插入

4.1.1 压力上限测试
测试方法

不断提升并发量,测试 server 仍能正常提供服务的压力上限

压力参数

持续时间:5min

顶点的最大插入速度:
image
结论:
  • 并发 2200,顶点的吞吐量是 2026.8,每秒可处理的数据:2026.8*200=405360/s
边的最大插入速度
image
结论:
  • 并发 900,边的吞吐量是 776.9,每秒可处理的数据:776.9*500=388450/s

4.2 single 插入

4.2.1 压力上限测试
测试方法

不断提升并发量,测试 server 仍能正常提供服务的压力上限

压力参数
  • 持续时间:5min
  • 服务异常标志:错误率大于 0.00%
顶点的单条插入
image
结论:
  • 并发 11500,吞吐量为 10730,顶点的单条插入并发能力为 11500
边的单条插入
image
结论:
  • 并发 9000,吞吐量是 8418,边的单条插入并发能力为 9000

4.3 按 id 查询

4.3.1 压力上限测试
测试方法

不断提升并发量,测试 server 仍能正常提供服务的压力上限

压力参数
  • 持续时间:5min
  • 服务异常标志:错误率大于 0.00%
顶点的按 id 查询
image
结论:
  • 并发 14000,吞吐量是 12663,顶点的按 id 查询的并发能力为 14000,平均延时为 44ms
边的按 id 查询
image
结论:
  • 并发 13000,吞吐量是 12225,边的按 id 查询的并发能力为 13000,平均延时为 12ms

8.2.2 - v0.5.6 Cluster(Cassandra)

Note:

当前的性能指标测试基于很早期的版本。最新版本在性能和功能上都有显著的改进。我们鼓励您参考最新的发布版本, 该版本具有自主分布式存储和增强的计算推下能力。或者,您可以等待社区更新相关测试数据 (也欢迎反馈共建)。

1 测试环境

被压机器信息

CPUMemory网卡磁盘
48 Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz128G10000Mbps750GB SSD,2.7T HDD
  • 起压力机器信息:与被压机器同配置
  • 测试工具:apache-Jmeter-2.5.1

注:起压机器和被压机器在同一机房

2 测试说明

2.1 名词定义(时间的单位均为 ms)

  • Samples – 本次场景中一共完成了多少个线程
  • Average – 平均响应时间
  • Median – 统计意义上面的响应时间的中值
  • 90% Line – 所有线程中 90% 的线程的响应时间都小于 xx
  • Min – 最小响应时间
  • Max – 最大响应时间
  • Error – 出错率
  • Throughput – 吞吐量
  • KB/sec – 以流量做衡量的吞吐量

2.2 底层存储

后端存储使用 15 节点 Cassandra 集群,HugeGraph 与 Cassandra 集群位于不同的服务器,server 相关的配置文件除主机和端口有修改外,其余均保持默认。

3 性能结果总结

  1. HugeGraph 单条插入顶点和边的速度分别为 9000 和 4500
  2. 顶点和边的批量插入速度分别为5w/s和15w/s,远大于单条插入速度
  3. 按 id 查询顶点和边的并发度可达到 12000 以上,且请求的平均延时小于 70ms

4 测试结果及分析

4.1 batch 插入

4.1.1 压力上限测试
测试方法

不断提升并发量,测试 server 仍能正常提供服务的压力上限

压力参数

持续时间:5min

顶点的最大插入速度:
image
结论:
  • 并发 3500,顶点的吞吐量是 261,每秒可处理的数据:261*200=52200/s
边的最大插入速度
image
结论:
  • 并发 1000,边的吞吐量是 323,每秒可处理的数据:323*500=161500/s

4.2 single 插入

4.2.1 压力上限测试
测试方法

不断提升并发量,测试 server 仍能正常提供服务的压力上限

压力参数
  • 持续时间:5min
  • 服务异常标志:错误率大于 0.00%
顶点的单条插入
image
结论:
  • 并发 9000,吞吐量为 8400,顶点的单条插入并发能力为 9000
边的单条插入
image
结论:
  • 并发 4500,吞吐量是 4160,边的单条插入并发能力为 4500

4.3 按 id 查询

4.3.1 压力上限测试
测试方法

不断提升并发量,测试 server 仍能正常提供服务的压力上限

压力参数
  • 持续时间:5min
  • 服务异常标志:错误率大于 0.00%
顶点的按 id 查询
image
结论:
  • 并发 14500,吞吐量是 13576,顶点的按 id 查询的并发能力为 14500,平均延时为 11ms
边的按 id 查询
image
结论:
  • 并发 12000,吞吐量是 10688,边的按 id 查询的并发能力为 12000,平均延时为 63ms

8.3 - HugeGraph-Loader Performance

Note:

当前的性能指标测试基于很早期的版本。最新版本在性能和功能上都有显著的改进。我们鼓励您参考最新的发布版本, 该版本具有自主分布式存储和增强的计算推下能力。或者,您可以等待社区更新相关测试数据 (也欢迎反馈共建)。

使用场景

当要批量插入的图数据(包括顶点和边)条数为 billion 级别及以下,或者总数据量小于 TB 时, 可以采用 HugeGraph-Loader 工具持续、高速导入图数据

性能

测试均采用网址数据的边数据

RocksDB 单机性能

  • 关闭 label index,22.8w edges/s
  • 开启 label index,15.3w edges/s

Cassandra 集群性能

  • 默认开启 label index,6.3w edges/s

8.4 - HugeGraph 0.4.4 性能测试

⚠️ 历史数据,暂不作为当前版本性能依据

本页面记录的是 HugeGraph 0.4.4 的性能测试,数据来自 2018 年。测试环境、软件版本和实现与当前版本差异很大,测试结果仅供历史参考,不能直接用于评估当前版本的性能。

后续将补充基于最新版本的性能测试报告,并归档本页面。当前版本的性能结论请以更新后的报告为准。

1 测试环境

1.1 硬件信息

CPUMemory网卡磁盘
48 Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz128G10000Mbps750GB SSD

1.2 软件信息

1.2.1 测试用例

测试使用graphdb-benchmark,一个图数据库测试集。该测试集主要包含4类测试:

  • Massive Insertion,批量插入顶点和边,一定数量的顶点或边一次性提交

  • Single Insertion,单条插入,每个顶点或者每条边立即提交

  • Query,主要是图数据库的基本查询操作:

    • Find Neighbors,查询所有顶点的邻居
    • Find Adjacent Nodes,查询所有边的邻接顶点
    • Find Shortest Path,查询第一个顶点到100个随机顶点的最短路径
  • Clustering,基于Louvain Method的社区发现算法

1.2.2 测试数据集

测试使用人造数据和真实数据

本测试用到的数据集规模
名称vertex数目edge数目文件大小
email-enron.txt36,691367,6614MB
com-youtube.ungraph.txt1,157,8062,987,62438.7MB
amazon0601.txt403,3933,387,38847.9MB

1.3 服务配置

  • HugeGraph版本:0.4.4,RestServer和Gremlin Server和backends都在同一台服务器上
  • Cassandra版本:cassandra-3.10,commit-log 和data共用SSD
  • RocksDB版本:rocksdbjni-5.8.6
  • Titan版本:0.5.4, 使用thrift+Cassandra模式

graphdb-benchmark适配的Titan版本为0.5.4

2 测试结果

2.1 Batch插入性能

Backendemail-enron(30w)amazon0601(300w)com-youtube.ungraph(300w)
Titan9.51688.123111.586
RocksDB2.34514.07616.636
Cassandra11.930108.709101.959
Memory3.07715.20413.841

说明

  • 表头"()“中数据是数据规模,以边为单位
  • 表中数据是批量插入的时间,单位是s
  • 例如,HugeGraph使用RocksDB插入amazon0601数据集的300w条边,花费14.076s,速度约为21w edges/s
结论
  • RocksDB和Memory后端插入性能优于Cassandra
  • HugeGraph和Titan同样使用Cassandra作为后端的情况下,插入性能接近

2.2 遍历性能

2.2.1 术语说明
  • FN(Find Neighbor), 遍历所有vertex, 根据vertex查邻接edge, 通过edge和vertex查other vertex
  • FA(Find Adjacent), 遍历所有edge,根据edge获得source vertex和target vertex
2.2.2 FN性能
Backendemail-enron(3.6w)amazon0601(40w)com-youtube.ungraph(120w)
Titan7.72470.935128.884
RocksDB8.87665.85263.388
Cassandra13.125126.959102.580
Memory22.309207.411165.609

说明

  • 表头”()“中数据是数据规模,以顶点为单位
  • 表中数据是遍历顶点花费的时间,单位是s
  • 例如,HugeGraph使用RocksDB后端遍历amazon0601的所有顶点,并查找邻接边和另一顶点,总共耗时65.852s
2.2.3 FA性能
Backendemail-enron(30w)amazon0601(300w)com-youtube.ungraph(300w)
Titan7.11963.353115.633
RocksDB6.03264.52652.721
Cassandra9.410102.76694.197
Memory12.340195.444140.89

说明

  • 表头”()“中数据是数据规模,以边为单位
  • 表中数据是遍历边花费的时间,单位是s
  • 例如,HugeGraph使用RocksDB后端遍历amazon0601的所有边,并查询每条边的两个顶点,总共耗时64.526s
结论
  • HugeGraph RocksDB > Titan thrift+Cassandra > HugeGraph Cassandra > HugeGraph Memory

2.3 HugeGraph-图常用分析方法性能

术语说明
  • FS(Find Shortest Path), 寻找最短路径
  • K-neighbor,从起始vertex出发,通过K跳边能够到达的所有顶点, 包括1, 2, 3…(K-1), K跳边可达vertex
  • K-out, 从起始vertex出发,恰好经过K跳out边能够到达的顶点
FS性能
Backendemail-enron(30w)amazon0601(300w)com-youtube.ungraph(300w)
Titan11.3330.313376.06
RocksDB44.3912.221268.792
Cassandra39.8453.337331.113
Memory35.6382.059388.987

说明

  • 表头”()“中数据是数据规模,以边为单位
  • 表中数据是找到从第一个顶点出发到达随机选择的100个顶点的最短路径的时间,单位是s
  • 例如,HugeGraph使用RocksDB查找第一个顶点到100个随机顶点的最短路径,总共耗时2.059s
结论
  • 在数据规模小或者顶点关联关系少的场景下,Titan最短路径性能优于HugeGraph
  • 随着数据规模增大且顶点的关联度增高,HugeGraph最短路径性能优于Titan
K-neighbor性能
顶点深度一度二度三度四度五度六度
v1时间0.031s0.033s0.048s0.500s11.27sOOM
v111时间0.027s0.034s0.1151.36sOOM–
v1111时间0.039s0.027s0.052s0.511s10.96sOOM

说明

  • HugeGraph-Server的JVM内存设置为32GB,数据量过大时会出现OOM
K-out性能
顶点深度一度二度三度四度五度六度
v1时间0.054s0.057s0.109s0.526s3.77sOOM
度10133245350,8301,128,688
v111时间0.032s0.042s0.136s1.25s20.62sOOM
度1021149441131502,629,970
v1111时间0.039s0.045s0.053s1.10s2.92sOOM
度101402555508251,070,230

说明

  • HugeGraph-Server的JVM内存设置为32GB,数据量过大时会出现OOM
结论
  • FS场景,HugeGraph性能优于Titan
  • K-neighbor和K-out场景,HugeGraph能够实现在5度范围内秒级返回结果

2.4 图综合性能测试-CW

数据库规模1000规模5000规模10000规模20000
Titan45.943849.1682737.1179791.46
Memory(core)41.0771825.905**
Cassandra(core)39.783862.7442423.1366564.191
RocksDB(core)33.383199.894763.8691677.813

说明

  • “规模"以顶点为单位
  • 表中数据是社区发现完成需要的时间,单位是s,例如HugeGraph使用RocksDB后端在规模10000的数据集,社区聚合不再变化,需要耗时763.869s
  • “*“表示超过10000s未完成
  • CW测试是CRUD的综合评估
  • 后三者分别是HugeGraph的不同后端,该测试中HugeGraph跟Titan一样,没有通过client,直接对core操作
结论
  • HugeGraph在使用Cassandra后端时,性能略优于Titan,随着数据规模的增大,优势越来越明显,数据规模20000时,比Titan快30%
  • HugeGraph在使用RocksDB后端时,性能远高于Titan和HugeGraph的Cassandra后端,分别比两者快了6倍和4倍

9 - 贡献指南

提交代码或文档前,请先阅读贡献流程。Committer 提名、邮件列表订阅和版本验证分别由对应页面说明;贡献者协议使用 ASF 官方 ICLA/CCLA。

9.1 - 参与 HugeGraph 社区

选择贡献方式

可以通过 GitHub Issues 报告问题,也可以提交代码、测试或文档。准备较大的改动前,建议先创建 Issue 并说明范围,避免重复工作。

下面以 apache/hugegraph 为例。其他 HugeGraph 仓库的流程相同,但构建和测试命令应以各仓库的 README.md、AGENTS.md 和 CI 配置为准。

准备仓库

在 GitHub 上 Fork HugeGraph 仓库

先在 GitHub 上 fork apache/hugegraph,再克隆自己的 fork:

1git clone https://github.com/<your-name>/hugegraph.git
2cd hugegraph
3git remote add upstream https://github.com/apache/hugegraph.git
4git fetch upstream master

不要直接在 master 上开发。每项改动使用单独分支:

1git switch master
2git merge --ff-only upstream/master
3git switch -c fix/<short-description>

修改和验证

HugeGraph Server 的代码位于 hugegraph-server/。例如,核心模块路径是:

1hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/

当前主仓库根目录的 Maven 模块如下;Server 的存储适配器 hugegraph-server/hugegraph-hstore/ 与独立的存储节点项目 hugegraph-store/ 是不同模块。

路径子模块
hugegraph-server/hugegraph-core/、hugegraph-api/、hugegraph-example/、hugegraph-dist/、hugegraph-test/、hugegraph-rocksdb/、hugegraph-hbase/、hugegraph-hstore/
hugegraph-pd/hg-pd-common/、hg-pd-client/、hg-pd-core/、hg-pd-service/、hg-pd-dist/、hg-pd-cli/、hg-pd-grpc/、hg-pd-test/
hugegraph-store/hg-store-common/、hg-store-client/、hg-store-core/、hg-store-node/、hg-store-dist/、hg-store-cli/、hg-store-grpc/、hg-store-rocksdb/、hg-store-test/
hugegraph-commons/hugegraph-common/、hugegraph-rpc/
hugegraph-cluster-test/hugegraph-clustertest-minicluster/、hugegraph-clustertest-dist/、hugegraph-clustertest-test/
独立根模块hugegraph-struct/、install-dist/

上述名称来自根 pom.xml 及各子项目 pom.xml;代码结构以正在使用的分支为准。

已合入 Server master、面向 1.8.0 的整合见共享基础模块职责和 Java 迁移指南。

当前 Server master 使用 Java 17 和 Maven 3.6.3 或更高版本构建。 CI-friendly 版本在 process-resources 阶段展开,安装或发布的 POM 使用具体版本号。 单独构建模块前,先对整仓执行 install;使用 Maven 3.10 时也应保持 Resolver 校验开启。

先运行与改动直接相关的测试。Server 常用测试入口如下:

1# Core 测试,使用内存后端
2mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,memory
3
4# API 测试,使用 RocksDB 后端
5mvn test -pl hugegraph-server/hugegraph-test -am -P api-test,rocksdb
6
7# 格式化并检查编译
8mvn editorconfig:format
9mvn clean compile -Dmaven.javadoc.skip=true

GitHub 已不支持通过用户名和密码直接推送代码。需要使用个人访问令牌时,请在令牌设置页创建并按需授权:

使用个人访问令牌认证 Git 推送

提交第三方依赖时,还要同步发行包中的许可证信息:

  1. 把依赖的许可证文件放入 install-dist/release-docs/licenses/。

  2. 更新 install-dist/release-docs/LICENSE;依赖包含 NOTICE 时,同时更新 NOTICE。

  3. 在仓库根目录,先准备当前 revision 的 Server、PD、Store 发行包库,再生成依赖清单:

    1mvn clean install -DskipTests -Dmaven.javadoc.skip=true
    2bash install-dist/scripts/dependency/regenerate_known_dependencies.sh

    clean 会重新构建当前版本的发行目录,避免残留已移除的依赖 jar。 它还会删除 hugegraph-server/、hugegraph-pd/ 与 hugegraph-store/ 目录下的所有 *.tar 和 *.tar.gz 文件,以及仓库根目录中当前版本的 apache-hugegraph-<revision>.tar.gz;其他版本的目录会保留。

    此构建跳过测试。依赖收集同时覆盖 Maven runtime 依赖和实际发行包中的平铺、嵌套 jar, 包括 Spring Boot repackaging 引入的 BOOT-INF/lib 依赖。缺失发行包必须使收集失败;只检查 POM 不能证明完整发行依赖集。 核查 install-dist/scripts/dependency/known-dependencies.txt 的严格增删对比及对应 license/NOTICE,并按需覆盖发布平台和 profile 变体。

提交 Pull Request

提交代码所用的邮箱需要绑定到 GitHub 账号。请在邮箱设置页完成绑定:

在 GitHub 中验证提交邮箱

提交信息使用 type(module): message 格式,例如:

1git add <changed-files>
2git commit -m "fix(core): handle empty vertex query"
3git push -u origin fix/<short-description>

然后从 fork 分支向 apache/hugegraph:master 创建 Pull Request。说明问题、修改方法和实际运行的验证命令;界面变化应附截图。

处理 Review

CI 失败或 reviewer 要求修改时,在原分支继续提交并推送。需要同步上游时,可以 rebase:

1git fetch upstream master
2git rebase upstream/master
3git push --force-with-lease

不要使用普通 --force 覆盖远端分支。完成所有 CI 和 review 要求后,由项目 maintainer 合并 Pull Request。

Contributor Agreement 使用 ASF 官方流程,见贡献者协议。

9.2 - 订阅社区邮件列表

HugeGraph 使用 dev@hugegraph.apache.org 讨论开发和使用问题。向列表发信前需要先订阅,否则邮件可能被拦截。

订阅

  1. 使用准备订阅的邮箱向 dev-subscribe@hugegraph.apache.org 发送一封任意主题、任意内容的邮件。
  2. 收到确认邮件后直接回复。
  3. 收到订阅成功邮件后,即可向 dev@hugegraph.apache.org 发信。

如果没有收到确认邮件,先检查垃圾邮件和自动分类目录。仍未收到时,等待一段时间后重新发送订阅邮件。

未订阅也可以在 ASF Mailing List Archives 浏览公开邮件。

退订

  1. 使用订阅邮箱向 dev-unsubscribe@hugegraph.apache.org 发信。
  2. 收到 dev-help@hugegraph.apache.org 的确认邮件后直接回复。
  3. 收到主题包含 GOODBYE 的邮件后,退订完成。

ASF 邮件列表的通用说明见 Apache Mailing Lists。

9.3 - 验证 Apache 发版

Note: 这篇文档会持续更新。 HugeGraph 1.8.0 的源码构建与发行包运行验证统一使用 Java 17(Maven 源码构建仅接受 JDK 17);1.7.0 请使用 Java 11。从 1.5.0 版本开始 (除 client 外) 不再支持 Java 8。

毕业说明:Apache HugeGraph 已于 2026 年 1 月毕业。正式发版投票现由 HugeGraph 社区内部完成(dev@hugegraph.apache.org 上的 PMC binding 投票),不再需要 Incubator general@incubator.apache.org 审批。

自动化发版验证

Workflow 与 dist/validate-release.sh 共用 Java 17 校验逻辑。发行版本与 SVN RC 路径分别指定, Maven staging repository 使用投票邮件中的地址。Server/Toolchain 四个源码和二进制包是必需项, 同一候选目录也可包含 AI、Computer 源码包。每个包均须附带 SHA512 与 GPG 签名;未知包名和版本不符会阻断验证。 所有包均检查完整性、内容和许可证,Computer 源码另执行 Maven 构建;AI、Computer 产品运行验证需另行完成。

1bash dist/validate-release.sh --svn-path 1.8.0/RC1 \
2  --staging-repository https://repository.apache.org/content/repositories/<staging-id>/ 1.8.0 imbajin
3# 原有本地包位置参数接口保留:
4bash dist/validate-release.sh 1.8.0 imbajin /path/to/rc 17

严格 RC 模式使用全新、相互隔离的 Maven 仓库,不预装本地 Server SDK。 源码构建产物和下载的二进制包分别执行 Server、Client、普通 Loader、Tools 与 Hubble 业务断言,失败后保留日志。 Workflow 的 source-prevalidation 模式使用明确的 Server/Toolchain commit SHA 和无签名源码归档, 它不证明真实 RC 签名、下载及远端 staging 依赖解析已通过。 license-review-*.txt 中的许可选择和例外仍需人工复核,明确的 Category-X-only 依赖会阻断验证;自动成功不等于发布批准。 本地预验证和证据目录说明见验证脚本指南。

控制台和 GitHub Job Summary 汇总结果、失败阶段、复核提示及日志位置;源码预验证不会显示为 RC 验收通过。

验证阶段

当内部的临时发布和打包工作完成后,其他的社区开发者 (尤其是 PMC) 需要按 ASF 发版规范参与验证,可参考:

1. 准备工作

如果本地没有 svn 或 gpg 或 wget 环境,建议先安装一下 (windows 推荐使用 WSL2 环境, 或者至少是 git-bash), 同时确保安装 Java 17(编译 1.7.0 请使用 Java 11)和 Maven 软件 (≥ 3.6.3)。

 1# 1. 安装svn
 2# ubuntu/debian
 3sudo apt install subversion -y
 4# MacOS
 5brew install subversion
 6# 验证安装是否成功, 执行以下命令:
 7svn --version
 8
 9# 2. 安装gpg
10# ubuntu/debian
11sudo apt-get install gnupg -y
12# MacOS
13brew install gnupg
14# 验证安装是否成功, 执行以下命令:
15gpg --version
16
17# 3. 安装wget
18# ubuntu/debian
19sudo apt-get install wget -y
20# MacOS
21brew install wget
22
23# 4. 下载 hugegraph-svn 目录 (版本号注意填写此次验证版本)
24svn co https://dist.apache.org/repos/dist/dev/hugegraph/1.x.x/
25# (注) 如果出现 svn 下载某个文件速度很慢的情况, 可以考虑 wget 单个文件下载, 如下 (或考虑使用 VPN / 代理)
26wget https://dist.apache.org/repos/dist/dev/hugegraph/1.x.x/apache-hugegraph-toolchain-1.x.x.tar.gz

2. 检查 hash 值

首先需要检查 source + binary 包的文件完整性,通过 shasum 进行校验,确保和发布到 apache/github 上的 hash 值一致 (一般是 sha512)

1执行命令:
2for i in *.tar.gz; do echo $i; shasum -a 512 --check  $i.sha512; done

3. 检查 gpg 签名

这个就是为了确保发布的包是由可信赖的人上传的,假设 tom 签名后上传,其他人应该下载 A 的公钥 然后进行签名确认, 相关命令:

 1# 1. 下载项目可信赖公钥到本地 (首次需要) & 导入
 2curl  https://downloads.apache.org/hugegraph/KEYS > KEYS
 3gpg --import KEYS
 4
 5# 导入后可以看到如下输出, 这代表导入了 x 个用户公钥
 6gpg: /home/ubuntu/.gnupg/trustdb.gpg: trustdb created
 7gpg: key BA7E78F8A81A885E: public key "imbajin (apache mail) <jin@apache.org>" imported
 8gpg: key 818108E7924549CC: public key "vaughn <vaughn@apache.org>" imported
 9gpg: key 28DCAED849C4180E: public key "coderzc (CODE SIGNING KEY) <zhaocong@apache.org>" imported
10....
11gpg: Total number processed: x
12gpg:               imported: x
13
14# 2. 将完整主密钥指纹与发版投票邮件中的签名者指纹对照
15release_signer_fingerprint='<signer-full-fingerprint>'
16gpg --fingerprint -- "$release_signer_fingerprint"
17
18# 3. 在子 shell 中验证,失败时停止检查但不退出交互终端
19(
20  for archive in *.tar.gz; do
21    gpg --status-fd 1 --verify -- "$archive.asc" "$archive" > "$archive.status" || {
22      status=$?
23      printf 'Signature verification failed: %s\n' "$archive" >&2
24      cat "$archive.status"
25      exit "$status"
26    }
27    cat "$archive.status"
28    if grep -Eq '^\[GNUPG:\] (REVKEYSIG|EXPKEYSIG|EXPSIG)( |$)' "$archive.status"; then
29      printf 'Expired or revoked signature: %s\n' "$archive" >&2
30      exit 1
31    fi
32    grep -q '^\[GNUPG:\] VALIDSIG ' "$archive.status" || {
33      printf 'Missing valid signature: %s\n' "$archive" >&2
34      exit 1
35    }
36  done
37)

必须同时确认验证退出码为零,且 VALIDSIG 中的指纹对应投票邮件的签名者;使用签名子密钥时,核对其报告的主密钥指纹。 密钥信任警告本身不表示签名无效,也不能只凭本地化的 Good signature 文本判断成功。 即使同时出现 VALIDSIG 或退出码为零,遇到 REVKEYSIG、EXPKEYSIG、EXPSIG 仍须停止,交由发版负责人复核或更新候选包。 格式见 GnuPG 状态说明。

先确认了整体的"完整性 + 一致性", 然后接下来确认具体的内容 (关键)

4. 检查压缩包内容

这里检查准备工作下载的压缩包内容。分源码包 + 二进制包两个方面,源码包更为严格,挑核心的部分说 (完整的列表可参考官方 Wiki, 比较长)

A. 源码包

解压 *hugegraph*src.tar.gz后,进行如下检查:

  1. 包名/目录名应符合当前发版命名(历史版本可能仍包含 incubating),且不存在空的文件/文件夹
  2. 存在 LICENSE + NOTICE 且内容正常;历史版本若在项目孵化期发布,还需检查 DISCLAIMER
  3. 不存在 缺乏 License 的二进制文件
  4. 源码文件都包含标准 ASF License 头 (这个用插件跑一下为主)
  5. 检查每个父 / 子模块的 pom.xml 版本号是否一致 (且符合期望)
  6. 最后,确保源码可以正常 / 正确编译 (然后看看测试和规范)

PMC 同学请特别注意认真检查 LICENSE + NOTICE 文件,确保文件严格遵循了 ASF 的发版要求, 大部分的发版问题都与之相关

1# 验证 HugeGraph 1.8.0+ 请优先使用/切换到 `java 17` 版本(1.7.0 请使用 `java 11`)进行后序的编译和运行操作 (注:`Computer` 仅支持 `java >= 11`)
2# java --version
3
4# 尝试在 Unix 环境下编译测试是否正常
5mvn -s /path/to/staging-settings.xml -Dmaven.repo.local=/path/to/fresh-m2 \
6  clean install -Papache-release -DskipTests -Dgpg.skip=true

手动 Maven 命令的 settings 必须指向投票邮件中的 staging repository,并使用全新的本地仓库。 不要预装本地 Server SDK 来掩盖 staging 缺少依赖;自动化验证脚本会生成这些设置。

B. 二进制包

解压 xxx-hugegraph.tar.gz后,进行如下检查:

  1. 包名/目录名应符合当前发版命名(历史版本可能仍包含 incubating)
  2. 存在 LICENSE + NOTICE 且内容正常(历史版本若在项目孵化期发布,还需检查 DISCLAIMER)
  3. 服务启动
 1# hugegraph-server
 2bin/start-hugegraph.sh
 3
 4# hugegraph-loader
 5bin/hugegraph-loader.sh -g hugegraph -f example/file/struct.json -s example/file/schema.groovy
 6
 7# hugegraph-hubble
 8bin/start-hubble.sh
 9
10更多参考官网: https://hugegraph.apache.org/cn/docs/quickstart

注: 如果二进制包里面引入了第三方依赖, 则需要更新 LICENSE, 加入第三方依赖的 LICENSE; 若第三方依赖 LICENSE 是 Apache 2.0, 且对应的项目中包含了 NOTICE, 则还需要更新我们的 NOTICE 文件

5. 检查官网以及 github 等页面

  1. 确保官网至少满足 apache website check, 以及没有死链等
  2. 更新下载链接存在,以及版本更新说明页面更新
  3. …

邮件模板

检查完成后,你应该按不同角色回复邮件:(普通开发者 & PMC 成员)

1[] +1 approve
2
3[] +0 no opinion
4
5[] -1 disapprove with the reason
 1+1 (non-binding)
 2I checked:
 31. Download link/tag in mail are valid
 42. Checksum and GPG signatures are OK
 53. LICENSE & NOTICE exist
 64. Build successfully on XX OS version XXX
 75. No unexpected binary files
 86. Date is right in the NOTICE file
 97. Compile from source is fine under JavaX
108. No empty file & directory found
119. Test running xxx service OK
1210. ....

特别注意 PMC 成员必须使用 binding 标记回复邮件,这对于统计有效投票很重要;

 1+1 (binding)
 2I checked:
 31. Download link/tag in mail are valid
 42. Checksum and GPG signatures are OK
 53. LICENSE & NOTICE exist
 64. Build successfully on XX OS Version XX
 75. No unexpected binary files
 86. Date is right in the NOTICE file
 97. Compile from source is fine under JavaXX
108. No empty file & directory found
119. Test running XXX service OK
1210. ....

9.4 - 在 IDEA 中配置 Server 开发环境

适用范围:下述 IDEA 配置基于 HugeGraph 1.2.0 发布标签,仅作为历史调试步骤保留。当前主线的源码目录和验证入口见贡献流程与 Server 快速上手;不要从本页推断当前模块清单。

背景

在 快速上手 部分已经介绍了使用脚本启停 HugeGraph-Server 的流程。下面以 Linux 平台为例,介绍使用 IntelliJ IDEA 运行与调试 HugeGraph-Server 的流程。

本地启动的核心与脚本启动是一样的:

  1. 初始化数据库后端,执行 InitStore 类初始化图
  2. 启动 HugeGraph-Server,执行 HugeGraphServer 类加载初始化的图信息启动

在执行下述流程之前,请确保已经克隆了 HugeGraph 的源代码,并且已经配置了开发环境(HugeGraph 1.8.0+ 需 Java 17,1.7.0 需 Java 11)& 可以参考这个 配置文档

1git clone https://github.com/apache/hugegraph.git

步骤

1. 配置文件拷贝

为了避免配置文件的更改影响 Git 的追踪,建议将所需的配置文件拷贝到一个单独的文件夹中:

1cp -r hugegraph-server/hugegraph-dist/src/assembly/static/scripts \
2      hugegraph-server/hugegraph-dist/src/assembly/static/conf \
3      path-to-your-directory

将 path-to-your-directory 替换为你创建的文件夹的路径。命令需在仓库根目录执行,hugegraph-dist 模块位于顶层的 hugegraph-server 目录之下。

下列 ToplingDB 步骤仅适用于历史定制构建。当前主线源码不包含 preload-topling.sh 或 ToplingDB 模块,按当前主线调试时跳过此说明。

2. InitStore 类初始化图

首先,需要在配置文件中配置数据库后端。以 RocksDB 为例,在 path-to-your-directory/conf/graphs/hugegraph.properties 文件中进行以下配置:

1backend=rocksdb
2serializer=binary
3rocksdb.data_path=.
4rocksdb.wal_path=.

然后,打开 IntelliJ IDEA 的 Run/Debug Configurations 面板,创建一个新的 Application 配置,按照以下步骤进行配置:

  • 在 Use classpath of module 中选择 hugegraph-dist
  • 将 Main class 设置为 org.apache.hugegraph.cmd.InitStore
  • 设置运行参数为 conf/rest-server.properties,这里的路径是相对于工作路径的,需要将工作路径设置为 path-to-your-directory
  • (可选,仅 ToplingDB 构建) ToplingDB 需要通过 LD_PRELOAD 机制预加载动态库,开发者需设置两个环境变量:LD_LIBRARY_PATH 指向 preload-topling.sh 解压出的 library 目录,LD_PRELOAD 设置为 libjemalloc.so:librocksdbjni-linux64.so,以确保相关库在运行时被正确加载
    • LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH
    • LD_PRELOAD=libjemalloc.so:librocksdbjni-linux64.so

若在 Java 11 环境下为 HugeGraph-Server 配置了用户认证 (authenticator),需要参考二进制包的脚本配置,添加下述 VM options:

1--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED

否则会报错:

1java.lang.reflect.InaccessibleObjectException: Unable to make public static synchronized void jdk.internal.reflect.Reflection.registerFieldsToFilter(java.lang.Class,java.lang.String[]) accessible: module java.base does not "exports jdk.internal.reflect" to unnamed module @xxx

配置完成后运行,如果运行成功,将会输出以下类似运行日志:

 12023-06-05 00:43:37 [main] [INFO] o.a.h.u.ConfigUtil - Scanning option 'graphs' directory './conf/graphs'
 22023-06-05 00:43:37 [main] [INFO] o.a.h.c.InitStore - Init graph with config file: ./conf/graphs/hugegraph.properties
 3......
 42023-06-05 00:43:39 [main] [INFO] o.a.h.b.s.r.RocksDBStore - Write down the backend version: 1.11
 52023-06-05 00:43:39 [main] [INFO] o.a.h.StandardHugeGraph - Graph 'hugegraph' has been initialized
 62023-06-05 00:43:39 [main] [INFO] o.a.h.StandardHugeGraph - Close graph standardhugegraph[hugegraph]
 72023-06-05 00:43:39 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStore - Opening RocksDB with data path: ./m
 82023-06-05 00:43:39 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStore - Opening RocksDB with data path: ./s
 92023-06-05 00:43:39 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStore - Opening RocksDB with data path: ./g
102023-06-05 00:43:39 [main] [INFO] o.a.h.HugeFactory - HugeFactory shutdown
112023-06-05 00:43:39 [hugegraph-shutdown] [INFO] o.a.h.HugeFactory - HugeGraph is shutting down

3. 运行 HugeGraphServer

类似地,打开 IntelliJ IDEA 的 Run/Debug Configurations 面板,创建一个新的 Application 配置,按照以下步骤进行配置:

  • 在 Use classpath of module 中选择 hugegraph-dist
  • 将 Main class 设置为 org.apache.hugegraph.dist.HugeGraphServer
  • 设置运行参数为 conf/gremlin-server.yaml conf/rest-server.properties,同样地,这里的路径是相对于工作路径的,需要将工作路径设置为 path-to-your-directory

二进制包中的 bin/hugegraph-server.sh 并不直接启动该类,而是启动 org.apache.hugegraph.bootstrap.HugeGraphServerBootstrap:它在两个配置文件路径之前多接收一个 true/false 的安全检查开关,为 true 时安装 HugeSecurityManager,随后再交给 HugeGraphServer。从 IDEA 直接运行 HugeGraphServer 会跳过这层包装,因此不会安装 security manager,这通常正是调试时想要的效果。

类似的,若在 Java 11 环境下为 HugeGraph-Server 配置了用户认证 (authenticator),同样需要参考二进制包的脚本配置,添加下述 VM options:

1--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED --add-modules=jdk.unsupported --add-exports=java.base/sun.nio.ch=ALL-UNNAMED

否则会报错:

1java.lang.reflect.InaccessibleObjectException: Unable to make public static synchronized void jdk.internal.reflect.Reflection.registerFieldsToFilter(java.lang.Class,java.lang.String[]) accessible: module java.base does not "exports jdk.internal.reflect" to unnamed module @xxx

配置完成后运行,如果看到以下类似日志,表示 HugeGraphServer 已经成功启动:

1......
22023-06-05 00:51:56 [gremlin-server-boss-1] [INFO] o.a.t.g.s.GremlinServer - Gremlin Server configured with worker thread pool of 1, gremlin pool of 8 and boss thread pool of 1.
32023-06-05 00:51:56 [gremlin-server-boss-1] [INFO] o.a.t.g.s.GremlinServer - Channel started at port 8182.

4. 调试 HugeGraphServer (可选)

在完成上述配置后,可以尝试对 HugeGraphServer 进行调试。在调试模式下运行 HugeGraphServer,并在以下位置设置断点:

1public String list(@Context GraphManager manager,
2                   @PathParam("graph") String graph, @QueryParam("label") String label,
3                   @QueryParam("properties") String properties, ......) {
4    // ignore log
5    Map<String, Object> props = parseProperties(properties);

然后,使用 RESTful API 请求 HugeGraphServer:

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

此时,可以在调试器中查看详细的变量信息。

5. Log4j2 日志配置

默认情况下,运行 InitStore 和 HugeGraphServer 时,读取的 Log4j2 配置文件路径为 hugegraph-server/hugegraph-dist/src/main/resources/log4j2.xml,而不是 path-to-your-directory/conf/log4j2.xml,这个配置文件是使用脚本启动 HugeGraph-Server 时读取的。

为了避免同时维护两份配置文件,可以考虑在 IntelliJ IDEA 运行与调试 HugeGraph-Server 时,修改读取的 Log4j2 配置文件路径:

  1. 打开之前创建的 Application 配置
  2. 点击 Modify options - Add VM options
  3. 设置 VM options 为 -Dlog4j.configurationFile=conf/log4j2.xml

可能遇到的问题

1. java: package sun.misc does not exist

原因可能是在使用 Java 11 编译时触发了交叉编译,导致项目中使用的 sun.misc.Unsafe 找不到符号。有两种解决方案可供选择:

  1. 在 IntelliJ IDEA 的 Preferences/Settings 中找到 Java Compiler 面板,然后关闭 --release 选项 (推荐)
  2. 或者将项目的 SDK 版本设置为 8 (Deprecated soon)

2. java: *.store.raft.rpc.RaftRequests does not exist (RPC Generated Files)

原因是源代码没有包含 RPC-generated 文件。可以尝试两种方法来解决:

  1. [命令] 在根目录下运行 mvn clean compile -DskipTests (推荐)
  2. [UI] 在 IDEA 中,右键点击 hugegraph 模块,选择 Manve -> Generate Sources and Update Folders

3. Log4j2 日志无法打印 %l 等位置信息

这是因为 Log4j2 中使用了 asynchronous loggers,可以参考官方文档进行配置


参考
  1. HugeGraph-Server 快速上手
  2. hugegraph-server 本地调试文档 (Win/Unix)
  3. “package sun.misc does not exist” compilation error
  4. Cannot compile: java: package sun.misc does not exist
  5. The code-style config for HugeGraph in IDEA

9.5 - Apache HugeGraph Committer 指南

本文档概述了 Apache Committer 推选要求以及流程,对应的 ASF 官方文档可见:https://community.apache.org/newcommitter.html

候选人要求

  1. 候选人应遵守 Apache Code of Conduct
  2. PMC 成员将通过搜索邮件列表、issues、PRs、官网文档等方式,了解候选人如何与他人互动,以及他们所做的贡献
  3. 以下是在评估候选人是否适合成为 Committer 时需要考虑的一些要点:
    1. 与社区成员合作的能力
    2. 担任导师的能力
    3. 社区参与度
    4. 贡献程度
    5. 个人技能/能力

推选详细流程

讨论 (DISCUSS) → 投票 (VOTE) → 邀请 (INVITE) → 公告 (ANNOUNCE)

发起社区邮件讨论 (DISCUSS)

任何 HugeGraph 的 PMC 成员都可以发起投票讨论,在发现社区贡献者任何有价值的贡献并取得候选人本人同意后,可以在 private@hugegraph.apache.org 发起讨论。 讨论邮件里提议者要把候选人的贡献说清楚,并最好给出确认贡献的 URL 等信息,便于大家讨论分析。

下面是 HugeGraph 对应的邮件模板:(仅供参考)

Note: 后续将使用 xxx 指代候选人名,一般 xxx 为一个容易读的名字 (例如 Simon Jay)

ASF-INFRA 建议避免使用不易读的 ID 直接作为邮件人名代指 (例如避免 simon321 或 wh0isSim0n 😄)

另发送邮件最好选择 “纯文本” 模式,否则排版在 ASF Mail UI 中可能会乱

 1To: private@hugegraph.apache.org
 2Subject: [DISCUSS] XXX as a HugeGraph Committer Candidate
 3
 4Hi all:
 5
 6I am pleased to nominate xxx for the role of HugeGraph Committer based on his/her contributions over the past few months.
 7
 8[ Candidate's Contribution Summary ]
 9
10Here are the relevant PRs (issues) he/she has participated in:
11
12**Core Features:**
13- Feature 1: [ Reference Links ]
14- ...
15
16**Fix/Chore/Release:**
17
18**Doc:**
19
20[ Candidate's Current Notable Contributions ]
21
22His/Her contributions bring the following benefits to the community, helping us in the following ways:
23
24[ Candidate's Contributions and Benefits to the Community ]
25
26In view of the above contributions, I elect xxx as Committer of the HugeGraph project.
27
28[ Reference Links ]
291. PR1
302. PR2
313. ...
32
33Welcome everyone to share opinions~
34
35Thanks!

对于讨论邮件中贡献链接,可以使用 GitHub Search 的统计功能,按需输入如下对应关键词查询即可,可以在此基础上添加新的 repo 如 repo:apache/hugegraph-computer,特别注意调整时间范围 (下面是一个模板参考,请自行调整参数):

Mailing Lists 的参与则可使用 https://lists.apache.org/list?dev@hugegraph.apache.org:lte=10M:xxx 查询。

发起社区邮件投票 (VOTE)

如果讨论邮件在规定时间内没有收到分歧信息,投票发起者需要在 private@hugegraph.apache.org 发起对 Committer 的选举投票。

下面是对应的邮件模板:

 1To: private@hugegraph.apache.org
 2Subject: [VOTE] xxx as a HugeGraph Committer
 3
 4Hi all:
 5
 6Through the discussion of last week:
 7[ Discussion Mailing List Link ]
 8
 9We have discussed and listed what xxx participated in the HugeGraph community.
10I believe making him/her a Committer will enhance the work for HugeGraph. 
11
12So, I am happy to call VOTE to accept xxx as a HugeGraph Committer.
13 
14Voting will continue for at least 72 hours or until the required number of votes is reached.
15 
16Please vote accordingly:
17[ ] +1 approve
18[ ] +0 no opinion
19[ ] -1 disapprove with the reason  
20
21Thanks!

然后 PMC 成员回复 +1 或 -1 的邮件回复表达意见,一般来说至少需要 ≥3 票 +1 才能结束投票。

宣布投票结果 (RESULT)

投票邮件结束后,投票发起者需要邮件里提醒投票结束。同时,投票发起者需要发起邮件宣布投票结果,发送至 private@hugegraph.apache.org,邮件模板可参考:

 1To: private@hugegraph.apache.org
 2Subject: [RESULTS][VOTE] xxx as a HugeGraph Committer
 3
 4Hi all: The vote for "xxx" as a HugeGraph Committer has PASSED and closed now.
 5
 6The result is as follows: X PMC +1 Votes: 
 7- A (PMC ID)
 8- B
 9- C...
10
11Vote thread:
12put vote thread link here
13 
14Then I'm going to invite xxx to join us soon. Thanks for everyone's support!

向候选人发起邮件邀请 (INVITE)

宣布投票结果邮件发出后,投票发起人要给候选人发送邀请邮件。邀请邮件主送候选人,抄送 private@hugegraph.apache.org,被邀请的候选人必须通过指定的邮箱地址回复接受或者拒绝该邀请。

下面是对应可参考的邮件模板:

 1To: [ Candidate's Email ]
 2Cc: private@hugegraph.apache.org
 3Subject: Invitation to become HugeGraph committer: xxx
 4
 5Hello xxx,
 6
 7The HugeGraph Project Management Committee (PMC)
 8hereby offers you committer privileges to the project.
 9These privileges are offered on the understanding that you'll use them
10reasonably and with common sense. We like to work on trust
11rather than unnecessary constraints.
12
13Being a committer enables you to more easily make
14changes without needing to go through the patch
15submission process.
16
17Being a committer does not require you to
18participate any more than you already do. It does
19tend to make one even more committed.  You will
20probably find that you spend more time here.
21
22Of course, you can decline and instead remain as a
23contributor, participating as you do now.
24
25A. This personal invitation is a chance for you to
26accept or decline in private.  Either way, please
27let us know in reply to the private@hugegraph.apache.org
28address only.
29
30B. If you accept, the next step is to register an iCLA:
31    1. Details of the iCLA and the forms are found
32    through this link: https://www.apache.org/licenses/#clas
33
34    2. Instructions for its completion and return to
35    the Secretary of the ASF are found at
36    https://www.apache.org/licenses/#submitting
37
38    3. When you transmit the completed iCLA, request
39    to notify the Apache HugeGraph project and choose a
40    unique Apache ID. Look to see if your preferred
41    ID is already taken at
42    https://people.apache.org/committer-index.html
43    This will allow the Secretary to notify the PMC
44    when your iCLA has been recorded.
45
46When recording of your iCLA is noted, you will
47receive a follow-up message with the next steps for
48establishing you as a committer.
49
50With the expectation of your acceptance, welcome!
51
52The Apache HugeGraph PMC

候选人接受邀请 (ACCEPT)

候选人应回复上述邮件 (选择 reply all),表明接受邀请,邮件模板可参考:

 1To: [ Sender's Email ]
 2Cc: private@hugegraph.apache.org
 3Subject: Re: Invitation to become HugeGraph committer: xxx
 4
 5Hello Apache HugeGraph PMC,
 6
 7I accept the invitation.
 8
 9Thanks to the Apache HugeGraph Community for recognizing my work, I
10will continue to actively participate in the work of the Apache
11HugeGraph.
12
13Next, I will follow the instructions to complete the next steps:
14Signing and submitting iCLA and registering Apache ID.
15
16xxx

当然,候选人也可以选择拒绝邀请,这里就没有模板了:)

一旦邀请被接受,候选人需要完成以下事项:

ICLA 签署流程

  1. 下载 ICLA
  2. 打开 PDF 并填写相关内容,均需要全英文填写,建议使用 PDF 工具编辑并署名
    1. Full name: 名字在前,姓氏在后
    2. Public name: 可以不填,默认和 Full name 相同
    3. 勾选 check this box only if you enter names with your family name first
    4. Postal Address: 英文地址,从小地方到大地方的顺序来写,需详细到门牌号
    5. Country: 所在国家英文
    6. E-mail: 邮箱地址,建议与上述邮件中使用的邮箱相同
    7. (optional) preferred Apache id(s): 选择一个 Apache committer 页面不存在的 SVN ID
    8. (optional) notify project:Apache HugeGraph
    9. 签名:务必使用 PDF 工具手写
    10. Date: 格式 xxxx-xx-xx
  3. 签署完之后将 icla.pdf 重命名为 姓名拼音-icla.pdf
  4. 发送下述邮件,并附件引用 姓名拼音-icla.pdf
 1To: secretary@apache.org
 2Subject: ICLA Information
 3
 4Hello everyone:
 5
 6I have accepted the Apache HugeGraph PMC invitation to
 7become a HugeGraph committer, the attachment is my ICLA information.
 8
 9(Optional) My GitHub account is https://github.com/xxx. Thanks!
10
11xxx

更多注意事项可参考 https://github.com/apache/hugegraph/issues/1732

PMC 成员将等待 Apache secretary 团队确认 ICLA 备案,候选人和 PMC 成员将收到以下电子邮件:

1Dear xxx,
2
3This message acknowledges receipt of your ICLA, which has been filed in the Apache Software Foundation records.
4
5Your account (with id xxx) has been requested for you and you should receive email with next steps
6within the next few days (this process can take up to a week).
7
8Please refer to https://www.apache.org/foundation/how-it-works.html#developers
9for more information about roles at Apache.

设置 Apache 账号和开发环境 (CONFIG)

备案完成后,候选人将收到来自 root@apache.org 主题为 Welcome to the Apache Software Foundation 的邮件,此时需按照邮件中的步骤设置 Apache 账号和开发环境:

  1. 重置密码 https://id.apache.org/reset/enter
  2. 配置个人信息 https://whimsy.apache.org/roster/committer/xxx
  3. 关联 GitHub 账号 https://gitbox.apache.org/boxer
    1. 这一步需要配置 GitHub 双重身份验证 (2FA)
  4. 负责提名的 PMC 成员需通过 Roster 页面,将新的 Committer 添加到官方提交者列表中 (重要, 否则仓库权限不生效)
    1. 在这一步后,候选人即新的 Committer 才拥有对 GitHub HugeGraph 仓库的写权限
  5. (可选) 新的 Committer 可以使用 Apache 账号申请免费使用 Jetbrains 的全系列产品

发布公告邮件 (ANNOUNCE)

当候选人完成上述步骤后,候选人将正式成为 HugeGraph 的 Committer,此时需要向 dev@hugegraph.apache.org 发送公告邮件,邮件模板可参考:

 1To: dev@hugegraph.apache.org
 2Subject: [ANNOUNCE] New Committer: xxx
 3
 4Hi everyone, The PMC for Apache HugeGraph has invited xxx to
 5become a Committer and we are pleased to announce that he/she has accepted.
 6
 7xxx is being active in the HugeGraph community & dedicated to ... modules, 
 8and we are glad to see his/her more interactions with the community in the future.
 9
10(Optional) His/Her GitHub account is https://github.com/xxx
11
12Welcome xxx, and please enjoy your community journey~ 
13
14Thanks! 
15
16The Apache HugeGraph PMC

更新治理信息入口

Apache HugeGraph 已于 2026 年 1 月毕业,治理信息不再通过 Incubator clutch 页面维护,而是通过 ASF committee/project 数据维护。

请优先检查:

若信息未自动同步,请按照 ASF 官方流程联系 Apache Community Development 或 ASF Infra 协助处理。

参考

  1. https://community.apache.org/newcommitter.html (ASF 官方文档)
  2. https://infra.apache.org/new-committers-guide.html
  3. https://www.apache.org/dev/pmc.html#newcommitter
  4. https://linkis.apache.org/zh-CN/community/how-to-vote-a-committer-pmc
  5. https://www.apache.org/licenses/contributor-agreements.html#submitting
  6. https://www.apache.org/licenses/cla-faq.html#printer
  7. https://linkis.apache.org/zh-CN/community/how-to-sign-apache-icla
  8. https://github.com/apache/hugegraph/issues/1732 (HugeGraph ICLA related issue)

10 - CHANGELOGS

10.1 - HugeGraph 1.8.0 Release Notes

WIP: This doc is under construction, please wait for the final version (BETA)

运行环境/版本说明

  • Java 运行环境:1.8.0 版 HugeGraph 组件(Server、PD、Store)统一要求 Java 17 运行与源码构建环境(1.7.0 是最后一个支持 Java 11 的版本)。
  • 查询与脚本引擎:图遍历与查询框架升级至 Apache TinkerPop 3.8.1,脚本引擎统一升级至 Groovy 4.0.25。

升级与兼容性重点(Breaking Changes)

1. Gremlin 查询语法重要破坏性变更

  • 移除 has(key, traversal) 重载:Groovy 下旧写法在 HugeGraph 1.8 下会因强类型校验直接抛出 Invalid data type of query value 异常报错(纯 TinkerGraph 下会返回空结果)。简单条件直写谓词 has('age', gt(30)),复杂过滤改用 filter(__.values('age').is(gt(30)))。
  • 移除 store() 与带 Scope 的 aggregate():全局贪心收集统一改用 aggregate('x'),局部/逐对象收集改用 local(__.aggregate('x'))。
  • 无参 none() 更名为 discard():丢弃输入遍历必须使用 discard()(避免与新集合过滤 none(P) 冲突)。
  • by() 缺失属性严检:缺失属性在 order().by() 下直接过滤顶点,在 project().by() 下不再返回该 key,在 path().by() 下直接过滤路径;需保留缺失字段请在 by() 中显式使用 coalesce() 补默认值。
  • choose() 分支语义收敛:多条件重叠仅执行首个匹配分支;无匹配或属性缺失默认原样放行穿透(需过滤请显式加 Pick.none / Pick.unproductive 分支配合 discard())。

完整改写代码对照与全量细则速查表请参阅:HugeGraph 1.8.0 Gremlin 迁移与兼容性指南。

2. 服务端配置与客户端兼容

  • Serializer 类名迁移:conf/gremlin-server.yaml 中序列化器包路径由 org.apache.tinkerpop.gremlin.driver.ser.* 迁移至 org.apache.tinkerpop.gremlin.util.ser.*。
  • HugeGraph Client 1.5.0:服务端提供向后兼容适配,1.5.0 客户端常规 CRUD 与 Schema 操作可正常连通 1.8.0;但 Gremlin 查询因别名缺少 GraphSpace 前缀会执行失败,且鉴权路径变更,需升级客户端或改用 HTTP 接口。
  • 不再默认捆绑 GPL word 分词器:因开源协议合规,默认发行包不再捆绑 GPLv3 的 word-1.3.jar。配置了 search.text_analyzer=word 的图仍受支持, 只需将 word-1.3.jar 放入 Server 的 lib/ 目录即可正常使用;亦可切换为内置的 IK 或 SmartCN(注意切换分词器后需重建已有搜索索引)。

hugegraph

API Changes

  • BREAKING CHANGE: Upgrade TinkerPop to 3.8.1 and require Java 17 runtime
  • BREAKING CHANGE: Shared foundation module migration (hugegraph-struct)

Feature Changes

  • 支持 TinkerPop 3.8 步骤,包括 discard()、mergeV()、mergeE() 以及日期步骤(datetime()、dateAdd()、dateDiff())
  • Adapt HugeSecurityManager and Groovy 4.0.25 on Java 17
  • Improve count query visibility inside uncommitted transactions

10.2 - HugeGraph 1.7.0 Release Notes

WIP: This doc is under construction, please wait for the final version (BETA)

运行环境/版本说明

1.7.0版 hugegraph 相关组件仅支持 Java 11 编译/运行环境

hugegraph

API Changes

  • BREAKING CHANGE: Disable legacy backends include MySQL/PG/c*(.etc) #2746
  • BREAKING CHANGE: Release version 1.7.0 [server + pd + store] #2889

Feature Changes

  • Support MemoryManagement for graph query framework #2649
  • LoginAPI support token_expire field #2754
  • Add option for task role election #2843
  • Optimize perf by avoid boxing long #2861
  • StringId hold bytes to avoid decode/encode #2862
  • Add PerfExample5 and PerfExample6 #2860
  • RocksDBStore remove redundant checkOpened() call #2863
  • Add path filter #2898
  • Init serena memory system & add memories #2902

Bug Fixes

  • Filter dynamice path(PUT/GET/DELETE) with params cause OOM #2569
  • JRaft Histogram Metrics Value NaN #2631
  • Update server image desc #2702
  • Kneigbor-api has unmatched edge type with server #2699
  • Add license for swagger-ui & reset use stage to false in ci yml #2706
  • Fix build pd-store arm image #2744
  • Fix graph server cache notifier mechanism #2729
  • Tx leak when stopping the graph server #2791
  • Ensure backend is initialized in gremlin script #2824
  • Fix some potential lock & type cast issues #2895
  • Fix npe in getVersion #2897
  • Fix the support for graphsapi in rocksdb and add testing for graphsapi #2900
  • Remove graph path in auth api path #2899
  • Migrate to LTS jdk11 in all Dockerfile #2901
  • Remove the judgment for java8 compatibility in the init-store #2905
  • Add missing license and remove binary license.txt & fix tinkerpop ci & remove duplicate module #2910

Option Changes

  • Remove some outdated configuration #2678

Other Changes

  • Update outdated docs for release 1.5.0 #2690
  • Fix licenses and remove empty files #2692
  • Update repo artifacts references #2695
  • Adjust release fury version #2698
  • Fix the JSON license issue #2697
  • Add debug info for tp test #2688
  • Enhance words in README #2734
  • Add collaborators in asf config #2741
  • Adjust the related filters of sofa-bolt #2735
  • Reopen discussion in .asf.yml config #2751
  • Fix typo in README #2806
  • Centralize version management in project #2797
  • Update notice year #2826
  • Improve maven Reproducible Builds → upgrade plugins #2874
  • Enhance docker instruction with auth opened graph #2881
  • Remove the package existing in java8 #2792
  • Revise Docker usage instructions in README #2882
  • Add DeepWiki badge to README #2883
  • Update guidance for store module #2894
  • Update test commands and improve documentation clarity #2893
  • Bump rocksdb version from 7.2.2 to 8.10.2 #2896

hugegraph-toolchain

API Changes

  • Support graphspace #633

Feature Changes

  • Support jdbc date type & sync .editorconfig #648
  • Add a useSSL option for mysql #650
  • Patch for father sub edge #654
  • Improve user experience for user script #666
  • Support concurrent readers, short-id & Graphsrc #683
  • Init serena onboarding & project memory files #692

Bug Fixes

  • Typo word in display #655
  • Patch up missing classes and methods for hubble #657
  • Adjust Client to 1.7.0 server #689
  • Remove json license for release 1.7.0 #698

Other Changes

  • Update hugegraph source commit id #640
  • Add collaborators in asf config #656
  • Update pom for version-1.7.0 #681
  • Add DeepWiki badge to README #684
  • Adjust APIs to compatible with 1.7.0 server #685
  • Adjust LoadContext to 1.7.0 version #687
  • Migrate to LTS jdk11 in all Dockerfile #691
  • Update copyright year in NOTICE file #697

hugegraph-computer

Feature Changes

  • Migration Vermeer to hugegraph-computer #316
  • Make startChan’s size configurable #328
  • Assign WorkerGroup via worker configuration #332
  • Support task priority based scheduling #336
  • Avoid 800k #340

Bug Fixes

  • Fix docker file build #341

Other Changes

  • Update release version to 1.5.0 #318
  • Update go depends module & fix headers #321
  • Update go version to 1.23 #322
  • Add collaborator in .asf.yaml #323
  • Update the Go version in docker image #333
  • Add DeepWiki badge to README #337
  • Bump project version to 1.7.0 (RELEASE) #338
  • Update copyright year in NOTICE file #342

hugegraph-ai

API Changes

  • Support choose template in api #135
  • Add post method for paths-api #162
  • Support switch graph in api & add some query configs #184
  • Text2gremlin api #258
  • Support switching prompt EN/CN #269
  • BREAKING CHANGE: Update keyword extraction method #282

Feature Changes

  • Added the process of text2gql in graphrag V1.0 #105
  • Use pydantic-settings for config management #122
  • Timely execute vid embedding & enhance some HTTP logic #141
  • Use retry from tenacity #143
  • Modify the summary info and enhance the request logic #147
  • Automatic backup graph data timely #151
  • Add a button to backup data & count together #153
  • Extract topk_per_keyword & topk_return_results to .env #154
  • Modify clear buttons #156
  • Support intent recognition V1 #159
  • Change vid embedding x:yy to yy & use multi-thread #158
  • Support mathjax in rag query block V1 #157
  • Use poetry to manage the dependencies #149
  • Return schema.groovy first when backup graph data #161
  • Merge all logs into one file #171
  • Use uv for the CI action #175
  • Use EN prompt for keywords extraction #174
  • Support litellm LLM provider #178
  • Improve graph extraction default prompt #187
  • Replace vid by full vertexes info #189
  • Support asynchronous streaming generation in rag block by using async_generator and asyncio.wait #190
  • Generalize the regex extraction func #194
  • Create quick_start.md #196
  • Support Docker & K8s deployment way #195
  • Multi-stage building in Dockerfile #199
  • Support graph checking before updating vid embedding #205
  • Disable text2gql by default #216
  • Use 4.1-mini and 0.01 temperature by default #214
  • Enhance the multi configs for LLM #212
  • Textbox to Code #217
  • Replace the IP + Port with URL #209
  • Update gradio’s version #235
  • Use asyncio to get embeddings #215
  • Change QPS -> RPM for timer decorator #241
  • Support batch embedding #238
  • Using nuitka to provide a binary/perf way for the service #242
  • Use uv instead poetry #226
  • Basic compatible in text2gremlin generation #261
  • Enhance config path handling and add project root validation #262
  • Add vermeer python client for graph computing #263
  • Use uv in client & ml modules & adapter the CI #257
  • Use uv to manage pkgs & update README #272
  • Limit the deps version to handle critical init problems #279
  • Support semi-automated prompt generation #281
  • Support semi-automated generated graph schema #274
  • Unify all modules with uv #287
  • Add GitHub Actions for auto upstream sync and update SEALData subsample logic #289
  • Add a basic LLM/AI coding instruction file #290
  • Add rules for AI coding guideline - V1.0 #293
  • Replace QianFan by OpenAI-compatible format #285
  • Optimize vector index with asyncio embedding #264
  • Refactor embedding parallelization to preserve order #295
  • Support storing vector data for a graph instance by model type/name #265
  • Add AGENTS.md as new document standard #299
  • Add Fixed Workflow Execution Engine: Flow, Node, and Scheduler Architecture #302
  • Support vector db layer V1.0 #304

Bug Fixes

  • Limit the length of log & improve the format #121
  • Pylint in ml #125
  • Critical bug with pylint usage #131
  • Multi vid k-neighbor query only return the data of first vid #132
  • Replace getenv usage to settings #133
  • Correct header writing errors #140
  • Update prompt to fit prefix cache #137
  • Extract_graph_data use wrong method #145
  • Use empty str for llm config #155
  • Update gremlin generate prompt to apply fuzzy match #163
  • Enable fastapi auto reload function #164
  • Fix tiny bugs & optimize reranker layout #202
  • Enable tasks concurrency configs in Gradio #188
  • Align regex extraction of json to json format of prompt #211
  • Fix documentation sample code error #219
  • Failed to remove vectors when updating vid embedding #243
  • Skip empty chunk in LLM steaming mode #245
  • Ollama batch embedding bug #250
  • Fix Dockerfile to add pyproject.toml anchor file #266
  • Add missing ‘properties’ in gremlin prompt formatting #298
  • Fixed cgraph version #305
  • Ollama embedding API usage and config param #306

Option Changes

  • Remove enable_gql logic in api & rag block #148

Other Changes

  • Update README for python-client/SDK #150
  • Enable pip cache #142
  • Enable discussion & change merge way #201
  • Synchronization with official documentation #273
  • Fix grammar errors #275
  • Improve README clarity and deployment instructions #276
  • Add docker-compose deployment and improve container networking instructions #280
  • Update docker compose command #283
  • Reduce third-party library log output #244
  • Update README with improved setup instructions #294
  • Add collaborators in asf config #182

发布细节

Please check the release details/contributor in each repository:

10.3 - HugeGraph 1.5.0 Release Notes

WIP: This doc is under construction, please wait for the final version (BETA)

运行环境/版本说明

  1. 1.5.0版开始, hugegraph 相关组件仅支持 Java 11 编译/运行环境

PS: 未来 HugeGraph 组件的版本会朝着 Java 11 -> Java 17 -> Java 21 演进

hugegraph

本版本新增了大量功能并进行了多项优化,尤其是针对自控分布式版本新后端 HStore (Raft + RocksDB) 的实现支持,欢迎试用反馈

API Changes

  • BREAKING CHANGE: Support “parent & child” EdgeLabel type #2662

Feature Changes

  • Integrate pd-grpc, pd-common, and pd-client #2498
  • Integrate store-grpc, store-common, and store-client #2476
  • Integrate store-rocksdb submodule #2513
  • Integrate pd-core into HugeGraph #2478
  • Integrate pd-service into HugeGraph #2528
  • Integrate pd-dist into HugeGraph and add core tests, client tests, and REST tests for PD #2532
  • Integrate server-hstore into HugeGraph #2534
  • Integrate store-core submodule #2548
  • Integrate store-node submodule #2537
  • Support new backend Hstore #2560
  • Support Docker deployment for PD and Store #2573
  • Add a tool method encode #2647
  • Add basic MiniCluster module for distributed system testing #2615
  • Support disabling RocksDB auto-compaction via configuration #2586

Bug Fixes

  • Switch RocksDB backend to memory when executing Gremlin examples #2518
  • Avoid overriding backend config in Gremlin example scripts #2519
  • Update resource references #2522
  • Randomly generate default values #2568
  • Update build artifact path for Docker deployment #2590
  • Ensure thread safety for range attributes in PD #2641
  • Correct server Docker copy source path #2637
  • Fix JRaft Timer Metrics bug in Hstore #2602
  • Enable JRaft MaxBodySize configuration #2633

Option Changes

  • Mark old raft configs as deprecated #2661
  • Enlarge bytes write limit and remove big parameter when encoding/decoding string ID length #2622

Other Changes

  • Add Swagger-UI LICENSE files #2495
  • Translate CJK comments and punctuations to English across multiple modules #2536, #2623, #2645
  • Introduce install-dist module in root #2552
  • Enable up-to-date checks for UI (CI) #2609
  • Minor improvements for POM properties #2574
  • Migrate HugeGraph Commons #2628
  • Tar source and binary packages for HugeGraph with PD-Store #2594
  • Refactor: Enhance cache invalidation of the partition → leader shard in ClientCache #2588
  • Refactor: Remove redundant properties in LogMeta and PartitionMeta #2598

hugegraph-toolchain

API Changes

  • Support “parent & child” EdgeLabel type #624

Feature Changes

  • Support English interface & add a script/doc for it in Hubble #631

Bug Fixes

  • Serialize source and target label for non-father EdgeLabel #628
  • Encode/decode Chinese error after building Hubble package #627
  • Configure IPv4 to fix timeout of yarn install in Hubble #636
  • Remove debugging output to speed up the frontend construction in Hubble #638

Other Changes

  • Bump express from 4.18.2 to 4.19.2 in Hubble Frontend #598
  • Make IDEA support IssueNavigationLink #600
  • Update yarn.lock for Hubble #605
  • Introduce editorconfig-maven-plugin for verifying code style defined in .editorconfig #614
  • Upgrade distribution version to 1.5.0 #639

Documentation Changes

  • Clarify the contributing guidelines #604
  • Enhance the README file for Hubble #613
  • Update README style referring to the server’s style #615

hugegraph-ai

API Changes

  • Added local LLM API and version API. #41, #44
  • Implemented new API and optimized code structure. #63
  • Support for graphspace and refactored all APIs. #67

Feature Changes

  • Added openai’s apibase configuration and asynchronous methods in RAG web demo. #41, #58
  • Support for multi reranker and enhanced UI. #73
  • Node embedding, node classify, and graph classify with models based on DGL. #83
  • Graph learning algorithm implementation (10+). #102
  • Support for any openai-style API (standard). #95

Bug Fixes

  • Fixed fusiform_similarity test in traverser for server 1.3.0. #37
  • Avoid generating config twice and corrected e_cache type. #56, #117
  • Fixed null value detection on vid attributes. #115
  • Handled profile regenerate error. #98

Option Changes

  • Added auth for fastapi and gradio. #70
  • Support for multiple property types and importing graph from the entire doc. #84

Other Changes

  • Reformatted documentation and updated README. #36, #81
  • Introduced a black for code format in GitHub actions. #47
  • Updated dependencies and environment preparations. #45, #65
  • Enhanced user-friendly README. #82

hugegraph-computer

Feature Changes

  • Support Single Source Shortest Path Algorithm #285
  • Support Output Filter #303

Bug Fixes

  • Fix: base-ref/head-ref Missed in Dependency-Review on Schedule Push #304

Option Changes

  • Refactor(core): StringEncoding #300

Other Changes

  • Improve(algorithm): Random Walk Vertex Inactive #301
  • Upgrade Version to 1.3.0 #305
  • Doc(readme): Clarify the Contributing Guidelines #306
  • Doc(readme): Add Hyperlink to Apache 2.0 #308
  • Migrate Project to Computer Directory #310
  • Update for Release 1.5 #317
  • Fix Path When Exporting Source Package #319

发布细节

Please check the release details/contributor in each repository:

10.4 - HugeGraph 1.3.0 Release Notes

运行环境/版本说明

  1. 优先在 hugegraph/toolchain/commons软件中使用 Java 11, 此次是这些模块最后一次主版本兼容 Java 8 了。(computer 则仅支持 Java11)
  2. 另外相比 Java11, 使用 Java8 会失去一些安全性的保障,我们推荐生产或对外网暴露访问的环境使用 Java11 并开启 Auth 权限认证

1.3.0 是最后兼容 Java 8 的版本,在 1.5.0 开始就会全面使用 Java 11 (除client外).

PS: 未来 HugeGraph 组件的版本会朝着 Java 11 -> Java 17 -> Java 21 演进

hugegraph

在此次版本中我们修复了一些 SEC 相关的问题,如果是线上或者对外服务请升级到最新版本 + 开启权限认证

API Changes

  • feat(api): optimize adjacent-edges query (#2408)

Feature Changes

  • feat: support docker use the auth when starting (#2403)
  • feat: added the OpenTelemetry trace support (#2477)

Bug Fix

  • fix(core): task restore interrupt problem on restart server (#2401)
  • fix(server): reinitialize the progress to set up graph auth friendly (#2411)
  • fix(chore): remove zgc in dockerfile for ARM env (#2421)
  • fix(server): make CacheManager constructor private to satisfy the singleton pattern (#2432)
  • fix(server): unify the license headers (#2438)
  • fix: format and clean code in dist and example modules (#2441)
  • fix: format and clean code in core module (#2440)
  • fix: format and clean code in modules (#2439)
  • fix(server): clean up the code (#2456)
  • fix(server): remove extra blank lines (#2459)
  • fix(server): add tip for gremlin api NPE with an empty query (#2467)
  • fix(server): fix the metric name when promthus collects hugegraph metric, see issue (#2462)
  • fix(server): serverStarted error when execute gremlin example (#2473)
  • fix(auth): enhance the URL check (#2422)

Option Changes

  • refact(server): enhance the storage path in RocksDB & clean code (#2491)

Other Changes

  • chore: add a license link (#2398)
  • doc: enhance NOTICE info to keep it clear (#2409)
  • chore(server): update swagger info for default server profile (#2423)
  • fix(server): unify license header for protobuf file (#2448)
  • chore: improve license header checker confs and pre-check header when validating (#2445)
  • chore: unify to call SchemaLabel.getLabelId() (#2458)
  • chore: refine the hg-style.xml specification (#2457)
  • chore: Add a newline formatting configuration and a comment for warning (#2464)
  • chore(server): clear context after req done (#2470)

hugegraph-toolchain

API Changes

Feature Changes

  • fix(loader): update shade plugin for spark loader (#566)
  • fix(hubble): yarn install timeout in arm64 (#583)
  • fix(loader): support file name with prefix for hdfs source (#571)
  • feat(hubble): warp the exception info in HugeClientUtil (#589)

Bug Fix

  • fix: concurrency issue causing file overwrite due to identical filenames (#572)

Option Changes

  • feat(client): support user defined OKHTTPClient configs (#590)

Other Changes

  • doc: update copyright date(year) in NOTICE (#567)
  • chore(deps): bump ip from 1.1.5 to 1.1.9 in /hugegraph-hubble/hubble-fe (#580)
  • refactor(hubble): enhance maven front plugin (#568)
  • chore(deps): bump es5-ext from 0.10.53 to 0.10.63 in /hugegraph-hubble/hubble-fe (#582)
  • chore(hubble): Enhance code style in hubble (#592)
  • chore: upgrade version to 1.3.0 (#596)
  • chore(ci): update profile commit id for 1.3 (#597)

hugegraph-commons

Feature Changes

  • feat: support user defined RestClientConfig/HTTPClient params (#140)

Bug Fix

Other Changes

  • chore: disable clean flatten for deploy (#141)

hugegraph-ai

这是 hugegraph-ai 的第一个发布版本,包含了多种特性,其中包括初始化的 Python 客户端、通过 LLM 构建知识图谱的能力, 以及基于 HugeGraph 的 RAG(Retrieval-Augmented Generation)集成。此外,该版本还在 python 客户端方面增加了重要的功能, 如变量 API、认证(auth)、度量(metric)、遍历器(traverser)和任务 API,以及使用 Gradio 创建交互式和可视化的演示。

除了这些新功能外,该版本还解决了多个错误和问题,确保了更加稳定和无误的用户体验。维护任务,如依赖更新、项目结构改进以及基本持续集成(CI)的添加, 进一步增强了项目的健壮性和开发工作流程。

这个版本的发布凝聚了 HugeGraph 社区的协作努力,感谢各位贡献者的付出。

Feature Changes

  • feat: initialize hugegraph python client (#5)
  • feat(llm): knowledge graph construction by llm (#7)
  • feat: initialize rag based on HugeGraph (#20)
  • feat(client): add variables api and test (#24)
  • feat: add llm wenxinyiyan & config util & spo_triple_extract (#27)
  • feat: add auth&metric&traverser&task api and ut (#28)
  • feat: refactor construct knowledge graph task (#29)
  • feat: Introduce gradio for creating interactive and visual demo (#30)

Bug Fix

  • fix: invalid GitHub label (#3)
  • fix: import error (#13)
  • fix: function getEdgeByPage(): the generated query url does not include the parameter page (#15)
  • fix: issue template (#23)
  • fix: base-ref/head-ref missed in dependency-check-ci on branch push (#25)

Other Changes

  • chore: add asf.yaml and ISSUE_TEMPLATE (#1)
  • Bump urllib3 from 2.0.3 to 2.0.7 in /hugegraph-python (#8)
  • chore: create .gitignore file for py (#9)
  • refact: improve project structure & add some basic CI (#17)
  • chore: Update LICENSE and NOTICE (#31)
  • chore: add release scripts (#33)
  • chore: change file chmod 755 (#34)

发布细节

Please check the release details/contributor in each repository:

10.5 - HugeGraph 1.2.0 Release Notes

Java version statement

In the future, we will gradually upgrade the java version, Java 11 -> Java 17 -> Java 21.

  1. Consider using Java 11 in hugegraph/hugegraph-toolchain/hugegraph-commons, also compatible with Java 8 now.
  2. hugegraph-computer required to use Java 11, not compatible with Java 8 now!

v1.2.0 是倒数第二个兼容 Java8 的大版本, 到 1.5.0 PD/Store 正式合入 master 后标志着 Java8 兼容的正式终结 (除 Client 外所有组件都将以 Java 11 作为基准,然后逐步迈向 Java17/21).

hugegraph

API Changes

  • feat(api&core): in oltp apis, add statistics info and support full info about vertices and edges (#2262)
  • feat(api): support embedded arthas agent in hugegraph-server (#2278,#2337)
  • feat(api): support metric API Prometheus format & add statistic metric api (#2286)
  • feat(api-core): support label & property filtering for both edge and vertex & support kout dfs mode (#2295)
  • feat(api): support recording slow query log (#2327)

Feature Changes

  • feat: support task auto manage by server role state machine (#2130)
  • feat: support parallel compress snapshot (#2136)
  • feat: use an enhanced CypherAPI to refactor it (#2143)
  • feat(perf): support JMH benchmark in HG-test module (#2238)
  • feat: optimising adjacency edge queries (#2242)
  • Feat: IP white list (#2299)
  • feat(cassandra): adapt cassandra from 3.11.12 to 4.0.10 (#2300)
  • feat: support Cassandra with docker-compose in server (#2307)
  • feat(core): support batch+parallel edges traverse (#2312)
  • feat: adapt Dockerfile for new project structur (#2344)
  • feat(server):swagger support auth for standardAuth mode by (#2360)
  • feat(core): add IntMapByDynamicHash V1 implement (#2377)

Bug Fix

  • fix: transfer add_peer/remove_peer command to leader (#2112)
  • fix query dirty edges of a vertex with cache (#2166)
  • fix exception of vertex-drop with index (#2181)
  • fix: remove dup ‘From’ in filterExpiredResultFromFromBackend (#2207)
  • fix: jdbc ssl mode parameter redundant (#2224)
  • fix: error when start gremlin-console with sample script (#2231)
  • fix(core): support order by id (#2233)
  • fix: update ssl_mode value (#2235)
  • fix: optimizing ClassNotFoundException error message for MYSQL (#2246)
  • fix: asf invalid notification scheme ‘discussions_status’ (#2247)
  • fix: asf invalid notification scheme ‘discussions_comment’ (#2250)
  • fix: incorrect use of ‘NO_LIMIT’ variable (#2253)
  • fix(core): close flat mapper iterator after usage (#2281)
  • fix(dist): avoid var PRELOAD cover environmnet vars (#2302)
  • fix: base-ref/head-ref missed in dependency-review on master (#2308)
  • fix(core): handle schema Cache expandCapacity concurrent problem (#2332)
  • fix: in wait-storage.sh, always wait for storage with default rocksdb (#2333)
  • fix(api): refactor/downgrade record logic for slow log (#2347)
  • fix(api): clean some code for release (#2348)
  • fix: remove redirect-to-master from synchronous Gremlin API (#2356)
  • fix HBase PrefixFilter bug (#2364)
  • chore: fix curl failed to request https urls (#2378)
  • fix(api): correct the vertex id in the edge-existence api (#2380)
  • fix: github action build docker image failed during the release 1.2 process (#2386)
  • fix: TinkerPop unit test lack some lables (#2387)

Option Changes

  • feat(dist): support pre-load test graph data in docker container (#2241)

Other Changes

  • refact: use standard UTF-8 charset & enhance CI configs (#2095)
  • move validate release to hugegraph-doc (#2109)
  • refact: use a slim way to build docker image on latest code & support zgc (#2118)
  • chore: remove stage-repo in pom due to release done & update mail rule (#2128)
  • doc: update issue template & README file (#2131)
  • chore: cmn algorithm optimization (#2134)
  • add github token for license check comment (#2139)
  • chore: disable PR up-to-date in branch (#2150)
  • refact(core): remove lock of globalMasterInfo to optimize perf (#2151)
  • chore: async remove left index shouldn’t effect query (#2199)
  • refact(rocksdb): clean & reformat some code (#2200)
  • refact(core): optimized batch removal of remaining indices consumed by a single consumer (#2203)
  • add com.janeluo.ikkanalyzer dependency to core model (#2206)
  • refact(core): early stop unnecessary loops in edge cache (#2211)
  • doc: update README & add QR code (#2218)
  • chore: update .asf.yaml for mail rule (#2221)
  • chore: improve the UI & content in README (#2227)
  • chore: add pr template (#2234)
  • doc: modify ASF and remove meaningless CLA (#2237)
  • chore(dist): replace wget to curl to download swagger-ui (#2277)
  • Update StandardStateMachineCallback.java (#2290)
  • doc: update README about start server with example graph (#2315)
  • README.md tiny improve (#2320)
  • doc: README.md tiny improve (#2331)
  • refact: adjust project structure for merge PD & Store[Breaking Change] (#2338)
  • chore: disable raft test in normal PR due to timeout problem (#2349)
  • chore(ci): add stage profile settings (#2361)
  • refact(api): update common 1.2 & fix jersey client code problem (#2365)
  • chore: move server info into GlobalMasterInfo (#2370)
  • chore: reset hugegraph version to 1.2.0 (#2382)

hugegraph-computer

Feature Changes

  • feat: implement fast-failover for MessageRecvManager and DataClientManager (#243)
  • feat: implement parallel send data in load graph step (#248)
  • feat(k8s): init operator project & add webhook (#259, #263)
  • feat(core): support load vertex/edge snapshot (#269)
  • feat(k8s): Add MinIO as internal(default) storage (#272)
  • feat(algorithm): support random walk in computer (#274, #280)
  • feat: use ‘foreground’ delete policy to cancel k8s job (#290)

Bug Fix

  • fix: superstep not take effect (#237)
  • fix(k8s): modify inconsistent apiGroups (#270)
  • fix(algorithm): record loop is not copied (#276)
  • refact(core): adaptor for common 1.2 & fix a string of possible CI problem (#286)
  • fix: remove okhttp1 due to conflicts risk (#294)
  • fix(core): io.grpc.grpc-core dependency conflic (#296)

Option Changes

  • feat(core): isolate namespace for different input data source (#252)
  • refact(core): support auth config for computer task (#265)

Other Changes

  • remove apache stage repo & update notification rule (#232)
  • chore: fix empty license file (#233)
  • chore: enhance mailbox settings & enable require ci (#235)
  • fix: typo errors in start-computer.sh (#238)
  • [Feature-241] Add PULL_REQUEST_TEMPLATE (#242, #257)
  • chore: change etcd url only for ci (#245)
  • doc: update readme & add QR code (#249)
  • doc(k8s): add building note for missing classes (#254)
  • chore: reduce mail to dev list (#255)
  • add: dependency-review (#266)
  • chore: correct incorrect comment (#268)
  • refactor(api): ListValue.getFirst() replaces ListValue.get(0) (#282)
  • Improve: Passing workerId to WorkerStat & Skip wait worker close if master executes failed (#292)
  • chore: add check dependencies (#293)
  • chore(license): update license for 1.2.0 (#299)

hugegraph-toolchain

API Changes

  • feat(client): support edgeExistence api (#544)
  • refact(client): update tests for new OLTP traverser APIs (#550)

Feature Changes

  • feat(spark): support spark-sink connector for loader (#497)
  • feat(loader): support kafka as datasource (#506)
  • feat(client): support go client for hugegraph (#514)
  • feat(loader): support docker for loader (#530)
  • feat: update common version and remove jersey code (#538)

Bug Fix

  • fix: convert numbers to strings (#465)
  • fix: hugegraph-spark-loader shell string length limit (#469)
  • fix: spark loader meet Exception: Class is not registered (#470)
  • fix: spark loader Task not serializable (#471)
  • fix: spark with loader has dependency conflicts (#480)
  • fix: spark-loader example schema and struct mismatch (#504)
  • fix(loader): error log (#499)
  • fix: checkstyle && add suppressions.xml (#500)
  • fix(loader): resolve error in loader script (#510)
  • fix: base-ref/head-ref missed in dependency-check-ci on branch push (#516, #551)
  • fix yarn network connection on linux/arm64 arch (#519)
  • fix(hubble): drop-down box could not display all options (#535)
  • fix(hubble): build with node and yarn (#543)
  • fix(loader): loader options (#548)
  • fix(hubble): parent override children dep version (#549)
  • fix: exclude okhttp1 which has different groupID with okhttp3 (#555)
  • fix: github action build docker image failed (#556, #557)
  • fix: build error with npm not exist & tiny improve (#558)

Option Changes

  • set default data when create graph (#447)

Other Changes

  • chore: remove apache stage repo & update mail rule (#433, #474, #479)
  • refact: clean extra store file in all modules (#434)
  • chore: use fixed node.js version 16 to avoid ci problem (#437, #441)
  • chore(hubble): use latest code in Dockerfile (#440)
  • chore: remove maven plugin for docker build (#443)
  • chore: improve spark parallel (#450)
  • doc: fix build status badge link (#455)
  • chore: keep hadoop-hdfs-client and hadoop-common version consistent (#457)
  • doc: add basic contact info & QR code in README (#462, #475)
  • chore: disable PR up-to-date in branch (#473)
  • chore: auto add pr auto label by path (#466, #528)
  • chore: unify the dependencies versions of the entire project (#478)
  • chore(deps): bump async, semver, word-wrap, browserify-sign in hubble-fe (#484, #491, #494, #529)
  • chore: add pr template (#498)
  • doc(hubble): add docker-compose to start with server (#522)
  • chore(ci): add stage profile settings (#536)
  • chore(client): increase the api num as the latest server commit + 10 (#546)
  • chore(spark): install hugegraph from source (#552)
  • doc: adjust docker related desc in readme (#559)
  • chore(license): update license for 1.2 (#560, #561)

hugegraph-commons

Feature Changes

  • feat(common): replace jersey dependencies with OkHttp (Breaking Change) (#133)

Bug Fix

  • fix(common): handle spring-boot2/jersey dependency conflicts (#131)
  • fix: Assert.assertThrows() should check result of exceptionConsumer (#135)
  • fix(common): json param convert (#137)

Other Changes

  • refact(common): add more construction methods for convenient (#132)
  • add: dependency-review (#134)
  • refact(common): rename jsonutil to avoid conflicts with server (#136)
  • doc: update README for release (#138)
  • update licence (#139)

Release Details

Please check the release details in each repository:

10.6 - HugeGraph 1.0.0 Release Notes

OLTP API & Client 更新

API/Client 接口更新

  • 支持热更新trace开关的 /exception/trace API。
  • 支持 Cypher 图查询语言 API。
  • 支持通过 Swagger UI 接口来查看提供的 API 列表。
  • 将各算法中 ’limit’ 参数的类型由 long 调整为 int。
  • 支持在 Client 端跳过 Server 对 HBase 写入数据 (Beta)。

Core & Server

功能更新

  • 支持 Java 11 版本。
  • 支持 2 个新的 OLTP 算法:adamic-adar 和 resource-allocation。
  • 支持 HBase 后端使用哈希 RowKey,并且允许预初始化 HBase 表。
  • 支持 Cypher 图查询语言。
  • 支持集群 Master 角色的自动管理与故障转移。
  • 支持 16 个 OLAP 算法,包括:LPA, Louvain, PageRank, BetweennessCentrality, RingsDetect 等。
  • 根据 Apache 基金会对项目的发版要求进行适配,包括 License 合规性、发版流程、代码风格等,支持 Apache 版本发布。

Bug 修复

  • 修复无法根据多个 Label 和属性来查询边数据。
  • 增加对环路检测算法的最大深度限制。
  • 修复 tree() 语句返回结果异常问题。
  • 修复批量更新边传入 Id 时的检查异常问题。
  • 解决非预期的 Task 状态问题。
  • 解决在更新顶点时未清除边缓存的问题。
  • 修复 MySQL 后端执行 g.V() 时的错误。
  • 修复因为 server-info 无法超时导致的问题。
  • 导出了 ConditionP 类型用于 Gremlin 中用户使用。
  • 修复 within + Text.contains 查询问题。
  • 修复 addIndexLabel/removeIndexLabel 接口的竞争条件问题。
  • 限制仅 Admin 允许输出图实例。
  • 修复 Profile API 的检查问题。
  • 修复在 count().is(0) 查询中 Empty Graph 的问题。
  • 修复在异常时无法关闭服务的问题。
  • 修复在 Apple M1 系统上的 JNA 报错 UnsatisfiedLinkError 的问题。
  • 修复启动 RpcServer 时报 NPE 的问题。
  • 修复 ACTION_CLEARED 参数数量的问题。
  • 修复 RpcServer 服务启动问题。
  • 修复用户传入参数可能得数字转换隐患问题。
  • 移除了 Word 分词器依赖。
  • 修复 Cassandra 与 MySQL 后端在异常时未优雅关闭迭代器的问题。

配置项更新

  • 将配置项 raft.endpoint 从 Graph 作用域移动到 Server 作用域中。

其它修改

  • refact(core): enhance schema job module.
  • refact(raft): improve raft module & test & install snapshot and add peer.
  • refact(core): remove early cycle detection & limit max depth.
  • cache: fix assert node.next==empty.
  • fix apache license conflicts: jnr-posix and jboss-logging.
  • chore: add logo in README & remove outdated log4j version.
  • refact(core): improve CachedGraphTransaction perf.
  • chore: update CI config & support ci robot & add codeQL SEC-check & graph option.
  • refact: ignore security check api & fix some bugs & clean code.
  • doc: enhance CONTRIBUTING.md & README.md.
  • refact: add checkstyle plugin & clean/format the code.
  • refact(core): improve decode string empty bytes & avoid array-construct columns in BackendEntry.
  • refact(cassandra): translate ipv4 to ipv6 metrics & update cassandra dependency version.
  • chore: use .asf.yaml for apache workflow & replace APPLICATION_JSON with TEXT_PLAIN.
  • feat: add system schema store.
  • refact(rocksdb): update rocksdb version to 6.22 & improve rocksdb code.
  • refact: update mysql scope to test & clean protobuf style/configs.
  • chore: upgrade Dockerfile server to 0.12.0 & add editorconfig & improve ci.
  • chore: upgrade grpc version.
  • feat: support updateIfPresent/updateIfAbsent operation.
  • chore: modify abnormal logs & upgrade netty-all to 4.1.44.
  • refact: upgrade dependencies & adopt new analyzer & clean code.
  • chore: improve .gitignore & update ci configs & add RAT/flatten plugin.
  • chore(license): add dependencies-check ci & 3rd-party dependency licenses.
  • refact: Shutdown log when shutdown process & fix tx leak & enhance the file path.
  • refact: rename package to apache & dependency in all modules (Breaking Change).
  • chore: add license checker & update antrun plugin & fix building problem in windows.
  • feat: support one-step script for apache release v1.0.0 release.

Computer (OLAP)

Algorithm Changes

  • 支持 PageRank 算法。
  • 支持 WCC 算法。
  • 支持 degree centrality 算法。
  • 支持 triangle count 算法。
  • 支持 rings detection 算法。
  • 支持 LPA 算法。
  • 支持 k-core 算法。
  • 支持 closeness centrality 算法。
  • 支持 betweenness centrality 算法。
  • 支持 cluster coefficient 算法。

Platform Changes

  • feat: init module computer-core & computer-algorithm & etcd dependency.
  • feat: add Id as base type of vertex id.
  • feat: init Vertex/Edge/Properties & JsonStructGraphOutput.
  • feat: load data from hugegraph server.
  • feat: init basic combiner, Bsp4Worker, Bsp4Master.
  • feat: init sort & transport interface & basic FileInput/Output Stream.
  • feat: init computation & ComputerOutput/Driver interface.
  • feat: init Partitioner and HashPartitioner
  • feat: init Master/WorkerService module.
  • feat: init Heap/LoserTree sorting.
  • feat: init rpc module.
  • feat: init transport server, client, en/decode, flowControl, heartbeat.
  • feat: init DataDirManager & PointerCombiner.
  • feat: init aggregator module & add copy() and assign() methods to Value class.
  • feat: add startAsync and finishAsync on client side, add onStarted and onFinished on server side.
  • feat: init store/sort module.
  • feat: link managers in worker sending end.
  • feat: implement data receiver of worker.
  • feat: implement StreamGraphInput and EntryInput.
  • feat: add Sender and Receiver to process compute message.
  • feat: add seqfile fromat.
  • feat: add ComputeManager.
  • feat: add computer-k8s and computer-k8s-operator.
  • feat: add startup and make docker image code.
  • feat: sort different type of message use different combiner.
  • feat: add HDFS output format.
  • feat: mount config-map and secret to container.
  • feat: support java11.
  • feat: support partition concurrent compute.
  • refact: abstract computer-api from computer-core.
  • refact: optimize data receiving.
  • fix: release file descriptor after input and compute.
  • doc: add operator deploy readme.
  • feat: prepare for Apache release.

Toolchain (loader, tools, hubble)

  • 支持 Loader 使用 SQL 格式来选取从关系数据库导入哪些数据。
  • 支持 Loader 从 Spark 导入数据(包括 JDBC 方式)。
  • 支持 Loader 增加 Flink-CDC 模式。
  • 解决 Loader 导入 ORC 格式数据时,报错 NPE。
  • 解决 Loader 在 Spark/Flink 模式时未缓存 Schema 的问题。
  • 解决 Loader 的 Json 反序列化问题。
  • 解决 Loader 的 Jackson 版本冲突与依赖问题。
  • 支持 Hubble 高级算法接口的 UI 界面。
  • 支持 Hubble 中 Gremlin 语句的高亮格式显示。
  • 支持 Hubble 使用 Docker 镜像部署。
  • 支持 输出构建日志。
  • 解决 Hubble 的端口输入框问题。
  • 支持 Apache 项目发版的适配。

Commons (common,rpc)

  • 支持 assert-throws 方法返回 Future。
  • 增加 Cnm 与 Anm 方法到 CollectionUtil 中。
  • 支持 用户自定义的 content-type。
  • 支持 Apache 项目发版的适配。

Release Details

更加详细的版本变更信息,可以查看各个子仓库的链接:

10.7 - HugeGraph 0.12 Release Notes

API & Client

接口更新

  • 支持 https + auth 模式连接图服务(hugegraph-client #109 #110)
  • 统一 kout/kneighbor 等 OLTP 接口的参数命名及默认值(hugegraph-client #122 #123)
  • 支持 RESTful 接口利用 P.textcontains() 进行属性全文检索(hugegraph #1312)
  • 增加 graph_read_mode API 接口,以切换 OLTP、OLAP 读模式(hugegraph #1332)
  • 支持 list/set 类型的聚合属性 aggregate property(hugegraph #1332)
  • 权限接口增加 METRICS 资源类型(hugegraph #1355、hugegraph-client #114)
  • 权限接口增加 SCHEMA 资源类型(hugegraph #1362、hugegraph-client #117)
  • 增加手动 compact API 接口,支持 rocksdb/cassandra/hbase 后端(hugegraph #1378)
  • 权限接口增加 login/logout API,支持颁发或回收 Token(hugegraph #1500、hugegraph-client #125)
  • 权限接口增加 project API(hugegraph #1504、hugegraph-client #127)
  • 增加 OLAP 回写接口,支持 cassandra/rocksdb 后端(hugegraph #1506、hugegraph-client #129)
  • 增加返回一个图的所有 Schema 的 API 接口(hugegraph #1567、hugegraph-client #134)
  • 变更 property key 创建与更新 API 的 HTTP 返回码为 202(hugegraph #1584)
  • 增强 Text.contains() 支持 3 种格式:“word”、"(word)"、"(word1|word2|word3)"(hugegraph #1652)
  • 统一了属性中特殊字符的行为(hugegraph #1670 #1684)
  • 支持动态创建图实例、克隆图实例、删除图实例(hugegraph-client #135)

其它修改

  • 修复在恢复 index label 时 IndexLabelV56 id 丢失的问题(hugegraph-client #118)
  • 为 Edge 类增加 name() 方法(hugegraph-client #121)

Core & Server

功能更新

  • 支持动态创建图实例(hugegraph #1065)
  • 支持通过 Gremlin 调用 OLTP 算法(hugegraph #1289)
  • 支持多集群使用同一个图权限服务,以共享权限信息(hugegraph #1350)
  • 支持跨多节点的 Cache 缓存同步(hugegraph #1357)
  • 支持 OLTP 算法使用原生集合以降低 GC 压力提升性能(hugegraph #1409)
  • 支持对新增的 Raft 节点打快照或恢复快照(hugegraph #1439)
  • 支持对集合属性建立二级索引 Secondary Index(hugegraph #1474)
  • 支持审计日志,及其压缩、限速等功能(hugegraph #1492 #1493)
  • 支持 OLTP 算法使用高性能并行无锁原生集合以提升性能(hugegraph #1552)

BUG 修复

  • 修复带权最短路径算法(weighted shortest path)NPE 问题(hugegraph #1250)
  • 增加 Raft 相关的安全操作白名单(hugegraph #1257)
  • 修复 RocksDB 实例未正确关闭的问题(hugegraph #1264)
  • 在清空数据 truncate 操作之后,显示的发起写快照 Raft Snapshot(hugegraph #1275)
  • 修复 Raft Leader 在收到 Follower 转发请求时未更新缓存的问题(hugegraph #1279)
  • 修复带权最短路径算法(weighted shortest path)结果不稳定的问题(hugegraph #1280)
  • 修复 rays 算法 limit 参数不生效问题(hugegraph #1284)
  • 修复 neighborrank 算法 capacity 参数未检查的问题(hugegraph #1290)
  • 修复 PostgreSQL 因为不存在与用户同名的数据库而初始化失败的问题(hugegraph #1293)
  • 修复 HBase 后端当启用 Kerberos 时初始化失败的问题(hugegraph #1294)
  • 修复 HBase/RocksDB 后端 shard 结束判断错误问题(hugegraph #1306)
  • 修复带权最短路径算法(weighted shortest path)未检查目标顶点存在的问题(hugegraph #1307)
  • 修复 personalrank/neighborrank 算法中非 String 类型 id 的问题(hugegraph #1310)
  • 检查必须是 master 节点才允许调度 gremlin job(hugegraph #1314)
  • 修复 g.V().hasLabel().limit(n) 因为索引覆盖导致的部分结果不准确问题(hugegraph #1316)
  • 修复 jaccardsimilarity 算法当并集为空时报 NaN 错误的问题(hugegraph #1324)
  • 修复 Raft Follower 节点操作 Schema 多节点之间数据不同步问题(hugegraph #1325)
  • 修复因为 tx 未关闭导致的 TTL 不生效问题(hugegraph #1330)
  • 修复 gremlin job 的执行结果大于 Cassandra 限制但小于任务限制时的异常处理(hugegraph #1334)
  • 检查权限接口 auth-delete 和 role-get API 操作时图必须存在(hugegraph #1338)
  • 修复异步任务结果中包含 path/tree 时系列化不正常的问题(hugegraph #1351)
  • 修复初始化 admin 用户时的 NPE 问题(hugegraph #1360)
  • 修复异步任务原子性操作问题,确保 update/get fields 及 re-schedule 的原子性(hugegraph #1361)
  • 修复权限 NONE 资源类型的问题(hugegraph #1362)
  • 修复启用权限后,truncate 操作报错 SecurityException 及管理员信息丢失问题(hugegraph #1365)
  • 修复启用权限后,解析数据忽略了权限异常的问题(hugegraph #1380)
  • 修复 AuthManager 在初始化时会尝试连接其它节点的问题(hugegraph #1381)
  • 修复特定的 shard 信息导致 base64 解码错误的问题(hugegraph #1383)
  • 修复启用权限后,使用 consistent-hash LB 在校验权限时,creator 为空的问题(hugegraph #1385)
  • 改进权限中 VAR 资源不再依赖于 VERTEX 资源(hugegraph #1386)
  • 规范启用权限后,Schema 操作仅依赖具体的资源(hugegraph #1387)
  • 规范启用权限后,部分操作由依赖 STATUS 资源改为依赖 ANY 资源(hugegraph #1391)
  • 规范启用权限后,禁止初始化管理员密码为空(hugegraph #1400)
  • 检查创建用户时 username/password 不允许为空(hugegraph #1402)
  • 修复更新 Label 时,PrimaryKey 或 SortKey 被设置为可空属性的问题(hugegraph #1406)
  • 修复 ScyllaDB 丢失分页结果问题(hugegraph #1407)
  • 修复带权最短路径算法(weighted shortest path)权重属性强制转换为 double 的问题(hugegraph #1432)
  • 统一 OLTP 算法中的 degree 参数命名(hugegraph #1433)
  • 修复 fusiformsimilarity 算法当 similars 为空的时候返回所有的顶点问题(hugegraph #1434)
  • 改进 paths 算法,当起始点与目标点相同时应该返回空路径(hugegraph #1435)
  • 修改 kout/kneighbor 的 limit 参数默认值 10 为 10000000(hugegraph #1436)
  • 修复分页信息中的 ‘+’ 被 URL 编码为空格的问题(hugegraph #1437)
  • 改进边更新接口的错误提示信息(hugegraph #1443)
  • 修复 kout 算法 degree 未在所有 label 范围生效的问题(hugegraph #1459)
  • 改进 kneighbor/kout 算法,起始点不允许出现在结果集中(hugegraph #1459 #1463)
  • 统一 kout/kneighbor 的 Get 和 Post 版本行为(hugegraph #1470)
  • 改进创建边时顶点类型不匹配的错误提示信息(hugegraph #1477)
  • 修复 Range Index 的残留索引问题(hugegraph #1498)
  • 修复权限操作未失效缓存的问题(hugegraph #1528)
  • 修复 sameneighbor 的 limit 参数默认值 10 为 10000000(hugegraph #1530)
  • 修复 clear API 不应该所有后端都调用 create snapshot 的问题(hugegraph #1532)
  • 修复当 loading 模式时创建 Index Label 阻塞问题(hugegraph #1548)
  • 修复增加图到 project 或从 project 移除图的问题(hugegraph #1562)
  • 改进权限操作的一些错误提示信息(hugegraph #1563)
  • 支持浮点属性设置为 Infinity/NaN 的值(hugegraph #1578)
  • 修复 Raft 启用 safe_read 时的 quorum read 问题(hugegraph #1618)
  • 修复 token 过期时间配置的单位问题(hugegraph #1625)
  • 修复 MySQL Statement 资源泄露问题(hugegraph #1627)
  • 修复竞争条件下 Schema.getIndexLabel 获取不到数据的问题(hugegraph #1629)
  • 修复 HugeVertex4Insert 无法系列化问题(hugegraph #1630)
  • 修复 MySQL count Statement 未关闭问题(hugegraph #1640)
  • 修复当删除 Index Label 异常时,导致状态不同步问题(hugegraph #1642)
  • 修复 MySQL 执行 gremlin timeout 导致的 statement 未关闭问题(hugegraph #1643)
  • 改进 Search Index 以兼容特殊 Unicode 字符:\u0000 to \u0003(hugegraph #1659)
  • 修复 #1659 引入的 Char 未转化为 String 的问题(hugegraph #1664)
  • 修复 has() + within() 查询时结果异常问题(hugegraph #1680)
  • 升级 Log4j 版本到 2.17 以修复安全漏洞(hugegraph #1686 #1698 #1702)
  • 修复 HBase 后端 shard scan 中 startkey 包含空串时 NPE 问题(hugegraph #1691)
  • 修复 paths 算法在深层环路遍历时性能下降问题(hugegraph #1694)
  • 改进 personalrank 算法的参数默认值及错误检查(hugegraph #1695)
  • 修复 RESTful 接口 P.within 条件不生效问题(hugegraph #1704)
  • 修复启用权限时无法动态创建图的问题(hugegraph #1708)

配置项修改:

  • 共享 SSL 相关配置项命名(hugegraph #1260)
  • 支持 RocksDB 配置项 rocksdb.level_compaction_dynamic_level_bytes(hugegraph #1262)
  • 去除 RESFful Server 服务协议配置项 restserver.protocol,自动提取 URL 中的 Schema(hugegraph #1272)
  • 增加 PostgreSQL 配置项 jdbc.postgresql.connect_database(hugegraph #1293)
  • 增加针对顶点主键是否编码的配置项 vertex.encode_primary_key_number(hugegraph #1323)
  • 增加针对聚合查询是否启用索引优化的配置项 query.optimize_aggregate_by_index(hugegraph #1549)
  • 修改 cache_type 的默认值 l1 为 l2(hugegraph #1681)
  • 增加 JDBC 强制重连配置项 jdbc.forced_auto_reconnect(hugegraph #1710)

其它修改

  • 增加默认的 SSL Certificate 文件(hugegraph #1254)
  • OLTP 并行请求共享线程池,而非每个请求使用单独的线程池(hugegraph #1258)
  • 修复 Example 的问题(hugegraph #1308)
  • 使用 jraft 版本 1.3.5(hugegraph #1313)
  • 如果启用了 Raft 模式时,关闭 RocksDB 的 WAL(hugegraph #1318)
  • 使用 TarLz4Util 来提升快照 Snapshot 压缩的性能(hugegraph #1336)
  • 升级存储的版本号(store version),因为 property key 增加了 read frequency(hugegraph #1341)
  • 顶点/边 vertex/edge 的 Get API 使用 queryVertex/queryEdge 方法来替代 iterator 方法(hugegraph #1345)
  • 支持 BFS 优化的多度查询(hugegraph #1359)
  • 改进 RocksDB deleteRange() 带来的查询性能问题(hugegraph #1375)
  • 修复 travis-ci cannot find symbol Namifiable 问题(hugegraph #1376)
  • 确保 RocksDB 快照的磁盘与 data path 指定的一致(hugegraph #1392)
  • 修复 MacOS 空闲内存 free_memory 计算不准确问题(hugegraph #1396)
  • 增加 Raft onBusy 回调来配合限速(hugegraph #1401)
  • 升级 netty-all 版本 4.1.13.Final 到 4.1.42.Final(hugegraph #1403)
  • 支持 TaskScheduler 暂停当设置为 loading 模式时(hugegraph #1414)
  • 修复 raft-tools 脚本的问题(hugegraph #1416)
  • 修复 license params 问题(hugegraph #1420)
  • 提升写权限日志的性能,通过 batch flush & async write 方式改进(hugegraph #1448)
  • 增加 MySQL 连接 URL 的日志记录(hugegraph #1451)
  • 提升用户信息校验性能(hugegraph# 1460)
  • 修复 TTL 因为起始时间问题导致的错误(hugegraph #1478)
  • 支持日志配置的热加载及对审计日志的压缩(hugegraph #1492)
  • 支持针对用户级别的审计日志的限速(hugegraph #1493)
  • 缓存 RamCache 支持用户自定义的过期时间(hugegraph #1494)
  • 在 auth client 端缓存 login role 以避免重复的 RPC 调用(hugegraph #1507)
  • 修复 IdSet.contains() 未复写 AbstractCollection.contains() 问题(hugegraph #1511)
  • 修复当 commitPartOfEdgeDeletions() 失败时,未回滚 rollback 的问题(hugegraph #1513)
  • 提升 Cache metrics 性能(hugegraph #1515)
  • 当发生 license 操作错误时,增加打印异常日志(hugegraph #1522)
  • 改进 SimilarsMap 实现(hugegraph #1523)
  • 使用 tokenless 方式来更新 coverage(hugegraph #1529)
  • 改进 project update 接口的代码(hugegraph #1537)
  • 允许从 option() 访问 GRAPH_STORE(hugegraph #1546)
  • 优化 kout/kneighbor 的 count 查询以避免拷贝集合(hugegraph #1550)
  • 优化 shortestpath 遍历方式,以数据量少的一端优先遍历(hugegraph #1569)
  • 完善 rocksdb.data_disks 配置项的 allowed keys 提示信息(hugegraph #1585)
  • 为 number id 优化 OLTP 遍历中的 id2code 方法性能(hugegraph #1623)
  • 优化 HugeElement.getProperties() 返回 Collection<Property>(hugegraph #1624)
  • 增加 APACHE PROPOSAL 文件(hugegraph #1644)
  • 改进 close tx 的流程(hugegraph #1655)
  • 当 reset() 时为 MySQL close 捕获所有类型异常(hugegraph #1661)
  • 改进 OLAP property 模块代码(hugegraph #1675)
  • 改进查询模块的执行性能(hugegraph #1711)

Loader

  • 支持导入 Parquet 格式文件(hugegraph-loader #174)
  • 支持 HDFS Kerberos 权限验证(hugegraph-loader #176)
  • 支持 HTTPS 协议连接到服务端导入数据(hugegraph-loader #183)
  • 修复 trust store file 路径问题(hugegraph-loader #186)
  • 处理 loading mode 重置的异常(hugegraph-loader #187)
  • 增加在插入数据时对非空属性的检查(hugegraph-loader #190)
  • 修复客户端与服务端时区不同导致的时间判断问题(hugegraph-loader #192)
  • 优化数据解析性能(hugegraph-loader #194)
  • 当用户指定了文件头时,检查其必须不为空(hugegraph-loader #195)
  • 修复示例程序中 MySQL struct.json 格式问题(hugegraph-loader #198)
  • 修复顶点边导入速度不精确的问题(hugegraph-loader #200 #205)
  • 当导入启用 check-vertex 时,确保先导入顶点再导入边(hugegraph-loader #206)
  • 修复边 Json 数据导入格式不统一时数组溢出的问题(hugegraph-loader #211)
  • 修复因边 mapping 文件不存在导致的 NPE 问题(hugegraph-loader #213)
  • 修复读取时间可能出现负数的问题(hugegraph-loader #215)
  • 改进目录文件的日志打印(hugegraph-loader #223)
  • 改进 loader 的的 Schema 处理流程(hugegraph-loader #230)

Tools

  • 支持 HTTPS 协议(hugegraph-tools #71)
  • 移除 –protocol 参数,直接从 URL 中自动提取(hugegraph-tools #72)
  • 支持将数据 dump 到 HDFS 文件系统(hugegraph-tools #73)
  • 修复 trust store file 路径问题(hugegraph-tools #75)
  • 支持权限信息的备份恢复(hugegraph-tools #76)
  • 支持无参数的 Printer 打印(hugegraph-tools #79)
  • 修复 MacOS free_memory 计算问题(hugegraph-tools #82)
  • 支持备份恢复时指定线程数 hugegraph-tools #83)
  • 支持动态创建图、克隆图、删除图等命令(hugegraph-tools #95)

11 - Apache 贡献者协议

Apache 贡献者协议

HugeGraph 使用 Apache Software Foundation(ASF)的标准贡献者协议,不再使用项目自定义的 CLA 或 GitHub CLA Assistant 流程。

普通的小型贡献按 Apache License 2.0 第 5 条提交。成为 committer 前,或提交较大贡献时,需要签署 ASF Individual Contributor License Agreement(ICLA)。如果贡献的知识产权属于公司,还可能需要 Corporate Contributor License Agreement(CCLA);CCLA 不能替代个人 ICLA。

协议正文、填写要求和提交方式以 ASF 官方页面为准:

请阅读协议后按官方要求签名,并将完整文件作为附件单独发送至 secretary@apache.org。不要把协议发送到 HugeGraph 开发者邮件列表,也不要提交到 GitHub 仓库。