架构设计 #
一、整体架构 #
1.1 分层架构 #
text
┌─────────────────────────────────────────────────────────────┐
│ 应用层 │
│ PostgreSQL Client / ORM / Application │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SQL层 │
│ SQL解析 → 优化器 → 执行器 → 分布式执行 │
│ (无状态,可水平扩展) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 事务层 │
│ 事务协调 / 并发控制 / 时间戳 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 分布式层 │
│ Range / Raft / 副本管理 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 存储层 │
│ Pebble (LSM-Tree) / MVCC │
└─────────────────────────────────────────────────────────────┘
1.2 架构特点 #
| 特点 | 说明 |
|---|---|
| 无共享架构 | 每个节点独立,无单点故障 |
| 对等节点 | 所有节点功能相同 |
| 水平扩展 | 添加节点即可扩展 |
| 自动均衡 | 数据自动分布和均衡 |
二、SQL层 #
2.1 SQL处理流程 #
text
SQL 处理流程
┌─────────────────────────────────────────────────────────────┐
│ │
│ SQL 语句 │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ SQL 解析 │ 词法分析 → 语法分析 → AST │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 语义分析 │ 类型检查 → 权限检查 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 查询优化 │ 逻辑优化 → 物理优化 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 执行计划 │ 生成执行计划树 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 分布式执行 │ 数据分发 → 并行执行 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ 查询结果 │
│ │
└─────────────────────────────────────────────────────────────┘
2.2 查询优化器 #
sql
-- 查看执行计划
EXPLAIN SELECT * FROM users WHERE id = 1;
-- 查看详细执行计划
EXPLAIN ANALYZE SELECT * FROM users WHERE id = 1;
-- 执行计划示例
-- │
-- • index join │
-- │ │
-- └── • scan │
-- missing stats │
-- table: users@primary │
-- spans: FULL SCAN │
2.3 PostgreSQL兼容性 #
sql
-- 支持的PostgreSQL特性
-- 数据类型
SELECT
'hello'::VARCHAR,
123::INTEGER,
3.14::DECIMAL(10,2),
'{"key": "value"}'::JSONB;
-- 数组类型
SELECT ARRAY[1, 2, 3];
SELECT '{1, 2, 3}'::INTEGER[];
-- 窗口函数
SELECT
id,
amount,
ROW_NUMBER() OVER (ORDER BY amount DESC) AS rank,
SUM(amount) OVER (PARTITION BY user_id) AS total
FROM orders;
-- CTE (Common Table Expression)
WITH user_orders AS (
SELECT user_id, COUNT(*) AS order_count
FROM orders
GROUP BY user_id
)
SELECT * FROM user_orders WHERE order_count > 10;
-- JSON操作
SELECT
data->>'name' AS name,
data->'age' AS age
FROM users
WHERE data->>'status' = 'active';
三、存储层 #
3.1 Pebble存储引擎 #
text
Pebble 存储引擎 (LSM-Tree)
┌─────────────────────────────────────────────────────────────┐
│ │
│ 写入流程: │
│ │
│ 写入请求 │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Write Ahead │ 预写日志 (WAL) │
│ │ Log │ 保证持久性 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ MemTable │ 内存表 (有序) │
│ │ (Active) │ 新数据写入 │
│ └─────────────┘ │
│ │ │
│ │ MemTable 满了 │
│ ▼ │
│ ┌─────────────┐ │
│ │ MemTable │ 不可变内存表 │
│ │ (Immutable) │ 等待刷盘 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ SSTable │ 磁盘文件 (Sorted String Table) │
│ │ (L0-L6) │ 分层存储 │
│ └─────────────┘ │
│ │
│ 读取流程: │
│ MemTable → Immutable MemTable → L0 → L1 → ... → L6 │
│ │
└─────────────────────────────────────────────────────────────┘
3.2 MVCC实现 #
sql
-- MVCC (多版本并发控制)
-- 每行数据有多个版本
-- Key: (table_id, index_id, primary_key)
-- Value: (timestamp, value)
-- 时间旅行查询
SELECT * FROM users
AS OF SYSTEM TIME '-10s';
-- 查看历史数据
SELECT * FROM users
AS OF SYSTEM TIME '2024-01-01 00:00:00';
-- 垃圾回收
-- CockroachDB 自动清理旧版本数据
-- 默认保留 25 小时
3.3 数据编码 #
text
数据编码格式
┌─────────────────────────────────────────────────────────────┐
│ │
│ Key 编码: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ /Table/<table_id>/<index_id>/<primary_key> │ │
│ │ │ │
│ │ 示例: │ │
│ │ /Table/53/1/1 (表53, 主键索引, 主键值1) │ │
│ │ /Table/53/2/'user@example.com' (二级索引) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Value 编码: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ <timestamp> + <value> │ │
│ │ │ │
│ │ timestamp: 事务时间戳 │ │
│ │ value: 行数据 (编码后的列值) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
四、分布式层 #
4.1 Range分片 #
text
Range 数据分片
┌─────────────────────────────────────────────────────────────┐
│ │
│ 数据按 Range 分片: │
│ │
│ 整个数据空间 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Range 1 │ Range 2 │ Range 3 │ Range 4 │ Range 5 │ │
│ │ [a-f) │ [f-m) │ [m-r) │ [r-w) │ [w-z] │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Range 特点: │
│ ├── 默认大小: 512MB │
│ ├── 自动分裂: 超过阈值自动分裂 │
│ ├── 自动合并: 数据减少自动合并 │
│ └── 自动均衡: 自动迁移到不同节点 │
│ │
│ Range 分布: │
│ │
│ Node 1 Node 2 Node 3 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Range 1 │ │ Range 2 │ │ Range 3 │ │
│ │ Range 4 │ │ Range 5 │ │ Range 6 │ │
│ │ Range 7 │ │ Range 8 │ │ Range 9 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
4.2 Raft共识 #
text
Raft 共识协议
┌─────────────────────────────────────────────────────────────┐
│ │
│ 每个 Range 是一个 Raft Group: │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Range 1 │ │
│ │ │ │
│ │ ┌──────────┐ │ │
│ │ │ Leader │ Node 1 │ │
│ │ │ (Raft) │ 处理读写请求 │ │
│ │ └──────────┘ │ │
│ │ │ │ │
│ │ ├─────────────────┐ │ │
│ │ ▼ ▼ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │Follower │ │Follower │ │ │
│ │ │ Node 2 │ │ Node 3 │ │ │
│ │ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ 写入流程: │ │
│ │ 1. 客户端发送写入到 Leader │ │
│ │ 2. Leader 追加日志 │ │
│ │ 3. 复制到 Followers │ │
│ │ 4. 多数确认后提交 │ │
│ │ 5. 返回客户端成功 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
4.3 副本管理 #
sql
-- 查看Range分布
SELECT
range_id,
start_key,
end_key,
replicas
FROM crdb_internal.ranges;
-- 配置副本数
ALTER DATABASE defaultdb CONFIGURE ZONE USING
num_replicas = 5;
-- 配置放置策略
ALTER DATABASE mydb CONFIGURE ZONE USING
constraints = '[+region=us-east]';
五、事务层 #
5.1 事务模型 #
text
分布式事务模型
┌─────────────────────────────────────────────────────────────┐
│ │
│ 事务执行流程: │
│ │
│ BEGIN TRANSACTION │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 获取时间戳 │ HLC (混合逻辑时钟) │
│ │ (Transaction ID)│ │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 读取数据 │ MVCC 快照读取 │
│ │ (Snapshot Read) │ │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 写入数据 │ 写入临时缓冲区 │
│ │ (Write Buffer) │ │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 两阶段提交 │ 1. Prepare (锁定) │
│ │ (2PC) │ 2. Commit (提交) │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ COMMIT TRANSACTION │
│ │
└─────────────────────────────────────────────────────────────┘
5.2 隔离级别 #
sql
-- 支持的隔离级别
-- READ COMMITTED (默认)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- SERIALIZABLE
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- 示例
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM accounts WHERE id = 1;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
-- 查看当前隔离级别
SHOW TRANSACTION ISOLATION LEVEL;
5.3 并发控制 #
text
并发控制机制
┌─────────────────────────────────────────────────────────────┐
│ │
│ 乐观并发控制: │
│ │
│ 1. 读取阶段 │
│ ├── 读取数据到本地 │
│ └── 记录读取的时间戳 │
│ │
│ 2. 验证阶段 │
│ ├── 检查是否有冲突 │
│ └── 冲突则重试 │
│ │
│ 3. 写入阶段 │
│ ├── 提交事务 │
│ └── 写入新版本数据 │
│ │
│ 冲突检测: │
│ ├── 写写冲突: 两个事务写同一行 │
│ ├── 读写冲突: 读后写 │
│ └── 写读冲突: 写后读 │
│ │
│ 重试机制: │
│ ├── 自动重试 (可序列化事务) │
│ └── 客户端重试 (其他事务) │
│ │
└─────────────────────────────────────────────────────────────┘
六、数据流 #
6.1 写入流程 #
text
写入数据流程
┌─────────────────────────────────────────────────────────────┐
│ │
│ INSERT INTO users (id, name) VALUES (1, 'Alice'); │
│ │
│ 1. SQL层解析和优化 │
│ │ │
│ ▼ │
│ 2. 确定目标Range │
│ │ │
│ ▼ │
│ 3. 发送到Range Leader │
│ │ │
│ ▼ │
│ 4. Leader处理写入 │
│ ├── 获取事务时间戳 │
│ ├── 写入WAL │
│ └── 写入MemTable │
│ │ │
│ ▼ │
│ 5. Raft复制到Followers │
│ │ │
│ ▼ │
│ 6. 多数确认后提交 │
│ │ │
│ ▼ │
│ 7. 返回客户端成功 │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 读取流程 #
text
读取数据流程
┌─────────────────────────────────────────────────────────────┐
│ │
│ SELECT * FROM users WHERE id = 1; │
│ │
│ 1. SQL层解析和优化 │
│ │ │
│ ▼ │
│ 2. 确定目标Range │
│ │ │
│ ▼ │
│ 3. 发送到Range Leader (或Follower) │
│ │ │
│ ▼ │
│ 4. 读取数据 │
│ ├── 确定时间戳 │
│ ├── 查找MemTable │
│ └── 查找SSTable │
│ │ │
│ ▼ │
│ 5. 返回结果 │
│ │
│ 一致性读取: │
│ ├── 强一致读: 从Leader读取 │
│ └── 过期读: 从Follower读取 (AS OF SYSTEM TIME) │
│ │
└─────────────────────────────────────────────────────────────┘
七、总结 #
架构要点:
| 层次 | 职责 | 关键技术 |
|---|---|---|
| SQL层 | SQL处理 | 解析、优化、执行 |
| 事务层 | 事务管理 | MVCC、2PC |
| 分布式层 | 数据分布 | Range、Raft |
| 存储层 | 数据存储 | Pebble、LSM-Tree |
下一步,让我们学习CockroachDB的数据类型!
最后更新:2026-03-27