# 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 实施建议 **推荐方案**: 1. **Phase 1**:实现基础 TDB 存储引擎(500 行) 2. **Phase 2**:实现节点管理和心跳(300 行) 3. **Phase 3**:实现控制协议(400 行) 4. **Phase 4**:实现公共 IP 管理(200 行) 5. **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