AnuDB

AnuDB 是一个轻量级的、无服务器的文档数据库,专为 C++ 应用程序设计,通过 MessagePack 序列化高效地存储 JSON 文档。它为需要灵活数据管理和强大查询功能的应用程序提供了一个无服务器、无模式的解决方案。

由于 AnuDB 构建于 RocksDB 之上,因此确保了文档的原子性、持久性和一致性。您可以根据 StorageEngine.cppStorageEngine.h 中提到的 RocksDB 选项,调整 AnuDB 的内存/CPU 使用率。 基于这些配置,您可以获得根据您的特定平台需求量身定制的理想性能结果。

开始使用 AnuDB!

准备好在您的项目中使用 AnuDB 吗? 请按照以下简单步骤快速入门:

  1. 安装 AnuDB 请参阅安装指南在您的机器上设置 AnuDB。
  2. 探索示例代码 查看我们的使用示例以了解如何与 AnuDB 交互。
  3. 开始构建! 通过在您的应用程序中使用 AnuDB 并开始以闪电般的速度存储数据来直接投入使用。
  4. Docker 支持 AnuDB 支持 Docker! 在容器化环境中轻松运行 AnuDB。 请参阅我们的 Docker 设置指南以开始使用。
  5. MQTT 支持 AnuDB 与 MQTT 无缝集成,实现设备和服务器之间的实时数据通信。 如果您正在开发物联网或实时消息系统,AnuDB 的 MQTT 支持将使您的工作更轻松。 查看我们的 MQTT 集成指南以开始使用 MQTT 和 AnuDB。
  6. 基准测试

特性

MQTT 接口

AnuDB 现在支持通过 MQTT 协议进行交互,允许您从各种平台连接和操作数据库,而无需直接 C++ 集成。 该实现使用 nlohmann::json 进行 JSON 处理。 AnuDB 订阅 MQTT anudb/request 主题,然后如果请求在提到的主题上带有请求 ID,那么它会执行该操作,然后在 anudb/response/requestid 上发回响应,我们可以在 anudb/response/+ 主题上获得所有响应,下图说明了这一点。

AnuDB MQTT 通信

在下面的演示中,显示了 AnuDBMqttBridge 和 mosquitto 代理服务器已启动,然后使用 client.bash 脚本,运行了所有支持的 MQTT 命令

AnuDBMqttDemo

MQTT 支持的命令

Docker 支持

要使用 Docker 运行 AnuDB:

1. 拉取 Docker 镜像

docker pull kanadaanu/anudb-mqtt:v1

2. 确保 MQTT 代理正在运行

在启动 AnuDB 之前,您需要运行一个 MQTT 代理(例如,EMQXMosquitto)。

3. 运行 Docker 容器

根据您的设置,使用以下命令之一:

# 使用 TLS (例如, EMQX public broker, mosquitto broker, 等)
docker run -v <disk folder>:/data kanadaanu/anudb-mqtt:v1 \
 --broker_url tls+mqtt-tcp://<broker_url>:8883 \
 --database_name AnuDB \
 --tls_cacert <> \
 --tls_cert <>
  ...
# 不使用 TLS
docker run -v <disk folder>:/data kanadaanu/anudb-mqtt:v1 \
 --broker_url mqtt-tcp://<broker_url>:1883 \
 --database_name AnuDB

注意

前提条件

从源码构建

无需安装任何其他第三方库。 以下命令将生成 AnuDB.exe bin,该 bin 执行 AnuDB 支持的所有操作,它还将生成 liblibanu.a 静态库,您可以在您的应用程序中使用它以及所需的头文件。

# 克隆仓库
git clone https://github.com/hash-anu/AnuDB.git
cd AnuDB/third_party/nanomq/
git submodule update --init --recursive
cd ../..
mkdir build
cd build
cmake ..
make
or
# 配置 ZSTD 压缩支持
cmake -DZSTD_INCLUDE_DIR=/path/to/zstd/include -DZSTD_LIB_DIR=/path/to/zstd/lib ..
make

嵌入式平台构建

对于嵌入式平台,您可能需要使用交叉编译器工具链:

# 配置交叉编译器
cmake .. \
 -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
 -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
 -DCMAKE_C_FLAGS="-march=armv7-a -mfpu=neon -mfloat-abi=hard -DNIOSTATS_CONTEXT=1" \
 -DCMAKE_CXX_FLAGS="-march=armv7-a -mfpu=neon -mfloat-abi=hard -DNIOSTATS_CONTEXT=1 -Wno-error" \
 -DWITH_ALL_TESTS=OFF \
 -DWITH_TESTS=OFF \
 -DWITH_TOOLS=OFF \
 -DWITH_GFLAGS=OFF \
 -DPORTABLE=ON \
 -DBUILD_TESTS=OFF

示例

AnuDB 数据库的示例已添加到 examples 文件夹中。API 概览

快速开始

#include "Database.h"
#include <iostream>
int main() {
  anudb::Database db("./my_database");
  anudb::Status status = db.open();
  if (!status.ok()) {
    std::cerr << "Failed to open database: " << status.message() << std::endl;
    return 1;
  }
  // 创建一个集合
  status = db.createCollection("users");
  // 获取集合
  anudb::Collection* users = db.getCollection("users");
  // 创建文档
  nlohmann::json userData = {
    {"name", "Hash"},
    {"email", "hash@example.com"},
    {"age", 33}
  };
  anudb::Document doc("user001", userData);
  // 插入文档
  status = users->createDocument(doc);
  anudb::Document doc1;
  status = users->readDocument("user001", doc1);
  std::cout << doc1.data().dump(4) << std::endl;
  // 关闭数据库
  db.close();
  return 0;
}

正常写入 -> 读取操作示例

获取集合列表的示例

导出然后导入操作的示例

高性能 MQTT Worker 架构

AnuDB 实现了高性能并发工作架构来高效处理 MQTT 请求:

Worker 线程架构图

              ┌─────────────────┐
              │ MQTT Broker  │
              │ (Mosquitto)  │
              └────────┬────────┘
                  │
                  ▼
              ┌─────────────────┐
              │ MQTT Bridge  │
              │  Connector   │
              └────────┬────────┘
                  │
                  ▼
          ┌───────────────────────────────┐
          │   Message Dispatcher    │
          └───┬───────┬───────┬───────┬───┘
     ┌─────────────┘    │    │    └─────────────┐
     │           │    │           │
┌─────────▼───────┐  ┌─────────▼───┐  ▲      ┌─────────▼───────┐
│ nng Workers  │  │ nng Workers │  │      │ nng Workers  │
│ (Threads 1-8)  │  │ (Threads 9-16)│  │      │ (Threads 25-32) │
└─────────────────┘  └─────────────┘  │      └─────────────────┘
                   ┌───┴───────┐
                   │nng Workers│
                   │(17-24)  │
                   └───────────┘
                     │
                     ▼
                 ┌─────────────────┐
                 │  AnuDB    │
                 │  Core Engine  │
                 └─────────────────┘

设置 MQTT 接口

  1. 安装并启动 Mosquitto MQTT 代理:
# 在 Ubuntu/Debian 上
sudo apt-get install mosquitto mosquitto-clients
sudo systemctl start mosquitto
# 在 Windows 上
# 从 https://mosquitto.org/download/ 下载并安装
# 通过 Windows 服务启动服务
  1. 运行 AnuDB MQTT 服务(在构建项目之后):
# 移动到 build/mqtt 文件夹
# Windows
# 使用 AnuDBMqttBridge 启动 AnuDB MQTT 服务 (TLS 示例)
.\AnuDBMqttBridge.exe --broker_url tls+mqtt-tcp://<mqtt broker URL>:8883 --database_name <您的数据库名称> --tls_cacert <ca-cert 路径>
# 使用 AnuDBMqttBridge 启动 AnuDB MQTT 服务 (不使用 TLS 的示例)
.\AnuDBMqttBridge.exe --broker_url mqtt-tcp://<mqtt broker URL>:1883 --database_name <您的数据库名称>
# Ubuntu/Debian
./AnuDBMqttBridge --broker_url mqtt-tcp://<mqtt broker URL>:1883 --database_name <您的数据库名称>
注意:如果在您的本地主机上安装了 mosquitto 代理,请在 <mqtt broker URL> 中使用 localhost。

AnuDBMqttBridge 的用法:

用法: AnuDBMqttBridge.exe --broker_url <url> --database_name <name> [--username <user>] [--password <pass>] [--tls_cacert <path>] [--tls_cert <path>] [--tls_key <path>] [--tls_pass <pass>]

使用 MQTT 客户端脚本

我们为 Linux (client.bash) 和 Windows (client.ps1) 环境提供了客户端脚本,以通过 MQTT 与 AnuDB 交互:

# 基本用法
./client.bash
# 运行负载测试
./client.bash --load-test --threads 16 --operations 1000

支持的 MQTT 命令

以下命令通过 MQTT 接口支持:

集合管理

命令 | 描述 | 示例 Payload ---|---|--- create_collection | 创建一个新集合 | {"command":"create_collection","collection_name":"users","request_id":"req123"} delete_collection | 删除现有集合 | {"command":"delete_collection","collection_name":"users","request_id":"req123"} get_collections | 列出所有集合 | {"command":"get_collections","request_id":"req123"} export_collection | 将集合导出到指定目录中的 JSON 文件 | {"command":"export_collection","collection_name":"users","dest_dir":"./product_mqtt_export/","request_id":"req123"}

文档操作

命令 | 描述 | 示例 Payload ---|---|--- create_document | 创建一个新文档(也用于更新) | {"command":"create_document","collection_name":"users","document_id":"user001","content":{"name":"John","age":30},"request_id":"req123"} read_document | 按 ID 读取文档 | {"command":"read_document","collection_name":"users","document_id":"user001","request_id":"req123"} delete_document | 删除文档 | {"command":"delete_document","collection_name":"users","document_id":"user001","request_id":"req123"}

注意:要更新文档,请使用 create_document 命令以及现有的文档 ID。 这将使用新内容覆盖先前的文档。

索引操作

命令 | 描述 | 示例 Payload ---|---|--- create_index | 在字段上创建索引 | {"command":"create_index","collection_name":"users","field":"age","request_id":"req123"} delete_index | 删除索引 | {"command":"delete_index","collection_name":"users","field":"age","request_id":"req123"} get_indexes | 列出集合的所有索引 | {"command":"get_indexes","collection_name":"users","request_id":"req123"}

查询操作

命令 | 描述 | 示例 Payload ---|---|--- find_documents | 查找与查询匹配的文档 | {"command":"find_documents","collection_name":"users","query":{"$eq":{"age":30}},"request_id":"req123"}

查询运算符

find_documents 命令支持以下查询运算符:

运算符 | 描述 | 示例 ---|---|--- $eq | 等式匹配 | {"$eq":{"field":"value"}} $gt | 大于 | {"$gt":{"field":value}} $lt | 小于 | {"$lt":{"field":value}} $and | 逻辑 AND | {"$and":[{"$eq":{"field":"value"}},{"$gt":{"field":value}}]} $or | 逻辑 OR | {"$or":[{"$eq":{"field":"value"}},{"$gt":{"field":value}}]} $orderBy | 排序结果 | {"$orderBy":{"field":"asc"}}

客户端脚本功能

提供的客户端脚本提供多种功能:

API 概览

数据库操作

操作 | 描述 ---|--- Database(const std::string& path) | 设置数据库路径的构造函数 Status open() | 打开数据库 Status close() | 关闭数据库 Status createCollection(const std::string& name) | 创建一个新集合 Collection* getCollection(const std::string& name) | 获取指向集合的指针 std::vector<std::string> getCollectionNames() | 列出所有集合名称 Status dropCollection(const std::string& name) | 删除集合 Status exportAllToJsonAsync(const std::string& collection, const std::string& outputDir) | 将集合导出到 JSON Status importFromJsonFile(const std::string& collection, const std::string& jsonFile) | 将 JSON 数据导入到集合中

集合操作

操作 | 描述 ---|--- Status createDocument(Document& doc) | 创建一个新文档 Status readDocument(const std::string& id, Document& doc) | 按 ID 读取文档 Status updateDocument(const std::string& id, const json& updateDoc, bool upsert = false) | 更新文档 Status deleteDocument(const std::string& id) | 删除文档 Status createIndex(const std::string& field) | 在字段上创建索引 Status deleteIndex(const std::string& field) | 删除索引 std::vector<std::string> findDocument(const json& query) | 查找与查询匹配的文档,为了使查找操作有效,强制对字段进行索引

文档类

操作 | 描述 ---|--- Document() | 默认构造函数 Document(const std::string& id, const json& data) | 带有 ID 和数据的构造函数 std::string id() const | 获取文档 ID void setId(const std::string& id) | 设置文档 ID json& data() | 获取对文档数据的引用 void setData(const json& data) | 设置文档数据

事务属性

AnuDB 利用 RocksDB 的存储引擎并继承以下事务特性:

查询操作

AnuDB 支持使用基于 JSON 的查询语言的各种查询操作:

运算符 | 描述 | 示例 ---|---|--- $eq | 等式匹配 | {"$eq": {"field": value}} 示例 $gt | 大于 | {"$gt": {"field": value}} 示例 $lt | 小于 | {"$lt": {"field": value}} 示例 $and | 逻辑 AND | {"$and": [query1, query2, ...]} 示例 $or | 逻辑 OR | {"$or": [query1, query2, ...]} 示例 $orderBy | 排序结果 | {"$orderBy": {"field": "asc"}} 示例

更新操作

运算符 | 描述 | 示例 ---|---|--- $set | 设置字段值,并使用 '.' 支持嵌套字段 | {"$set": {"field": value}} 示例 $unset | 删除字段,并使用 '.' 支持嵌套字段 | {"$unset": {"field": ""}} 示例 $push | 添加到数组 | {"$push": {"array": value}} 示例 $pull | 从数组中删除 | {"$pull": {"array": value}} 示例

使用示例

创建和填充集合

#include "Database.h"
#include <iostream>
anudb::Database db("./product_db");
db.open();
// 创建一个集合
db.createCollection("products");
anudb::Collection* products = db.getCollection("products");
// 创建文档
nlohmann::json productData = {
  {"name", "Laptop"},
  {"price", 1299.99},
  {"category", "Electronics"},
  {"specs", {
    {"processor", "i9"},
    {"ram", "32GB"}
  }}
};
anudb::Document doc("prod001", productData);
products->createDocument(doc);

查询示例

// 查找所有电子产品
nlohmann::json query = {
  {"$eq", {
    {"category", "Electronics"}
  }}
};
std::vector<std::string> results = products->findDocument(query);
// 价格范围查询
nlohmann::json priceRangeQuery = {
  {"$and", {
    {{"$gt", {{"price", 1000.0}}}},
    {{"$lt", {{"price", 2000.0}}}}
  }}
};
results = products->findDocument(priceRangeQuery);

更新示例

// 更新文档字段
nlohmann::json updateOp = {
  {"$set", {
    {"price", 1399.99},
    {"specs.ram", "64GB"}
  }}
};
products->updateDocument("prod001", updateOp);
// 向文档添加标签
nlohmann::json pushOp = {
  {"$push", {
    {"tags", "sale"}
  }}
};
products->updateDocument("prod001", pushOp);

性能考虑

嵌入式平台优化

限制

致谢

关于

AnuDB:基于 C++ 的文档存储,基于 RocksDB,具有本机 MQTT 支持

主题

lightweight rocksdb mqtt iot ai cpp nosql document-database messagepack zstd messagepack-serializer mosquitto-mqtt-broker nlohmann-json nanomq anudb

资源

Readme

许可证

MIT license

Activity

Stars

10 stars

Watchers

1 watching

Forks

0 forks