diff --git a/.github/configs/settings.xml b/.github/configs/settings.xml index 45c87139a9..6cc7dc435c 100644 --- a/.github/configs/settings.xml +++ b/.github/configs/settings.xml @@ -27,6 +27,13 @@ staged-releases https://repository.apache.org/content/groups/staging/ + + github + https://maven.pkg.github.com/hugegraph/toplingdb + + true + + diff --git a/.github/workflows/check-dependencies.yml b/.github/workflows/check-dependencies.yml index fa804e260c..75a104c019 100644 --- a/.github/workflows/check-dependencies.yml +++ b/.github/workflows/check-dependencies.yml @@ -14,8 +14,10 @@ jobs: dependency-check: runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. SCRIPT_DEPENDENCY: install-dist/scripts/dependency + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} steps: - name: Checkout source uses: actions/checkout@v4 diff --git a/.github/workflows/cluster-test-ci.yml b/.github/workflows/cluster-test-ci.yml index 3ef269e878..0537f31a6a 100644 --- a/.github/workflows/cluster-test-ci.yml +++ b/.github/workflows/cluster-test-ci.yml @@ -12,7 +12,9 @@ jobs: cluster-test: runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} steps: - name: Install JDK 11 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d66dc8cee9..52f3d2a93e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -12,7 +12,9 @@ on: jobs: analyze: env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} name: Analyze runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/commons-ci.yml b/.github/workflows/commons-ci.yml index 5311ebeee0..3bacaf9816 100644 --- a/.github/workflows/commons-ci.yml +++ b/.github/workflows/commons-ci.yml @@ -13,12 +13,14 @@ jobs: build-commons: runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} strategy: fail-fast: false matrix: - JAVA_VERSION: ['11'] + JAVA_VERSION: [ '11' ] steps: - name: Install JDK ${{ matrix.JAVA_VERSION }} diff --git a/.github/workflows/licence-checker.yml b/.github/workflows/licence-checker.yml index a6e6990a64..e1b8ee9f93 100644 --- a/.github/workflows/licence-checker.yml +++ b/.github/workflows/licence-checker.yml @@ -11,7 +11,9 @@ jobs: check-license: runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index 62006794c7..c59686d644 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -62,10 +62,12 @@ jobs: runs-on: ubuntu-latest env: # TODO: avoid duplicated env setup in pd & store - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. # TODO: remove outdated env TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis REPORT_DIR: target/site/jacoco + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} steps: - name: Install JDK 11 @@ -92,6 +94,16 @@ jobs: cp $HOME/.m2/settings.xml /tmp/settings.xml mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml + - name: Install deps + run: | + "${TRAVIS_DIR}/install-deps.sh" || exit 1 + + - name: Package + # todo remove --fail-at-end after test + run: | + mvn clean package -U -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp --fail-at-end + source "${TRAVIS_DIR}/install-rocksdb.sh" + - name: Run common test run: | mvn test -pl hugegraph-pd/hg-pd-test -am -P pd-common-test @@ -152,10 +164,12 @@ jobs: needs: struct runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. # TODO: remove outdated env TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis REPORT_DIR: target/site/jacoco + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} steps: - name: Install JDK 11 @@ -182,10 +196,15 @@ jobs: cp $HOME/.m2/settings.xml /tmp/settings.xml mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml + - name: Install deps + run: | + "${TRAVIS_DIR}/install-deps.sh" || exit 1 + - name: Package # todo remove --fail-at-end after test run: | mvn clean package -U -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp --fail-at-end + source "${TRAVIS_DIR}/install-rocksdb.sh" - name: Check startup test prerequisites (Store) id: store-preflight @@ -255,11 +274,13 @@ jobs: needs: struct runs-on: ubuntu-latest env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis REPORT_DIR: target/site/jacoco BACKEND: hstore RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') || startsWith(github.base_ref, 'release-') }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} steps: - name: Install JDK 11 @@ -280,6 +301,10 @@ jobs: with: fetch-depth: 2 + - name: Install deps + run: | + "${TRAVIS_DIR}/install-deps.sh" || exit 1 + - name: use staged maven repo settings if: ${{ env.USE_STAGE == 'true' }} run: | @@ -290,6 +315,7 @@ jobs: # todo remove --fail-at-end after test run: | mvn clean package -U -Dmaven.javadoc.skip=true -Dmaven.test.skip=true -ntp --fail-at-end + source "${TRAVIS_DIR}/install-rocksdb.sh" - name: Prepare env and service run: | diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index 586e36da49..e80b353d7e 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -12,8 +12,11 @@ jobs: build-server: # TODO: we need test & replace it to ubuntu-24.04 or ubuntu-latest runs-on: ubuntu-22.04 + permissions: + contents: read + packages: read env: - USE_STAGE: 'false' # Whether to include the stage repository. + USE_STAGE: 'true' # Whether to include the stage repository. TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis REPORT_DIR: target/site/jacoco BACKEND: ${{ matrix.BACKEND }} @@ -23,6 +26,8 @@ jobs: TARGET_BRANCH_NAME: ${{ github.base_ref != '' && github.base_ref || github.ref_name }} RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') }} RAFT_MODE: ${{ startsWith(github.head_ref, 'test') || startsWith(github.head_ref, 'raft') }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} strategy: fail-fast: false @@ -43,16 +48,16 @@ jobs: java-version: '8' distribution: 'zulu' - - name: Prepare backend environment - run: | - $TRAVIS_DIR/install-backend.sh $BACKEND && jps -l - - name: Install Java ${{ matrix.JAVA_VERSION }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.JAVA_VERSION }} distribution: 'zulu' + - name: Install deps + run: | + ${TRAVIS_DIR}/install-deps.sh + - name: Cache Maven packages uses: actions/cache@v4 with: @@ -66,9 +71,14 @@ jobs: cp $HOME/.m2/settings.xml /tmp/settings.xml cp -vf .github/configs/settings.xml $HOME/.m2/settings.xml && cat $HOME/.m2/settings.xml - - name: Compile + - name: Package + run: | + mvn clean package -Dmaven.test.skip=true -ntp + source $TRAVIS_DIR/install-rocksdb.sh + + - name: Prepare backend environment run: | - mvn clean compile -U -Dmaven.javadoc.skip=true -ntp + $TRAVIS_DIR/install-backend.sh $BACKEND && jps -l - name: Check startup test prerequisites id: server-preflight diff --git a/.specs/hugegraph-server/ToplingDB/design.md b/.specs/hugegraph-server/ToplingDB/design.md new file mode 100644 index 0000000000..4a4cc378b6 --- /dev/null +++ b/.specs/hugegraph-server/ToplingDB/design.md @@ -0,0 +1,228 @@ +# Design of ToplingDB + +## Overview + +HugeGraph ToplingDB aims to enhance compatibility with ToplingDB, providing users with an additional storage engine option that improves performance, functionality, and usability. + +## Design Goals + +* **Dynamic Configuration**: Support flexible configuration of RocksDB parameters via YAML files, replacing hardcoded values to improve maintainability and adaptability. +* **Strong Compatibility**: Maintain full compatibility with the RocksDB API, ensuring seamless migration and integration with existing RocksDB code and data. +* **Visual Monitoring**: Provide a Web Server interface for real-time visibility into storage engine status and configuration, enhancing observability. +* **Simplified Deployment**: Automatically load dynamic libraries from JAR packages without requiring manual `LD_PRELOAD` setup or complex startup procedures, lowering the barrier for users. + +## Architecture Diagram + +### HugeGraph Startup Script Logic + +Steps ❷ ~ ❻ in the diagram below illustrate the preload logic added to support ToplingDB. + +From the user's perspective, startup remains unchanged—simply execute `start-hugegraph.sh`. + +```mermaid +sequenceDiagram + autonumber + participant User as User + participant StartSh as start-hugegraph.sh + participant Preload as preload-topling.sh + participant JVM as JVM/LD Loader + participant Server as HugeGraph Server + + User->>StartSh: Execute startup script + StartSh->>Preload: Source preload script + Preload->>Preload: Locate rocksdbjni*.jar and extract .so to TOP/library + Preload->>Preload: Extract .html/.css to /dev/shm/rocksdb_resource + Preload->>JVM: Set LD_LIBRARY_PATH and LD_PRELOAD + Preload-->>StartSh: Return + StartSh->>Server: Start service + Server-->>User: Service running +``` + +### RocksDB Startup Logic + +Use reflection to detect whether ToplingDB APIs are available. If present, attempt to start the storage engine using ToplingDB; otherwise, fall back to standard RocksDB APIs. + +```mermaid +sequenceDiagram + autonumber + participant Store as HugeGraph Store + participant Config as HugeConfig + participant Sessions as RocksDBStdSessions + participant SPR as SidePluginRepo (Reflection) + participant Repo as Repo Instance + participant Rocks as RocksDB + + Store->>Config: Read OPTION_PATH / OPEN_HTTP + Store->>Sessions: Create Sessions(..., optionPath, openHttp) + alt optionPath provided and SPR available + Sessions->>SPR: Reflectively load/create Repo + Sessions->>Repo: importAutoFile(optionPath) + Sessions->>Repo: open (with JSON descriptor) + opt openHttp is true and instance is GRAPH_STORE + Sessions->>Repo: startHttpServer() + end + Sessions->>Rocks: Get RocksDB instance (with CF handles) + Sessions-->>Store: Return OpenedRocksDB(repo, handles) + else optionPath not provided or SPR unavailable + Sessions->>Rocks: Standard open() + Sessions-->>Store: Return OpenedRocksDB(null, handles) + end + note over Store,Sessions: On shutdown, if repo exists, call repo.closeAllDB() +``` + +## Involved Modules + +### ToplingDB JAR and Maven Setup + +There are two ways to obtain the JAR package: + +1. Pull from GitHub repository +2. Build manually and install to Maven + +#### Pull JAR from GitHub Repository + +Since ToplingDB is not published to Maven Central, the JAR can only be obtained from GitHub Actions releases: +[JAR Package](https://github.com/hugegraph/toplingdb/packages/2550860) + +Add GitHub repository configuration to your Maven `settings.xml`: + +```xml + + + + + github + YOUR_GITHUB_ACTOR + + YOUR_GITHUB_TOKEN + + + + + + ... + + ... + + + github + https://maven.pkg.github.com/hugegraph/toplingdb + + true + + + + + +``` + +Also, update the `rocksdbjni` version in `hugegraph-server/hugegraph-rocksdb/pom.xml` from `7.2.2` to `8.10.2-SNAPSHOT` to match the GitHub release: + +```xml + + org.rocksdb + rocksdbjni + 8.10.2-SNAPSHOT + +``` + +#### Build ToplingDB JAR Manually + +Clone [ToplingDB](https://github.com/topling/toplingdb) and run the following commands: + +```bash +# Build shared library +make -j$(nproc) DEBUG_LEVEL=0 shared_lib +# Install shared library +sudo make install-shared PREFIX=/opt DEBUG_LEVEL=0 +# Package JAR +make rocksdbjava -j$(nproc) DEBUG_LEVEL=0 STRIP_DEBUG_INFO=1 ROCKSDB_JAR_WITH_DYNAMIC_LIBS=1 + +# Set JAVA_HOME (especially for root) +export JAVA_HOME=/usr/lib/jvm/jre-openjdk-yourpath +# Install librocksdbjni dynamic library +sudo make -j install-jni PREFIX=/opt DEBUG_LEVEL=0 STRIP_DEBUG_INFO=1 +# Install JAR to local Maven repository +cd java/target +cp rocksdbjni-8.10.2-linux64.jar rocksdbjni-8.10.2-SNAPSHOT-linux64.jar +mvn install:install-file -Dfile=rocksdbjni-8.10.2-SNAPSHOT-linux64.jar \ + -DgroupId=org.rocksdb -DartifactId=rocksdbjni \ + -Dversion=8.10.2-SNAPSHOT -Dpackaging=jar +``` + +### Preloading Dynamic Libraries and Static Resources + +ToplingDB uses thread-local storage (TLS), requiring dynamic libraries to be preloaded via `LD_PRELOAD`. + +Additionally, the Web Server needs static resources to render the visualization interface. + +To support this, the `preload-topling.sh` script was added to preload ToplingDB dynamic libraries and Web Server resources. + +Main tasks of `preload-topling.sh`: + +- Extract `.so` libraries and Web resources (HTML/CSS) from `rocksdbjni*.jar` +- Set `LD_LIBRARY_PATH` and `LD_PRELOAD` environment variables +- Handle `libaio` compatibility issues on Ubuntu 24.04+ + +Both `init-hugegraph.sh` and `start-hugegraph.sh` now invoke `preload-topling.sh`, so users don’t need to worry about preload details. + +### HugeGraph Configuration Options for RocksDB + +Two new configuration options were added to `hugegraph.properties`: `option_path` for the YAML file and `open_http` to enable the Web Server. + +```properties +# rocksdb backend config +#rocksdb.data_path=/path/to/disk +#rocksdb.wal_path=/path/to/disk +#rocksdb.option_path=./conf/graphs/rocksdb_plus.yaml +#rocksdb.open_http=true +``` + +Java-side parsing and default values: + +```java +public static final ConfigOption OPTION_PATH = + new ConfigOption<>( + "rocksdb.option_path", + "The YAML file for configuring Topling/RocksDB parameters", + null, + "" + ); + +public static final ConfigOption OPEN_HTTP = + new ConfigOption<>( + "rocksdb.open_http", + "Whether to start Topling's HTTP service", + disallowEmpty(), + false + ); +``` + +### ToplingDB Startup Logic + +When `option_path` is configured and the JAR contains ToplingDB APIs, HugeGraph will load the YAML file and start ToplingDB. Otherwise, it falls back to standard RocksDB. + +To keep port configuration simple, the Web Server is only enabled for the `GRAPH_STORE` instance. + +```mermaid +flowchart LR + A[Start Initialization] --> B{Is optionPath provided?} + + B -- No --> Z[Use standard RocksDB to open DB] --> O[Finish standard init] + + B -- Yes --> C{Is SidePluginRepo class available?} + C -- No --> Z + + C -- Yes --> D[Set useTopling = true] --> E["Load SidePluginRepo class and call importAutoFile(optionPath)"] + + E --> K{Is openHttp true?} + K -- No --> M[Finish Topling init] + K -- Yes --> L{Is dbName GRAPH_STORE?} + L -- No --> M + L -- Yes --> N["startHttpServer()"] --> M +``` + +## Design Decisions and Rationale + +1. **Why is the Web Server only started for GRAPH_STORE?** + - All graph data is stored in GRAPH_STORE, and performance tuning and observability are primarily focused on this instance. diff --git a/.specs/hugegraph-server/ToplingDB/requirements.md b/.specs/hugegraph-server/ToplingDB/requirements.md new file mode 100644 index 0000000000..6530b32cae --- /dev/null +++ b/.specs/hugegraph-server/ToplingDB/requirements.md @@ -0,0 +1,35 @@ +# Requirements of ToplingDB + +## Introduction + +RocksDB is the primary standalone/distributed backend storage engine planned for HugeGraph. +However, the current `rocksdb-jni` design makes it difficult for HugeGraph to dynamically modify or adjust RocksDB parameters, resulting in limited flexibility and extensive hard-coding logic. + +To improve performance, functionality, and usability, HugeGraph introduces `ToplingDB` as an optional enhancement. +It allows users to configure RocksDB parameters via external configuration files and visualize storage engine status through a built-in Web Server. + +## Requirement List + +### 1. Support ToplingDB while maintaining compatibility with RocksDB + +**User Story**: As a long-term user, I want the system to support the enhanced features of ToplingDB without affecting existing RocksDB functionality or data compatibility. + +**Acceptance Criteria**: Users can choose between RocksDB and ToplingDB via configuration files or startup parameters. + +### 2. Support configuring RocksDB parameters via external configuration files + +**User Story**: As a user, I want to adjust storage engine parameters based on my business needs and hardware environment to optimize database performance. + +**Acceptance Criteria**: The system supports passing configuration files to customize RocksDB parameters. + +### 3. Support runtime observability of the RocksDB storage engine + +**User Story**: As a system operator, I want clear and intuitive visibility into RocksDB configuration and runtime status. + +**Acceptance Criteria**: The system supports enhancing storage engine observability via a Web Server. + +## Success Criteria + +* The system maintains API compatibility with both RocksDB and ToplingDB. +* The system supports configuring ToplingDB parameters via external configuration files. +* The system enhances storage engine observability through a built-in Web Server. diff --git a/.specs/hugegraph-server/ToplingDB/task.md b/.specs/hugegraph-server/ToplingDB/task.md new file mode 100644 index 0000000000..7ae83eff1b --- /dev/null +++ b/.specs/hugegraph-server/ToplingDB/task.md @@ -0,0 +1,54 @@ +# Tasks of ToplingDB + +This document translates the design of HugeGraph ToplingDB into a series of executable development tasks. Each task follows a test-driven approach to ensure incremental progress and early validation. + +## Common Development Commands + +### Runtime + +ToplingDB (ToplingDB) requires dynamic libraries to be preloaded via `LD_PRELOAD`. The `preload-topling.sh` script parses the JAR package, extracts the necessary libraries, and performs the preload setup. + +When using an IDE such as IntelliJ IDEA, you need to configure the following environment variables in Run/Debug Configurations: + +```shell +LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH +LD_PRELOAD=libjemalloc.so:librocksdbjni-linux64.so +``` + +When running from the terminal, simply use `init-store.sh` and `start-hugegraph.sh`, as `preload-topling.sh` is already embedded in these scripts. + +## 1. Project Infrastructure Setup + +- [x] **1.1 Build ToplingDB JAR Package** + - Publish the package to GitHub Packages via GitHub Actions and update Maven's `settings.xml` + - Provide documentation for manually building the ToplingDB JAR package + +## 2. Compatibility with ToplingDB and Standard RocksDB + +- [x] **2.1 Modify openRocksDB logic in RocksDBStdSession** + - Use reflection to detect whether the current JAR contains ToplingDB APIs; if so, start the storage engine using ToplingDB + - If not available, fall back to the standard RocksDB API for engine startup + +## 3. Add Configuration Options for ToplingDB in HugeGraph + +- [x] **3.1 Add `rocksdb.option_path` configuration** + - Type: string, used to specify the path to the YAML configuration file + - Allow users to pass the YAML file via `hugegraph.properties` using `rocksdb.option_path` + - This option is invalid for standard RocksDB JARs, as RocksDB APIs do not support file-based configuration + +- [x] **3.2 Add `rocksdb.open_http` configuration** + - Type: boolean, used to specify whether to enable the ToplingDB Web Server + - Allow users to configure Web Server activation via `rocksdb.open_http` in `hugegraph.properties` + - The Web Server port is defined in the YAML file specified by `option_path`, under `http.listening_ports` + - For simplicity, the Web Server is only enabled for the `GRAPH_STORE` instance that stores graph data + +## 4. End-to-End Performance Testing + +- [x] **4.1 Write Performance Testing** + - Use `hugegraph-loader` to load the twitter-2010 dataset + - Shuffle the twitter-2010 dataset to simulate real-world random insertion patterns and evaluate the write performance of ToplingDB. + - ToplingDB improves random write performance by up to 40% and reduces storage overhead by approximately 50% + +- [x] **4.2 Read Performance Testing** + - Execute edge traversal, vertex traversal, and KOUT queries to evaluate read performance improvements + - Under cold start conditions, edge traversal latency is reduced by up to 50%, and KOUT query average latency is reduced by approximately 15% diff --git a/docs/toplingdb/rocksdb-provider-pattern-reference.md b/docs/toplingdb/rocksdb-provider-pattern-reference.md new file mode 100644 index 0000000000..748722c70e --- /dev/null +++ b/docs/toplingdb/rocksdb-provider-pattern-reference.md @@ -0,0 +1,163 @@ +# RocksDB Provider Pattern 参考文档 + +> 本文档记录 `hugegraph-rocksdb-provider` 模块的 SPI 设计模式,供未来参考。 +> 如果后续需要重新引入 Provider 抽象层(例如支持新的存储引擎变体),可基于此设计恢复。 + +## 设计概述 + +采用 Java SPI (ServiceLoader) + Strategy Pattern,通过配置项 `rocksdb.provider` 在运行时选择 RocksDB 引擎实现。 + +``` +RocksDBProvider (接口) + └── AbstractRocksDBProvider (模板方法基类) + ├── StandardRocksDBProvider ("standard") + └── ToplingRocksDBProvider ("topling") + +RocksDBProviderLoader (单例注册中心,对外提供静态方法) +``` + +## 核心接口 + +```java +public interface RocksDBProvider { + String getProviderName(); + boolean isAvailable(); + void initialize(); + void shutdown(); + + RocksDB openRocksDB(Options options, String dataPath) throws RocksDBException; + RocksDB openRocksDB(DBOptions dbOptions, String dataPath, + List cfDescriptors, + List cfHandles) throws RocksDBException; + void closeRocksDB(RocksDB db); + void closeRocksDB(RocksDB db, List cfHandles); +} +``` + +## 抽象基类(模板方法) + +```java +public abstract class AbstractRocksDBProvider implements RocksDBProvider { + + protected static final Logger LOG = LoggerFactory.getLogger(AbstractRocksDBProvider.class); + + @Override + public final RocksDB openRocksDB(Options options, String dataPath) throws RocksDBException { + LOG.info("Opening RocksDB via [{}] provider at: {}", getProviderName(), dataPath); + return doOpenRocksDB(options, dataPath); + } + + @Override + public final RocksDB openRocksDB(DBOptions dbOptions, String dataPath, + List cfDescriptors, + List cfHandles) throws RocksDBException { + LOG.info("Opening RocksDB with {} CFs via [{}] provider at: {}", + cfDescriptors.size(), getProviderName(), dataPath); + return doOpenRocksDB(dbOptions, dataPath, cfDescriptors, cfHandles); + } + + @Override + public void closeRocksDB(RocksDB db) { + if (db != null) { + performProviderSpecificClose(db); + db.close(); + } + } + + @Override + public void closeRocksDB(RocksDB db, List cfHandles) { + if (cfHandles != null) { + cfHandles.forEach(ColumnFamilyHandle::close); + } + closeRocksDB(db); + } + + protected abstract RocksDB doOpenRocksDB(Options options, String dataPath) throws RocksDBException; + protected abstract RocksDB doOpenRocksDB(DBOptions dbOptions, String dataPath, + List cfDescriptors, + List cfHandles) throws RocksDBException; + protected abstract void performProviderSpecificClose(RocksDB rocksDB); +} +``` + +## ProviderLoader(单例注册中心) + +```java +public class RocksDBProviderLoader { + + private static final RocksDBProviderLoader INSTANCE = new RocksDBProviderLoader(); + private final Map providers = new ConcurrentHashMap<>(); + private volatile RocksDBProvider activeProvider; + + public static RocksDBProviderLoader getInstance() { return INSTANCE; } + + public void reload() { + providers.clear(); + ServiceLoader loader = ServiceLoader.load(RocksDBProvider.class); + for (RocksDBProvider provider : loader) { + providers.put(provider.getProviderName(), provider); + } + } + + public void selectProvider(String name) { + RocksDBProvider provider = providers.get(name); + if (provider == null) throw new IllegalArgumentException("Unknown provider: " + name); + if (!provider.isAvailable()) throw new IllegalStateException("Provider not available: " + name); + provider.initialize(); + activeProvider = provider; + } + + // 静态便捷方法 + public static RocksDB openRocksDB(Options options, String dataPath) throws RocksDBException { + return INSTANCE.activeProvider.openRocksDB(options, dataPath); + } + + public static RocksDB openRocksDB(DBOptions dbOptions, String dataPath, + List cfDescriptors, + List cfHandles) throws RocksDBException { + return INSTANCE.activeProvider.openRocksDB(dbOptions, dataPath, cfDescriptors, cfHandles); + } + + public static void closeRocksDB(RocksDB db) { + INSTANCE.activeProvider.closeRocksDB(db); + } +} +``` + +## SPI 注册 + +文件:`META-INF/services/org.apache.hugegraph.rocksdb.provider.RocksDBProvider` + +``` +org.apache.hugegraph.rocksdb.provider.StandardRocksDBProvider +org.apache.hugegraph.rocksdb.provider.ToplingRocksDBProvider +``` + +## 调用方使用方式 + +```java +// 初始化(在 HugeGraph 启动时调用一次) +RocksDBProviderLoader loader = RocksDBProviderLoader.getInstance(); +loader.reload(); +loader.selectProvider(config.get("rocksdb.provider")); // "standard" or "topling" + +// 使用(在 RocksDBStdSessions / RocksDBSession 中) +RocksDB db = RocksDBProviderLoader.openRocksDB(options, dataPath); +RocksDBProviderLoader.closeRocksDB(db); +``` + +## 去除原因 + +Easy Migrate 重构后,`ToplingRocksDBProvider` 和 `StandardRocksDBProvider` 的 `doOpenRocksDB` 实现完全相同(都是 `RocksDB.open()`)。差异化逻辑已移至启动脚本: + +- JAR 切换:`preload-topling.sh` 根据配置替换 classpath 中的 JAR +- 环境变量:启动脚本设置 `TOPLINGDB_EASY_MIGRATE_CONF` +- Native 库:启动脚本设置 `LD_PRELOAD` / `LD_LIBRARY_PATH` + +Provider 抽象层不再承载实质性逻辑,因此可安全移除。 + +## 何时考虑恢复 + +- 需要在 Java 层根据不同引擎执行不同的 open/close 逻辑 +- 需要支持第三种 RocksDB 变体(如 SpeeDB、TerarkDB 等) +- 需要在运行时动态切换引擎(而非启动时确定) diff --git a/docs/toplingdb/toplingdb-explicit-config-independent-provider-sop.md b/docs/toplingdb/toplingdb-explicit-config-independent-provider-sop.md new file mode 100644 index 0000000000..e563479da2 --- /dev/null +++ b/docs/toplingdb/toplingdb-explicit-config-independent-provider-sop.md @@ -0,0 +1,420 @@ +# ToplingDB 显式配置 + 独立 Provider 重构 SOP + +## 一、背景与问题 + +### 1.1 现状 + +当前 ToplingDB 集成方案存在以下核心问题: + +| 问题 | 具体表现 | +|------|----------| +| **隐式激活** | `ToplingRocksDBProvider` 通过 `Class.forName("org.rocksdb.SidePluginRepo")` 自动探测 classpath,只要 ToplingDB JAR 存在就自动接管所有 RocksDB 操作(priority=200 > standard=100),用户无法显式选择 | +| **共享坐标污染** | ToplingDB 与标准 RocksDB 共用 `org.rocksdb:rocksdbjni` 坐标(仅版本/来源不同),导致 Maven 依赖仲裁不可控 | +| **影响纯 RocksDB 用户** | 不需要 ToplingDB 的用户也被 SNAPSHOT 依赖、GitHub Packages 仓库配置所困扰 | + +### 1.2 目标 + +1. **显式配置**:用户通过 `rocksdb.provider=standard|topling` 明确选择引擎,不再依赖 classpath 自动探测 +2. **部署时 Drop-in**:运维不需要 Maven 配置,下载 ToplingDB addon 包放入部署目录即可 +3. **模块结构不变**:保留现有 `hugegraph-rocksdb-provider` 单模块,内部简化逻辑 + +--- + +## 二、分发模型 + +### 2.1 构建与部署分离 + +ToplingDB 本身就需要下载 native `.so` 库和可能的外置二进制文件,因此对终端用户来说是一个 **部署时 addon**,而非编译时依赖。 + +``` +┌──────────────────────────────────────────────────────────┐ +│ 默认构建产物 │ +│ mvn clean package │ +│ ├── lib/rocksdbjni-8.10.2.jar (标准 RocksDB) │ +│ └── lib/hugegraph-rocksdb-provider.jar │ +└──────────────────────────────────────────────────────────┘ + + ↓ 运维选择启用 ToplingDB ↓ + +┌──────────────────────────────────────────────────────────┐ +│ ToplingDB Addon 包 (独立下载) │ +│ toplingdb-addon-1.0.0-linux-x86_64.tar.gz │ +│ ├── lib/toplingdb-jni-1.0.0.jar (替换 rocksdbjni) │ +│ ├── native/librocksdbjni-linux64.so │ +│ ├── native/libterark-*.so (可选) │ +│ ├── web/ (ToplingDB HTTP 监控 UI) │ +│ └── conf/rocksdb_plus.yaml.template │ +└──────────────────────────────────────────────────────────┘ +``` + +### 2.2 两种角色 + +| 角色 | ToplingDB 怎么来 | 需要 Maven 配置? | +|------|-----------------|-----------------| +| **运维/部署者** | 下载 addon 包,解压到部署目录,改配置 | 不需要 | +| **开发者** | POM 中 `-P toplingdb` 引入(仅编译/调试用) | 需要 | + +### 2.3 部署流程(运维视角) + +```bash +# 1. 下载 ToplingDB addon 包 +wget https://github.com/hugegraph/toplingdb/releases/download/v1.0.0/toplingdb-addon-1.0.0-linux-x86_64.tar.gz + +# 2. 解压到 HugeGraph 安装目录 +tar -xzf toplingdb-addon-1.0.0-linux-x86_64.tar.gz -C /opt/hugegraph/ + +# 3. 替换标准 RocksDB JAR(互斥) +rm /opt/hugegraph/lib/rocksdbjni-*.jar + +# 4. 修改配置 +vi conf/hugegraph.properties +# rocksdb.provider=topling +# rocksdb.option_path=./conf/graphs/rocksdb_plus.yaml + +# 5. 启动 +bin/start-hugegraph.sh +``` + +--- + +## 三、模块改造设计 + +### 3.1 保持单模块结构 + +`hugegraph-rocksdb-provider` 模块保持不变,内部简化为配置驱动: + +``` +hugegraph-rocksdb-provider/ +├── src/main/java/.../rocksdb/provider/ +│ ├── RocksDBProvider.java (接口,移除 getPriority()) +│ ├── AbstractRocksDBProvider.java (模板基类,保持不变) +│ ├── RocksDBProviderLoader.java (改为配置驱动选择) +│ ├── StandardRocksDBProvider.java (保持不变) +│ └── ToplingRocksDBProvider.java (保持不变) +├── src/main/resources/META-INF/services/ (SPI 注册,保持不变) +└── pom.xml (依赖改造) +``` + +### 3.2 POM 依赖改造 + +```xml + + + + + org.rocksdb + rocksdbjni + ${rocksdb.version} + + + + + + + + + + standard-rocksdb + + true + + + org.rocksdb + rocksdbjni + ${rocksdb.version} + + + + toplingdb + + org.apache.hugegraph + toplingdb-jni + ${toplingdb.version} + + + +``` + +`hugegraph-rocksdb-provider/pom.xml` 中依赖改为变量引用: + +```xml + + ${rocksdb.engine.groupId} + ${rocksdb.engine.artifactId} + ${rocksdb.engine.version} + +``` + +### 3.3 RocksDBProviderLoader 改造 + +从"按 priority 自动选最高"改为"按配置名精确匹配": + +```java +public class RocksDBProviderLoader { + + private final Map providerRegistry = new ConcurrentHashMap<>(); + private volatile RocksDBProvider activeProvider; + + /** + * 加载所有 SPI 注册的 Provider 到 registry + */ + public synchronized void loadProviders() { + ServiceLoader loader = ServiceLoader.load(RocksDBProvider.class); + for (RocksDBProvider provider : loader) { + providerRegistry.put(provider.getProviderName(), provider); + LOG.info("Discovered RocksDB provider: {}", provider.getProviderName()); + } + } + + /** + * 根据配置值选择并激活 Provider + */ + public synchronized RocksDBProvider selectProvider(String providerName) { + if (providerRegistry.isEmpty()) { + loadProviders(); + } + + RocksDBProvider provider = providerRegistry.get(providerName); + if (provider == null) { + throw new IllegalStateException(String.format( + "RocksDB provider '%s' not found. Available: %s. " + + "If using ToplingDB, ensure the addon is installed in lib/.", + providerName, providerRegistry.keySet())); + } + + if (!provider.isAvailable()) { + throw new IllegalStateException(String.format( + "RocksDB provider '%s' found but not available. " + + "Check native libraries and LD_PRELOAD.", + providerName)); + } + + this.activeProvider = provider; + provider.initialize(); + LOG.info("Activated RocksDB provider: {}", providerName); + return provider; + } + + /** + * 获取已激活的 Provider + */ + public RocksDBProvider getActiveProvider() { + if (activeProvider == null) { + throw new IllegalStateException( + "No RocksDB provider activated. Call selectProvider() first."); + } + return activeProvider; + } + + // static 便捷方法内部改为 getActiveProvider() + public static RocksDB openRocksDB(Options options, String dataPath, + String optionPath, Boolean openHttp) throws RocksDBException { + return getInstance().getActiveProvider() + .openRocksDB(options, dataPath, optionPath, openHttp); + } + + public static void closeRocksDB(RocksDB rocksDB) { + getInstance().getActiveProvider().closeRocksDB(rocksDB); + } +} +``` + +### 3.4 Provider 接口简化 + +```java +public interface RocksDBProvider { + + /** Provider 标识名,与 rocksdb.provider 配置值匹配 */ + String getProviderName(); // "standard" or "topling" + + /** 当前环境是否可用 */ + boolean isAvailable(); + + // open/close 方法签名保持不变... + + // 移除 getPriority() — 不再需要优先级竞争 +} +``` + +### 3.5 新增配置项 + +在 `RocksDBOptions.java`(server 和 store 两处)新增: + +```java +public static final ConfigOption PROVIDER = + new ConfigOption<>( + "rocksdb.provider", + "The RocksDB engine provider. 'standard' for vanilla RocksDB, " + + "'topling' for ToplingDB (requires addon installation).", + allowValues("standard", "topling"), + "standard" + ); +``` + +### 3.6 调用方改造 + +在 RocksDB Backend 初始化时读取配置并激活 Provider: + +```java +// RocksDBStdSessions 构造函数 或 RocksDBStoreProvider.open() 中 +String providerName = config.get(RocksDBOptions.PROVIDER); +RocksDBProviderLoader.getInstance().selectProvider(providerName); + +// 后续 open/close 调用方式不变 +RocksDBProviderLoader.openRocksDB(options, dataPath, optionPath, openHttp); +``` + +--- + +## 四、ToplingDB Addon 包 + +### 4.1 包内容 + +``` +toplingdb-addon-1.0.0-linux-x86_64.tar.gz +├── lib/ +│ └── toplingdb-jni-1.0.0.jar ← 替换 rocksdbjni-*.jar +├── native/ +│ ├── librocksdbjni-linux64.so +│ ├── libterark-zip-rocksdb-trial.so (可选) +│ └── libjemalloc.so (可选) +├── web/ +│ ├── index.html +│ └── style.css +├── conf/ +│ └── rocksdb_plus.yaml.template +└── install.sh (可选安装脚本) +``` + +### 4.2 启动脚本适配 + +`common-topling.sh` 查找逻辑改为优先使用 `native/` 目录: + +```bash +# 优先从 native/ 目录加载(addon 已安装) +if [ -d "$HUGEGRAPH_HOME/native" ] && ls "$HUGEGRAPH_HOME/native"/librocksdbjni*.so >/dev/null 2>&1; then + export LD_PRELOAD="$HUGEGRAPH_HOME/native/librocksdbjni-linux64.so" +else + # 回退:从 JAR 中提取(兼容旧方式) + jar_file=$(ls -1 "$lib_dir"/toplingdb-jni*.jar 2>/dev/null | head -1) + if [ -z "$jar_file" ]; then + jar_file=$(ls -1 "$lib_dir"/rocksdbjni*.jar 2>/dev/null | head -1) + fi + extract_so_from_jar "$jar_file" +fi +``` + +--- + +## 五、配置使用 + +### 5.1 标准 RocksDB(默认) + +```properties +backend=rocksdb +# rocksdb.provider=standard ← 默认值,可不写 +``` + +### 5.2 ToplingDB + +```properties +backend=rocksdb +rocksdb.provider=topling +rocksdb.option_path=./conf/graphs/rocksdb_plus.yaml +rocksdb.open_http=true +``` + +### 5.3 错误提示 + +| 场景 | 错误信息 | +|------|----------| +| 配置 `topling` 但未安装 addon | `RocksDB provider 'topling' not found. Available: [standard]. Install ToplingDB addon to lib/.` | +| addon JAR 在但 native lib 缺失 | `RocksDB provider 'topling' found but not available. Check native libraries and LD_PRELOAD.` | + +--- + +## 六、实施步骤 + +### Phase 1:改造 RocksDBProviderLoader(核心) + +1. 移除 `getBestProvider()` 的 priority 竞争逻辑 +2. 新增 `selectProvider(String name)` 按名精确匹配 +3. 新增 `getActiveProvider()` 替代原 `getBestProvider()` +4. `RocksDBProvider` 接口移除 `getPriority()` +5. **验证**:编译通过,配置 `standard` 时行为与原来一致 + +### Phase 2:新增配置项 + 调用方改造 + +1. `RocksDBOptions.java` (server + store) 新增 `rocksdb.provider` +2. `RocksDBStdSessions` 初始化时调用 `selectProvider(config.get(PROVIDER))` +3. `hg-store-rocksdb` 的 `RocksDBSession` 同理 +4. **验证**:`provider=standard` 正常工作 + +### Phase 3:POM 独立坐标 + Profile + +1. Root `pom.xml` 新增 `standard-rocksdb` / `toplingdb` 两个 Profile +2. `hugegraph-rocksdb-provider/pom.xml` 依赖改为 `${rocksdb.engine.*}` 变量 +3. 移除 `8.10.2-SNAPSHOT` 硬编码,标准 profile 用正式 release +4. **验证**:`mvn package` 默认无 SNAPSHOT,`mvn package -P toplingdb` 引入 ToplingDB + +### Phase 4:Addon 包 + 脚本改造 + +1. 设计 addon 包打包流程(CI) +2. 改造 `common-topling.sh` 支持 `native/` 目录 +3. 编写 `install.sh` +4. **验证**:全新部署环境通过 addon 安装 ToplingDB 正常启动 + +### Phase 5:清理 + +1. 移除 `.github/configs/settings.xml` 中 GitHub Packages 仓库(默认构建不再需要) +2. 更新配置文件模板 +3. 更新文档 +4. **验证**:完整测试矩阵 + +--- + +## 七、验证矩阵 + +| 验证项 | 操作 | 预期 | +|--------|------|------| +| 默认构建 | `mvn clean package` | 无 SNAPSHOT,无 GitHub Token,产物仅含标准 RocksDB | +| 开发者构建 | `mvn clean package -P toplingdb` | 含 ToplingDB JNI | +| 标准模式启动 | `provider=standard` | 使用原生 RocksDB | +| ToplingDB 启动 | `provider=topling` + addon 安装 | 使用 ToplingDB | +| 配置不匹配 | `provider=topling` + 未安装 addon | 明确错误信息 | +| Addon 安装 | 解压 addon + 改配置 | 无需重新编译 | +| HStore 模式 | Store 节点同验证 | 一致 | + +--- + +## 八、设计决策 + +### 为什么保持单模块? + +- `hugegraph-rocksdb-provider` 已被 `hugegraph-server/hugegraph-rocksdb` 和 `hugegraph-store/hg-store-rocksdb` 共同依赖,是两者共享 open/close 逻辑的自然位置 +- 拆成 api + standard + topling 三个模块增加了维护成本,但 Provider 实现本身代码量很小,不值得拆 +- 单模块内通过配置驱动切换,足够简洁 + +### 为什么运维走 Drop-in 而非 Maven? + +- ToplingDB 本身就需要 native lib 下载,addon 包是天然的分发单元 +- 运维不需要理解 Maven Profile,下载解压改配置即可 +- 离线环境友好 +- CI/CD 中普通构建不需要 GitHub Token + +### 为什么 `rocksdb.provider` 而非 `backend=toplingdb`? + +ToplingDB 是 RocksDB 引擎层替换,不是新的存储后端。表结构、序列化、查询全部复用 RocksDB Backend 代码。`rocksdb.provider=topling` 语义精确。 + +--- + +## 九、时间估算 + +| Phase | 工作量 | +|-------|--------| +| Phase 1:Loader 改造 | 0.5 天 | +| Phase 2:配置项 + 调用方 | 0.5 天 | +| Phase 3:POM + Profile | 0.5 天 | +| Phase 4:Addon + 脚本 | 1.5 天 | +| Phase 5:清理 | 0.5 天 | +| **合计** | **3.5 天** | diff --git a/docs/toplingdb/toplingdb-hstore-integration.md b/docs/toplingdb/toplingdb-hstore-integration.md new file mode 100644 index 0000000000..f10cc4acef --- /dev/null +++ b/docs/toplingdb/toplingdb-hstore-integration.md @@ -0,0 +1,637 @@ +# HugeGraph 集成 ToplingDB 与 HStore 技术文档 + +## 一、整体架构概览 + +HugeGraph 的存储层采用**可插拔后端架构(Pluggable Backend Architecture)**,通过 `BackendStoreProvider` SPI 支持多种存储引擎。当前支持的后端类型为:`memory`、`rocksdb`、`hbase`、`hstore`。 + +``` +┌─────────────────────────────────────────────────────────┐ +│ HugeGraph Server │ +│ │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ BackendProviderFactory │ │ +│ │ (根据配置选择: rocksdb / hstore / hbase / memory) │ │ +│ └──────────┬───────────────────────┬───────────────┘ │ +│ │ │ │ +│ ┌─────────▼──────────┐ ┌────────▼──────────┐ │ +│ │ RocksDBStoreProvider│ │ HstoreProvider │ │ +│ │ (type="rocksdb") │ │ (type="hstore") │ │ +│ └─────────┬──────────┘ └────────┬──────────┘ │ +│ │ │ │ +│ ┌─────────▼──────────┐ ┌────────▼──────────┐ │ +│ │ RocksDBStdSessions │ │HstoreSessionsImpl │ │ +│ └─────────┬──────────┘ └────────┬──────────┘ │ +│ │ │ │ +│ ┌─────────▼──────────┐ ┌────────▼──────────┐ │ +│ │RocksDBProviderLoader│ │ HgStoreClient │ │ +│ │ (SPI: Standard / │ │ (gRPC → Store节点) │ │ +│ │ ToplingDB) │ └────────┬──────────┘ │ +│ └─────────┬──────────┘ │ │ +└─────────────┼───────────────────────┼─────────────────────┘ + │ │ + ┌─────────▼──────────┐ ┌────────▼──────────────────┐ + │ RocksDB / ToplingDB │ │ hugegraph-store 集群 │ + │ (本地嵌入式) │ │ (Raft + PD + RocksDB/ │ + │ │ │ ToplingDB 节点) │ + └─────────────────────┘ └──────────────────────────┘ +``` + +**关键设计点**:ToplingDB 和 HStore 是**正交的两个维度**: + +- **ToplingDB** = 增强版 RocksDB 存储引擎(可替换标准 RocksDB) +- **HStore** = 分布式存储架构(客户端-服务端 + Raft 共识) +- 两者可以组合使用:HStore 节点内部也能使用 ToplingDB + +--- + +## 二、ToplingDB 接入详解 + +### 2.1 设计思路:SPI + 反射,零硬依赖 + +ToplingDB 的集成采用了 **Java SPI(Service Provider Interface) + 反射** 的方式,核心原则是: + +1. **编译时不依赖 ToplingDB 特有 API** —— 通过 `Class.forName("org.rocksdb.SidePluginRepo")` 探测 +2. **运行时自动选择最优 Provider** —— 优先级机制(ToplingDB=200 > Standard=100) +3. **完全向后兼容** —— 没有 ToplingDB JAR 时自动降级为标准 RocksDB + +### 2.2 模块结构 + +``` +hugegraph-rocksdb-provider/ ← 独立 Maven 模块 +├── pom.xml ← 依赖 rocksdbjni:8.10.2-SNAPSHOT (ToplingDB 增强版) +└── src/main/java/org/apache/hugegraph/rocksdb/provider/ + ├── RocksDBProvider.java ← SPI 接口定义 + ├── AbstractRocksDBProvider.java ← 模板方法基类 + ├── StandardRocksDBProvider.java ← 标准 RocksDB 实现 (priority=100) + ├── ToplingRocksDBProvider.java ← ToplingDB 实现 (priority=200) + └── RocksDBProviderLoader.java ← ServiceLoader 加载器 (单例) +``` + +SPI 注册文件位于 `META-INF/services/org.apache.hugegraph.rocksdb.provider.RocksDBProvider`: + +``` +org.apache.hugegraph.rocksdb.provider.StandardRocksDBProvider +org.apache.hugegraph.rocksdb.provider.ToplingRocksDBProvider +``` + +### 2.3 核心接口 RocksDBProvider + +> 源码位置:`hugegraph-rocksdb-provider/src/main/java/org/apache/hugegraph/rocksdb/provider/RocksDBProvider.java` + +```java +public interface RocksDBProvider { + String getProviderName(); // "standard" 或 "topling" + int getPriority(); // 数值越大优先级越高 + boolean isAvailable(); // 运行时环境检测 + + // 核心 open 方法 —— 1:1 替换 RocksDB.open() + RocksDB openRocksDB(Options options, String dataPath) throws RocksDBException; + + RocksDB openRocksDB(Options options, String dataPath, + String optionPath, Boolean openHttp) throws RocksDBException; + + RocksDB openRocksDB(DBOptions dbOptions, String dataPath, + List cfDescriptors, + List cfHandles, + String optionPath, Boolean openHttp) throws RocksDBException; + + // 核心 close 方法 + void closeRocksDB(RocksDB rocksDB); +} +``` + +### 2.4 ToplingDB Provider 的工作原理 + +> 源码位置:`hugegraph-rocksdb-provider/src/main/java/org/apache/hugegraph/rocksdb/provider/ToplingRocksDBProvider.java` + +#### Step 1: 可用性检测 + +```java +@Override +public boolean isAvailable() { + try { + Class.forName("org.rocksdb.SidePluginRepo"); // ToplingDB 特有类 + return true; + } catch (ClassNotFoundException e) { + return false; + } +} +``` + +#### Step 2: 反射初始化 SidePluginRepo + +```java +private Object initializeToplingRepo(Object options, String dataPath, String optionPath) { + // 动态加载 SidePluginRepo 类 + Class sidePluginRepoClass = Class.forName("org.rocksdb.SidePluginRepo"); + Object repo = sidePluginRepoClass.getConstructor().newInstance(); + + // 将 Options 注入 repo + String dbName = getDbName(dataPath); + Method putMethod = sidePluginRepoClass.getMethod("put", String.class, Options.class); + putMethod.invoke(repo, dbName, options); + + // 加载 YAML 配置文件 + Method importAutoFileMethod = sidePluginRepoClass.getMethod("importAutoFile", String.class); + importAutoFileMethod.invoke(repo, optionPath); + + return repo; +} +``` + +#### Step 3: 通过 SidePluginRepo 打开 DB + +```java +Method openDBMethod = sidePluginRepoClass.getMethod("openDB", String.class); +Object result = openDBMethod.invoke(repo, converseOptionsToJsonString(dataPath, null)); +``` + +传递给 `openDB` 的 JSON 格式: + +```json +{ + "method": "DB::Open", + "params": { + "db_options": "$dbo", + "cf_options": "$default", + "column_families": { "default": "$default" }, + "path": "/data/hugegraph/graph" + } +} +``` + +#### Step 4: 启动 HTTP 监控服务器(可选) + +```java +if (Boolean.TRUE.equals(openHttp)) { + Method openHttpMethod = sidePluginRepoClass.getMethod("startHttpServer"); + openHttpMethod.invoke(repo); +} +``` + +#### Step 5: 关闭时清理 SidePluginRepo + +```java +@Override +protected void performProviderSpecificClose(RocksDB rocksDB) { + Object repo = rocksDBToRepoMap.remove(rocksDB); + if (repo != null) { + Method closeAllDBMethod = repo.getClass().getMethod("closeAllDB"); + closeAllDBMethod.invoke(repo); + } +} +``` + +### 2.5 Provider 加载器 + +> 源码位置:`hugegraph-rocksdb-provider/src/main/java/org/apache/hugegraph/rocksdb/provider/RocksDBProviderLoader.java` + +```java +public class RocksDBProviderLoader { + private static final RocksDBProviderLoader INSTANCE = new RocksDBProviderLoader(); + + public synchronized void loadProviders() { + ServiceLoader serviceLoader = ServiceLoader.load(RocksDBProvider.class); + for (RocksDBProvider provider : serviceLoader) { + if (provider.isAvailable()) { + providerCache.put(provider.getProviderName(), provider); + } + } + } + + public RocksDBProvider getBestProvider() { + // 选择 priority 最高的可用 Provider + RocksDBProvider bestProvider = null; + int highestPriority = Integer.MIN_VALUE; + for (RocksDBProvider provider : providerCache.values()) { + if (provider.isAvailable() && provider.getPriority() > highestPriority) { + bestProvider = provider; + highestPriority = provider.getPriority(); + } + } + return bestProvider; + } + + // 静态便捷方法,供消费方直接调用 + public static RocksDB openRocksDB(Options options, String dataPath, + String optionPath, Boolean openHttp) { + RocksDBProvider provider = getInstance().getBestProvider(); + return provider.openRocksDB(options, dataPath, optionPath, openHttp); + } + + public static void closeRocksDB(RocksDB rocksDB) { + RocksDBProvider provider = getInstance().getBestProvider(); + provider.closeRocksDB(rocksDB); + } +} +``` + +### 2.6 调用链路 + +以 `hugegraph-server` 单机模式为例: + +> 源码位置:`hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java:385-431` + +``` +RocksDBStdSessions.openRocksDB(config, dataPath, walPath) + │ + ├─ config.get(RocksDBOptions.OPTION_PATH) → e.g. "conf/topling.yaml" + ├─ config.get(RocksDBOptions.OPEN_HTTP) → true/false + │ + └─ RocksDBProviderLoader.openRocksDB(options, dataPath, optionPath, openHttp) + │ + └─ getInstance().getBestProvider() + │ + ├─ [有 ToplingDB JAR] → ToplingRocksDBProvider (priority=200) + │ └─ 反射: SidePluginRepo → importAutoFile → openDB → startHttpServer + │ + └─ [无 ToplingDB JAR] → StandardRocksDBProvider (priority=100) + └─ 直接 RocksDB.open(options, dataPath) +``` + +关键代码(`RocksDBStdSessions.java` 第 385-391 行): + +```java +// Only enable HTTP server for GRAPH_STORE when openHttp is true +boolean openHttp = Boolean.TRUE.equals(config.get(RocksDBOptions.OPEN_HTTP)) && + BackendStoreProvider.GRAPH_STORE.equals(getDbName(dataPath)); +RocksDB rocksdb = RocksDBProviderLoader.openRocksDB(options, dataPath, + config.get(RocksDBOptions.OPTION_PATH), + openHttp); +``` + +### 2.7 Native Library 预加载 + +ToplingDB 依赖额外的 `.so` 动态库,通过启动脚本处理。 + +> 源码位置:`hugegraph-server/hugegraph-dist/src/assembly/static/bin/common-topling.sh` + +**`bin/preload-topling.sh`** → 调用 **`bin/common-topling.sh`** 中的 `preload_toplingdb()` 函数: + +```bash +function preload_toplingdb() { + local lib_dir="$1" + local dest_dir="$2" + + # 1. 从 rocksdbjni*.jar 中解压 .so 文件 + extract_so_with_jar "$jar_file" "$dest_dir" + + # 2. 处理 Ubuntu 24.04+ 的 libaio 兼容性 + ensure_libaio_symlink + + # 3. 下载并预加载 jemalloc(优先使用系统已安装的) + download_and_setup_jemalloc "$top" + + # 4. 设置 LD_LIBRARY_PATH + export LD_LIBRARY_PATH="$dest_dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + + # 5. 设置 LD_PRELOAD 预加载 librocksdbjni-linux64.so + export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dest_dir/librocksdbjni-linux64.so" + + # 6. 解压 HTML/CSS(ToplingDB Web 监控界面资源) + extract_html_css_from_jar "$jar_file" "$dest_dir" +} +``` + +### 2.8 配置选项 + +> 源码位置:`hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBOptions.java:89-103` + +| 配置项 | 类型 | 说明 | +|--------|------|------| +| `rocksdb.option_path` | String | ToplingDB YAML 配置文件路径(如 `conf/topling.yaml`) | +| `rocksdb.open_http` | Boolean | 是否启动 ToplingDB 内嵌 Web 监控服务器 | + +安全验证规则(`ToplingRocksDBProvider.validateOptionPath()`): + +- 路径必须匹配正则 `^[a-zA-Z0-9/_.-]+\.yaml$` +- 不允许包含 `..` 或 `://` +- 必须位于 `./conf/` 目录下(路径遍历防护) +- 文件必须存在且可读 +- 文件大小限制 10MB(防止 DoS) +- YAML 使用 `SafeConstructor` 解析(防止反序列化攻击) + +### 2.9 StandardRocksDBProvider(降级方案) + +> 源码位置:`hugegraph-rocksdb-provider/src/main/java/org/apache/hugegraph/rocksdb/provider/StandardRocksDBProvider.java` + +当 ToplingDB 不可用时,`StandardRocksDBProvider`(priority=100)接管: + +```java +public class StandardRocksDBProvider extends AbstractRocksDBProvider { + @Override + public boolean isAvailable() { + RocksDB.loadLibrary(); // 只要标准 RocksDB 能加载就可用 + return true; + } + + @Override + protected RocksDB doOpenRocksDB(Options options, String dataPath) { + return RocksDB.open(options, dataPath); // 直接调用标准 API + } + + // ToplingDB 专有参数会被忽略并打印 warn 日志 + @Override + protected RocksDB doOpenRocksDB(Options options, String dataPath, + String optionPath, Boolean openHttp) { + if (optionPath != null) { + LOG.warn("Standard RocksDB does not support optionPath, ignoring: {}", optionPath); + } + return RocksDB.open(options, dataPath); + } +} +``` + +--- + +## 三、HStore 接入详解 + +### 3.1 设计思路:分布式存储客户端 + +HStore 是 HugeGraph 的**分布式存储后端**,它将一个独立的 `hugegraph-store` 集群(多节点 Raft + RocksDB)封装为与单机 RocksDB 相同的 `BackendStoreProvider` 接口。对上层查询引擎完全透明。 + +### 3.2 模块结构 + +``` +hugegraph-server/hugegraph-hstore/ ← 客户端适配模块 +├── HstoreProvider.java ← BackendStoreProvider 实现 (type="hstore") +├── HstoreStore.java ← 抽象 Store (HstoreSchemaStore / HstoreGraphStore) +├── HstoreSessions.java ← 会话抽象层 +├── HstoreSessionsImpl.java ← 具体实现:通过 gRPC 与 Store 集群通信 +├── HstoreTable.java ← 表操作抽象 +├── HstoreTables.java ← 具体表定义 (vertex, edge, index 等) +├── HstoreFeatures.java ← 后端能力声明 +├── HstoreOptions.java ← 配置项(如 partition_count) +└── HstoreMetrics.java ← 指标收集 + +hugegraph-store/ ← 存储节点服务(独立部署) +├── hg-store-grpc/ ← gRPC 协议定义 +├── hg-store-common/ ← 公共类 +├── hg-store-client/ ← 客户端库 (HgStoreClient) +├── hg-store-core/ ← 核心逻辑(Raft、分区管理) +├── hg-store-node/ ← 节点服务主程序 +├── hg-store-rocksdb/ ← 节点层 RocksDB 访问(也支持 ToplingDB) +├── hg-store-cli/ ← 命令行工具 +├── hg-store-test/ ← 测试 +└── hg-store-dist/ ← 打包分发 +``` + +### 3.3 HstoreProvider —— 入口 + +> 源码位置:`hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreProvider.java` + +```java +public class HstoreProvider extends AbstractBackendStoreProvider { + + @Override + public String type() { + return "hstore"; + } + + @Override + public String driverVersion() { + return "1.13"; + } + + @Override + protected BackendStore newSchemaStore(HugeConfig config, String store) { + return new HstoreStore.HstoreSchemaStore(this, this.namespace(), store); + } + + @Override + protected BackendStore newGraphStore(HugeConfig config, String store) { + return new HstoreStore.HstoreGraphStore(this, this.namespace(), store); + } +} +``` + +### 3.4 HstoreSessionsImpl —— 核心连接层 + +> 源码位置:`hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreSessionsImpl.java` + +这是 HStore 最关键的实现类,负责与分布式存储集群通信: + +```java +public class HstoreSessionsImpl extends HstoreSessions { + private static volatile PDClient defaultPdClient; // PD 元数据客户端 + private static volatile HgStoreClient hgStoreClient; // Store 数据客户端 + + // 初始化 Store 节点连接(单例,只执行一次) + private void initStoreNode(HugeConfig config) { + if (!initializedNode) { + synchronized (this) { + if (!initializedNode) { + // 创建 PD 客户端(Placement Driver,负责元数据和路由) + PDConfig pdConfig = PDConfig.of(config.get(CoreOptions.PD_PEERS)) + .setAuthority(PDAuthConfig.service(), + PDAuthConfig.token()) + .setEnableCache(true); + defaultPdClient = PDClient.create(pdConfig); + + // 基于 PD 客户端创建 Store 客户端(负责数据读写) + hgStoreClient = HgStoreClient.create(defaultPdClient); + initializedNode = Boolean.TRUE; + } + } + } + } + + // 打开会话时向 PD 注册图的分区信息 + @Override + public void open() { + if (!infoInitializedGraph.contains(this.graphName)) { + Integer partitionCount = this.config.get(HstoreOptions.PARTITION_COUNT); + defaultPdClient.setGraph(Metapb.Graph.newBuilder() + .setGraphName(this.graphName) + .setPartitionCount(partitionCount) + .build()); + infoInitializedGraph.add(this.graphName); + } + this.session.open(); + } + + // 表操作委托给远程 Store 节点 + @Override + public synchronized void createTable(String... tables) { ... } + + @Override + public synchronized void dropTable(String... tables) { ... } + + @Override + public boolean existsTable(String table) { ... } +} +``` + +### 3.5 HstoreStore —— 存储抽象 + +> 源码位置:`hugegraph-server/hugegraph-hstore/src/main/java/org/apache/hugegraph/backend/store/hstore/HstoreStore.java` + +```java +public abstract class HstoreStore extends AbstractBackendStore { + + // 支持的索引类型 + private static final Set INDEX_TYPES = ImmutableSet.of( + HugeType.SECONDARY_INDEX, HugeType.VERTEX_LABEL_INDEX, + HugeType.EDGE_LABEL_INDEX, HugeType.RANGE_INT_INDEX, + HugeType.RANGE_FLOAT_INDEX, HugeType.RANGE_LONG_INDEX, + HugeType.RANGE_DOUBLE_INDEX, HugeType.SEARCH_INDEX, + HugeType.SHARD_INDEX, HugeType.UNIQUE_INDEX + ); + + // 两种具体实现 + public static class HstoreSchemaStore extends HstoreStore { ... } + public static class HstoreGraphStore extends HstoreStore { ... } +} +``` + +### 3.6 HStore 运行时数据流 + +``` +HugeGraph Server (hugegraph-hstore 客户端) + │ + ├─ HstoreSessionsImpl + │ ├─ PDClient ──────────── gRPC ──→ PD (Placement Driver) + │ │ • 获取 partition 路由表 │ • 管理分区分配 + │ │ • 注册图元数据 │ • 调度数据均衡 + │ │ │ + │ └─ HgStoreClient ──── gRPC ──→ Store Node (hg-store-node) + │ • put / get / scan / delete │ • Raft 共识保证一致性 + │ • 按 partition 路由到对应节点 │ • RocksDB / ToplingDB 存储 + │ │ • 数据分片与副本 + │ │ + └─ HstoreTable └─→ hg-store-rocksdb + • 序列化/反序列化 vertex/edge/index │ + • 构建 HgScanQuery └─ RocksDBProviderLoader (同样的 SPI) + ├─ ToplingRocksDBProvider + └─ StandardRocksDBProvider +``` + +### 3.7 BackendProviderFactory —— 后端注册与发现 + +> 源码位置:`hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendProviderFactory.java` + +```java +public class BackendProviderFactory { + // 允许的后端类型白名单 + private static final List ALLOWED_BACKENDS = + List.of("memory", "rocksdb", "hbase", "hstore"); + + public static BackendStoreProvider open(HugeGraphParams params) { + String backend = config.get(CoreOptions.BACKEND).toLowerCase(); // e.g. "hstore" + BackendStoreProvider provider = newProvider(config); + + // 如果开启 Raft 模式,包装为 RaftBackendStoreProvider + if (raftMode) { + provider = new RaftBackendStoreProvider(params, provider); + } + provider.open(graph); + return provider; + } +} +``` + +### 3.8 关键配置 + +HStore 模式配置示例: + +```properties +# hugegraph.properties +backend=hstore +pd.peers=127.0.0.1:8686,127.0.0.1:8687,127.0.0.1:8688 +hstore.partition_count=24 +``` + +Store 节点也支持 ToplingDB(`hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml`): + +```yaml +rocksdb: + option_path: conf/topling-store.yaml + open_http: true +``` + +--- + +## 四、两者的关系与对比 + +| 维度 | ToplingDB | HStore | +|------|-----------|--------| +| **是什么** | 增强版存储引擎 | 分布式存储架构 | +| **替换什么** | 替换标准 RocksDB 的 open/close | 替换单机嵌入式存储模式 | +| **接入方式** | Java SPI + 反射,运行时探测 | BackendStoreProvider 插件注册 | +| **影响范围** | 仅引擎层(open/close 两个点) | 全栈(路由、分片、复制、事务) | +| **能否组合** | ✅ 可用于 HStore 节点内部 | ✅ 节点内部可用 ToplingDB | +| **侵入性** | 极低,零编译时依赖 | 中等,需要完整实现 Store 接口 | +| **依赖模块** | `hugegraph-rocksdb-provider` | `hugegraph-hstore` + `hugegraph-store` 集群 | +| **部署要求** | 只需替换 JAR + 运行启动脚本 | 需要独立部署 PD + Store 节点集群 | + +### 组合部署矩阵 + +| 部署模式 | 配置 | 效果 | +|----------|------|------| +| 单机 + 标准 RocksDB | `backend=rocksdb` + 标准 JAR | StandardRocksDBProvider | +| 单机 + ToplingDB | `backend=rocksdb` + ToplingDB JAR | ToplingRocksDBProvider(自动) | +| 分布式 + 标准 RocksDB | `backend=hstore` + Store 节点用标准 JAR | HStore + StandardRocksDBProvider | +| 分布式 + ToplingDB | `backend=hstore` + Store 节点用 ToplingDB JAR | HStore + ToplingRocksDBProvider | + +--- + +## 五、Maven 依赖链 + +``` +hugegraph (root pom.xml) +│ +├── hugegraph-rocksdb-provider ← 独立模块 +│ └── rocksdbjni:8.10.2-SNAPSHOT ← ToplingDB 增强版 RocksDB JNI +│ └── snakeyaml:2.2 ← YAML 配置解析 +│ └── json-smart:2.3 ← JSON 构建(SidePluginRepo 参数) +│ +├── hugegraph-server/hugegraph-rocksdb ← 单机 RocksDB 后端 +│ └── depends on: hugegraph-rocksdb-provider +│ +├── hugegraph-server/hugegraph-hstore ← HStore 客户端 +│ └── depends on: hg-store-client ← gRPC 客户端 +│ └── depends on: hg-pd-client ← PD 客户端 +│ +└── hugegraph-store/hg-store-rocksdb ← Store 节点存储层 + └── depends on: hugegraph-rocksdb-provider ← 同一个 SPI 模块! +``` + +ToplingDB Maven artifact 来源(`.github/configs/settings.xml`): + +```xml + + github-toplingdb + https://maven.pkg.github.com/hugegraph/toplingdb + +``` + +--- + +## 六、关键源码文件索引 + +| 文件 | 作用 | +|------|------| +| `hugegraph-rocksdb-provider/src/.../RocksDBProvider.java` | SPI 接口定义 | +| `hugegraph-rocksdb-provider/src/.../ToplingRocksDBProvider.java` | ToplingDB 适配核心 | +| `hugegraph-rocksdb-provider/src/.../StandardRocksDBProvider.java` | 标准 RocksDB 降级方案 | +| `hugegraph-rocksdb-provider/src/.../RocksDBProviderLoader.java` | ServiceLoader + Provider 选择 | +| `hugegraph-server/hugegraph-rocksdb/src/.../RocksDBStdSessions.java` | 单机模式调用入口 | +| `hugegraph-server/hugegraph-rocksdb/src/.../RocksDBOptions.java` | 配置项定义 | +| `hugegraph-server/hugegraph-rocksdb/src/.../OpenedRocksDB.java` | close 调用入口 | +| `hugegraph-server/hugegraph-hstore/src/.../HstoreProvider.java` | HStore 后端入口 | +| `hugegraph-server/hugegraph-hstore/src/.../HstoreSessionsImpl.java` | HStore gRPC 通信核心 | +| `hugegraph-server/hugegraph-hstore/src/.../HstoreStore.java` | HStore 存储抽象 | +| `hugegraph-store/hg-store-rocksdb/src/.../RocksDBSession.java` | Store 节点 RocksDB 层 | +| `hugegraph-server/hugegraph-core/src/.../BackendProviderFactory.java` | 后端工厂(注册与发现) | +| `hugegraph-server/hugegraph-dist/src/.../bin/common-topling.sh` | Native 库预加载脚本 | +| `hugegraph-server/hugegraph-dist/src/.../bin/preload-topling.sh` | 启动时调用入口 | + +--- + +## 七、总结 + +1. **ToplingDB 接入的精髓**是"最小侵入":只在 `RocksDB.open()` 和 `rocksdb.close()` 两个调用点做替换,通过 Java SPI 机制实现零编译时依赖、运行时自动发现和优雅降级。所有 ToplingDB 特有 API(`SidePluginRepo`)均通过反射调用,确保标准 RocksDB 环境下代码完全正常运行。 + +2. **HStore 接入的精髓**是"透明分布式":通过实现 `BackendStoreProvider` 接口,将分布式集群(PD + Store 节点 + Raft 共识)封装为与单机 RocksDB 相同的语义。上层查询引擎无需任何修改即可从单机切换到分布式。 + +3. **两者共享 `hugegraph-rocksdb-provider` 模块**:无论是单机 `hugegraph-server/hugegraph-rocksdb` 路径,还是分布式 `hugegraph-store/hg-store-rocksdb` 路径,都依赖同一个 Provider SPI 模块。这意味着 ToplingDB 的性能优势在两种部署模式下都能获得。 diff --git a/docs/toplingdb/toplingdb-operations.md b/docs/toplingdb/toplingdb-operations.md new file mode 100644 index 0000000000..b5e3ea9055 --- /dev/null +++ b/docs/toplingdb/toplingdb-operations.md @@ -0,0 +1,87 @@ +# ToplingDB Operations Guide + +This guide outlines key operational practices for deploying, monitoring, tuning, and upgrading ToplingDB in production environments. It is intended for system administrators, DevOps engineers, and database maintainers seeking to ensure stability, performance, and scalability. + +--- + +## Monitoring Metrics + +- **Key Performance Indicators (KPI)** + - Write throughput (bytes/sec, ops/sec) + - Read latency (P95/P99) + - MemTable usage and flush frequency + - Block cache hit ratio + +- **Alert Thresholds** + - L0 file count exceeding `level0_stop_writes_trigger` + - Background job saturation (`max_background_jobs`) + - WAL size growth beyond expected limits + - Cache eviction rate anomalies + +- **Monitoring Tool Integration** + - Export metrics via HTTP endpoints + - Integrate with Prometheus using custom exporters + - Visualize trends and thresholds in Grafana dashboards + - Use SidePlugin’s web server (`listening_ports`) for live inspection + +--- + +## Performance Tuning + +- **Cache Size Optimization** + - Adjust `capacity` in `lru_cache` based on workload and memory budget + - Tune `high_pri_pool_ratio` to prioritize index/filter caching + +- **Compression Algorithm Selection** + - Use `kSnappyCompression` for balanced speed and space + - Disable compression (`kNoCompression`) for latency-sensitive workloads + +- **Compaction Strategy Adjustment** + - Set `level0_file_num_compaction_trigger` to control L0 flush frequency + - Use `level_compaction_dynamic_file_size: true` to adapt SST sizing + - Tune `max_subcompactions` and `max_background_jobs` for parallelism + +- **I/O Tuning Parameters** + - Evaluate `convert_to_sst: kFileMmap` to bypass traditional flush + - Set `sync_sst_file: false` for performance, with caution on durability + - Adjust `compaction_readahead_size` for sequential disk access + +--- + +## Capacity Planning + +- **Disk Space Estimation** + - Base on `write_buffer_size`, `target_file_size_base`, and compaction amplification + - Include space for WAL, MANIFEST, and temporary files + +- **Memory Requirement Calculation** + - Sum of MemTable (`mem_cap`), block cache (`capacity`), and background buffers + - Consider `max_write_buffer_number` and `min_write_buffer_number_to_merge` + +- **CPU Resource Planning** + - Allocate cores for compaction (`max_background_compactions`) + - Reserve CPU for Hugegraph query threads and SidePlugin HTTP services + - Monitor mutex contention (`use_adaptive_mutex`) and shard parallelism + +--- + +## Upgrade Procedure + +- **Version Compatibility Check** + - Review changelogs and YAML schema changes + - Validate plugin compatibility (e.g., `cspp`, `DispatcherTable`) + +- **Data Backup Strategy** + - Snapshot SST files and MANIFEST + - Backup column family metadata and configuration files + +- **Rolling Upgrade Steps** + - Drain traffic from target node + - Stop ToplingDB process and apply new binary + - Validate startup with `create_if_missing: false` + - Rejoin cluster and monitor metrics + +- **Rollback Plan** + - Restore previous binary and configuration + - Revert SST and MANIFEST from backup + - Disable incompatible plugins if needed diff --git a/docs/toplingdb/toplingdb-security.md b/docs/toplingdb/toplingdb-security.md new file mode 100644 index 0000000000..e57b877426 --- /dev/null +++ b/docs/toplingdb/toplingdb-security.md @@ -0,0 +1,50 @@ +# ToplingDB Security Hardening Guide + +This document provides best practices for securing a ToplingDB deployment. It covers file permissions, network access control, firewall rules, and additional hardening measures to reduce the attack surface and ensure safe operation in production environments. + +--- + +## 1. File Permissions + +Restrict file permissions to prevent unauthorized access or modification of scripts and configuration files: + +```bash +chmod 750 $HUGEGRAPH_HOME/bin/*.sh +chmod 640 $HUGEGRAPH_HOME/conf/graphs/*.yaml +chown -R hugegraph:hugegraph $HUGEGRAPH_HOME +``` + +- `750` ensures only the owner can execute scripts, while group members can read them. +- `640` ensures configuration files are readable by the owner and group, but not world-readable. +- Ownership should be assigned to a dedicated service account (e.g., `hugegraph`). + +--- + +## 2. Network Access Control + +Restrict network exposure by binding services to localhost or specific interfaces: + +```yaml +# Localhost-only access +http: + listening_ports: '127.0.0.1:2011' +``` + +- Avoid binding to `0.0.0.0` unless absolutely necessary. +- Use reverse proxies (e.g., Nginx) or VPN tunnels if remote access is required. + +--- + +## 3. Firewall Rules + +Use firewall rules to limit access to trusted IP ranges: + +```bash +# Allow only specific subnet to access the Web Server +iptables -A INPUT -p tcp --dport 2011 \ + -s 192.168.1.0/24 -j ACCEPT +iptables -A INPUT -p tcp --dport 2011 -j DROP +``` + +- Replace `192.168.1.0/24` with your trusted network. +- Consider using `firewalld` or `ufw` for simplified management. diff --git a/docs/toplingdb/toplingdb-troubleshooting.md b/docs/toplingdb/toplingdb-troubleshooting.md new file mode 100644 index 0000000000..68d8072c46 --- /dev/null +++ b/docs/toplingdb/toplingdb-troubleshooting.md @@ -0,0 +1,138 @@ +# ToplingDB Troubleshooting + +## Issues + +### Issue 1: Startup Failure Due to YAML Format Error + +Sample log output: + +```java +2025-10-15 01:55:50 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStdSessions - SidePluginRepo found. Will attempt to open multi CFs RocksDB using Topling plugin. +21:1: (891B):ERROR: +sideplugin/rockside/3rdparty/rapidyaml/src/c4/yml/parse.cpp:3310: ERROR parsing yml: parse error: incorrect indentation? +``` + +**Solution**: + +1. Check that YAML indentation is correct (must use spaces, not tabs). +2. Validate YAML syntax: + + ```bash + python -c "import yaml; yaml.safe_load(open('conf/graphs/rocksdb_plus.yaml'))" + ``` + +3. Review the specific error message in the logs for further clues. + +--- + +### Issue 2: Web Server Port Conflict + +Sample log output: + +```java +2025-10-15 01:57:34 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStdSessions - SidePluginRepo found. Will attempt to open multi CFs RocksDB using Topling plugin. +2025-10-15 01:57:34 [db-open-1] [ERROR] o.a.h.b.s.r.RocksDBStore - Failed to open RocksDB 'rocksdb-data/data/g' +org.rocksdb.RocksDBException: rocksdb::Status rocksdb::SidePluginRepo::StartHttpServer(): null context when constructing CivetServer. Possible problem binding to port. + at org.rocksdb.SidePluginRepo.startHttpServer(Native Method) ~[rocksdbjni-8.10.2-20250804.074027-4.jar:?] +``` + +**Solution**: + +1. Check if the port is already in use: + + ```bash + lsof -i :2011 + ``` + +2. Modify the `listening_ports` setting in the YAML configuration file. +3. Restart the HugeGraph Server. + +--- + +### Issue 3: Database Initialization Failure + +This error indicates the database lock file cannot be acquired, possibly due to insufficient write permissions or another process holding the lock: + +```java +Caused by: org.rocksdb.RocksDBException: While lock file: rocksdb-data/data/m/LOCK: Resource temporarily unavailable + at org.rocksdb.SidePluginRepo.nativeOpenDBMultiCF(Native Method) + at org.rocksdb.SidePluginRepo.openDB(SidePluginRepo.java:22) +``` + +**Solution**: + +1. Confirm the configuration file path is correct: + + ```properties + rocksdb.option_path=./conf/graphs/rocksdb_plus.yaml + ``` + +2. Check permissions on the data directory to ensure the running user has read/write access. +3. Review detailed logs: + + ```bash + bin/init-store.sh 2>&1 | tee init.log + ``` + +--- + +## Log Analysis + +### Enable Debug Logging + +```properties +# conf/log4j2.xml + +``` + +### Key Log Locations + +- Application logs: `logs/hugegraph-server.log` +- RocksDB logs: `data/rocksdb/LOG` +- Web Server logs: check the `access_log` setting in the YAML configuration + +Additional notes: + +- Enable debug logging only during troubleshooting, as it may generate large log files and impact performance. +- Rotate and archive logs regularly to prevent disk space exhaustion. + +--- + +## Performance Diagnostics + +### High CPU Usage + +1. Review and tune **compaction** configuration (e.g., compaction style, trigger thresholds). +2. Adjust **thread pool size** to match available CPU cores and workload characteristics. +3. Optimize **write batching** to reduce per-operation overhead. +4. Monitor for **hot keys** or skewed workloads that may cause uneven CPU usage. +5. Use performance profiling tools (e.g., `perf`, `async-profiler`) to identify hotspots. + +--- + +### Excessive Memory Usage + +1. Adjust **block cache size** to balance between read performance and memory footprint. +2. Review **write buffer** (memtable) configuration, including number and size. +3. Monitor for **memory leaks** in the application layer or plugins. +4. Enable **JVM GC logging** to analyze garbage collection behavior. + +--- + +### Disk I/O Bottlenecks + +1. Use **SSD storage** for RocksDB data directories to improve latency and throughput. +2. Tune **WAL (Write-Ahead Log)** configuration, such as enabling `wal_dir` on a separate disk. +3. Optimize **compaction strategy** (e.g., level-based vs. universal compaction) based on workload. +4. Monitor **disk utilization** and IOPS using tools like `iostat` or `dstat`. +5. Separate **data, WAL, and log directories** onto different physical devices if possible. + +--- + +### General Recommendations + +- Always benchmark configuration changes in a staging environment before applying them to production. +- Use monitoring systems (e.g., Prometheus + Grafana) to track CPU, memory, and I/O metrics over time. +- Regularly review RocksDB’s internal statistics (`rocksdb.stats`) for deeper insights into performance. +- Automate log collection and alerting to quickly detect anomalies. diff --git a/docs/toplingdb/toplingdb.md b/docs/toplingdb/toplingdb.md new file mode 100644 index 0000000000..2a0566fde0 --- /dev/null +++ b/docs/toplingdb/toplingdb.md @@ -0,0 +1,179 @@ +# ToplingDB Support and Configuration + +- **Status**: Implemented +- **Pull Request**: [#15](https://github.com/hugegraph/hugegraph/pull/15) + +## Background knowledge + +[ToplingDB](https://github.com/topling/toplingdb) is a high-performance, cloud-native key-value store built as a fork of RocksDB. + +ToplingDB extends RocksDB with several advanced features: + +- **Searchable Compression**: ToplingDB introduces compression algorithms that preserve searchability, enabling efficient queries directly on compressed data. +- **SidePlugin Architecture**: It supports configuration via YAML files through a plugin system, allowing tuning parameters without recompilation. +- **Built-in Observability**: A lightweight HTTP server exposes internal metrics and configuration states, making it easier to monitor and debug storage behavior. +- **Distributed Compaction**: Designed for cloud environments, ToplingDB supports distributed compaction strategies to reduce write amplification and improve throughput. +- **Compatibility**: Drop-in replacement for RocksDB in most use cases. + +## Motivation + +Introduce a new optional storage component in HugeGraph to support [ToplingDB](https://github.com/topling/toplingdb)), a configurable and observable extension of the RocksDB storage engine. + +ToplingDB resolves key limitations in HugeGraph’s current `rocksdbjni` integration, which relies heavily on hard-coding parameters and lacks runtime configurability and observability. + +By enabling YAML-based configuration and exposing a Web Server interface, ToplingDB allows users to fine-tune performance and monitor engine behavior without modifying code or restarting services. + +This is especially valuable in environments where storage workloads vary across deployments, and where operational transparency is critical for debugging and optimization. + +For example, in production clusters with heterogeneous hardware or mixed graph workloads, users can adjust compaction, caching, and I/O settings to match their performance goals. + +Additionally, ToplingDB maintains full compatibility with the existing RocksDB API, allowing seamless migration and fallback. Users can opt into ToplingDB via configuration, without impacting legacy data or workflows. + +By supporting ToplingDB, HugeGraph empowers users with greater control over storage behavior, simplifies deployment through automated dynamic library loading, and enhances operational insight—all while preserving compatibility and ease of use. + +## Goals + +**Introduce ToplingDB as a configurable and observable alternative to RocksDB.** + +Enable users to select ToplingDB via configuration, allowing tuning parameters through YAML files without recompilation and real-time monitoring via Web Server—without sacrificing compatibility with existing RocksDB APIs. + +## Design + +### Configuration Parameters + +To support ToplingDB in HugeGraph, two new configuration parameters have been introduced: `rocksdb.option_path` and `rocksdb.open_http`. These options allow users to configure RocksDB parameters and enable real-time observability. + +#### `rocksdb.option_path`: External YAML Configuration + +This parameter allows users to specify a YAML file that defines ToplingDB settings such as compaction strategy, cache size, compression type, and more. + +- **Purpose**: Replace hard-coding parameters with flexible, file-based configuration. + +- **Usage**: Add the following line to your `hugegraph.properties` file: + + ```properties + rocksdb.option_path=./conf/graphs/rocksdb_plus.yaml + ``` + + The specified YAML file will be automatically loaded during database initialization if ToplingDB is available. + + For security reasons, HugeGraph only allows YAML files to be stored under the `$HUGEGRAPH_HOME/conf/graphs` directory. + + For details on the YAML structure and supported configuration fields, please refer to [SidePlugin](https://github.com/topling/sideplugin-wiki-en/wiki). + +- **Implementation**: During initialization, HugeGraph checks whether the configured JAR contains ToplingDB APIs. If so, it uses reflection to load the SidePluginRepo class and calls `importAutoFile(optionPath)` to parse the YAML file. The resulting configuration is applied to the RocksDB instance. + +- **Fallback**: If the YAML file is not provided or ToplingDB is unavailable, HugeGraph will fall back to standard RocksDB behavior. + +#### `rocksdb.open_http`: Enable Web Server for Observability + +This boolean flag controls whether the embedded Web Server in ToplingDB should be started. The server exposes runtime metrics, configuration status, and internal RocksDB statistics via a browser-accessible interface. + +- **Purpose**: Provide real-time visibility into the storage engine for debugging and performance tuning. + +- **Usage**: Add the following line to your `hugegraph.properties` file: + + ```properties + rocksdb.open_http=true + ``` + + The listening port is defined in the YAML file specified by `option_path`, under the key `http.listening_ports`: + + ```yaml + http: + document_root: /dev/shm/rocksdb_resource + listening_ports: '127.0.0.1:2011' # by default, only local access is allowed + ``` + + For security reasons, the default configuration only allows local access. + When adjusting this setting, users should carefully manage port and network access permissions to avoid potential security incidents. + To preview the Web Server interface and its layout, see [Web Server](https://github.com/topling/sideplugin-wiki-en/wiki/WebView). + +- **Implementation**: If `open_http` is set to true and the database instance is `GRAPH_STORE`, HugeGraph invokes `startHttpServer()` on the ToplingDB repo object. This exposes a browser-accessible dashboard for monitoring RocksDB internals. + +- **Scope**: For simplicity, the Web Server is only enabled for the `GRAPH_STORE` instance, which holds the main graph data. + +- **Security**: The Web Server does **not** provide built-in authentication. In production environments, configure firewalls or network access controls carefully to prevent unauthorized access. + +### Reflection-Based Loading Mechanism + +To support ToplingDB without introducing hard dependencies, HugeGraph uses Java reflection to detect and load enhanced APIs at runtime. + +During initialization, HugeGraph checks whether the current JAR contains the class `com.topling.sideplugin.SidePluginRepo`. If present, it assumes ToplingDB is available and proceeds to: + +1. **Load the SidePluginRepo class via reflection** This avoids compile-time coupling and allows fallback to standard RocksDB if the class is missing. + - If the ToplingDB API cannot be found, HugeGraph silently falls back to the standard RocksDB API for startup. +2. **Invoke** `importAutoFile(optionPath)` This method parses the YAML configuration file specified by `rocksdb.option_path` to configure storage engine parameters. + - If the `option_path` is incorrect or parsing fails, ToplingDB throws an error and terminates the startup process. +3. **Call** `open()` **with a JSON descriptor** The parsed configuration is converted to a JSON structure and passed to the ToplingDB engine to initialize the database. +4. **Optionally start the Web Server** If `rocksdb.open_http` is true and the instance is `GRAPH_STORE`, HugeGraph invokes `startHttpServer()` via reflection to enable observability. + - If the Web Server cannot be started due to misconfiguration **or if the specified HTTP port is already in use**, ToplingDB throws an error and the startup process is terminated + +This design ensures that ToplingDB can be integrated as an optional enhancement, without breaking compatibility or requiring changes to the core HugeGraph codebase. + +## Impact + +### For Users + +The way users operate remains unchanged by default, and adding ToplingDB configuration provides additional functionality. +The ToplingDB integration is fully embedded into the existing startup scripts (`init-store.sh` and `start-hugegraph.sh`). Users only need to set `rocksdb.option_path` to specify the YAML file path and adjust its contents as needed to tune the storage engine. + +### For Developers + +Developers need to make two adjustments to enable ToplingDB during development: + +1. **Maven Repository Configuration**: since ToplingDB is published via GitHub Packages, developers must add the GitHub repository to their `settings.xml` to fetch the correct JAR: + + ```xml + + + + + github + YOUR_GITHUB_ACTOR + + YOUR_GITHUB_TOKEN + + + + + + ... + + ... + + + github + https://maven.pkg.github.com/hugegraph/toplingdb + + true + + + + + + ``` + +2. **IDE Environment Setup**: developers must configure runtime environment variables to preload required native libraries. + The `preload-topling.sh` script not only extracts the necessary dynamic libraries and web server static resources into the `library` directory next to the `bin` directory, + but also sets the required environment variables in the current process. + When executed in a terminal using `source preload-topling.sh`, these variables take effect immediately in that shell session. + + However, when launching HugeGraph from an IDE, the program typically runs in a separate process, + so environment variables defined in scripts run from the terminal are not inherited. + In this case, developers need to manually configure the IDE's run/debug environment variables to ensure proper preloading of native libraries. + + In your IDE’s Run/Debug Configuration, set: + + ```bash + LD_LIBRARY_PATH="/path/to/your/library:${LD_LIBRARY_PATH}" + LD_PRELOAD="libjemalloc.so:librocksdbjni.so" + ``` + +These steps ensure that ToplingDB loads correctly in development environments and behaves consistently with production deployments. + +## Links + +- **ToplingDB**: [https://github.com/topling/toplingdb](https://github.com/topling/toplingdb) +- **Configuration YAML of ToplingDB**: [https://github.com/topling/sideplugin-wiki-en/wiki](https://github.com/topling/sideplugin-wiki-en/wiki) +- **Web Server of ToplingDB**: [https://github.com/topling/sideplugin-wiki-en/wiki/WebView](https://github.com/topling/sideplugin-wiki-en/wiki/WebView) diff --git a/hugegraph-pd/hg-pd-cli/pom.xml b/hugegraph-pd/hg-pd-cli/pom.xml index 4920174d76..98b5954278 100644 --- a/hugegraph-pd/hg-pd-cli/pom.xml +++ b/hugegraph-pd/hg-pd-cli/pom.xml @@ -49,7 +49,7 @@ com.alipay.sofa jraft-core - 1.3.13 + 1.3.14 org.rocksdb diff --git a/hugegraph-pd/hg-pd-core/pom.xml b/hugegraph-pd/hg-pd-core/pom.xml index e17570d592..48d43dbd41 100644 --- a/hugegraph-pd/hg-pd-core/pom.xml +++ b/hugegraph-pd/hg-pd-core/pom.xml @@ -38,7 +38,7 @@ com.alipay.sofa jraft-core - 1.3.13 + 1.3.14 org.rocksdb @@ -49,7 +49,7 @@ org.rocksdb rocksdbjni - 6.29.5 + ${rocksdb.version} org.apache.hugegraph diff --git a/hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/store/HgKVStoreImpl.java b/hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/store/HgKVStoreImpl.java index bd2e7a9e22..6f7ea817b5 100644 --- a/hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/store/HgKVStoreImpl.java +++ b/hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/store/HgKVStoreImpl.java @@ -67,7 +67,7 @@ public void init(PDConfig config) { final Lock writeLock = this.readWriteLock.writeLock(); writeLock.lock(); try { - this.dbPath = config.getDataPath() + "/rocksdb/"; + this.dbPath = config.getDataPath() + "/rocksdb"; File file = new File(this.dbPath); if (!file.exists()) { try { diff --git a/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh b/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh index 1329df2271..cbea4cee0e 100755 --- a/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh +++ b/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/start-hugegraph-pd.sh @@ -63,9 +63,20 @@ PID_FILE="$BIN/pid" . "$BIN"/util.sh +PARENT_DIR="$(cd "$TOP"/../ && pwd)" +SERVER_VERSION_DIR="${SERVER_VERSION_DIR:-$(find_hugegraph_server_dir "$PARENT_DIR")}" + ensure_path_writable "$LOGS" ensure_path_writable "$PLUGINS" +# preload rocksdb/toplingdb +if [ -n "$SERVER_VERSION_DIR" ] && [ -e "$SERVER_VERSION_DIR/bin/preload-topling.sh" ]; then + if [ -z "${TOPLINGDB_EASY_MIGRATE_CONF:-}" ]; then + TOPLINGDB_EASY_MIGRATE_CONF="$CONF/rocksdb_pd.yaml" + fi + source "$SERVER_VERSION_DIR/bin/preload-topling.sh" +fi + # The maximum and minimum heap memory that service can use MAX_MEM=$((32 * 1024)) MIN_MEM=$((1 * 512)) diff --git a/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/util.sh b/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/util.sh index 0b7ad0f0f0..21ae82acf8 100644 --- a/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/util.sh +++ b/hugegraph-pd/hg-pd-dist/src/assembly/static/bin/util.sh @@ -371,3 +371,21 @@ function kill_process_and_wait() { kill_process "$process_name" "$pid" wait_for_shutdown "$process_name" "$pid" "$timeout_s" } + +# Find HugeGraph server directory in parent path using prefix glob. +# Usage: find_hugegraph_server_dir "/path/to/parent" +# Returns: first matching directory path or empty string +function find_hugegraph_server_dir() { + local parent_dir="$1" + if [ -z "$parent_dir" ]; then + parent_dir="$(cd "${TOP:-$(pwd)}"/.. && pwd)" + fi + local found="" + for d in "$parent_dir"/apache-hugegraph-server*; do + if [ -d "$d" ]; then + found="$d" + break + fi + done + echo "$found" +} diff --git a/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/application.yml b/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/application.yml index eb8fda4526..8828674874 100644 --- a/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/application.yml +++ b/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/application.yml @@ -39,6 +39,9 @@ grpc: port: 8686 # The service address of grpc needs to be changed to the actual local IPv4 address when deploying. host: 127.0.0.1 +# rocksdb: + # option-path: ./conf/graphs/rocksdb_pd.yaml + # open-http: true server: # REST service port number diff --git a/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/rocksdb_pd.yaml b/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/rocksdb_pd.yaml new file mode 100644 index 0000000000..9dadbc73c4 --- /dev/null +++ b/hugegraph-pd/hg-pd-dist/src/assembly/static/conf/rocksdb_pd.yaml @@ -0,0 +1,158 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# common parameters +http: + # normally parent path of db path + document_root: /dev/shm/rocksdb_resource + listening_ports: '127.0.0.1:2012' + auto_start_http: true +setenv: + StrSimpleEnvNameNotOverwrite: StringValue + IntSimpleEnvNameNotOverwrite: 16384 + OverwriteThisEnv: + #comment: overwrite is default to false + overwrite: true + value: force overwrite this env by overwrite true +Cache: + lru_cache: + class: LRUCache + params: + capacity: 8G + num_shard_bits: -1 + strict_capacity_limit: false + high_pri_pool_ratio: 0.5 + use_adaptive_mutex: false + metadata_charge_policy: kFullChargeCacheMetadata +Statistics: + stat: + class: default + params: + discard_tickers: + - rocksdb.block.cache + - rocksdb.block.cachecompressed + - rocksdb.block + - rocksdb.memtable.payload.bytes.at.flush + - rocksdb.memtable.garbage.bytes.at.flush + - rocksdb.txn + - rocksdb.blobdb + - rocksdb.row.cache + - rocksdb.number.block + - rocksdb.bloom.filter + - rocksdb.persistent + - rocksdb.sim.block.cache + discard_histograms: + # comment: .... + - rocksdb.blobdb + - rocksdb.bytes.compressed + - rocksdb.bytes.decompressed + - rocksdb.num.index.and.filter.blocks.read.per.level + - rocksdb.num.data.blocks.read.per.level + - rocksdb.compression.times.nanos + - rocksdb.decompression.times.nanos + - rocksdb.read.block.get.micros + - rocksdb.write.raw.block.micros + # comment end of array + #stats_level: kAll + stats_level: kDisableAll +MemTableRepFactory: + cspp: + class: cspp + params: + mem_cap: 16G + use_vm: false + token_use_idle: true + chunk_size: 16K + convert_to_sst: kFileMmap + sync_sst_file: false + skiplist: + class: SkipList + params: + lookahead: 0 +TableFactory: + cspp_memtab_sst: + class: CSPPMemTabTable + params: # empty params + bb: + class: BlockBasedTable + params: + checksum: kCRC32c + block_size: 4K + block_restart_interval: 16 + index_block_restart_interval: 1 + metadata_block_size: 4K + enable_index_compression: true + block_cache: "${lru_cache}" + readers: + BlockBasedTable: bb + CSPPMemTabTable: cspp_memtab_sst + block_cache_compressed: + persistent_cache: + filter_policy: + dispatch: + class: DispatcherTable + params: + default: bb + readers: + BlockBasedTable: bb + CSPPMemTabTable: cspp_memtab_sst + level_writers: [ bb, bb, bb, bb, bb, bb ] +CFOptions: + default: + max_write_buffer_number: 6 + memtable_factory: "${cspp}" + write_buffer_size: 128M + # set target_file_size_base as small as 512K is to make many SST files, + # thus key prefix cache can present efficiency + target_file_size_base: 64M + target_file_size_multiplier: 1 + table_factory: dispatch + max_bytes_for_level_base: 512M + max_bytes_for_level_multiplier: 10 + level_compaction_dynamic_level_bytes: false + level0_slowdown_writes_trigger: 20 + level0_stop_writes_trigger: 36 + level0_file_num_compaction_trigger: 2 + merge_operator: uint64add # support merge + level_compaction_dynamic_file_size: true + optimize_filters_for_hits: true + allow_merge_memtables: true + min_write_buffer_number_to_merge: 2 + compression_per_level: + - kNoCompression + - kNoCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression +DBOptions: + log: + create_if_missing: true + create_missing_column_families: true + default: + create_if_missing: true + create_missing_column_families: false # this is important, must be false to hugegraph + max_background_compactions: -1 + max_subcompactions: 4 + max_level1_subcompactions: 0 + inplace_update_support: false + WAL_size_limit_MB: 0 + statistics: "${stat}" + max_manifest_file_size: 100M + max_background_jobs: 8 + compaction_readahead_size: 0 + memtable_as_log_index: true diff --git a/hugegraph-server/hugegraph-core/pom.xml b/hugegraph-server/hugegraph-core/pom.xml index 2334496329..c85feffaaa 100644 --- a/hugegraph-server/hugegraph-core/pom.xml +++ b/hugegraph-server/hugegraph-core/pom.xml @@ -29,7 +29,7 @@ ${basedir}/.. - 1.3.11 + 1.3.14 0.7.4 5.12.1 1.8.1 diff --git a/hugegraph-server/hugegraph-dist/pom.xml b/hugegraph-server/hugegraph-dist/pom.xml index 5914b038be..fbf898b21a 100644 --- a/hugegraph-server/hugegraph-dist/pom.xml +++ b/hugegraph-server/hugegraph-dist/pom.xml @@ -140,6 +140,9 @@ ${basedir}/src/assembly/static true + + lib/topling/** + ${basedir}/src/main/resources diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/common-topling.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/common-topling.sh new file mode 100644 index 0000000000..7ea9599b02 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/common-topling.sh @@ -0,0 +1,306 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -Eeuo pipefail +IFS=$'\n\t' +trap 'echo "[common-topling] error at line ${LINENO}: ${BASH_COMMAND}" >&2' ERR + +GITHUB="https://github.com" + +function abs_path() { + local SOURCE + SOURCE="${BASH_SOURCE[0]}" + while [[ -h "$SOURCE" ]]; do + local DIR + DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" + done + cd -P "$(dirname "$SOURCE")" && pwd +} + +function extract_so_with_jar() { + local jar_file="$1" + local dest_dir="$2" + local abs_jar_path + + if [ ! -f "$jar_file" ]; then + echo "'$jar_file' Not Exist" >&2 + return 1 + fi + + mkdir -p "$dest_dir" || { + echo "Cannot mkdir '$dest_dir'" >&2 + return 1 + } + + if command -v realpath >/dev/null 2>&1; then + abs_jar_path="$(realpath "$jar_file")" + else + abs_jar_path="$(readlink -f "$jar_file")" + fi + if ! command -v unzip >/dev/null 2>&1; then + echo "Error: 'unzip' command not found. Please install unzip." >&2 + return 1 + fi + unzip -j -o "$abs_jar_path" "*.so" -d "$dest_dir" > /dev/null 2>&1 || { + local code=$? + if [ $code -eq 11 ]; then + echo "Error: No .so files found in '$abs_jar_path' (unzip exit 11)" >&2 + else + echo "Error: unzip failed (exit $code) for '$abs_jar_path'" >&2 + fi + return $code + } +} + +function extract_html_css_from_jar() { + local jar_file="$1" + local dest_dir="$2" + local abs_jar_path + # Prefer /dev/shm on Linux for speed; fallback to TMPDIR or /tmp + local resource_target + if [ "$(uname -s)" = "Linux" ] && [ -d /dev/shm ]; then + resource_target="/dev/shm/rocksdb_resource" + else + resource_target="${TMPDIR:-/tmp}/rocksdb_resource" + fi + + if [ ! -f "$jar_file" ]; then + echo "Error: JAR file '$jar_file' does not exist." >&2 + return 1 + fi + + mkdir -p "$dest_dir" || { + echo "Error: Cannot create destination directory '$dest_dir'." >&2 + return 1 + } + + if command -v realpath >/dev/null 2>&1; then + abs_jar_path="$(realpath "$jar_file")" + else + abs_jar_path="$(readlink -f "$jar_file")" + fi + if ! command -v unzip >/dev/null 2>&1; then + echo "Error: 'unzip' command not found. Please install unzip." >&2 + return 1 + fi + unzip -j -o "$abs_jar_path" "*.html" "*.css" -d "$dest_dir" > /dev/null || { + local code=$? + if [ $code -eq 11 ]; then + echo "Notice: No .html or .css files found in '$jar_file'." >&2 + return 0 + else + echo "Error: unzip failed with exit code $code" >&2 + return $code + fi + } + + mkdir -p "$resource_target" || { + echo "Error: Cannot create target directory '$resource_target'." >&2 + return 1 + } + + if compgen -G "$dest_dir"/*.html >/dev/null 2>&1; then + cp -f "$dest_dir"/*.html "$resource_target"/ + fi + if compgen -G "$dest_dir"/*.css >/dev/null 2>&1; then + cp -f "$dest_dir"/*.css "$resource_target"/ + fi +} + +function ensure_libaio_symlink() { + # Check for Ubuntu 24.04+ and create a symlink for libaio if needed. + # This is a workaround for software expecting the old libaio.so.1 name, + # as it was renamed to libaio.so.1t64 in the new release. + # https://askubuntu.com/questions/1512196/libaio1-on-noble/1516639#1516639 + if [ -f /etc/os-release ]; then + . /etc/os-release + if [ "${ID:-}" = "ubuntu" ] && command -v dpkg >/dev/null 2>&1 && dpkg --compare-versions "${VERSION_ID:-0}" "ge" "24.04"; then + local libaio_link_target="/usr/lib/x86_64-linux-gnu/libaio.so.1" + if [ ! -e "$libaio_link_target" ]; then + echo "Ubuntu ${VERSION_ID:-?} detected. Creating compatibility symlink for libaio." + if [ -e /usr/lib/x86_64-linux-gnu/libaio.so.1t64 ]; then + if [ "$EUID" -eq 0 ]; then + ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64 "$libaio_link_target" || true + elif command -v sudo >/dev/null 2>&1; then + sudo ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64 "$libaio_link_target" || true + else + echo "Warn: sudo not available, skip creating $libaio_link_target" >&2 + fi + else + echo "Warn: libaio.so.1t64 not found, skip creating compat symlink" >&2 + fi + fi + fi + fi +} + +function download_and_verify() { + local url=$1 + local filepath=$2 + local expected_sha256=$3 + local actual_sha256 + + if [[ -f $filepath ]]; then + echo "File $filepath exists. Verifying SHA-256 checksum..." + actual_sha256=$(sha256sum "$filepath" | awk '{ print $1 }') + if [[ $actual_sha256 != $expected_sha256 ]]; then + echo "SHA-256 checksum verification failed for $filepath. Expected: $expected_sha256, but got: $actual_sha256" + echo "Deleting $filepath..." + rm -f "$filepath" + else + echo "SHA-256 checksum verification succeeded for $filepath." + return 0 + fi + fi + + echo "Downloading $filepath..." + curl -fL -o "$filepath" "$url" + + actual_sha256=$(sha256sum "$filepath" | awk '{ print $1 }') + if [[ $actual_sha256 != $expected_sha256 ]]; then + echo "SHA-256 checksum verification failed for $filepath after download. Expected: $expected_sha256, but got: $actual_sha256" + return 1 + fi + + return 0 +} + +function download_and_setup_jemalloc() { + local arch lib_file download_url expected_sha256 system_lib top + top=$1 + + if [[ "${LD_PRELOAD:-}" == *"libjemalloc"* ]]; then + return 0 + fi + + # Prefer system-installed jemalloc if available + # Try ldconfig first to locate the shared object + if command -v ldconfig >/dev/null 2>&1; then + system_lib=$(ldconfig -p 2>/dev/null | awk '/jemalloc/{print $4}' | head -n1) + fi + # Fallback to common library paths if ldconfig is not available or found nothing + if [[ -z "$system_lib" ]]; then + for p in \ + /usr/lib/libjemalloc.so \ + /usr/lib/libjemalloc.so.2 \ + /usr/lib64/libjemalloc.so \ + /usr/lib64/libjemalloc.so.2 \ + /usr/local/lib/libjemalloc.so \ + /usr/local/lib/libjemalloc.so.2 \ + /usr/lib/x86_64-linux-gnu/libjemalloc.so \ + /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 \ + /usr/lib/aarch64-linux-gnu/libjemalloc.so \ + /usr/lib/aarch64-linux-gnu/libjemalloc.so.2; do + if [[ -f "$p" ]]; then + system_lib="$p" + break + fi + done + fi + + # If found, set LD_PRELOAD and return immediately + if [[ -n "$system_lib" ]]; then + export LD_PRELOAD="${system_lib}${LD_PRELOAD:+:$LD_PRELOAD}" + return 0 + fi + + # Detect system architecture + arch=$(uname -m) + + # System jemalloc not found, try to download the correct library for the architecture + # Checksums match apache/hugegraph-doc@567625c6ec66907fc60f1864146fbec91b5f6204. + if [[ $arch == "aarch64" || $arch == "arm64" ]]; then + lib_file="$top/bin/libjemalloc_aarch64.so" + download_url="${GITHUB}/apache/hugegraph-doc/raw/binary-1.5/dist/server/libjemalloc_aarch64.so" + expected_sha256="6b7e6099b6da798829c6ce6fcb55a787508841edd52446332a73300889dcd1dc" + elif [[ $arch == "x86_64" ]]; then + lib_file="$top/bin/libjemalloc.so" + download_url="${GITHUB}/apache/hugegraph-doc/raw/binary-1.5/dist/server/libjemalloc.so" + expected_sha256="53b25e8626e1605cbd8b60befb3431cabc1b8851a54285e0dda412796feab67d" + else + echo "Unsupported architecture: $arch" + return 1 + fi + + # Download and verify jemalloc library (fallback when system lib not found) + if download_and_verify "$download_url" "$lib_file" "$expected_sha256"; then + export LD_PRELOAD="${lib_file}${LD_PRELOAD:+:$LD_PRELOAD}" + else + echo "Failed to verify or download jemalloc for $arch, skipping" + return 1 + fi +} + +function require_topling_platform() { + local os_name machine_arch + + os_name="$(uname -s)" + machine_arch="$(uname -m)" + if [ "$os_name" != "Linux" ] || + [[ "$machine_arch" != "x86_64" ]]; then + printf 'Error: ToplingDB native runtime supports Linux x86_64 only; ' >&2 + printf 'current platform is %s/%s\n' "$os_name" "$machine_arch" >&2 + return 1 + fi +} + +function preload_toplingdb() { + local lib_dir="$1" + local dest_dir="$2" + + require_topling_platform || return 1 + + local top="$(cd "$lib_dir"/../ && pwd)" + + local jar_file + jar_file=$(ls -1 "$lib_dir"/rocksdbjni*.jar 2>/dev/null | sort -V | tail -n1 || true) + if [ -z "${jar_file:-}" ]; then + echo "Error: No rocksdbjni*.jar found under '$lib_dir'" >&2 + return 1 + fi + + ensure_libaio_symlink + download_and_setup_jemalloc "$top" + extract_so_with_jar "$jar_file" "$dest_dir" + if [ -d "$dest_dir" ]; then + if [[ ":${LD_LIBRARY_PATH:-}:" != *":$dest_dir:"* ]]; then + export LD_LIBRARY_PATH="$dest_dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + fi + + if [ -f "$dest_dir/librocksdbjni-linux64.so" ] && [[ ":${LD_PRELOAD:-}:" != *"librocksdbjni-linux64.so:"* ]]; then + export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}$dest_dir/librocksdbjni-linux64.so" + fi + + # Persist environment for subsequent GitHub Actions steps + # so LD_* variables survive across separate run blocks. + if [ -n "${GITHUB_ENV:-}" ] && [ -w "$GITHUB_ENV" ]; then + { + echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" + echo "LD_PRELOAD=$LD_PRELOAD" + if [ -n "${SERVER_VERSION_DIR:-}" ]; then + echo "SERVER_VERSION_DIR=$SERVER_VERSION_DIR" + fi + } >> "$GITHUB_ENV" || true + echo "[common-topling] Exported LD_LIBRARY_PATH and LD_PRELOAD to GITHUB_ENV" >&2 || true + fi + else + echo "Warn: LD paths skipped, directory '$dest_dir' does not exist." >&2 + fi + extract_html_css_from_jar "$jar_file" "$dest_dir" +} diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh index 9aefd1160b..779605fe8c 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/init-store.sh @@ -47,6 +47,8 @@ cd "${TOP}" || exit DEFAULT_JAVA_OPTIONS="--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED" +source $BIN/preload-topling.sh + echo "Initializing HugeGraph Store..." # Build classpath with hugegraph*.jar first to avoid class loading conflicts diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/preload-topling.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/preload-topling.sh new file mode 100644 index 0000000000..13704bb9a8 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/preload-topling.sh @@ -0,0 +1,108 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -Eeuo pipefail +# Save original IFS to avoid leaking into parent shell when sourced +ORIG_IFS="${IFS}" +IFS=$'\n\t' +# Unified error capture for easy positioning +trap 'echo "[preload-topling] error at line ${LINENO}: ${BASH_COMMAND}" >&2' ERR + +SERVER_BIN="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVER_TOP="$(cd "$SERVER_BIN"/../ && pwd)" +SERVER_LIB="$SERVER_TOP/lib" +DEST_DIR="$SERVER_TOP/library" + +if [ ! -d "$SERVER_LIB" ]; then + echo "Error: LIB dir not found: $SERVER_LIB" >&2 + exit 1 +fi +if [ ! -f "$SERVER_BIN/common-topling.sh" ]; then + echo "Error: common-topling.sh not found under: $SERVER_BIN" >&2 + exit 1 +fi + +# Detect if ToplingDB provider is configured +# Check both .properties files (hugegraph-server) and .yml files (HStore) +PROVIDER=$(grep -sh "rocksdb.provider" "$SERVER_TOP"/conf/graphs/*.properties 2>/dev/null \ + | grep -v "^#" | grep -o "topling" | head -1 || true) +if [ -z "$PROVIDER" ]; then + PROVIDER=$(grep -sh "provider:" "$SERVER_TOP"/conf/application*.yml 2>/dev/null \ + | grep -v "^#" | grep -o "topling" | head -1 || true) +fi + +if [ "$PROVIDER" = "topling" ]; then + # --- ToplingDB mode: swap JAR and set up environment --- + + source "$SERVER_BIN/common-topling.sh" + type require_topling_platform >/dev/null 2>&1 || { + echo "Error: function require_topling_platform not found" >&2 + exit 1 + } + require_topling_platform || exit 1 + + TOPLING_JAR=$(ls -1 "$SERVER_LIB"/topling/rocksdbjni*.jar 2>/dev/null | sort -V | tail -1 || true) + if [ -z "${TOPLING_JAR:-}" ]; then + echo "Error: rocksdb.provider=topling but no ToplingDB JAR found in $SERVER_LIB/topling/" >&2 + echo " Please place the ToplingDB rocksdbjni JAR in lib/topling/ directory." >&2 + exit 1 + fi + + # Swap: move standard JAR aside, copy ToplingDB JAR into lib/ + STANDARD_JAR=$(ls -1 "$SERVER_LIB"/rocksdbjni*.jar 2>/dev/null | sort -V | tail -1 || true) + if [ -n "$STANDARD_JAR" ]; then + mv "$STANDARD_JAR" "$SERVER_LIB/topling/.standard-backup.jar" + echo "[preload-topling] Backed up standard JAR: $(basename "$STANDARD_JAR")" + fi + cp "$TOPLING_JAR" "$SERVER_LIB/" + echo "[preload-topling] Activated ToplingDB JAR: $(basename "$TOPLING_JAR")" + + # Run native library preload (extract .so, set LD_PRELOAD/LD_LIBRARY_PATH, jemalloc) + type preload_toplingdb >/dev/null 2>&1 || { echo "Error: function preload_toplingdb not found" >&2; exit 1; } + preload_toplingdb "$SERVER_LIB" "$DEST_DIR" + + # Prefer an Easy Migrate config supplied by the caller; + # otherwise check the existing Server and HStore config locations. + CONF_FILE="${TOPLINGDB_EASY_MIGRATE_CONF:-}" + if [ -z "$CONF_FILE" ]; then + CONF_FILE="$SERVER_TOP/conf/toplingdb.yaml" + if [ ! -f "$CONF_FILE" ]; then + CONF_FILE="$SERVER_TOP/conf/rocksdb_store.yaml" + fi + fi + if [ -f "$CONF_FILE" ]; then + export TOPLINGDB_EASY_MIGRATE_CONF="$CONF_FILE" + echo "[preload-topling] TOPLINGDB_EASY_MIGRATE_CONF=$CONF_FILE" + else + echo "[preload-topling] Warning: no ToplingDB config found, advanced features may not activate" >&2 + fi + + # Persist for GitHub Actions + if [ -n "${GITHUB_ENV:-}" ] && [ -w "$GITHUB_ENV" ]; then + echo "TOPLINGDB_EASY_MIGRATE_CONF=$TOPLINGDB_EASY_MIGRATE_CONF" >> "$GITHUB_ENV" || true + fi +else + # --- Standard RocksDB mode: no ToplingDB setup needed --- + echo "[preload-topling] rocksdb.provider=standard (or unset), skipping ToplingDB setup" +fi + +# Reset shell options to prevent affecting the parent shell when sourced +set +Eeuo pipefail +trap - ERR +# Restore original IFS +IFS="$ORIG_IFS" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/start-hugegraph.sh b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/start-hugegraph.sh index 2c99238327..02ed05a232 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/bin/start-hugegraph.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/bin/start-hugegraph.sh @@ -99,6 +99,8 @@ if [[ $PRELOAD == "true" ]]; then sed -i -e '/registerBackends/d; /serverStarted/d' "${SCRIPTS}/${EXAMPLE_SCRIPT}" fi +source $BIN/preload-topling.sh + if [[ $DAEMON == "true" ]]; then echo "Starting HugeGraphServer in daemon mode..." "${BIN}"/hugegraph-server.sh "${CONF}/${GREMLIN_SERVER_CONF}" "${CONF}"/rest-server.properties \ diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties index 26adfe0183..f424cdb1f8 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/graphs/hugegraph.properties @@ -43,6 +43,10 @@ search.text_analyzer_mode=INDEX # rocksdb backend config #rocksdb.data_path=/path/to/disk #rocksdb.wal_path=/path/to/disk +# To enable ToplingDB: uncomment the line below (requires ToplingDB JAR in lib/topling/) +# The startup script detects this setting and handles JAR swap + env var setup automatically. +# ToplingDB config: conf/toplingdb.yaml (auto-loaded via TOPLINGDB_EASY_MIGRATE_CONF env var) +#rocksdb.provider=topling # hbase backend config #hbase.hosts=localhost diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/toplingdb.yaml b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/toplingdb.yaml new file mode 100644 index 0000000000..d7108a711c --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/toplingdb.yaml @@ -0,0 +1,158 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# common parameters +http: + # normally parent path of db path + document_root: /dev/shm/rocksdb_resource + listening_ports: '127.0.0.1:2011' + auto_start_http: true +setenv: + StrSimpleEnvNameNotOverwrite: StringValue + IntSimpleEnvNameNotOverwrite: 16384 + OverwriteThisEnv: + #comment: overwrite is default to false + overwrite: true + value: force overwrite this env by overwrite true +Cache: + lru_cache: + class: LRUCache + params: + capacity: 8G + num_shard_bits: -1 + strict_capacity_limit: false + high_pri_pool_ratio: 0.5 + use_adaptive_mutex: false + metadata_charge_policy: kFullChargeCacheMetadata +Statistics: + stat: + class: default + params: + discard_tickers: + - rocksdb.block.cache + - rocksdb.block.cachecompressed + - rocksdb.block + - rocksdb.memtable.payload.bytes.at.flush + - rocksdb.memtable.garbage.bytes.at.flush + - rocksdb.txn + - rocksdb.blobdb + - rocksdb.row.cache + - rocksdb.number.block + - rocksdb.bloom.filter + - rocksdb.persistent + - rocksdb.sim.block.cache + discard_histograms: + # comment: .... + - rocksdb.blobdb + - rocksdb.bytes.compressed + - rocksdb.bytes.decompressed + - rocksdb.num.index.and.filter.blocks.read.per.level + - rocksdb.num.data.blocks.read.per.level + - rocksdb.compression.times.nanos + - rocksdb.decompression.times.nanos + - rocksdb.read.block.get.micros + - rocksdb.write.raw.block.micros + # comment end of array + #stats_level: kAll + stats_level: kDisableAll +MemTableRepFactory: + cspp: + class: cspp + params: + mem_cap: 16G + use_vm: false + token_use_idle: true + chunk_size: 16K + convert_to_sst: kFileMmap + sync_sst_file: false + skiplist: + class: SkipList + params: + lookahead: 0 +TableFactory: + cspp_memtab_sst: + class: CSPPMemTabTable + params: # empty params + bb: + class: BlockBasedTable + params: + checksum: kCRC32c + block_size: 4K + block_restart_interval: 16 + index_block_restart_interval: 1 + metadata_block_size: 4K + enable_index_compression: true + block_cache: "${lru_cache}" + readers: + BlockBasedTable: bb + CSPPMemTabTable: cspp_memtab_sst + block_cache_compressed: + persistent_cache: + filter_policy: + dispatch: + class: DispatcherTable + params: + default: bb + readers: + BlockBasedTable: bb + CSPPMemTabTable: cspp_memtab_sst + level_writers: [ bb, bb, bb, bb, bb, bb ] +CFOptions: + default: + max_write_buffer_number: 6 + memtable_factory: "${cspp}" + write_buffer_size: 128M + # set target_file_size_base as small as 512K is to make many SST files, + # thus key prefix cache can present efficiency + target_file_size_base: 64M + target_file_size_multiplier: 1 + table_factory: dispatch + max_bytes_for_level_base: 512M + max_bytes_for_level_multiplier: 10 + level_compaction_dynamic_level_bytes: false + level0_slowdown_writes_trigger: 20 + level0_stop_writes_trigger: 36 + level0_file_num_compaction_trigger: 2 + merge_operator: uint64add # support merge + level_compaction_dynamic_file_size: true + optimize_filters_for_hits: true + allow_merge_memtables: true + min_write_buffer_number_to_merge: 2 + compression_per_level: + - kNoCompression + - kNoCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression +DBOptions: + log: + create_if_missing: true + create_missing_column_families: true + default: + create_if_missing: true + create_missing_column_families: false # this is important, must be false to hugegraph + max_background_compactions: -1 + max_subcompactions: 4 + max_level1_subcompactions: 0 + inplace_update_support: false + WAL_size_limit_MB: 0 + statistics: "${stat}" + max_manifest_file_size: 100M + max_background_jobs: 8 + compaction_readahead_size: 0 + memtable_as_log_index: true diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/lib/topling/rocksdbjni-8.10.2-20260725.141011-1.jar b/hugegraph-server/hugegraph-dist/src/assembly/static/lib/topling/rocksdbjni-8.10.2-20260725.141011-1.jar new file mode 100644 index 0000000000..61c401bb01 Binary files /dev/null and b/hugegraph-server/hugegraph-dist/src/assembly/static/lib/topling/rocksdbjni-8.10.2-20260725.141011-1.jar differ diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/install-deps.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/install-deps.sh new file mode 100755 index 0000000000..c5719254a4 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/install-deps.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +set -ev + +if [ -f /etc/debian_version ]; then + sudo apt-get update && sudo apt-get install -y liburing-dev libaio-dev libjemalloc-dev +elif [ -f /etc/redhat-release ]; then + sudo yum install -y liburing-devel libaio-devel jemalloc-devel +fi diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/install-rocksdb.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/install-rocksdb.sh new file mode 100755 index 0000000000..a3750c99f2 --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/install-rocksdb.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if [ "$(uname -s)" != "Linux" ]; then + echo "[install-rocksdb] Skip native preload on non-Linux platform: $(uname -s)" + return 0 2>/dev/null || exit 0 +fi + +ORIG_SHELL_FLAGS="$-" +ORIG_PIPEFAIL="$(set -o | awk '$1 == "pipefail" { print $2 }')" +ORIG_ERR_TRAP="$(trap -p ERR)" +# Save original IFS to avoid leaking into parent shell when sourced +ORIG_IFS="${IFS}" +set -Eeuo pipefail +IFS=$'\n\t' +# Unified error capture for easy positioning +trap 'echo "[install-rocksdb] error at line ${LINENO}: ${BASH_COMMAND}" >&2' ERR + +VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) +SERVER_VERSION_DIR="$(pwd)/hugegraph-server/apache-hugegraph-server-$VERSION" +SERVER_BIN="$SERVER_VERSION_DIR/bin" +SERVER_LIB="$SERVER_VERSION_DIR/lib" +INSTALL_DEST_DIR="$SERVER_VERSION_DIR/library" + +if [ ! -d "$SERVER_VERSION_DIR" ]; then + echo "Error: SERVER_VERSION_DIR not found: $SERVER_VERSION_DIR" >&2 + exit 1 +fi +if [ ! -d "$SERVER_LIB" ]; then + echo "Error: SERVER_LIB dir not found: $SERVER_LIB" >&2 + exit 1 +fi +if [ ! -f "$SERVER_BIN/common-topling.sh" ]; then + echo "Error: common-topling.sh not found under: $SERVER_BIN" >&2 + exit 1 +fi + +source "$SERVER_BIN/common-topling.sh" +type preload_toplingdb >/dev/null 2>&1 || { echo "Error: function preload_toplingdb not found" >&2; exit 1; } +preload_toplingdb "$SERVER_LIB" "$INSTALL_DEST_DIR" + +# Restore original IFS +IFS="$ORIG_IFS" +if [ -n "$ORIG_ERR_TRAP" ]; then + eval "$ORIG_ERR_TRAP" +else + trap - ERR +fi +# Reset shell options to prevent affecting the parent shell when sourced +case "$ORIG_SHELL_FLAGS" in *e*) set -e ;; *) set +e ;; esac +case "$ORIG_SHELL_FLAGS" in *u*) set -u ;; *) set +u ;; esac +case "$ORIG_SHELL_FLAGS" in *E*) set -E ;; *) set +E ;; esac +if [ "$ORIG_PIPEFAIL" = "on" ]; then + set -o pipefail +else + set +o pipefail +fi diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh index a038370ad7..e2195b5961 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-api-test.sh @@ -67,6 +67,9 @@ JACOCO_PORT=36320 mvn package -Dmaven.test.skip=true -ntp +# install rocksdb +source $TRAVIS_DIR/install-rocksdb.sh + # add mysql dependency download_to_dir "$SERVER_DIR/lib/" \ "https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar" diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh index a95d2f0806..6ced5d93b0 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-core-test.sh @@ -18,5 +18,9 @@ set -ev BACKEND=$1 +TRAVIS_DIR=$(dirname $0) + +# install rocksdb +source $TRAVIS_DIR/install-rocksdb.sh mvn test -pl hugegraph-server/hugegraph-test -am -P core-test,$BACKEND diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-unit-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-unit-test.sh index 5fe9b476b3..6b1b22225a 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-unit-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-unit-test.sh @@ -19,6 +19,9 @@ set -ev BACKEND=$1 +# install rocksdb +source $TRAVIS_DIR/install-rocksdb.sh + if [[ "$BACKEND" == "memory" ]]; then mvn test -pl hugegraph-server/hugegraph-test -am -P unit-test fi diff --git a/hugegraph-server/hugegraph-rocksdb/pom.xml b/hugegraph-server/hugegraph-rocksdb/pom.xml index 845cf40f9c..276f8163cd 100644 --- a/hugegraph-server/hugegraph-rocksdb/pom.xml +++ b/hugegraph-server/hugegraph-rocksdb/pom.xml @@ -37,7 +37,7 @@ org.rocksdb rocksdbjni - 8.10.2 + ${rocksdb.version} diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java index c1cc1c5075..eb8f223640 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java @@ -37,6 +37,7 @@ import org.apache.hugegraph.backend.store.BackendEntry.BackendColumn; import org.apache.hugegraph.backend.store.BackendEntry.BackendColumnIterator; import org.apache.hugegraph.backend.store.BackendEntryIterator; +import org.apache.hugegraph.backend.store.BackendStoreProvider; import org.apache.hugegraph.backend.store.rocksdb.RocksDBIteratorPool.ReusedRocksIterator; import org.apache.hugegraph.config.CoreOptions; import org.apache.hugegraph.config.HugeConfig; @@ -83,23 +84,28 @@ public class RocksDBStdSessions extends RocksDBSessions { private final AtomicInteger refCount; public RocksDBStdSessions(HugeConfig config, String database, String store, - String dataPath, String walPath) throws RocksDBException { + String dataPath, String walPath) throws + RocksDBException { super(config, database, store); this.config = config; this.dataPath = dataPath; this.walPath = walPath; + this.rocksdb = RocksDBStdSessions.openRocksDB(config, dataPath, walPath); this.refCount = new AtomicInteger(1); } public RocksDBStdSessions(HugeConfig config, String database, String store, String dataPath, String walPath, - List cfNames) throws RocksDBException { + List cfNames) throws + RocksDBException { super(config, database, store); this.config = config; this.dataPath = dataPath; this.walPath = walPath; - this.rocksdb = RocksDBStdSessions.openRocksDB(config, cfNames, dataPath, walPath); + + this.rocksdb = + RocksDBStdSessions.openRocksDB(config, cfNames, dataPath, walPath); this.refCount = new AtomicInteger(1); this.ingestExternalFile(); @@ -366,25 +372,25 @@ private void ingestExternalFile() throws RocksDBException { } private static OpenedRocksDB openRocksDB(HugeConfig config, String dataPath, - String walPath) throws RocksDBException { + String walPath) throws + RocksDBException { // Init options Options options = new Options(); RocksDBStdSessions.initOptions(config, options, options, options, options); options.setWalDir(walPath); SstFileManager sstFileManager = new SstFileManager(Env.getDefault()); options.setSstFileManager(sstFileManager); - /* - * Open RocksDB at the first time - * Don't merge old CFs, we expect a clear DB when using this one - */ + RocksDB rocksdb = RocksDB.open(options, dataPath); + Map cfs = new ConcurrentHashMap<>(); return new OpenedRocksDB(rocksdb, cfs, sstFileManager); } private static OpenedRocksDB openRocksDB(HugeConfig config, List cfNames, String dataPath, - String walPath) throws RocksDBException { + String walPath) throws + RocksDBException { // Old CFs should always be opened Set mergedCFs = RocksDBStdSessions.mergeOldCFs(dataPath, cfNames); @@ -407,9 +413,9 @@ private static OpenedRocksDB openRocksDB(HugeConfig config, } SstFileManager sstFileManager = new SstFileManager(Env.getDefault()); options.setSstFileManager(sstFileManager); - // Open RocksDB with CFs List cfhs = new ArrayList<>(); + RocksDB rocksdb = RocksDB.open(options, dataPath, cfds, cfhs); E.checkState(cfhs.size() == cfs.size(), @@ -443,6 +449,10 @@ public static Set listCFs(String path) throws RocksDBException { return cfs; } + private static String getDbName(String dataPath) { + return Paths.get(dataPath).getFileName().toString(); + } + public static void initOptions(HugeConfig conf, DBOptionsInterface db, MutableDBOptionsInterface mdb, diff --git a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java index 3b6b54eadb..2117e1c24f 100644 --- a/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java +++ b/hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java @@ -372,7 +372,8 @@ protected RocksDBSessions open(HugeConfig config, String dataPath, protected RocksDBSessions openSessionPool(HugeConfig config, String dataPath, String walPath, - List tableNames) throws RocksDBException { + List tableNames) throws + RocksDBException { if (tableNames == null) { return new RocksDBStdSessions(config, this.database, this.store, dataPath, walPath); } else { diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionsTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionsTest.java index 5dbc96c5c6..accc5e7f6b 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionsTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionsTest.java @@ -190,7 +190,8 @@ public void testIngestSst() throws RocksDBException { Assert.assertFalse(sstSessions.existsTable(TABLE1)); Assert.assertFalse(sstSessions.existsTable(TABLE2)); - RocksDBSessions rocks = new RocksDBStdSessions(config, "db", "store", sstPath, sstPath); + RocksDBSessions rocks = + new RocksDBStdSessions(config, "db", "store", sstPath, sstPath); // Will ingest sst file of TABLE1 rocks.createTable(TABLE1); Assert.assertEquals(ImmutableList.of("1000"), diff --git a/hugegraph-store/hg-store-core/pom.xml b/hugegraph-store/hg-store-core/pom.xml index 0ecf723280..84e23e8b88 100644 --- a/hugegraph-store/hg-store-core/pom.xml +++ b/hugegraph-store/hg-store-core/pom.xml @@ -55,7 +55,7 @@ com.alipay.sofa jraft-core - 1.3.13 + 1.3.14 org.rocksdb diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh b/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh index 5a11eeab39..8b0d864a55 100755 --- a/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh +++ b/hugegraph-store/hg-store-dist/src/assembly/static/bin/start-hugegraph-store.sh @@ -38,6 +38,8 @@ GITHUB="https://github.com" PID_FILE="$BIN/pid" . "$BIN"/util.sh +PARENT_DIR="$(cd "$TOP"/../ && pwd)" +SERVER_VERSION_DIR="${SERVER_VERSION_DIR:-$(find_hugegraph_server_dir "$PARENT_DIR")}" arch=$(uname -m) echo "Current arch: $arch" @@ -64,6 +66,14 @@ else echo "Unsupported architecture: $arch" fi +# preload rocksdb/toplingdb +if [ -n "$SERVER_VERSION_DIR" ] && [ -e "$SERVER_VERSION_DIR/bin/preload-topling.sh" ]; then + if [ -z "${TOPLINGDB_EASY_MIGRATE_CONF:-}" ]; then + TOPLINGDB_EASY_MIGRATE_CONF="$CONF/rocksdb_store.yaml" + fi + source "$SERVER_VERSION_DIR/bin/preload-topling.sh" +fi + ##pd/store max user processes, ulimit -u # Reduce the maximum number of processes that can be opened by a normal dev/user export PROC_LIMITN=1024 diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/bin/util.sh b/hugegraph-store/hg-store-dist/src/assembly/static/bin/util.sh index 3b3d660102..fd9674a425 100644 --- a/hugegraph-store/hg-store-dist/src/assembly/static/bin/util.sh +++ b/hugegraph-store/hg-store-dist/src/assembly/static/bin/util.sh @@ -400,3 +400,21 @@ function kill_process_and_wait() { kill_process "$process_name" "$pid" wait_for_shutdown "$process_name" "$pid" "$timeout_s" } + +# Find HugeGraph server directory in parent path using prefix glob. +# Usage: find_hugegraph_server_dir "/path/to/parent" +# Returns: first matching directory path or empty string +function find_hugegraph_server_dir() { + local parent_dir="$1" + if [ -z "$parent_dir" ]; then + parent_dir="$(cd "${TOP:-$(pwd)}"/.. && pwd)" + fi + local found="" + for d in "$parent_dir"/apache-hugegraph-server*; do + if [ -d "$d" ]; then + found="$d" + break + fi + done + echo "$found" +} diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml b/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml index 0315c4b4fe..4f8ff2aaad 100644 --- a/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml +++ b/hugegraph-store/hg-store-dist/src/assembly/static/conf/application-pd.yml @@ -32,3 +32,6 @@ rocksdb: write_buffer_size: 32000000 # For each rocksdb, the number of memtables reaches this value for writing to disk. min_write_buffer_number_to_merge: 16 + # To enable ToplingDB: set provider to 'topling' (requires ToplingDB JAR in lib/topling/) + # ToplingDB config is in conf/toplingdb.yaml (auto-loaded via TOPLINGDB_EASY_MIGRATE_CONF env var) + # provider: topling diff --git a/hugegraph-store/hg-store-dist/src/assembly/static/conf/rocksdb_store.yaml b/hugegraph-store/hg-store-dist/src/assembly/static/conf/rocksdb_store.yaml new file mode 100644 index 0000000000..63300e6983 --- /dev/null +++ b/hugegraph-store/hg-store-dist/src/assembly/static/conf/rocksdb_store.yaml @@ -0,0 +1,158 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# common parameters +http: + # normally parent path of db path + document_root: /dev/shm/rocksdb_resource + listening_ports: '127.0.0.1:2013' + auto_start_http: true +setenv: + StrSimpleEnvNameNotOverwrite: StringValue + IntSimpleEnvNameNotOverwrite: 16384 + OverwriteThisEnv: + #comment: overwrite is default to false + overwrite: true + value: force overwrite this env by overwrite true +Cache: + lru_cache: + class: LRUCache + params: + capacity: 8G + num_shard_bits: -1 + strict_capacity_limit: false + high_pri_pool_ratio: 0.5 + use_adaptive_mutex: false + metadata_charge_policy: kFullChargeCacheMetadata +Statistics: + stat: + class: default + params: + discard_tickers: + - rocksdb.block.cache + - rocksdb.block.cachecompressed + - rocksdb.block + - rocksdb.memtable.payload.bytes.at.flush + - rocksdb.memtable.garbage.bytes.at.flush + - rocksdb.txn + - rocksdb.blobdb + - rocksdb.row.cache + - rocksdb.number.block + - rocksdb.bloom.filter + - rocksdb.persistent + - rocksdb.sim.block.cache + discard_histograms: + # comment: .... + - rocksdb.blobdb + - rocksdb.bytes.compressed + - rocksdb.bytes.decompressed + - rocksdb.num.index.and.filter.blocks.read.per.level + - rocksdb.num.data.blocks.read.per.level + - rocksdb.compression.times.nanos + - rocksdb.decompression.times.nanos + - rocksdb.read.block.get.micros + - rocksdb.write.raw.block.micros + # comment end of array + #stats_level: kAll + stats_level: kDisableAll +MemTableRepFactory: + cspp: + class: cspp + params: + mem_cap: 16G + use_vm: false + token_use_idle: true + chunk_size: 16K + convert_to_sst: kFileMmap + sync_sst_file: false + skiplist: + class: SkipList + params: + lookahead: 0 +TableFactory: + cspp_memtab_sst: + class: CSPPMemTabTable + params: # empty params + bb: + class: BlockBasedTable + params: + checksum: kCRC32c + block_size: 4K + block_restart_interval: 16 + index_block_restart_interval: 1 + metadata_block_size: 4K + enable_index_compression: true + block_cache: "${lru_cache}" + readers: + BlockBasedTable: bb + CSPPMemTabTable: cspp_memtab_sst + block_cache_compressed: + persistent_cache: + filter_policy: + dispatch: + class: DispatcherTable + params: + default: bb + readers: + BlockBasedTable: bb + CSPPMemTabTable: cspp_memtab_sst + level_writers: [ bb, bb, bb, bb, bb, bb ] +CFOptions: + default: + max_write_buffer_number: 6 + memtable_factory: "${cspp}" + write_buffer_size: 128M + # set target_file_size_base as small as 512K is to make many SST files, + # thus key prefix cache can present efficiency + target_file_size_base: 64M + target_file_size_multiplier: 1 + table_factory: dispatch + max_bytes_for_level_base: 512M + max_bytes_for_level_multiplier: 10 + level_compaction_dynamic_level_bytes: false + level0_slowdown_writes_trigger: 20 + level0_stop_writes_trigger: 36 + level0_file_num_compaction_trigger: 2 + merge_operator: uint64add # support merge + level_compaction_dynamic_file_size: true + optimize_filters_for_hits: true + allow_merge_memtables: true + min_write_buffer_number_to_merge: 2 + compression_per_level: + - kNoCompression + - kNoCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression + - kSnappyCompression +DBOptions: + log: + create_if_missing: true + create_missing_column_families: true + default: + create_if_missing: true + create_missing_column_families: false # this is important, must be false to hugegraph + max_background_compactions: -1 + max_subcompactions: 4 + max_level1_subcompactions: 0 + inplace_update_support: false + WAL_size_limit_MB: 0 + statistics: "${stat}" + max_manifest_file_size: 100M + max_background_jobs: 8 + compaction_readahead_size: 0 + memtable_as_log_index: true diff --git a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/metrics/RocksDBMetricsConst.java b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/metrics/RocksDBMetricsConst.java index 94bdc4c6bc..ceecc43399 100644 --- a/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/metrics/RocksDBMetricsConst.java +++ b/hugegraph-store/hg-store-node/src/main/java/org/apache/hugegraph/store/node/metrics/RocksDBMetricsConst.java @@ -54,12 +54,12 @@ public final class RocksDBMetricsConst { TickerType.BLOCK_CACHE_INDEX_HIT, // Index cache hits. TickerType.BLOCK_CACHE_INDEX_ADD, // Index blocks added to cache. TickerType.BLOCK_CACHE_INDEX_BYTES_INSERT, // Bytes inserted into index cache. - TickerType.BLOCK_CACHE_INDEX_BYTES_EVICT, // Bytes evicted from index cache. + // BLOCK_CACHE_INDEX_BYTES_EVICT removed in RocksDB 8.x TickerType.BLOCK_CACHE_FILTER_MISS, // Filter cache misses. TickerType.BLOCK_CACHE_FILTER_HIT, // Filter cache hits. TickerType.BLOCK_CACHE_FILTER_ADD, // Filter blocks added to cache. TickerType.BLOCK_CACHE_FILTER_BYTES_INSERT, // Bytes inserted in filter cache. - TickerType.BLOCK_CACHE_FILTER_BYTES_EVICT, // Bytes evicted from filter cache. + // BLOCK_CACHE_FILTER_BYTES_EVICT removed in RocksDB 8.x TickerType.BLOCK_CACHE_DATA_MISS, // Data cache misses. TickerType.BLOCK_CACHE_DATA_HIT, // Data cache hits. TickerType.BLOCK_CACHE_DATA_ADD, // Data blocks added to cache. @@ -95,31 +95,31 @@ public final class RocksDBMetricsConst { TickerType.NUMBER_DB_NEXT_FOUND, // Number of successful next operations. TickerType.NUMBER_DB_PREV_FOUND, // Number of successful previous operations. TickerType.ITER_BYTES_READ, // Bytes read by iterators. - TickerType.NO_FILE_CLOSES, // Number of file close operations. + // NO_FILE_CLOSES removed in RocksDB 8.x TickerType.NO_FILE_OPENS, // Number of file open operations. TickerType.NO_FILE_ERRORS, // Number of file errors. TickerType.STALL_MICROS, // Time spent in a stall micro. TickerType.DB_MUTEX_WAIT_MICROS, // Time spent waiting on a mutex. - TickerType.RATE_LIMIT_DELAY_MILLIS, // Rate limiting delay in milliseconds. - TickerType.NO_ITERATORS, // Number of iterators created. + // RATE_LIMIT_DELAY_MILLIS removed in RocksDB 8.x + // NO_ITERATORS removed in RocksDB 8.x TickerType.NUMBER_MULTIGET_BYTES_READ, // Bytes read by multi-get operations. TickerType.NUMBER_MULTIGET_KEYS_READ, // Keys read in multi-get operations. TickerType.NUMBER_MULTIGET_CALLS, // Number of multi-get operations. - TickerType.NUMBER_FILTERED_DELETES, // Number of deletes filtered. + // NUMBER_FILTERED_DELETES removed in RocksDB 8.x TickerType.NUMBER_MERGE_FAILURES, // Number of merge failures. TickerType.BLOOM_FILTER_PREFIX_CHECKED, // Number of prefix bloom filter checks. TickerType.BLOOM_FILTER_PREFIX_USEFUL, // Number of useful prefix bloom filter checks. TickerType.NUMBER_OF_RESEEKS_IN_ITERATION, // Number of reseeks in iteration. TickerType.GET_UPDATES_SINCE_CALLS, // Number of get updates since calls. - TickerType.BLOCK_CACHE_COMPRESSED_MISS, // Misses in compressed block cache. - TickerType.BLOCK_CACHE_COMPRESSED_HIT, // Hits in compressed block cache. - TickerType.BLOCK_CACHE_COMPRESSED_ADD, // Compressed blocks added to cache. - TickerType.BLOCK_CACHE_COMPRESSED_ADD_FAILURES, // Failures adding compressed blocks. + // BLOCK_CACHE_COMPRESSED_MISS removed in RocksDB 8.x + // BLOCK_CACHE_COMPRESSED_HIT removed in RocksDB 8.x + // BLOCK_CACHE_COMPRESSED_ADD removed in RocksDB 8.x + // BLOCK_CACHE_COMPRESSED_ADD_FAILURES removed in RocksDB 8.x TickerType.WAL_FILE_SYNCED, // Number of synced WAL files. TickerType.WAL_FILE_BYTES, // Bytes written to WAL files. TickerType.WRITE_DONE_BY_SELF, // Writes completed by self. TickerType.WRITE_DONE_BY_OTHER, // Writes completed by others. - TickerType.WRITE_TIMEDOUT, // Number of write timeouts. + // WRITE_TIMEDOUT removed in RocksDB 8.x TickerType.WRITE_WITH_WAL, // Writes involving WAL. TickerType.COMPACT_READ_BYTES, // Bytes read during compaction. TickerType.COMPACT_WRITE_BYTES, // Bytes written during compaction. @@ -167,12 +167,10 @@ public final class RocksDBMetricsConst { // Time spent reading blocks during compaction. HistogramType.READ_BLOCK_GET_MICROS, // Time spent reading blocks during get. HistogramType.WRITE_RAW_BLOCK_MICROS, // Time spent writing raw blocks. - HistogramType.STALL_L0_SLOWDOWN_COUNT, // Count of stalls due to L0 slowdown. - HistogramType.STALL_MEMTABLE_COMPACTION_COUNT, - // Count of stalls due to memtable compaction. - HistogramType.STALL_L0_NUM_FILES_COUNT, // Count of stalls due to number of files at L0. - HistogramType.HARD_RATE_LIMIT_DELAY_COUNT, // Count of delays due to hard rate limits. - HistogramType.SOFT_RATE_LIMIT_DELAY_COUNT, // Count of delays due to soft rate limits. + // STALL_L0_SLOWDOWN_COUNT removed in RocksDB 8.x + // Note: The following constants were removed in RocksDB 8.10.2: + // STALL_MEMTABLE_COMPACTION_COUNT, STALL_L0_NUM_FILES_COUNT, + // HARD_RATE_LIMIT_DELAY_COUNT, SOFT_RATE_LIMIT_DELAY_COUNT HistogramType.NUM_FILES_IN_SINGLE_COMPACTION, // Number of files in a single compaction. HistogramType.DB_SEEK, // Latency of database seek operations. HistogramType.WRITE_STALL, // Time spent in write stalls. diff --git a/hugegraph-store/hg-store-rocksdb/pom.xml b/hugegraph-store/hg-store-rocksdb/pom.xml index bb463d7ed9..2235e64596 100644 --- a/hugegraph-store/hg-store-rocksdb/pom.xml +++ b/hugegraph-store/hg-store-rocksdb/pom.xml @@ -57,7 +57,7 @@ org.rocksdb rocksdbjni - 7.7.3 + ${rocksdb.version} org.projectlombok diff --git a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBOptions.java b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBOptions.java index 7fcd07f3b8..374778d9e2 100644 --- a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBOptions.java +++ b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBOptions.java @@ -56,7 +56,6 @@ public class RocksDBOptions extends OptionHolder { disallowEmpty(), false ); - // public static final ConfigListOption DATA_DISKS = // new ConfigListOption<>( // "rocksdb.data_disks", diff --git a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java index f4e7605a7f..bfd3240ba7 100644 --- a/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java +++ b/hugegraph-store/hg-store-rocksdb/src/main/java/org/apache/hugegraph/rocksdb/access/RocksDBSession.java @@ -450,8 +450,9 @@ private void openRocksDB(String dbDataPath, long version) { new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOptions)); } List columnFamilyHandleList = new ArrayList<>(); - this.rocksDB = RocksDB.open(dbOptions, dbPath, columnFamilyDescriptorList, - columnFamilyHandleList); + this.rocksDB = + RocksDB.open(dbOptions, dbPath, columnFamilyDescriptorList, + columnFamilyHandleList); Asserts.isTrue(columnFamilyHandleList.size() > 0, "must have column family"); for (ColumnFamilyHandle handle : columnFamilyHandleList) { diff --git a/install-dist/release-docs/LICENSE b/install-dist/release-docs/LICENSE index 0014317824..440f842de6 100644 --- a/install-dist/release-docs/LICENSE +++ b/install-dist/release-docs/LICENSE @@ -504,6 +504,12 @@ non-Apache-2.0 license text is required for a bundled component. https://central.sonatype.com/artifact/net.java.dev.jna/jna/5.12.1 -> Apache 2.0 https://central.sonatype.com/artifact/net.java.dev.jna/jna/5.5.0 -> Apache 2.0 https://central.sonatype.com/artifact/net.java.dev.jna/jna/5.7.0 -> Apache 2.0 + https://central.sonatype.com/artifact/com.github.jnr/jnr-ffi/2.1.7 -> Apache 2.0 + https://central.sonatype.com/artifact/joda-time/joda-time/2.10.8 -> Apache 2.0 + https://central.sonatype.com/artifact/com.alipay.sofa/jraft-core/1.3.14 -> Apache 2.0 + https://central.sonatype.com/artifact/org.skyscreamer/jsonassert/1.5.0 -> Apache 2.0 + https://central.sonatype.com/artifact/com.jayway.jsonpath/json-path/2.5.0 -> Apache 2.0 + https://central.sonatype.com/artifact/com.googlecode.json-simple/json-simple/1.1 -> Apache 2.0 https://central.sonatype.com/artifact/net.jodah/failsafe/2.4.1 -> Apache 2.0 https://central.sonatype.com/artifact/net.minidev/accessors-smart/1.2 -> Apache 2.0 https://central.sonatype.com/artifact/net.minidev/json-smart/2.3 -> Apache 2.0 @@ -694,10 +700,48 @@ non-Apache-2.0 license text is required for a bundled component. https://central.sonatype.com/artifact/org.powermock/powermock-module-junit4-rule/2.0.0-RC.3 -> Apache 2.0 https://central.sonatype.com/artifact/org.powermock/powermock-module-junit4/2.0.0-RC.3 -> Apache 2.0 https://central.sonatype.com/artifact/org.powermock/powermock-reflect/2.0.0-RC.3 -> Apache 2.0 + https://central.sonatype.com/artifact/com.google.api.grpc/proto-google-common-protos/1.17.0 -> Apache 2.0 + https://central.sonatype.com/artifact/com.google.api.grpc/proto-google-common-protos/2.0.1 -> Apache 2.0 + https://central.sonatype.com/artifact/io.protostuff/protostuff-api/1.6.0 -> Apache 2.0 + https://central.sonatype.com/artifact/io.protostuff/protostuff-collectionschema/1.6.0 -> Apache 2.0 + https://central.sonatype.com/artifact/io.protostuff/protostuff-core/1.6.0 -> Apache 2.0 + https://central.sonatype.com/artifact/io.protostuff/protostuff-runtime/1.6.0 -> Apache 2.0 + https://central.sonatype.com/artifact/com.addthis.metrics/reporter-config3/3.0.3 -> Apache 2.0 + https://central.sonatype.com/artifact/com.addthis.metrics/reporter-config-base/3.0.3 -> Apache 2.0 + https://central.sonatype.com/artifact/org.opencypher/rewriting-9.0/9.0.20190305 -> Apache 2.0 + https://central.sonatype.com/artifact/org.rocksdb/rocksdbjni/8.10.2 -> Apache 2.0 + https://github.com/hugegraph/toplingdb/packages/3151853 -> Apache 2.0 + https://central.sonatype.com/artifact/org.fusesource/sigar/1.6.4 -> Apache 2.0 + https://central.sonatype.com/artifact/io.prometheus/simpleclient/0.10.0 -> Apache 2.0 + https://central.sonatype.com/artifact/io.prometheus/simpleclient_common/0.10.0 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-agent/0.22 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-cli/0.14 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-cli/0.22 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-core/0.14 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-core/0.22 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-hflame/0.22 -> Apache 2.0 + https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-jfr5/0.5 -> Apache 2.0 + https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-jfr6/0.7 -> Apache 2.0 + https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-jfr-standalone/0.7 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-json/0.14 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-json/0.22 -> Apache 2.0 + https://central.sonatype.com/artifact/org.perfkit.sjk.parsers/sjk-nps/0.9 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-stacktrace/0.14 -> Apache 2.0 + https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-stacktrace/0.22 -> Apache 2.0 + https://central.sonatype.com/artifact/org.yaml/snakeyaml/1.18 -> Apache 2.0 + https://central.sonatype.com/artifact/org.yaml/snakeyaml/1.26 -> Apache 2.0 + https://central.sonatype.com/artifact/org.yaml/snakeyaml/1.27 -> Apache 2.0 + https://central.sonatype.com/artifact/org.yaml/snakeyaml/1.28 -> Apache 2.0 + https://central.sonatype.com/artifact/org.yaml/snakeyaml/2.2 -> Apache 2.0 + https://central.sonatype.com/artifact/org.xerial.snappy/snappy-java/1.1.2.6 -> Apache 2.0 + https://central.sonatype.com/artifact/com.alipay.sofa.common/sofa-common-tools/1.0.12 -> Apache 2.0 + https://central.sonatype.com/artifact/com.alipay.sofa/sofa-rpc-all/5.7.6 -> Apache 2.0 + https://central.sonatype.com/artifact/org.springframework/spring-aop/5.3.20 -> Apache 2.0 + https://central.sonatype.com/artifact/org.springframework/spring-beans/5.3.20 -> Apache 2.0 + https://central.sonatype.com/artifact/org.springframework.boot/spring-boot/2.5.14 -> Apache 2.0 + https://central.sonatype.com/artifact/org.springframework.boot/spring-boot-actuator/2.5.14 -> Apache 2.0 https://central.sonatype.com/artifact/org.roaringbitmap/RoaringBitmap/0.9.38 -> Apache 2.0 https://central.sonatype.com/artifact/org.roaringbitmap/shims/0.9.38 -> Apache 2.0 - https://central.sonatype.com/artifact/org.rocksdb/rocksdbjni/6.29.5 -> Apache 2.0 - https://central.sonatype.com/artifact/org.rocksdb/rocksdbjni/7.7.3 -> Apache 2.0 https://central.sonatype.com/artifact/org.rocksdb/rocksdbjni/8.10.2 -> Apache 2.0 https://central.sonatype.com/artifact/org.skyscreamer/jsonassert/1.5.0 -> Apache 2.0 https://central.sonatype.com/artifact/org.springframework.boot/spring-boot-actuator-autoconfigure/2.5.14 -> Apache 2.0 diff --git a/install-dist/release-docs/licenses/LICENSE-rocksdbjni-8.10.2-SNAPSHOT.txt b/install-dist/release-docs/licenses/LICENSE-rocksdbjni-8.10.2-SNAPSHOT.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/install-dist/release-docs/licenses/LICENSE-rocksdbjni-8.10.2-SNAPSHOT.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/install-dist/scripts/dependency/known-dependencies.txt b/install-dist/scripts/dependency/known-dependencies.txt index 326ac3dd76..c0242d56b0 100644 --- a/install-dist/scripts/dependency/known-dependencies.txt +++ b/install-dist/scripts/dependency/known-dependencies.txt @@ -318,8 +318,7 @@ jnr-ffi-2.1.7.jar jnr-x86asm-1.0.2.jar joda-time-2.10.8.jar joni-2.2.1.jar -jraft-core-1.3.11.jar -jraft-core-1.3.13.jar +jraft-core-1.3.14.jar jraft-core-1.3.9.jar json-path-2.5.0.jar json-simple-1.1.jar @@ -511,8 +510,6 @@ psjava-0.1.19.jar reporter-config-base-3.0.3.jar reporter-config3-3.0.3.jar rewriting-9.0-9.0.20190305.jar -rocksdbjni-6.29.5.jar -rocksdbjni-7.7.3.jar rocksdbjni-8.10.2.jar scala-java8-compat_2.12-0.8.0.jar scala-library-2.12.7.jar diff --git a/pom.xml b/pom.xml index 850ac99fa8..3acfc63406 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,7 @@ UTF-8 bash 1.5.0 + 8.10.2 @@ -220,6 +221,9 @@ **/src/main/java/org/apache/hugegraph/pd/grpc/** **/src/main/java/org/apache/hugegraph/store/grpc/** + + **/library/*.html + **/library/*.css true