12 KiB
12 KiB
CTDB (Cluster Trivial Database) 架构分析
概述
CTDB 是 Samba 的集群数据库系统,用于在高可用性(HA)集群环境中管理共享状态和数据库记录。
核心功能:
- 集群节点间状态同步
- 分布式数据库存储
- 故障检测和自动恢复
- 公共 IP 地址管理(浮动 IP)
1. CTDB 核心组件
1.1 分布式数据库引擎
功能:
- 字储 TDB (Trivial Database) 记录
- 在多个节点间复制数据
- 提供原子性和一致性保证
TDB 格式:
┌─────────────────────────────────────┐
│ TDB Header │
│ ├── Magic number: 0x1BADFACE │
│ ├── Version: 1 │
│ ├── Hash size: 1024 │
│ └── Record count: N │
├─────────────────────────────────────┤
│ Hash Table │
│ ├── Bucket 0: offset to record │
│ ├── Bucket 1: offset to record │
│ └── ... │
├─────────────────────────────────────┤
│ Free List │
│ ├── Offset to next free block │
│ └── Free block size │
├─────────────────────────────────────┤
│ Records │
│ ├── Key (variable length) │
│ ├── Data (variable length) │
│ └── Hash next pointer │
└─────────────────────────────────────┘
1.2 集群节点管理
功能:
- 节点状态监控(UP/DOWN/UNHEALTHY)
- 心跳检测(heartbeat)
- 自动故障转移(failover)
节点状态定义:
| 状态 | 说明 | 处理 |
|---|---|---|
| UP | 节点正常运行 | 参与集群操作 |
| DOWN | 节点离线 | 等待恢复 |
| UNHEALTHY | 节点不健康 | 停止服务 |
| BANNED | 节点被禁止 | 重新加入需手动操作 |
1.3 公共 IP 管理
功能:
- 动态分配浮动 IP(public IP)
- 节点故障时自动迁移 IP
- 客户端透明重连
公共 IP 分配逻辑:
┌─────────────────────────────────────┐
│ Public IP Pool │
│ ├── 192.168.1.100 (node 0) │
│ ├── 192.168.1.101 (node 1) │
│ ├── 192.168.1.102 (node 2) │
│ └── ... │
├─────────────────────────────────────┤
│ IP Assignment │
│ ├── Node 0 UP → owns .100 │
│ ├── Node 1 DOWN → .101 moves to N0 │
│ └── Node 2 UP → owns .102 │
└─────────────────────────────────────┘
1.4 事件脚本系统
功能:
- 监控脚本(健康检查)
- 启动/停止脚本(服务管理)
- IP 分配脚本(网络配置)
事件类型:
| 事件 | 说明 | 脚本 |
|---|---|---|
startup |
节点启动 | 01.startup.sh |
shutdown |
节点停止 | 50.shutdown.sh |
takeip |
分配 IP | 11.takeip.sh |
releaseip |
释放 IP | 10.releaseip.sh |
monitor |
健康检查 | 00.monitor.sh |
2. CTDB 协议架构
2.1 控制协议
CTDB 控制消息(基于 TCP):
┌─────────────────────────────────────┐
│ CTDB Header │
│ ├── Magic: 0xCtdb │
│ ├── Version: 1 │
│ ├── Command: CTDB_CMD_* │
│ ├── Status: SUCCESS/ERROR │
│ ├── Length: payload size │
├─────────────────────────────────────┤
│ Payload │
│ ├── Command-specific data │
│ └── Optional response data │
└─────────────────────────────────────┘
CTDB_CMD 类型:
| Command | 说明 | 用途 |
|---|---|---|
CTDB_CMD_CONNECT |
连接请求 | 初始化连接 |
CTDB_CMD_GETDB |
获取数据库 | 访问 TDB |
CTDB_CMD_FETCH |
读取记录 | 查询数据 |
CTDB_CMD_STORE |
存储记录 | 写入数据 |
CTDB_CMD_DELETE |
删除记录 | 清除数据 |
CTDB_CMD_PING |
心跳检测 | 节点监控 |
CTDB_CMD_SETNODEMASK |
设置节点掩码 | 集群配置 |
2.2 数据库复制协议
复制策略:
- 主从复制(Master-Slave):一个节点为主,其他为副本
- 多主复制(Multi-Master):所有节点可写入(需要冲突解决)
复制流程:
Node A Node B
| |
|── STORE(key, value) ────>| (write request)
| |── Validate
| |── Write to local TDB
| |── Replicate to other nodes
|<── ACK (success) ────────|
| |
|── FETCH(key) ───────────>| (read request)
|<── value ────────────────| (return data)
2.3 故障恢复协议
故障检测:
┌─────────────────────────────────────┐
│ Health Monitor Loop │
│ ├── Ping all nodes (every 1s) │
│ ├── Check response timeout (5s) │
│ ├── Mark DOWN if timeout │
│ └── Trigger recovery process │
└─────────────────────────────────────┘
恢复流程:
Node A (DOWN) Cluster
| |
|── Mark as DOWN ─────────>| (detected)
| |── Reassign public IPs
| |── Notify other nodes
| |── Update node mask
| |
|── Recovery attempt ─────>| (after 30s)
|── Rejoin cluster ───────>| (if successful)
| |── Restore IPs
3. CTDB 与 SMB 集成
3.1 Samba 集成点
共享数据库:
| TDB 文件 | 说明 | 集群支持 |
|---|---|---|
secrets.tdb |
认证密钥 | ✅ CTDB 复制 |
brlock.tdb |
字节锁 | ✅ CTDB 复制 |
locking.tdb |
文件锁 | ✅ CTDB 复制 |
connections.tdb |
连接状态 | ✅ CTDB 复制 |
session_info.tdb |
会话信息 | ✅ CTDB 复制 |
share_info.tdb |
共享配置 | ✅ CTDB 复制 |
关键特性:
- 所有节点访问相同的数据库
- 实时同步锁定状态
- 故障后自动恢复连接
3.2 实施架构
高可用性架构:
┌─────────────────────────────────────────────┐
│ Client Layer │
│ ├── SMB clients (Windows/macOS/Linux) │
│ └── Connect via floating IP │
├─────────────────────────────────────────────┤
│ CTDB Cluster (3+ nodes) │
│ ├── Node 0: 192.168.1.100 (SMB + CTDB) │
│ ├── Node 1: 192.168.1.101 (SMB + CTDB) │
│ ├── Node 2: 192.168.1.102 (SMB + CTDB) │
│ └── Public IPs: .100, .101, .102 │
├─────────────────────────────────────────────┤
│ Shared Storage │
│ ├── GlusterFS / Ceph / NFS │
│ └── All nodes access same filesystem │
└─────────────────────────────────────────────┘
4. 实施评估
4.1 核心功能需求
| 功能 | 优先级 | 工作量 | 风险 |
|---|---|---|---|
| 分布式 TDB | P0 | 500 行 | 中 ⚠️⚠️⚠️ |
| 节点管理 | P0 | 300 行 | 中 ⚠️⚠️⚠️ |
| 公共 IP 管理 | P1 | 200 行 | 低 ⚠️⚠️ |
| 事件脚本系统 | P1 | 200 行 | 低 ⚠️⚠️ |
| 控制协议 | P0 | 400 行 | 高 ⚠️⚠️⚠️⚠️ |
| 故障恢复 | P0 | 300 行 | 高 ⚠️⚠️⚠️⚠️⚠️ |
| 总计 | 1900 行 | 高 ⚠️⚠️⚠️⚠️⚠️ |
4.2 技术挑战
挑战 1:分布式一致性
- 问题:多节点写入冲突
- 解决方案:
- 使用 Raft/Paxos 算法(需要实现 consensus)
- 或使用主从模式(简化但牺牲可用性)
挑战 2:故障检测准确性
- 问题:网络分区导致误判
- 解决方案:
- 使用多路径心跳(多个检测点)
- 设置合理的超时阈值(避免误判)
挑战 3:浮动 IP 管理
- 问题:IP 迁移需要内核支持
- 解决方案:
- 使用 Linux network namespace
- macOS 需要 ifconfig + route 管理
4.3 Rust 实施建议
推荐方案:
- Phase 1:实现基础 TDB 存储引擎(500 行)
- Phase 2:实现节点管理和心跳(300 行)
- Phase 3:实现控制协议(400 行)
- Phase 4:实现公共 IP 管理(200 行)
- Phase 5:实现故障恢复逻辑(300 行)
总计:约 1700 行代码(不包括测试)
预计时间:约 5-7 天(高复杂度)
4.4 替代方案
方案 1:使用现有 Rust crate
raft-rs:分布式共识算法tikv:分布式 KV 存储- 优点:减少实现工作量
- 缺点:需要集成适配
方案 2:简化 CTDB 实现
- 仅实现单主模式(避免分布式共识)
- 使用 SQLite 作为共享数据库(简化存储)
- 优点:降低实施风险
- 缺点:牺牲可用性(主节点故障无法写入)
方案 3:不实施 CTDB
- 使用外部高可用方案(HAProxy + Keepalived)
- MarkBase SMB 保持单节点部署
- 优点:最小工作量
- 缺点:无法实现真正的集群
5. 决策建议
5.1 推荐策略 ⭐⭐⭐⭐
短期(P3 不建议实施):
- ✅ 保持单节点部署(Phase 1-6 已完成)
- ✅ 使用外部 HAProxy + Keepalived 实现高可用
- ❌ 不实施 CTDB(复杂度高,收益有限)
长期(企业需求):
- ⭐⭐⭐⭐ 实施简化 CTDB(单主模式)
- ⭐⭐⭐ 使用 Raft-rs 实现分布式共识
- ⭐⭐⭐⭐⭐ 完整 CTDB 实现(需要 5-7 天)
5.2 最终建议
| 场景 | 推荐方案 | 工作量 |
|---|---|---|
| 个人/小团队 | 单节点 + 外部 HA | 0 行 |
| 中小企业 | 简化 CTDB(单主) | ~800 行 |
| 大型企业 | 完整 CTDB + Raft | ~2000 行 |
结论:Phase 7 (CTDB 集群) 复杂度高(⚠️⚠️⚠️⚠️⚠️),建议根据实际需求决定是否实施。
最后更新:2026-06-22