提起实时分析, 大家会想到什么?
ETL? 是的, 大概率会想到ETL, 例如通过binlog、PG 逻辑订阅将上游诸多oltp数据库的日志数据抽取到下游的数据仓库或入湖. 如果还有流数据库或时许数据库之类, 以同样ETL的方式进行同步入仓或入湖. 然后在下游进行分析查询. 这个架构的问题是延迟、一致性、事务错误等.
HTAP? 哦这个就是解决以上ETL问题的解决方案之一, 通常是在OLTP数据库中提供列存储引擎、列索引的方式, 在数据库内部将行存表异步转换为列存表或增加列式索引, 提供分析能力. 但是这个解决方案仅限于当前数据库实例, 如果是跨实例怎么办呢? 还得入湖或入仓.
那么有没有更优雅的方案? 既能实现当前实例实时查湖的数据, 又能让当前实例的数据实时入湖?
答案是有的, Mooncake-Labs 架构进化, 就要干这件事.
核心模块是 moonlink !
简单理解一下 moonlink 核心功能包括
另外配合 moonlink 使用的模块包括
是不是秒懂了?
Mooncake-Labs 在做的事情是打通oltp和数据湖, 给oltp数据库插上“实时同步”的翅膀和“实时分析”的翅膀.
让我们来看看moonlink的项目文档: 以下翻译自 readme.md
Moonlink 是 Iceberg 原生的摄取引擎,可为您的 Lakehouse 带来流式插入和更新插入。
将 Postgres CDC、事件流(Kafka)和 OTEL 摄取到 Iceberg 中,无需复杂的维护和压缩。
Moonlink 缓冲、缓存和索引数据,因此 Iceberg 表保持读取优化。
┌──────────moonlink───────────┐
│ ┌───────────────────────┐ │ ┌───────Iceberg───────┐
│ │ │ │ │ obj. store │
Postgres ───►│ │┌ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ┐│ │ │┌───────┐ ┌─────────┐│
│ │ │ │ ││ │ │ ││
Kafka ───►│ ││ index │ │ cache ││ ├──►│ index │ │ parquet ││
│ │ │ │ ││ │ │ ││
Events ───►│ │└ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ┘│ │ │└───────┘ └─────────┘│
│ │ nvme │ │ │ │
│ └───────────────────────┘ │ └─────────────────────┘
└─────────────────────────────┘
注意: Moonlink 处于预览阶段。预计会有变化。加入我们的社区,获取最新资讯! https://join.slack.com/t/mooncakelabs/shared_invite/zt-2sepjh5hv-rb9jUtfYZ9bvbxTCUrsEEA
传统的采集工具每次更新都会将数据和元数据文件写入 Iceberg。这对于缓慢变化的数据来说还好,但对于实时数据流来说,它会导致:
这导致:
Moonlink 通过缓冲传入数据、在 NVMe 上构建索引和缓存以及将读取优化的文件和删除向量提交给 Iceberg 来最大限度地减少写入放大和元数据流失。
插入数据被缓冲并刷新为大小调整后的 Parquet
┌───moonlink───┐ ┌────iceberg───┐
│┌─ ─ ─ ─ ─ ─ ┐│ │┌─ ─ ─ ─ ─ ─ ┐│
raw insert│ │ │ │
────────► ││ Arrow │├─►││ Parquet ││
│ │ │ │
│└─ ─ ─ ─ ─ ─ ┘│ │└─ ─ ─ ─ ─ ─ ┘│
└──────────────┘ └──────────────┘
使用基于行位置构建的索引将delete映射到delete向量
┌───moonlink───┐ ┌────iceberg───┐
│┌─ ─ ─── ─ ─ ┐│ │┌─ ─ ─ ─ ─ ─ ┐│
raw deletes│ │ │ │
────────►││ index │├──►││ deletion ││
│ │ │ vectors │
│└─ ─ ─── ─ ─ ┘│ │└─ ─ ─ ─ ─ ─ ┘│
└──────────────┘ └──────────────┘
Moonlink 支持多种输入源:
Moonlink 将数据提交为带有删除向量的 Iceberg v3 表。这些表可以从任何兼容 Iceberg 的引擎进行查询。
计算引擎
元数据(catalog)
<秒 的 新鲜度)对于需要亚秒级查看新数据的工作负载,Moonlink 支持实时查询:
1. 克隆并构建
克隆存储库并构建服务二进制文件:
git clone https://github.com/Mooncake-Labs/moonlink.git
cd moonlink
cargo build --release --bin moonlink_service
2. 启动 Moonlink 服务
启动Moonlink服务,它将数据存储在./data目录中:
./target/release/moonlink_service ./data
3. 验证服务健康状况
检查服务是否正常运行:
curl http://localhost:3030/health
4.创建表
创建一个具有已定义架构的表。以下是创建表的示例users:
curl -X POST http://localhost:3030/tables/users \
-H "Content-Type: application/json" \
-d '{
"database": "my_database",
"table": "users",
"schema": [
{"name": "id", "data_type": "int32", "nullable": false},
{"name": "name", "data_type": "string", "nullable": false},
{"name": "email", "data_type": "string", "nullable": true},
{"name": "age", "data_type": "int32", "nullable": true},
{"name": "created_at", "data_type": "date32", "nullable": true}
],
"table_config": {}
}'
5.插入数据
向创建的表中插入数据:
curl -X POST http://localhost:3030/ingest/users \
-H "Content-Type: application/json" \
-d '{
"operation": "insert",
"request_mode": "async",
"data": {
"id": 1,
"name": "Alice Johnson",
"email": "alice@example.com",
"age": 30,
"created_at": "2024-01-01"
}
}'
你怎么看? 反正我认为解决了大问题, 架构明晰, 非常值得一试!
https://github.com/Mooncake-Labs/moonlink
https://docs.mooncake.dev/pg/intro
https://github.com/Mooncake-Labs/moonlink/tree/main/src/moonlink_datafusion
https://github.com/Mooncake-Labs/duckdb_mooncake
https://github.com/Mooncake-Labs/pg_mooncake