跳转到主要内容

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

返回本页常规视图.

使用指南

本节说明 HugeGraph 的架构、设计、备份恢复、插件开发、安全设置和常见问题。

1 - HugeGraph Architecture Overview

1 概述

作为一套覆盖图数据库、图计算与图 AI 的全栈图系统,HugeGraph 以高性能图引擎(HugeGraph Server)为核心,支持 OLTP 和 OLAP 两种图计算类型。其中 OLTP 层实现了 Apache TinkerPop3 框架,支持 GremlinCypher 查询语言,拥有功能齐全的应用工具链,还提供了插件式后端存储驱动框架。

下面是 HugeGraph 的整体架构图:

image

HugeGraph 包括三个层次的功能,分别是应用程序层、图引擎层和存储层。

  • 应用程序层:
    • Hubble: 一站式可视化分析平台,平台涵盖了从数据建模,到数据快速导入,再到数据的在线、离线分析、以及图的统一管理的全过程,实现了图应用的全流程向导式操作。
    • Loader: 数据导入组件,能够将多种数据源的数据转化为图的顶点和边并批量导入到图数据库中。
    • Tools: 命令行工具,用于部署、管理和备份/恢复 HugeGraph 中的数据。
    • Computer: 分布式图处理系统 (OLAP),它是 Pregel 的一个实现,可以运行在 Kubernetes 上。
    • Client:客户端 SDK 封装了 HugeGraph Server 的连接、Schema 管理、图数据读写和查询等核心操作。目前支持 JavaPythonGo 版本,Rust 客户端正在开发中。
  • 图引擎层
    • REST Server: 提供 RESTful API 用于查询 Graph/Schema 等信息,支持 GremlinCypher 查询语言,提供服务监控和运维的 APIs。
    • Graph Engine: 支持 OLTP 和 OLAP 两种图计算类型,其中 OLTP 实现了 Apache TinkerPop3 框架。
    • Backend Interface: 实现将图数据存储到后端。
  • 存储层:
    • Storage Backend: 1.7.0 支持 RocksDB、HStore、HBase 和 Memory。自定义后端可通过插件扩展。

2 - HugeGraph Design Concepts

1. Property Graph

常见的图数据表示模型有两种,分别是RDF(Resource Description Framework)模型和属性图(Property Graph)模型。 RDF和Property Graph都是最基础、最有名的图表示模式,都能够表示各种图的实体关系建模。 RDF是W3C标准,而Property Graph是工业标准,受到广大图数据库厂商的广泛支持。HugeGraph目前采用Property Graph。

HugeGraph对应的存储概念模型也是参考Property Graph而设计的,具体示例详见下图:(此图为旧版设计已过时,请忽略它,后续更新

image

在HugeGraph内部,每个顶点 / 边由唯一的 VertexId / EdgeId 标识,属性存储在对应点 / 边内部。而顶点与顶点之间的关系 / 映射则是通过边来存储的。

顶点属性值通过边指针方式存储时,如果要更新一个顶点特定的属性值直接通过覆盖写入即可,其弊端是冗余存储了VertexId; 如果要更新关系的属性需要通过read-and-modify方式,先读取所有属性,修改部分属性,然后再写入存储系统,更新效率较低。 从经验来看顶点属性的修改需求较多,而边的属性修改需求较少,例如PageRank和Graph Cluster等计算都需要频繁修改顶点的属性值。

2. 图分区方案

对于分布式图数据库而言,图的分区存储方式有两种:分别是边分割存储(Edge Cut)和点分割存储(Vertex Cut),如下图所示。 使用Edge Cut方式存储图时,任何一个顶点只会出现在一台机器上,而边可能分布在不同机器上,这种存储方式有可能导致边多次存储。 使用Vertex Cut方式存储图时,任何一条边只会出现在一台机器上,而每相同的一个点可能分布到不同机器上,这种存储方式可能会导致顶点多次存储。

image

采用EdgeCut分区方案可以支持高性能的插入和更新操作,而VertexCut分区方案更适合静态图查询分析,因此EdgeCut适合OLTP图查询,VertexCut更适合OLAP的图查询。 HugeGraph目前采用EdgeCut的分区方案。

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策略
schema.vertexLabel("person")
     .useAutomaticId()
     .properties("name", "age", "city")
     .create();
graph.addVertex(T.label, "person","name", "marko", "age", 18, "city", "Beijing");
  1. PRIMARY_KEY ID策略
schema.vertexLabel("person")
     .usePrimaryKeyId()
     .properties("name", "age", "city")
     .primaryKeys("name", "age")
     .create();
graph.addVertex(T.label, "person","name", "marko", "age", 18, "city", "Beijing");
  1. CUSTOMIZE_STRING ID策略
schema.vertexLabel("person")
     .useCustomizeStringId()
     .properties("name", "age", "city")
     .create();
graph.addVertex(T.label, "person", T.id, "123456", "name", "marko","age", 18, "city", "Beijing");
  1. CUSTOMIZE_NUMBER ID策略
schema.vertexLabel("person")
     .useCustomizeNumberId()
     .properties("name", "age", "city")
     .create();
graph.addVertex(T.label, "person", T.id, 123456, "name", "marko","age", 18, "city", "Beijing");
  1. CUSTOMIZE_UUID ID策略
schema.vertexLabel("person")
     .useCustomizeUuidId()
     .properties("name", "age", "city")
     .create();
graph.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 策略

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 transaction overview

TinkerPop事务概述

TinkerPop transaction事务是指对数据库执行操作的工作单元,一个事务内的一组操作要么执行成功,要么全部失败。 详细介绍请参考TinkerPop官方文档:http://tinkerpop.apache.org/docs/current/reference/#transactions

TinkerPop事务操作接口
  • open 打开事务
  • commit 提交事务
  • rollback 回滚事务
  • close 关闭事务
TinkerPop事务规范
  • 事务必须显式提交后才可生效(未提交时修改操作只有本事务内查询可看到)
  • 事务必须打开之后才可提交或回滚
  • 如果事务设置自动打开则无需显式打开(默认方式),如果设置手动打开则必须显式打开
  • 可设置事务关闭时:自动提交、自动回滚(默认方式)、手动(禁止显式关闭)等3种模式
  • 事务在提交或回滚后必须是关闭状态
  • 事务在查询后必须是打开状态
  • 事务(非threaded tx)必须线程隔离,多线程操作同一事务互不影响

更多事务规范用例见:Transaction Test

HugeGraph事务实现
  • 一个事务中所有的操作要么成功要么失败
  • 一个事务只能读取到另外一个事务已提交的内容(Read committed)
  • 所有未提交的操作均能在本事务中查询出来,包括:
    • 增加顶点能够查询出该顶点
    • 删除顶点能够过滤掉该顶点
    • 删除顶点能够过滤掉该顶点相关边
    • 增加边能够查询出该边
    • 删除边能够过滤掉该边
    • 增加/修改(顶点、边)属性能够在查询时生效
    • 删除(顶点、边)属性能够在查询时生效
  • 所有未提交的操作在事务回滚后均失效,包括:
    • 顶点、边的增加、删除
    • 属性的增加/修改、删除

示例:一个事务无法读取另一个事务未提交的内容

    static void testUncommittedTx(final HugeGraph graph) throws InterruptedException {

        final CountDownLatch latchUncommit = new CountDownLatch(1);
        final CountDownLatch latchRollback = new CountDownLatch(1);

        Thread thread = new Thread(() -> {
            // this is a new transaction in the new thread
            graph.tx().open();

            System.out.println("current transaction operations");

            Vertex james = graph.addVertex(T.label, "author",
                                           "id", 1, "name", "James Gosling",
                                           "age", 62, "lived", "Canadian");
            Vertex java = graph.addVertex(T.label, "language", "name", "java",
                                          "versions", Arrays.asList(6, 7, 8));
            james.addEdge("created", java);

            // we can query the uncommitted records in the current transaction
            System.out.println("current transaction assert");
            assert graph.vertices().hasNext() == true;
            assert graph.edges().hasNext() == true;

            latchUncommit.countDown();

            try {
                latchRollback.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println("current transaction rollback");
            graph.tx().rollback();
        });

        thread.start();

        // query none result in other transaction when not commit()
        latchUncommit.await();
        System.out.println("other transaction assert for uncommitted");
        assert !graph.vertices().hasNext();
        assert !graph.edges().hasNext();

        latchRollback.countDown();
        thread.join();

        // query none result in other transaction after rollback()
        System.out.println("other transaction assert for rollback");
        assert !graph.vertices().hasNext();
        assert !graph.edges().hasNext();
    }
事务实现原理
  • 服务端内部通过将事务与线程绑定实现隔离(ThreadLocal)
  • 本事务未提交的内容按照时间顺序覆盖老数据以供本事务查询最新版本数据
  • 底层依赖后端数据库保证事务原子性操作(如RocksDB的batch接口保证原子性)
注意

RESTful API暂时未暴露事务接口

TinkerPop API允许打开事务,请求完成时会自动关闭(Gremlin Server强制关闭)

3 - HugeGraph Plugin 机制及插件扩展流程

背景

  1. HugeGraph 不仅开源开放,而且要做到简单易用,一般用户无需更改源码也能轻松增加插件扩展功能。
  2. HugeGraph 支持多种内置存储后端,也允许用户无需更改现有源码的情况下扩展自定义后端。
  3. HugeGraph 支持全文检索,全文检索功能涉及到各语言分词,目前已内置 7 种分词器(ansj、hanlp、smartcn、jieba、jcseg、mmseg4j、ikanalyzer),也允许用户无需更改现有源码的情况下扩展自定义分词器。

可扩展维度

目前插件方式提供如下几个维度的扩展项:

  • 后端存储
  • 序列化器
  • 自定义配置项
  • 分词器

插件实现机制

  1. HugeGraph 提供插件接口 HugeGraphPlugin,通过 Java SPI 机制支持插件化
  2. HugeGraph 在 HugeGraphPlugin 接口上以静态方法提供了 4 个扩展项注册函数:registerOptions()registerBackend()registerSerializer()registerAnalyzer()
  3. 插件实现者实现相应的 Options、Backend、Serializer 或 Analyzer 的接口
  4. 插件实现者实现 HugeGraphPlugin 接口的register()方法,在该方法中注册上述第 3 点所列的具体实现类,并打成 jar 包
  5. 插件使用者将 jar 包放在 HugeGraph Server 安装目录的plugins目录下,修改相关配置项为插件自定义值,重启即可生效

插件实现流程实例

1 新建一个 maven 项目

1.1 项目名称取名:hugegraph-plugin-demo
1.2 添加hugegraph-core Jar 包依赖

maven pom.xml 详细内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.hugegraph</groupId>
    <artifactId>hugegraph-plugin-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>hugegraph-plugin-demo</name>

    <dependencies>
        <dependency>
            <groupId>org.apache.hugegraph</groupId>
            <artifactId>hugegraph-core</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
</project>

2 实现扩展功能

2.1 扩展自定义后端
2.1.1 实现接口 BackendStoreProvider
  • 可实现接口:org.apache.hugegraph.backend.store.BackendStoreProvider
  • 或者继承抽象类:org.apache.hugegraph.backend.store.AbstractBackendStoreProvider

以 RocksDB 后端 RocksDBStoreProvider 为例:

public class RocksDBStoreProvider extends AbstractBackendStoreProvider {

    protected String database() {
        return this.graph().toLowerCase();
    }

    @Override
    protected BackendStore newSchemaStore(HugeConfig config, String store) {
        return new RocksDBStore.RocksDBSchemaStore(this, this.database(), store);
    }

    @Override
    protected BackendStore newGraphStore(HugeConfig config, String store) {
        return new RocksDBStore.RocksDBGraphStore(this, this.database(), store);
    }

    @Override
    protected BackendStore newSystemStore(HugeConfig config, String store) {
        return new RocksDBStore.RocksDBSystemStore(this, this.database(), store);
    }

    @Override
    public String type() {
        return "rocksdb";
    }

    @Override
    public String driverVersion() {
        return "1.11";
    }
}
2.1.2 实现接口 BackendStore

BackendStore 接口定义如下:

public interface BackendStore {
    // Store name
    String store();

    // Stored version
    String storedVersion();

    // Database name
    String database();

    // Get the parent provider
    BackendStoreProvider provider();

    // Get the system schema store
    SystemSchemaStore systemSchemaStore();

    // Whether it is the storage of schema
    boolean isSchemaStore();

    // Open/close database
    void open(HugeConfig config);
    void close();
    boolean opened();

    // Initialize/clear database
    void init();
    void clear(boolean clearSpace);
    boolean initialized();

    // Delete all data of database (keep table structure)
    void truncate();

    // Add/delete data
    void mutate(BackendMutation mutation);

    // Query data
    Iterator<BackendEntry> query(Query query);
    Number queryNumber(Query query);

    // Transaction
    void beginTx();
    void commitTx();
    void rollbackTx();

    // Get metadata by key
    <R> R metadata(HugeType type, String meta, Object[] args);

    // Backend features
    BackendFeatures features();

    // Increase next id for specific type
    void increaseCounter(HugeType type, long increment);

    // Get current counter for a specific type
    long getCounter(HugeType type);
}
2.1.3 扩展自定义序列化器

序列化器必须继承抽象类:org.apache.hugegraph.backend.serializer.AbstractSerializer(implements GraphSerializer, SchemaSerializer) 主要接口的定义如下:

public interface GraphSerializer {
    BackendEntry writeVertex(HugeVertex vertex);
    BackendEntry writeOlapVertex(HugeVertex vertex);
    BackendEntry writeVertexProperty(HugeVertexProperty<?> prop);
    HugeVertex readVertex(HugeGraph graph, BackendEntry entry);
    BackendEntry writeEdge(HugeEdge edge);
    BackendEntry writeEdgeProperty(HugeEdgeProperty<?> prop);
    HugeEdge readEdge(HugeGraph graph, BackendEntry entry);
    CIter<Edge> readEdges(HugeGraph graph, BackendEntry bytesEntry);
    BackendEntry writeIndex(HugeIndex index);
    HugeIndex readIndex(HugeGraph graph, ConditionQuery query, BackendEntry entry);
    BackendEntry writeId(HugeType type, Id id);
    Query writeQuery(Query query);
}

public interface SchemaSerializer {
    BackendEntry writeVertexLabel(VertexLabel vertexLabel);
    VertexLabel readVertexLabel(HugeGraph graph, BackendEntry entry);
    BackendEntry writeEdgeLabel(EdgeLabel edgeLabel);
    EdgeLabel readEdgeLabel(HugeGraph graph, BackendEntry entry);
    BackendEntry writePropertyKey(PropertyKey propertyKey);
    PropertyKey readPropertyKey(HugeGraph graph, BackendEntry entry);
    BackendEntry writeIndexLabel(IndexLabel indexLabel);
    IndexLabel readIndexLabel(HugeGraph graph, BackendEntry entry);
}
2.1.4 扩展自定义配置项

增加自定义后端时,可能需要增加新的配置项,实现流程主要包括:

  • 增加配置项容器类,并实现接口org.apache.hugegraph.config.OptionHolder
  • 提供单例方法public static OptionHolder instance(),并在对象初始化时调用方法OptionHolder.registerOptions()
  • 增加配置项声明,单值配置项类型为ConfigOption、多值配置项类型为ConfigListOption

以 RocksDB 配置项定义为例:

public class RocksDBOptions extends OptionHolder {

    private RocksDBOptions() {
        super();
    }

    private static volatile RocksDBOptions instance;

    public static synchronized RocksDBOptions instance() {
        if (instance == null) {
            instance = new RocksDBOptions();
            instance.registerOptions();
        }
        return instance;
    }

    public static final ConfigOption<String> DATA_PATH =
            new ConfigOption<>(
                    "rocksdb.data_path",
                    "The path for storing data of RocksDB.",
                    disallowEmpty(),
                    "rocksdb-data/data"
            );

    public static final ConfigOption<String> WAL_PATH =
            new ConfigOption<>(
                    "rocksdb.wal_path",
                    "The path for storing WAL of RocksDB.",
                    disallowEmpty(),
                    "rocksdb-data/wal"
            );

    public static final ConfigListOption<String> DATA_DISKS =
            new ConfigListOption<>(
                    "rocksdb.data_disks",
                    false,
                    "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]",
                    null,
                    String.class,
                    ImmutableList.of()
            );
}
2.2 扩展自定义分词器

分词器需要实现接口org.apache.hugegraph.analyzer.Analyzer,以实现一个 SpaceAnalyzer 空格分词器为例。

package org.apache.hugegraph.plugin;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.apache.hugegraph.analyzer.Analyzer;

public class SpaceAnalyzer implements Analyzer {

    @Override
    public Set<String> segment(String text) {
        return new HashSet<>(Arrays.asList(text.split(" ")));
    }
}

3. 实现插件接口,并进行注册

插件注册入口为HugeGraphPlugin.register(),自定义插件必须实现该接口方法,在其内部注册上述定义好的扩展项。 接口org.apache.hugegraph.plugin.HugeGraphPlugin定义如下:

public interface HugeGraphPlugin {

    String name();

    void register();

    String supportsMinVersion();

    String supportsMaxVersion();
}

并且 HugeGraphPlugin 提供了 4 个静态方法用于注册扩展项:

  • registerOptions(String name, String classPath):注册配置项
  • registerBackend(String name, String classPath):注册后端(BackendStoreProvider)
  • registerSerializer(String name, String classPath):注册序列化器
  • registerAnalyzer(String name, String classPath):注册分词器

下面以注册 SpaceAnalyzer 分词器为例:

package org.apache.hugegraph.plugin;

public class DemoPlugin implements HugeGraphPlugin {

    @Override
    public String name() {
        return "demo";
    }

    @Override
    public void register() {
        HugeGraphPlugin.registerAnalyzer("demo", SpaceAnalyzer.class.getName());
    }

    @Override
    public String supportsMinVersion() {
        return "1.7.0";
    }

    @Override
    public String supportsMaxVersion() {
        return "1.8.0";
    }
}

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目录,重启服务即可生效。

4 - 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 克隆代码

git clone https://github.com/apache/hugegraph-toolchain.git
cd 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

# 设置 Server 基线;需要可复现结果时请使用完整 commit SHA
export COMMIT_ID="master"

# 执行安装(脚本位于 /assembly/travis/ 目录)
hugegraph-client/assembly/travis/install-hugegraph-from-source.sh $COMMIT_ID
  • 脚本会启动 HTTP 8080 和 HTTPS 8443 两个实例,并配置 admin/pa 认证。
  • 执行前确认两个端口未被占用。

2. 安装可选依赖

# Hadoop (仅 Loader HDFS 测试需要)
hugegraph-loader/assembly/travis/install-hadoop.sh

# MySQL (仅 Loader JDBC 测试需要)
hugegraph-loader/assembly/travis/install-mysql.sh $DB_DATABASE $DB_PASS

3. 健康检查

curl -u admin:pa http://localhost:8080/graphspaces/DEFAULT/graphs
# 返回 {"graphs":["hugegraph"]} 表示成功

3.2 Docker 部署

注意:Docker 镜像可能版本滞后,如遇兼容性问题请使用脚本部署

快速启动

docker network create hugegraph-net
docker run -itd --name=server -p 8080:8080 --network hugegraph-net hugegraph/hugegraph:latest

docker-compose 配置(可选)

完整配置示例,包含 Server、MySQL、Hadoop 服务(需要 Docker Compose V2):

version: '3.8'

services:
  hugegraph-server:
    image: hugegraph/hugegraph:latest  # 可以替换为特定版本,或构建自己的镜像
    container_name: hugegraph-server
    ports:
      - "8080:8080"  # HugeGraph Server HTTP 端口
    environment:
      # 根据需要配置HugeGraph Server的参数,例如后端存储
      - HUGEGRAPH_SERVER_OPTIONS="-Dstore.backend=rocksdb"
    volumes:
      # 如果需要持久化数据或挂载配置文件,可以在这里添加卷
      # - ./hugegraph-data:/opt/hugegraph/data
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/graphspaces/DEFAULT/graphs || exit 1"]
      interval: 5s
      timeout: 3s
      retries: 5
    networks:
      - hugegraph-net
  
  # 如果需要hugegraph-loader的JDBC测试,可以添加以下服务
  #   mysql:
  #     image: mysql:5.7
  #     container_name: mysql-db
  #     environment:
  #       MYSQL_ROOT_PASSWORD: ${DB_PASS:-your_mysql_root_password} # 从环境变量读取,或使用默认值
  #       MYSQL_DATABASE: ${DB_DATABASE:-hugegraph_test_db} # 从环境变量读取,或使用默认值
  #     ports:
  #       - "3306:3306"
  #     volumes:
  #       - ./mysql-data:/var/lib/mysql # 数据持久化
  #     healthcheck:
  #       test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p${DB_PASS:-your_mysql_root_password}"]
  #       interval: 5s
  #       timeout: 3s
  #       retries: 5
  #     networks:
  #       - hugegraph-net

  # 如果需要hugegraph-loader的Hadoop/HDFS测试,可以添加以下服务
  #   namenode:
  #     image: johannestang/hadoop-namenode:2.0.0-hadoop2.8.5-java8
  #     container_name: namenode
  #     ports:
  #       - "0.0.0.0:9870:9870"
  #       - "0.0.0.0:8020:8020"
  #     environment:
  #       - CLUSTER_NAME=test-cluster
  #       - HDFS_NAMENODE_USER=root
  #       - HADOOP_CONF_DIR=/hadoop/etc/hadoop
  #     volumes:
  #       - ./config/core-site.xml:/hadoop/etc/hadoop/core-site.xml
  #       - ./config/hdfs-site.xml:/hadoop/etc/hadoop/hdfs-site.xml
  #       - namenode_data:/hadoop/dfs/name
  #     command: bash -c "if [ ! -d /hadoop/dfs/name/current ]; then hdfs namenode -format; fi && /entrypoint.sh"
  #     healthcheck:
  #       test: ["CMD", "hdfs", "dfsadmin", "-report"]
  #       interval: 5s
  #       timeout: 3s
  #       retries: 5
  #     networks:
  #       - hugegraph-net

  #   datanode:
  #     image: johannestang/hadoop-datanode:2.0.0-hadoop2.8.5-java8
  #     container_name: datanode
  #     depends_on:
  #       - namenode
  #     environment:
  #       - CLUSTER_NAME=test-cluster
  #       - HDFS_DATANODE_USER=root
  #       - HADOOP_CONF_DIR=/hadoop/etc/hadoop
  #     volumes:
  #       - ./config/core-site.xml:/hadoop/etc/hadoop/core-site.xml
  #       - ./config/hdfs-site.xml:/hadoop/etc/hadoop/hdfs-site.xml
  #       - datanode_data:/hadoop/dfs/data
  #     healthcheck:
  #       test: ["CMD", "hdfs", "dfsadmin", "-report"]
  #       interval: 5s
  #       timeout: 3s
  #       retries: 5
  #     networks:
  #       - hugegraph-net

networks:
  hugegraph-net:
    driver: bridge
volumes:
  namenode_data:
  datanode_data:

Hadoop 配置挂载

在与 docker-compose.yml 相同的目录下创建 ./config 文件夹用于挂载 Hadoop 配置文件。如果不需要 HDFS 测试,可以跳过此步骤。

📁 ./config/core-site.xml 内容:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://namenode:8020</value>
    </property>
</configuration>

📁 ./config/hdfs-site.xml 内容:

<configuration>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/hadoop/hdfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/hadoop/hdfs/data</value>
    </property>
    <property>
        <name>dfs.permissions.superusergroup</name>
        <value>hadoop</value>
    </property>
    <property>
        <name>dfs.support.append</name>
        <value>true</value>
    </property>
</configuration>

Docker 操作

# 启动服务
docker compose up -d

# 检查状态
docker compose ps
lsof -i:8080  # Server
lsof -i:8020  # Hadoop
lsof -i:3306  # MySQL

# 停止服务
docker compose down

4. 运行测试

各工具的测试流程:

HugeGraph工具链测试流程图

4.1 hugegraph-client

编译

mvn -e compile -pl hugegraph-client -Dmaven.javadoc.skip=true -ntp

依赖服务

启动 HugeGraph Server(参考 第3节

Server 鉴权配置

ApiTest 需要认证。使用 3.1 节的脚本安装时无需重复配置;自行部署 Server 时,认证配置和测试凭证必须与测试代码一致。

# 1. 修改鉴权模式
cp conf/rest-server.properties conf/rest-server.properties.backup
sed -i 's|#auth.authenticator=.*|auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator|' conf/rest-server.properties
grep auth.authenticator conf/rest-server.properties
sed -i 's|gremlin.graph=org.apache.hugegraph.HugeFactory|gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy|' conf/graphs/hugegraph.properties

# 2. 设置密码
# 注:测试代码中默认使用 "pa" 作为密码,设置时需与测试保持一致
bin/stop-hugegraph.sh
export PASSWORD="pa"  # 设置为测试默认密码
echo -e "${PASSWORD}" | bin/init-store.sh
bin/start-hugegraph.sh

运行测试

# 检查环境
curl -u admin:pa http://localhost:8080/graphspaces/DEFAULT/graphs

# 运行测试
cd hugegraph-client
mvn test -Dtest=UnitTestSuite -ntp      # 单元测试
mvn test -Dtest=ApiTestSuite -ntp       # API测试(需 Server)
mvn test -Dtest=FuncTestSuite -ntp      # 功能测试(需 Server)

测试失败时检查 Server 日志:logs/hugegraph-server.log

4.2 hugegraph-loader

编译

mvn install -pl hugegraph-client,hugegraph-loader -am -Dmaven.javadoc.skip=true -DskipTests -ntp

依赖服务

  • 必需:HugeGraph Server
  • 可选:Hadoop (HDFS 测试)、MySQL (JDBC 测试)

运行测试

cd hugegraph-loader
mvn test -P unit -ntp   # 单元测试
mvn test -P file -ntp   # 文件测试(需 Server)
mvn test -P hdfs -ntp   # HDFS测试(需 Server + Hadoop)
mvn test -P jdbc -ntp   # JDBC测试(需 Server + MySQL)
mvn test -P kafka -ntp  # Kafka测试(需 Server)

4.3 hugegraph-hubble

编译

mvn install -pl hugegraph-client,hugegraph-loader -am -Dmaven.javadoc.skip=true -DskipTests -ntp
cd hugegraph-hubble
mvn -e compile -Dmaven.javadoc.skip=true -ntp

依赖服务

1. 启动 Server(参考 第3节

2. Python 环境

python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
python -m pip install -r hubble-dist/assembly/travis/requirements.txt

3. 构建并验证

mvn package -Dmaven.test.skip=true
# 可选:启动验证
cd apache-hugegraph-hubble*/bin
./start-hubble.sh -d && sleep 10
curl http://localhost:8088/actuator/health
./stop-hubble.sh

运行测试

# 单元测试
mvn test -P unit-test -pl hugegraph-hubble/hubble-be -ntp

# 旧版 Python API 测试(需 Server;脚本会安装并启动 Hubble)
curl -u admin:pa http://localhost:8080/graphspaces/DEFAULT/graphs  # 检查 Server
cd hugegraph-hubble
./hubble-dist/assembly/travis/run-api-test.sh

# 当前 CI 的完整验收入口(需先生成 Hubble tar 包)
HUBBLE_TARBALL="$(ls target/apache-hugegraph-hubble-*.tar.gz | head -n 1)"
hubble-dist/assembly/travis/verify-hubble-issue-694.sh \
  "$HUBBLE_TARBALL" http://127.0.0.1:8080

4.4 hugegraph-spark-connector

编译

mvn install -pl hugegraph-client,hugegraph-spark-connector -am -Dmaven.javadoc.skip=true -DskipTests -ntp

运行测试

cd hugegraph-spark-connector
mvn test -ntp  # 需 Server 运行

4.5 hugegraph-tools

编译

mvn install -pl hugegraph-client,hugegraph-tools -am -Dmaven.javadoc.skip=true -DskipTests -ntp

运行测试

cd hugegraph-tools
mvn test -Dtest=FuncTestSuite -ntp  # 需 Server 运行

5. 常见问题

服务连接问题

无法连接 Server、MySQL 或 Hadoop 时:

  • 确认服务已启动(Server 必须在 8080 端口)
  • 检查端口占用:lsof -i:8080
  • Docker 检查:docker compose psdocker 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. 参考资料

5 - Backup Restore

描述

Backup 和 Restore 是备份图和恢复图的功能。备份和恢复的数据包括元数据(schema)和图数据(vertex 和 edge)。

Backup

将 HugeGraph 系统中的一张图的元数据和图数据以 JSON 格式导出。

Restore

将 Backup 导出的JSON格式的数据,重新导入到 HugeGraph 系统中的一个图中。

Restore 有两种模式:

  • Restoring 模式,将 Backup 导出的元数据和图数据原封不动的恢复到 HugeGraph 系统中。可用于图的备份和恢复,一般目标图是新图(没有元数据和图数据)。比如:
    • 系统升级,先备份图,然后升级系统,最后将图恢复到新的系统中
    • 图迁移,从一个 HugeGraph 系统中,使用 Backup 功能将图导出,然后使用 Restore 功能将图导入另一个 HugeGraph 系统中
  • Merging 模式,将 Backup 导出的元数据和图数据导入到另一个已经存在元数据或者图数据的图中,过程中元数据的 ID 可能发生改变,顶点和边的 ID 也会发生相应变化。
    • 可用于合并图

使用方法

可以使用hugegraph-tools进行图的备份和恢复。

Backup

bin/hugegraph backup -t all -d data

该命令将 http://127.0.0.1:8080(默认 –url)的 hugegraph 图的全部元数据和图数据备份到data目录下。

Backup 在任意图模式下都可以正常工作,它不会检查图模式

Restore

Restore 有两种模式: RESTORING 和 MERGING,恢复之前首先要根据需要设置图模式,图处于其他模式时 restore 命令会失败。

步骤1:查看并设置图模式
bin/hugegraph graph-mode-get

该命令用于查看当前图模式,包括:NONE、RESTORING、MERGING、LOADING。

bin/hugegraph graph-mode-set -m RESTORING

该命令用于设置图模式,Restore 之前可以设置成 RESTORING 或者 MERGING 模式,例子中设置成 RESTORING。

步骤2:Restore 数据
bin/hugegraph restore -t all -d data

该命令将data目录下的全部元数据和图数据重新导入到 http://127.0.0.1:8080 的 hugegraph 图中。

步骤3:恢复图模式
bin/hugegraph graph-mode-set -m NONE

该命令用于恢复图模式为 NONE。

至此,一次完整的图备份和图恢复流程结束。

帮助

备份和恢复命令的详细使用方式可以参考hugegraph-tools文档

Backup/Restore使用和实现的API说明

Backup

Backup 使用元数据图数据的相应的 list(GET) API 导出,并未增加新的 API。

Restore

Restore 使用元数据图数据的相应的 create(POST) API 导入,并未增加新的 API。

Restore 时存在两种不同的模式: Restoring 和 Merging,另外,还有常规模式 NONE(默认),区别如下:

  • None 模式,元数据和图数据的写入属于正常状态,可参见功能说明。特别的:
    • 元数据(schema)创建时不允许指定 ID
    • 图数据(vertex)在 id strategy 为 Automatic 时,不允许指定 ID
  • Restoring 模式,恢复到一个新图中,特别的:
    • 元数据(schema)创建时允许指定 ID
    • 图数据(vertex)在 id strategy 为 Automatic 时,允许指定 ID
  • Merging 模式,合并到一个已存在元数据和图数据的图中,特别的:
    • 元数据(schema)创建时不允许指定 ID
    • 图数据(vertex)在 id strategy 为 Automatic 时,允许指定 ID

正常情况下,图模式为 None,当需要 Restore 图时,需要根据需要临时修改图模式为 Restoring 模式或者 Merging 模式,并在完成 Restore 时,恢复图模式为 None。

实现的设置图模式的 RESTful API 如下:

查看某个图的模式. 该操作需要管理员权限
Method & Url
GET http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/mode
Response Status
200
Response Body
{
    "mode": "NONE"
}

合法的图模式包括:NONE,RESTORING,MERGING,LOADING

设置某个图的模式. 该操作需要管理员权限
Method & Url
PUT http://localhost:8080/graphspaces/DEFAULT/graphs/{graph}/mode
Request Body
"RESTORING"

合法的图模式包括:NONE,RESTORING,MERGING,LOADING

Response Status
200
Response Body
{
    "mode": "RESTORING"
}

6 - 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/pdhugegraph/storehugegraph/server tag。Hubble 由 ${HUBBLE_IMAGE:-hugegraph/hubble:latest} 单独选择。

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

鉴权环境

所有拓扑都从 Compose 环境读取管理员密码和共享 JWT 密钥,通常放在 docker/.env 文件中:

HUGEGRAPH_ADMIN_PASSWORD='replace-with-your-password'
HUGEGRAPH_AUTH_TOKEN_SECRET='<32 字节随机值,例如 openssl rand -hex 32>'

HUGEGRAPH_ADMIN_PASSWORD 非空即开启 Server 鉴权,Hubble 通过 Server API 自动识别该模式。不设置或设为空值则关闭鉴权,这只适用于可信的本地环境。保持同一个 JWT 密钥可以在容器重建后继续使用已签发的 token,多 Server 拓扑中的每个副本都会收到同一个密钥。HA 拓扑设置了 HG_SERVER_REQUIRE_AUTH_TOKEN_SECRET: "true",因此只提供密码而没有共享密钥时会快速失败。请不要提交 .env

HUGEGRAPH_ADMIN_PASSWORD 只在第一次以鉴权模式启动时初始化内置的 admin 账号。之后修改它不会轮换已有密码,请使用用户 API 修改。

单节点快速启动

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

验证:

curl http://localhost:8080/versions
curl http://localhost:8088/about        # Hubble

Hubble 默认只发布在宿主机回环地址(127.0.0.1:8088)。只有在 HTTPS 反向代理和可信网络管控之后才应设置 HUBBLE_PUBLISH_HOST

最小 HStore 快速启动

cd hugegraph/docker
HUGEGRAPH_VERSION=1.7.0 docker compose -f docker-compose-hstore.yml up -d --wait

验证:

curl http://localhost:8620/v1/health    # PD
curl http://localhost:8520/v1/health    # Store
curl http://localhost:8080/versions     # Server
curl http://localhost:8088/about        # Hubble

若要从本地源码构建该拓扑而不是拉取镜像,可加上开发覆盖文件,并在后续所有生命周期命令中同时带上这两个文件:

docker compose -f docker-compose-hstore.yml -f docker-compose.dev.yml up -d --build --wait

3 节点集群快速启动

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

默认内置的启动顺序:

  1. PD (节点)最先启动,且必须通过 /v1/health 健康检查
  2. Store (节点)在所有 PD 健康后再启动
  3. Server (节点)在所有 Store + PD 健康后最后启动

验证集群正常:(重要)

curl http://localhost:8620/v1/health      # PD 健康检查
curl http://localhost:8520/v1/health      # Store 健康检查
curl http://localhost:8080/versions        # Server
curl http://localhost:8620/v1/stores       # 已注册的 Store
curl http://localhost:8620/v1/partitions   # 分区分配

开启鉴权后,图列表接口应拒绝匿名请求并接受管理员:

curl -o /dev/null -w '%{http_code}\n' \
  http://localhost:8080/graphspaces/DEFAULT/graphs                      # 期望 401
curl -o /dev/null -w '%{http_code}\n' -u "admin:${HUGEGRAPH_ADMIN_PASSWORD}" \
  http://localhost:8080/graphspaces/DEFAULT/graphs                      # 期望 200

另外两个 Server 分别在 80818082 上提供服务,其余 PD 和 Store 节点分别在 8621/86228521/8522

环境变量参考

PD 和 Store 的入口脚本会把各自的变量拼成 SPRING_APPLICATION_JSON,并在启动时打印生效值,因此 docker logs 中能看到容器实际解析出的配置。Server 的入口脚本则直接改写 conf/graphs/hugegraph.propertiesconf/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_PORT8686grpc.port
HG_PD_REST_PORT8620server.port
HG_PD_DATA_PATH/hugegraph-pd/pd_datapd.data-path
HG_PD_INITIAL_STORE_COUNT1pd.initial-store-count

已弃用的别名GRPC_HOSTHG_PD_GRPC_HOSTRAFT_ADDRESSHG_PD_RAFT_ADDRESSRAFT_PEERSHG_PD_RAFT_PEERS_LISTPD_INITIAL_STORE_LISTHG_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_PORT8500grpc.port
HG_STORE_REST_PORT8520server.port
HG_STORE_DATA_PATH/hugegraph-store/storageapp.data-path

已弃用的别名PD_ADDRESSHG_STORE_PD_ADDRESSGRPC_HOSTHG_STORE_GRPC_HOSTRAFT_ADDRESSHG_STORE_RAFT_ADDRESS

Server 变量

与 PD、Store 不同,Server 入口脚本没有必填变量:只有实际设置了的变量才会被写入配置文件。但分布式部署至少需要 HG_SERVER_BACKENDHG_SERVER_PD_PEERS

变量默认值映射配置
HG_SERVER_BACKEND模板取值(rocksdb,在 hugegraph/server 镜像中为 hstoreconf/graphs/hugegraph.properties 中的 backend
HG_SERVER_PD_PEERS(无)hugegraph.propertiesrest-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_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_SECRETfalsetrue 时,只设置 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,允许范围为 186400;详见下文的 Server 启动等待超时
STORE_RESTstore:8520wait-partition.sh 轮询的 Store REST 地址,仅 hstore 后端使用
HG_SERVER_PD_REST_ENDPOINTpd.peers:8686 改写为 :8620 得到wait-storage.sh 轮询的 PD REST 地址
PD_AUTH_USER / PD_AUTH_PASSWORDstore / adminwait-storage.sh 访问 PD REST API 使用的凭据
WAIT_PARTITION_TIMEOUT_S120wait-partition.sh 等待分区分配的时长

已弃用的别名BACKENDHG_SERVER_BACKENDPD_PEERSHG_SERVER_PD_PEERS

wait-storage.sh 最多等待 300 秒直到出现状态为 Up 的 Store。该时长写死在脚本中,无法通过环境变量调整。

HG_SERVER_INIT_STORE_ENABLED 只接受 HugeConfig 能识别的写法(忽略大小写):ytyesontruenfnoofffalse。其他取值(包括 01)都会让入口脚本终止。

入口脚本在初始化成功后写入 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(无)HG_SERVER_AUTH_TOKEN_SECRET 传给 Server

端口参考

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

单机拓扑只发布 80808088;最小 HStore 拓扑发布 8620(PD REST)、8520(Store REST)、80808088。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. 分区分配未完成:检查 curl http://localhost:8620/v1/stores,3 个 Store 必须都显示 "state":"Up" 才能完成分区分配

  4. 连接被拒:确保 HG_* 环境变量使用容器主机名(pd0store0),而非 127.0.0.1

  5. 数据在意料之外地保留了下来docker compose down 会保留命名卷。要同时删除该拓扑的数据,请使用 docker compose down -v

查看运行时日志:使用 docker logs <container-name>(如 docker logs hg-pd0)可直接查看日志,无需进入容器。单机镜像 hugegraph/hugegraph 设置了 STDOUT_MODE=true,其服务日志会输出到容器 stdout。hugegraph/server(HStore)镜像没有设置该变量,因此对 HStore 拓扑的 Server 执行 docker logs 只能看到入口脚本的输出,其余内容需在容器内查看 logs/hugegraph-server.log

容器监控与健康检查

版本说明:本节描述的行为不包含在 1.7.0 镜像中。请使用 HUGEGRAPH_VERSION=latest 或等待下一个发布版本。

进程监控模型

此前,三个 Docker 入口脚本均以 tail -f /dev/null 结尾,即使 Java 进程崩溃,容器仍会保持运行状态。由于容器从未退出,Docker 的 restart: unless-stopped 策略也不会触发。

现在,入口脚本直接监控 Java 进程:

  • PD 和 Store 容器:入口脚本向启动脚本传入 -d false 参数,启动脚本通过 exec 直接替换为 Java 进程。容器进程即为 Java 进程,当 Java 退出(崩溃或正常关闭)时,容器立即退出,Docker 的重启策略随即触发。
  • Server 容器:入口脚本使用 tail --pid=$PID -f /dev/null 阻塞,直到 Java 退出。SIGTERM/SIGINT 信号陷阱会将 docker stop 信号转发给 Java 并等待其正常关闭(退出码 0)。若 Java 崩溃,入口脚本以退出码 1 退出,从而触发重启策略。
  • 所有镜像中的 PID 1 均为 dumb-init,负责将 Docker 信号转发给入口脚本进程。

Server 启动等待超时

HG_SERVER_STARTUP_TIMEOUT_S 控制 Server 启动脚本等待 REST 服务响应的时长,未设置时默认 120 秒。取值必须是不带前导零的十进制整数,范围为 1–86400 秒。空字符串、0、负数、小数和超出范围的值都会使入口脚本记录错误并以退出码 1 退出。

入口脚本通过 bin/start-hugegraph.sh -t 传入该值。如果 Server 在等待期限内未就绪,或进程提前退出,启动失败,容器以退出码 1 退出;配置的重启策略可能会重新启动容器。此时长不包括此前的存储初始化或等待后端就绪的时间。

例如,在 HugeGraph 仓库的 docker/ 目录下,将单机 Server 的启动等待时间增加到 300 秒(Compose 文件会将该变量传入容器):

HG_SERVER_STARTUP_TIMEOUT_S=300 HUGEGRAPH_VERSION=latest \
  docker compose -f docker-compose.yml up -d --wait

该设置与 Docker 健康检查的 start_periodintervaltimeoutretries 相互独立。健康检查参数决定何时将容器标记为 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 文件在此之上还定义了自己的健康检查,因此 --waitdepends_on: condition: service_healthy 不依赖镜像内置的检查。Compose 中的检查使用更短的启动期(视服务和拓扑为 30 到 120 秒)和更多的重试次数。

注意start-hugegraph.sh 中的 -m true 标志(基于 cron 的监控)仅适用于虚拟机/裸机部署,Docker 镜像中未安装也不使用该功能。Docker 用户应依赖内置的 HEALTHCHECK 和 Docker 重启策略。

7 - FAQ

  • 如何选择后端存储? 选 RocksDB 还是分布式存储?

    HugeGraph 支持多种部署模式,根据数据规模和场景选择:

    • 单机模式:Server + RocksDB,适合开发测试和中小规模数据(≤ 2 TB)
    • 分布式模式:HugeGraph-PD + HugeGraph-Store(HStore),用于需要水平扩展和多副本的部署,支持 ≤ 1 PB 的数据规模

    1.7.0 支持 RocksDB、HStore、HBase 和 Memory。Cassandra、ScyllaDB、MySQL、PostgreSQL 等旧后端需使用 1.5.x 或更早版本。

  • 启动服务时提示:xxx (core dumped) xxx

    请先确认 JDK 版本不低于 Java 11。HugeGraph 1.7.0 不再支持 Java 8。

  • 启动服务成功了,但是操作图时有类似于"无法连接到后端或连接未打开"的提示

    RocksDB、HBase 等本地持久化后端首次启动前需要使用 init-store 初始化。HStore 由 PD、Store 管理,不执行该脚本。

  • 所有的后端在使用前都需要执行init-store吗,序列化的选择可以随意填写么?

    Memory 和 HStore 不执行 init-store;RocksDB、HBase 等本地持久化后端首次使用前需要初始化。序列化器必须与后端匹配,例如 RocksDB 使用 binary

  • 执行init-store报错:Exception in thread "main" java.lang.UnsatisfiedLinkError: /tmp/librocksdbjni3226083071221514754.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.10' not found (required by /tmp/librocksdbjni3226083071221514754.so)

    RocksDB需要 gcc 4.3.0 (GLIBCXX_3.4.10) 及以上版本

  • bin目录下包含start-hugegraph.shstart-restserver.shstart-gremlinserver.sh三个似乎与启动有关的脚本,到底该使用哪个

    当前发布包只保留 start-hugegraph.sh 作为 Server 启动脚本。GremlinServer 和 REST Server 由同一进程启动。

  • 配置了两个图,名字是hugegraphhugegraph1,而启动服务的命令是start-hugegraph.sh,是只打开了hugegraph这个图吗

    脚本名称与图名无关。需要从 graphs 目录加载多个本地图时,在 rest-server.properties 中设置 graph.load_from_local_config=true;该选项的源码默认值是 false

  • 服务启动成功后,使用curl查询所有顶点时返回乱码

    服务端返回的批量顶点/边是压缩(gzip)过的,可以使用管道重定向至 gunzip 进行解压(curl http://example | gunzip),也可以用Firefoxpostman或者Chrome浏览器的restlet插件发请求,会自动解压缩响应数据。

  • 使用顶点Id通过RESTful API查询顶点时返回空,但是顶点确实是存在的

    检查顶点Id的类型,如果是字符串类型,APIurl中的id部分需要加上双引号,数字类型则不用加。

  • 已经根据需要给顶点Id加上了双引号,但是通过RESTful API查询顶点时仍然返回空

    检查顶点id中是否包含+空格/?%&=这些URL的保留字符,如果存在则需要进行编码。下表给出了编码值:

    特殊字符 | 编码值
    --------| ----
    +       | %2B
    空格     | %20
    /       | %2F
    ?       | %3F
    %       | %25
    #       | %23
    &       | %26
    =       | %3D
  • 查询某一类别的顶点或边(query by label)时提示超时

    由于属于某一label的数据量可能比较多,请加上limit限制。

  • 通过RESTful API操作图是可以的,但是发送Gremlin语句就报错:Request Failed(500)

    可能是GremlinServer的配置有误,检查gremlin-server.yamlhostport是否与rest-server.propertiesgremlinserver.url匹配,如不匹配则修改,然后重启服务。

  • 使用Loader导数据出现Socket Timeout异常,然后导致Loader中断

    持续地导入数据会使Server的压力过大,然后导致有些请求超时。可以通过调整Loader的参数来适当缓解Server压力(如:重试次数,重试间隔,错误容忍数等),降低该问题出现频率。

  • 如何删除图中的全部数据

    管理员可调用 DELETE /graphspaces/{graphspace}/graphs/{graph}/clear?confirm_message=I'm sure to delete all dataconfirm_message 查询参数必须与该值完全一致,否则请求会被拒绝,详见 Graph API。该操作会清除 schema、顶点、边和索引。

  • 清空了数据库,并且执行了init-store,但是添加schema时提示"xxx has existed"

    HugeGraphServer内是有缓存的,清空数据库的同时是需要重启Server的,否则残留的缓存会产生不一致。

  • 插入顶点或边的过程中报错:The max length of vertex id is 16384, but got xxx {yyy}The max length of edge id is 65536, but got xxx {yyy}

    为了保证查询性能,目前的后端存储对id列的长度做了限制,顶点id不能超过16384字节,边id长度不能超过65536字节;索引id超过32字节时会转为哈希存储,而不是报错。

  • 是否支持嵌套属性,如果不支持,是否有什么替代方案

    嵌套属性目前暂不支持。替代方案:可以把嵌套属性作为单独的顶点拿出来,然后用边连接起来。

  • 一个EdgeLabel是否可以连接多对VertexLabel,比如"投资"关系,可以是"个人"投资"企业",也可以是"企业"投资"企业"

    可以。创建EdgeLabel时对每一对顶点标签各调用一次link(sourceLabel, targetLabel),所有配对都会被保留,因此同一个"投资"标签可以同时覆盖"个人"投资"企业"和"企业"投资"企业"。旧的sourceLabel()targetLabel()构建方法已废弃,且只支持单一配对。

  • 通过RestAPI发送请求时提示HTTP 415 Unsupported Media Type

    请求头中需要指定Content-Type:application/json

其他问题可以在对应项目的 issue 区搜索,例如 Server-Issues / Loader Issues

8 - 报告安全问题

报告 Apache HugeGraph 的安全问题

⚠️ SEC 提醒:致漏洞研究人员关于图查询语言的说明

鉴于图查询语言 (如 Gremlin/Cypher) 本身在解析与执行上的灵活性,HugeGraph 推荐在生产环境依赖 "Auth (配置鉴权) + IP 白名单 + Audit Log (审计日志)" 机制来践行最小权限原则。同时由于 Server 节点基本是无状态的,所有生产环境均明确建议使用容器环境 (Docker/K8s) 进行隔离部署

近期社区已收到较多关于图查询语言灵活性的安全反馈。在 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/..)