HugeGraph Plugin機制及插件擴展流程

HugeGraph是一個Java語言實現的開源圖數據庫,內置支持多種後端存儲(Cassandra、RocksDB等),此外還支持通過插件的方式擴展存儲後端。插件實現者無需更改HugeGraph本身源代碼,插件使用者無需關注代碼細節,就能輕鬆增加插件擴展功能。這篇文章主要講述了HugeGraph擴展自定義插件的流程。

可擴展維度

目前插件方式提供如下幾個維度的擴展項:

  • 後端存儲:HugeGraph支持多種內置存儲後端,也允許用戶無需更改現有源碼的情況下擴展自定義後端。
  • 系列化器:配合自定義後端實現系列化器,或者擴展內置後端的系列化器。
  • 自定義配置項:配合自定義插件擴展配置項。
  • 分詞器:HugeGraph支持全文檢索,全文檢索功能涉及到各語言分詞,目前已內置8種中文分詞器,也允許用戶無需更改現有源碼的情況下擴展自定義分詞器。

插件實現機制

  1. HugeGraph提供插件接口HugeGraphPlugin,通過Java SPI機制支持插件化
  2. HugeGraph提供了4個擴展項註冊函數:registerOptions()registerBackend()registerSerializer()registerAnalyzer()
  3. 插件實現者實現相應的Options、Backend、Serializer或Analyzer的接口
  4. 插件實現者實現HugeGraphPlugin接口的register()方法,在register()中調用上述第2步中的函數,來註冊第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>com.baidu.hugegraph</groupId>
    <artifactId>hugegraph-plugin-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

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

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

2 實現擴展功能

擴展功能一般包括:擴展自定義後端存儲(下文2.1講述)和擴展自定義分詞器(下文2.2講述)。插件實現者關注其中之一即可,若有需要當然也可兩者同時進行擴展,或者只擴展下文2.1.3所述系列化器等。

2.1 擴展自定義後端

2.1.1 實現接口BackendStoreProvider
  • 可實現接口:com.baidu.hugegraph.backend.store.BackendStoreProvider
  • 或者繼承抽象類:com.baidu.hugegraph.backend.store.AbstractBackendStoreProvider

以RocksDB後端RocksDBStoreProvider爲例:

public class RocksDBStoreProvider extends AbstractBackendStoreProvider {

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

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

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

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

    @Override
    public String version() {
        return "1.0";
    }
}
2.1.2 實現接口BackendStore

BackendStore接口定義如下:

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

    // Database name
    public String database();

    // Get the parent provider
    public BackendStoreProvider provider();

    // Open/close database
    public void open(HugeConfig config);
    public void close();

    // Initialize/clear database
    public void init();
    public void clear();

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

    // Query data
    public Iterator<BackendEntry> query(Query query);

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

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

    // Backend features
    public BackendFeatures features();

    // Generate an id for a specific type
    public Id nextId(HugeType type);
}
2.1.3 擴展自定義系列化器

系列化器必須繼承抽象類:com.baidu.hugegraph.backend.serializer.AbstractSerializer(implements GraphSerializer, SchemaSerializer)
主要接口的定義如下:

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

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

增加自定義後端時,可能需要增加新的配置項,實現流程主要包括:

  • 增加配置項容器類,並實現接口com.baidu.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"
            );

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

    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/to/disk`." +
                    "Allowed keys are [graph/vertex, graph/edge_out, graph/edge_in, " +
                    "graph/secondary_index, graph/range_index]",
                    null,
                    String.class,
                    ImmutableList.of()
            );
}

2.2 擴展自定義分詞器

分詞器需要實現接口com.baidu.hugegraph.analyzer.Analyzer,以實現一個SpaceAnalyzer空格分詞器爲例。

package com.baidu.hugegraph.plugin;

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

import com.baidu.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(),自定義插件必須實現該接口方法,在其內部註冊上述定義好的擴展項。
接口com.baidu.hugegraph.plugin.HugeGraphPlugin定義如下:

public interface HugeGraphPlugin {

    public String name();

    public void register();

    public String supportsMinVersion();

    public 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 com.baidu.hugegraph.plugin;

public class DemoPlugin implements HugeGraphPlugin {

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

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

4 配置SPI入口

  1. 確保services目錄存在:hugegraph-plugin-demo/resources/META-INF/services
  2. 在services目錄下建立文本文件:com.baidu.hugegraph.plugin.HugeGraphPlugin
  3. 文件內容如下:com.baidu.hugegraph.plugin.DemoPlugin

5 打Jar包

通過maven打包,在項目目錄下執行命令mvn package,在target目錄下會生成Jar包文件。
使用插件時將該Jar包拷到plugins目錄,重啓服務即可生效。

HugeGraph擴展Stanford分詞器完整示例: https://github.com/hugegraph/hugegraph-plugin-stanford-analyzer
HugeGraph GitHub地址: https://github.com/hugegraph/hugegraph

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章