1. DRBD 分布式复制块设备指南
DRBD(Distributed Replicated Block Device)是一种基于Linux内核实现的分布式存储解决方案,它通过网络将块设备(如硬盘、分区或逻辑卷)实时镜像到另一台服务器上。我第一次在生产环境接触DRBD是在2015年一个金融支付系统的灾备项目中,当时我们需要在两座城市的数据中心之间实现存储级同步,而传统的存储阵列复制方案成本过高。DRBD以其开源特性和接近裸金属的性能表现,最终成为我们的选择。
这个技术本质上是在两台服务器的块设备层建立了一个实时同步的"镜像"关系。当应用程序在主节点写入数据时,DRBD会将这些写入操作通过网络传输到备用节点,并在备用节点上执行相同的写入操作。这种机制使得备用节点上的数据始终保持与主节点一致,在主节点发生故障时可以实现快速切换。
2. DRBD 核心架构与工作原理
2.1 数据同步流程解析
DRBD工作在Linux内核的块设备层,位于文件系统和磁盘驱动之间。它的核心同步流程可以分为以下几个步骤:
- 写入拦截:当应用程序向主节点的块设备写入数据时,DRBD驱动会拦截这些IO请求
- 本地提交:数据首先被写入主节点的本地磁盘
- 网络传输:写入的数据块通过网络传输到备用节点
- 远程确认:备用节点将数据写入本地磁盘后,向主节点发送确认
- 完成通知:主节点收到确认后,才向应用程序返回写入成功
这种"本地优先+远程确认"的机制(称为Protocol C)确保了数据的强一致性,即使主节点突然宕机,也能保证至少有一个副本已经完整写入数据。
2.2 三种同步协议对比
DRBD支持三种不同的同步协议,适用于不同场景:
| 协议类型 | 确认时机 | 数据安全性 | 性能影响 | 典型应用场景 |
|---|---|---|---|---|
| Protocol A | 本地写入完成即返回 | 较低(可能丢失最近写入) | 最小 | 对性能敏感且可容忍少量数据丢失 |
| Protocol B | 数据到达备节点内存即返回 | 中等 | 中等 | 平衡性能与安全性的通用场景 |
| Protocol C | 备节点磁盘写入完成才返回 | 最高 | 最大 | 金融、数据库等关键业务 |
在大多数生产环境中,特别是涉及数据库存储时,建议使用Protocol C。虽然它会引入额外的网络延迟(通常增加1-3ms的写入延迟),但能确保故障切换时不丢失任何已确认的写入操作。
3. DRBD 部署与配置实战
3.1 基础环境准备
假设我们有两台服务器:node1(192.168.1.101)和node2(192.168.1.102),计划使用/dev/sdb1作为DRBD设备。以下是详细部署步骤:
- 安装必要软件包(在两台节点上执行):
# CentOS/RHEL yum install -y drbd kmod-drbd84 drbd-utils # Ubuntu/Debian apt-get install -y drbd8-utils linux-image-extra-`uname -r`- 加载DRBD内核模块:
modprobe drbd- 检查模块加载情况:
lsmod | grep drbd # 应输出类似:drbd 423936 03.2 资源配置文件详解
DRBD的主配置文件位于/etc/drbd.d/,我们需要创建一个新的资源配置文件,例如/etc/drbd.d/r0.res:
resource r0 { protocol C; disk { on-io-error detach; } net { max-buffers 8000; max-epoch-size 8000; sndbuf-size 512k; } on node1 { device /dev/drbd0; disk /dev/sdb1; address 192.168.1.101:7788; meta-disk internal; } on node2 { device /dev/drbd0; disk /dev/sdb1; address 192.168.1.102:7788; meta-disk internal; } }关键参数说明:
protocol C:指定使用最严格的同步协议on-io-error detach:当发生IO错误时自动分离设备max-buffers和max-epoch-size:影响同步性能的内存参数meta-disk internal:将元数据存储在同一个物理设备上
3.3 初始化与启动流程
- 创建元数据存储(两台节点):
drbdadm create-md r0- 启动DRBD服务:
systemctl enable drbd systemctl start drbd- 查看初始状态:
cat /proc/drbd # 应显示"Secondary/Secondary"状态- 设置主节点(在node1执行):
drbdadm primary --force r0- 开始初始同步:
drbdadm up r0初始同步时间取决于磁盘大小和网络带宽。可以使用以下命令监控同步进度:
watch -n 1 'cat /proc/drbd'4. DRBD 高级管理与优化技巧
4.1 日常运维命令集锦
状态检查:
drbdadm status r0 drbd-overview # 输出示例: # 0:r0/0 Connected Primary/Secondary UpToDate/UpToDate角色切换:
# 将node1降级为备用节点 drbdadm secondary r0 # 将node2提升为主节点 drbdadm primary r0强制切换(当网络分区时):
drbdadm disconnect r0 drbdadm secondary --force r0 # 在另一个节点上 drbdadm connect --discard-my-data r04.2 性能优化实践
- 网络优化:
# 增大TCP缓冲区大小 sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216" sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"- DRBD参数调优:
net { cram-hmac-alg "sha1"; shared-secret "MySecurePassword"; max-buffers 36k; max-epoch-size 18k; sndbuf-size 2M; rcvbuf-size 2M; }- 磁盘调度器调整:
echo deadline > /sys/block/sdb/queue/scheduler4.3 与常见集群软件的集成
与Pacemaker/Corosync集成示例:
<primitive id="drbd-r0" class="ocf" provider="linbit" type="drbd"> <instance_attributes id="drbd-r0-attrs"> <nvpair id="drbd-r0-res" name="drbd_resource" value="r0"/> </instance_attributes> </primitive> <ms id="drbd-r0-ms" meta master-max="1" master-node-max="1"> <clone id="drbd-r0-clone"> <meta globally-unique="false"/> <primitive-ref id="drbd-r0"/> </clone> </ms>与Kubernetes的集成: 可以通过DRBD的LINSTOR项目实现Kubernetes持久化存储:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: drbd-storage provisioner: linstor.csi.linbit.com parameters: autoPlace: "2" storagePool: "lvm-thin"5. 生产环境常见问题排查
5.1 脑裂(Split-Brain)处理
脑裂是DRBD最严重的问题之一,表现为两个节点都认为自己是主节点。处理步骤:
- 确定哪个节点包含更重要的数据(通常是最新写入的)
- 在另一个节点上执行:
drbdadm secondary r0 drbdadm disconnect r0 drbdadm -- --discard-my-data connect r0- 在保留数据的节点上:
drbdadm connect r05.2 同步速度慢的优化
如果发现同步速度不理想,可以检查:
- 网络带宽和延迟:
iperf3 -c 192.168.1.102- 磁盘性能:
fio --filename=/dev/sdb1 --rw=write --ioengine=libaio --direct=1 --bs=4k --numjobs=1 --size=1G --runtime=60 --name=test- 调整DRBD的同步速率:
drbdadm disk-options --resync-rate=100M r05.3 常见错误代码解析
| 错误代码 | 含义 | 解决方案 |
|---|---|---|
| 17 (Network failure) | 网络连接中断 | 检查网络配置和防火墙 |
| 20 (Peer is outdated) | 对端节点数据过时 | 需要完整同步 |
| 91 (Protocol error) | 协议不匹配 | 确保两端使用相同DRBD版本 |
| 103 (No route to host) | 网络不可达 | 检查路由和IP配置 |
在多年的DRBD使用中,我总结出一个重要经验:定期执行手动故障转移测试。很多配置问题只有在实际切换时才会暴露,建议至少每季度进行一次完整的故障转移演练,包括:
- 模拟主节点宕机
- 手动提升备用节点
- 验证应用可用性
- 恢复原始配置
- 验证反向同步过程