X-ADB 是一个基于 MPP (Massively Parallel Processing) 架构的分布式 OLAP 数据库系统,采用列式存储引擎,支持 MySQL 协议,专为大规模数据分析场景设计。
- Frontend (FE): 负责 SQL 解析、查询优化、任务调度和元数据管理
- Worker: 负责数据存储和查询执行,支持水平扩展
- gRPC 通信: FE 和 Worker 之间通过 gRPC 进行高效通信
- 列式存储: 针对 OLAP 场景优化,支持高效的列扫描和聚合
- 多种压缩算法: 支持 LZ4、Snappy、Zstd 等压缩算法
- 智能索引:
- ShortKey Index (前缀稀疏索引)
- ZoneMap Index (页级统计索引)
- BloomFilter Index (布隆过滤器索引)
- 逻辑计划优化: 谓词下推、列裁剪、常量折叠
- 物理计划生成: 基于代价的优化器
- 并行执行: 支持多线程并行查询执行
- 延迟物化: 减少不必要的数据读取
- 支持标准 MySQL 客户端连接
- 兼容常用 SQL 语法 (DDL/DML/DQL)
- 支持 JDBC/ODBC 驱动
┌─────────────────────────────────────────────────────────────┐
│ MySQL Client │
│ (mysql-cli, JDBC, etc.) │
└────────────────────────┬────────────────────────────────────┘
│ MySQL Protocol (Port 3307)
▼
┌─────────────────────────────────────────────────────────────┐
│ Frontend (FE) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL Server │ │ SQL Parser │ │ Metadata │ │
│ │ (Netty) │ │ (ANTLR4) │ │ Manager │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Logical │ │ Physical │ │ Coordinator │ │
│ │ Optimizer │ │ Planner │ │ (Scheduler) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ gRPC Server (Port 50051) │ │
│ │ (Worker Registration & Communication) │ │
│ └──────────────────────────────────────────────────┘ │
└────────────────────────┬────────────────────────────────────┘
│ gRPC Protocol
┌──────────────┼──────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Worker 1 │ │ Worker 2 │ │ Worker N │
│ │ │ │ │ │
│ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
│ │ gRPC │ │ │ │ gRPC │ │ │ │ gRPC │ │
│ │ Server │ │ │ │ Server │ │ │ │ Server │ │
│ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │
│ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
│ │Fragment │ │ │ │Fragment │ │ │ │Fragment │ │
│ │Executor │ │ │ │Executor │ │ │ │Executor │ │
│ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │
│ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
│ │Columnar │ │ │ │Columnar │ │ │ │Columnar │ │
│ │ Storage │ │ │ │ Storage │ │ │ │ Storage │ │
│ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │
└─────────────┘ └─────────────┘ └─────────────┘
1. Client → FE: SQL Query (MySQL Protocol)
2. FE: SQL Parsing (ANTLR4) → Logical Plan
3. FE: Logical Optimization → Optimized Logical Plan
4. FE: Physical Planning → Physical Plan
5. FE: Fragment Generation → Execution Fragments
6. FE → Workers: Distribute Fragments (gRPC)
7. Workers: Execute Fragments in Parallel
8. Workers → FE: Return Results (gRPC)
9. FE: Merge Results
10. FE → Client: Final Results (MySQL Protocol)
| 组件 | 技术 | 版本 | 用途 |
|---|---|---|---|
| 编程语言 | Java | 11+ | 主要开发语言 |
| 构建工具 | Maven | 3.6+ | 项目构建和依赖管理 |
| 网络框架 | Netty | 4.1.100 | MySQL 协议服务器 |
| RPC 框架 | gRPC | 1.58.0 | FE-Worker 通信 |
| SQL 解析 | ANTLR4 | 4.13.1 | SQL 语法解析 |
| 序列化 | Protobuf | 3.24.0 | 数据序列化 |
| 日志框架 | SLF4J + Logback | 2.0.9 | 日志记录 |
| 工具库 | Guava | 32.1.3 | 通用工具类 |
| JSON 处理 | Jackson | 2.15.3 | JSON 序列化 |
| 代码简化 | Lombok | 1.18.30 | 减少样板代码 |
| 测试框架 | JUnit 5 | 5.10.0 | 单元测试 |
- JDK 11 或更高版本
- Maven 3.6 或更高版本
- 至少 2GB 可用内存
# 克隆项目
git clone https://github.com/x-infra-lab/x-adb.git
cd x-adb
# 编译整个项目
mvn clean install -DskipTests
# 或者只编译特定模块
mvn clean install -pl x-adb-fe -am
mvn clean install -pl x-adb-worker -am# 方式1: 使用 Maven 运行
cd x-adb-fe
mvn exec:java -Dexec.mainClass="io.github.xinfra.lab.adb.server.FEServerMain"
# 方式2: 使用 JAR 包运行
java -jar x-adb-fe/target/x-adb-fe-1.0.0-SNAPSHOT.jar [mysqlPort] [grpcPort]
# 示例: 指定端口启动
java -jar x-adb-fe/target/x-adb-fe-1.0.0-SNAPSHOT.jar 3307 50051FE 默认端口:
- MySQL 协议端口:
3307 - gRPC 服务端口:
50051
# 方式1: 使用 Maven 运行
cd x-adb-worker
mvn exec:java -Dexec.mainClass="io.github.xinfra.lab.adb.worker.server.WorkerServerMain"
# 方式2: 使用 JAR 包运行
java -jar x-adb-worker/target/x-adb-worker-1.0.0-SNAPSHOT.jar \
--worker-id worker-1 \
--worker-host localhost \
--grpc-port 9091 \
--coordinator-host localhost \
--coordinator-grpc-port 50051
# 启动多个 Worker 实例
java -jar x-adb-worker/target/x-adb-worker-1.0.0-SNAPSHOT.jar \
--worker-id worker-2 --grpc-port 9092
java -jar x-adb-worker/target/x-adb-worker-1.0.0-SNAPSHOT.jar \
--worker-id worker-3 --grpc-port 9093Worker 命令行参数:
--worker-id: Worker 唯一标识 (默认: 自动生成)--worker-host: Worker 主机地址 (默认: localhost)--grpc-port: Worker gRPC 端口 (默认: 9091)--coordinator-host: Coordinator 主机地址 (默认: localhost)--coordinator-grpc-port: Coordinator gRPC 端口 (默认: 50051)
# 使用 MySQL 客户端连接
mysql -h 127.0.0.1 -P 3307 -u root
# 或使用 JDBC 连接
jdbc:mysql://localhost:3307/database_nameFrontend 是系统的协调节点,负责:
- MySQL 协议服务器: 接收客户端 SQL 请求
- SQL 解析: 使用 ANTLR4 解析 SQL 语句
- 查询优化: 逻辑计划优化和物理计划生成
- 元数据管理: 管理数据库、表、列等元数据
- 任务调度: 将查询任务分发到 Worker 节点
- 结果聚合: 收集并合并 Worker 返回的结果
核心组件:
x-adb-fe/
├── mysql/ # MySQL 协议实现
├── parser/ # SQL 解析和逻辑计划
├── optimizer/ # 查询优化器
├── coordinator/ # 任务协调和调度
├── metadata/ # 元数据管理
└── grpc/ # gRPC 服务端
Worker 是数据存储和计算节点,负责:
- 数据存储: 列式存储引擎,支持多种压缩算法
- 查询执行: 执行 FE 分发的查询片段
- 索引管理: 维护 ShortKey、ZoneMap、BloomFilter 索引
- Worker 注册: 向 FE 注册并保持心跳
核心组件:
x-adb-worker/
├── storage/ # 列式存储引擎
│ └── columnar/ # 列式存储实现
│ ├── index/ # 索引实现
│ ├── compression/ # 压缩算法
│ ├── io/ # 数据读写
│ └── optimization/# 查询优化
├── executor/ # 查询执行器
├── grpc/ # gRPC 服务端
└── server/ # Worker 服务器
列式存储特性:
- Tablet: 表的分片单元
- Rowset: 数据版本管理
- Segment: 数据文件单元
- DataPage: 数据页,支持压缩
- ColumnData: 列数据,支持索引
定义 FE 和 Worker 之间的通信协议:
- gRPC 服务定义: Worker 注册、任务执行等
- 数据结构定义: 查询片段、执行结果等
- Protobuf 消息: 高效的序列化格式
主要服务:
service WorkerRegistrationService {
rpc RegisterWorker(RegisterWorkerRequest) returns (RegisterWorkerResponse);
rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse);
rpc UnregisterWorker(UnregisterWorkerRequest) returns (UnregisterWorkerResponse);
}
service WorkerExecutionService {
rpc ExecuteFragment(ExecuteFragmentRequest) returns (ExecuteFragmentResponse);
rpc CancelFragment(CancelFragmentRequest) returns (CancelFragmentResponse);
}集成测试模块,用于测试整个系统的端到端功能:
- 启动 FE 和多个 Worker
- 执行完整的 SQL 查询流程
- 验证查询结果正确性
- 测试分布式场景
-- 创建数据库
CREATE DATABASE test_db;
-- 使用数据库
USE test_db;
-- 创建表
CREATE TABLE users (
id INT,
name VARCHAR(100),
age INT,
city VARCHAR(50)
);
-- 删除表
DROP TABLE users;
-- 删除数据库
DROP DATABASE test_db;-- 插入数据
INSERT INTO users VALUES (1, 'Alice', 25, 'Beijing');
INSERT INTO users VALUES (2, 'Bob', 30, 'Shanghai');
INSERT INTO users VALUES (3, 'Charlie', 35, 'Guangzhou');
-- 更新数据
UPDATE users SET age = 26 WHERE id = 1;
-- 删除数据
DELETE FROM users WHERE id = 3;-- 简单查询
SELECT * FROM users;
-- 条件查询
SELECT name, age FROM users WHERE age > 25;
-- 聚合查询
SELECT city, COUNT(*), AVG(age)
FROM users
GROUP BY city;
-- 排序查询
SELECT * FROM users ORDER BY age DESC LIMIT 10;
-- JOIN 查询
SELECT u.name, o.order_id
FROM users u
JOIN orders o ON u.id = o.user_id;X-ADB 支持三种索引类型,可显著提升查询性能:
适用于前缀列的等值和范围查询:
// 对前2列建立索引,每1024行一个索引条目
segment.buildShortKeyIndex(2, 1024);性能提升: 减少 50%+ 的数据扫描范围
自动为每个 DataPage 记录 Min/Max/NullCount:
// 自动构建,无需手动配置
column.buildZoneMapIndex();性能提升: 减少 80%+ 的不必要页扫描
专门优化等值查询:
// 期望10000个元素,1%误判率
column.buildBloomFilterIndex(10000, 0.01);性能提升: 避免 100% 的无效查询
-
使用列裁剪: 只查询需要的列
-- 好的做法 SELECT id, name FROM users WHERE age > 25; -- 避免 SELECT * FROM users WHERE age > 25;
-
利用索引列: 在 WHERE 条件中使用索引列
-- 利用 ShortKey 索引 SELECT * FROM users WHERE id = 1 AND name = 'Alice';
-
合理使用聚合: 利用列式存储的聚合优势
SELECT city, COUNT(*), AVG(age) FROM users GROUP BY city;
-
分区裁剪: 使用分区键过滤数据
SELECT * FROM orders WHERE date >= '2024-01-01' AND date < '2024-02-01';
| 算法 | 压缩比 | 压缩速度 | 解压速度 | 适用场景 |
|---|---|---|---|---|
| NONE | 1:1 | 最快 | 最快 | 已压缩数据 |
| LZ4 | 2-3:1 | 快 | 非常快 | 通用场景 (推荐) |
| Snappy | 2-3:1 | 快 | 快 | 低延迟场景 |
| Zstd | 3-5:1 | 中等 | 快 | 高压缩比场景 |
// 创建列数据时指定压缩算法
ColumnData column = new ColumnData(metadata, CompressionType.LZ4);x-adb/
├── pom.xml # 父 POM 文件
├── README.MD # 项目说明文档
├── x-adb-fe/ # Frontend 模块
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/ # Java 源代码
│ │ └── antlr4/ # ANTLR4 语法文件
│ └── test/ # 单元测试
├── x-adb-worker/ # Worker 模块
│ ├── pom.xml
│ └── src/
│ ├── main/java/ # Java 源代码
│ └── test/ # 单元测试
├── x-adb-protocol/ # Protocol 模块
│ ├── pom.xml
│ └── src/main/proto/ # Protobuf 定义
└── x-adb-integration-tests/ # 集成测试模块
├── pom.xml
└── src/test/java/ # 集成测试
# 运行所有测试
mvn test
# 运行特定模块的测试
mvn test -pl x-adb-fe
mvn test -pl x-adb-worker
# 运行集成测试
mvn test -pl x-adb-integration-tests
# 运行特定测试类
mvn test -Dtest=LogicalPlanBuilderTest- 使用 Lombok 减少样板代码
- 遵循 Java 命名规范
- 添加必要的注释和文档
- 编写单元测试覆盖核心逻辑
-
启用详细日志:
<!-- logback.xml --> <logger name="io.github.xinfra.lab.adb" level="DEBUG"/>
-
使用 IDE 调试:
- 在 IntelliJ IDEA 中设置断点
- 使用 Debug 模式启动 FE 和 Worker
-
查看 gRPC 通信:
# 启用 gRPC 日志 export GRPC_VERBOSITY=DEBUG export GRPC_TRACE=all
| 文档 | 说明 |
|---|---|
| 架构设计 | 系统整体架构、模块分层、数据流 |
| 快速入门 | 编译、部署、连接、基本 SQL 操作 |
| API 参考 | SQL 语法、数据类型、gRPC 服务接口 |
| 内部设计 | 存储引擎、查询优化器、Pipeline 执行引擎、事务模型 |
| 开发者指南 | 项目结构、开发环境、测试、扩展新功能 |
| 详细设计 | 完整的技术设计文档(行业调研、架构选型、详细实现) |
欢迎贡献代码、报告问题或提出建议!
- Fork 本项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 创建 Pull Request
如果发现 Bug 或有功能建议,请创建 Issue 并包含:
- 问题描述
- 复现步骤
- 期望行为
- 实际行为
- 环境信息 (JDK 版本、操作系统等)
本项目采用 Apache License 2.0 许可证。详见 LICENSE 文件。
本项目参考了以下优秀的开源项目:
- Apache Doris - MPP 架构和列式存储设计
- ClickHouse - 索引设计和查询优化
- Apache Parquet - 列式存储格式
- Presto - 分布式查询引擎