1. 项目概述
很多人一听TC,就以为是"天车"或者"Twitter客户端",但在存储圈子混久了,看到TC这两个字母,脑子里第一反应就是某厂商高端存储的TrueCopy,也就是真复制。简单说,TC是一种基于存储阵列的同步远程复制技术,能把一台存储上的数据实时复制到另一台存储,两块盘上的数据始终保持一模一样。我最早接触TC是在一个省级客户的容灾项目里,当时业务系统要求RPO接近0,机房距离不到20公里,光缆时延大概0.5毫秒,客户兜里预算又不支持购买小机上的数据库复制软件,最后就是用TC把存储层面的灾备扛起来了。
这篇文章就是把这几年玩TC的经验沉淀一下:先讲清楚TC的原理机制,再聊配置前的那些坑,紧接着给一套可以直接照着做的配置步骤,最后是日常运维中常见的状态、切换和故障排查方法。无论你是刚入门存储的运维新人,还是已经干了几年想系统梳理一下复制技术的老人,这篇文章都适合。不需要你有很高深的存储基础,只要知道LUN、RAID、SAN这些基本概念,就能跟得上。
2. TC是什么,为什么我们需要它
2.1 从业务连续性说起
任何容灾方案解决的无非是两件事:数据不丢和业务不停。RPO是能容忍丢多少数据,RTO是能容忍停多长时间。如果业务系统只允许丢失一次提交的事务,那就必须做同步复制;如果业务能够容忍丢失几十秒甚至几分钟的数据,那异步复制也能接受。TC属于同步复制,意味着主阵列承接的每一次写I/O,必须等从阵列也写成功之后,才向主机返回"写入完成"。所以TC天然把RPO逼近到0,这是它最大的价值。
2.2 TC在整个复制技术里的位置
复制技术分两类:主机层复制和存储层复制。主机层复制大家熟悉的比如数据库的DataGuard,或者卷管理器的镜像,它依赖主机上必须安装对应的软件或代理,一旦主机本身崩了,复制链路也断了。存储层复制则完全由磁盘阵列来实现,主机无感知,哪怕主机宕机,只要阵列还活着,复制链路依然在工作。TC就属于存储层复制,它利用阵列控制器内部的功能模块,把主卷(P-VOL)的数据块实时发送到从卷(S-VOL)。从实现层次来看,TC与存储虚拟化、快照这些功能不同,它不需要额外购买服务器,不占用主机资源,这也是很多金融客户愿意用它的原因。
2.3 TC与其它远程复制功能的分工
同一厂商的高端存储上通常有好几种复制技术,TC的同类产品还有UR(Universal Replicator),UR可以理解成异步版本的TC,它在同步复制的基础上引入了磁盘中间缓冲(Journal),先把数据落到本地的日志卷,再异步发送到远端,因而在远距离传输时对应用性能影响更小。而TC更强调"每一笔都要确认",这也就决定了它对时延、带宽的要求非常苛刻。实际项目里经常是TC用于同城双活或近距灾备,UR用于异地异步容灾,两者配合着用。搞清楚TC能做到什么、不能做到什么,才知道什么时候该选它。
3. TC的工作原理,别再只记命令
3.1 核心组件和数据路径
TC体系里最基本的单位是复制对,由主卷P-VOL和从卷S-VOL组成。P-VOL是业务主机实际访问的那块卷,S-VOL是远端阵列上的备份卷。每台存储的控制器里都有负责处理复制的专用功能模块,叫SSP(Storage Side Processor),它主要负责解析写入请求、维护复制的位图和状态机。当主阵列的SSP收到主机写入命令后,会先记录该LBA(逻辑块地址)对应的复制状态,然后把数据打成固定大小的包,通过光纤通道或IP网络送到从阵列。从阵列的SSP接收到数据后,把数据写入S-VOL对应的逻辑块,并返回确认。主阵列收到确认后,才告诉主机本次写入已完成。
这个流程可以用一个生活场景来类比:你在银行柜台上转账,柜员不会立刻说"办好了",而是先打电话给收款行,确认对方账户已经到账,才给你回执。虽然多等几秒钟,但两边账目绝对一致。TC就是这种"两边确认"的机制,安全性极高,代价是每一次写请求的延迟都会被放大,变成"本地延迟+传输时延+对方写延迟"的总和。
3.2 同步复制过程拆解
我想把同步复制的每一步拆得更细一点,因为在调优和排查的时候要用到。一次完整的TC写流程是这样的:
- 主机发出写I/O到主阵列的P-VOL。
- 主阵列控制器判断P-VOL属于TC复制对,于是除了在本地缓存中更新数据外,同时把写请求发送给TC控制模块。
- TC控制模块生成一条复制记录,向远端S-VOL所在阵列发送写请求。
- 远端阵列收到数据后,将数据写入S-VOL缓存,并执行远程I/O确认。
- 主阵列收到远端确认后,才对主机返回写I/O完成信号。
注意这里有一个关键点:TC保障的是“顺序一致性”,即所有写操作必须按发送顺序在S-VOL上生效,不能因为链路乱序或者网卡丢包导致数据错序。因此TC在内部为每个复制对维护了一个序列号机制,每一条写记录都带顺序号,远端按顺序号依次提交。这也是为什么TC不能随便修改主机总线队列深度或乱序策略。
3.3 一致性组的本质
单看一个复制对,比如数据库有一块数据卷和一块日志卷,如果只保证每一块卷都复制,但两块卷之间没有统一的时间对齐点,一旦切换到灾备端,数据卷和日志卷可能各差了一截,数据库照样起不来。一致性组(Consistency Group)就是把多个复制对组成一个组,组内所有复制对的复制操作会同时暂停、同时恢复、同时切换,这样就能保证灾难切换时,整个跨多卷的应用得到一个全局一致的数据镜像。这个对于多卷业务来说不是可选项,而是必选项。
注意:创建TC一致性组时,组内最好不要混入不同用途的卷。我见过有人把一个业务的生产卷跟另一个测试卷放同组,结果测试卷频繁断开导致整个一致性组进入挂起状态,生产也跟着受影响。
3.4 TC与UR的选型逻辑
很多朋友问,既然TC保证零丢失,为什么不所有场景都用TC?答案是距离和时延。TC要求往返时延小于等于10毫秒,最好在5毫秒以内;距离超过100公里,光纤传输延迟本身就可能超过1毫秒,再加上链路上的设备抖动,就很难撑住。而UR引入日志卷后,本地返回主机写入成功,日志再异步复制,距离和时延影响很小。所以选型逻辑很清晰:
| 需求特征 | 推荐方案 |
|---|---|
| RPO=0,同城或园区距离,时延低 | TC |
| RPO可容忍秒或分钟级,跨城/异地,长距离链路 | UR |
| 既要同步复制又要保留历史状态 | TC配合快照使用 |
| 超远距离且链路不稳定 | 建议考虑异步复制,不要把宝押在TC上 |
4. 配置前的设计和规划
4.1 判断该不该用TC
TC不是万能的,配置前需要先算四笔账。
第一笔是距离账。用光纤直连的话,光在新光纤里的传播速度大约是20万公里每秒,往返100公里链路就消耗了0.5毫秒的延迟。加上交换机转发延迟和存储内部处理延迟,100公里内通常没问题,超过200公里就要认真核算了。第二笔是带宽账。TC是把每次写I/O都发一份副本,假设业务写带宽是100MB/s,链路上至少预留150MB/s以上,保险起见按两倍规划,否则链路拥塞会导致连锁的性能问题。第三笔是时延账。如果主机写I/O平均延迟原本只有0.5毫秒,TC会把复制往返时间加进去,变成2毫秒或更多。对时延极度敏感的OLTP系统,需要提前做数据库负载模拟,不能只看存储指标。第四笔是故障域账。TC复制链路如果断开,是立刻停业务还是让主阵列继续运行但标记异常?这需要在项目层面决定,不能靠存储管理员拍脑袋。
4.2 网络与端口规划
TC可以通过FC端口、以太网端口和专用复制端口传输。常见做法是在主备阵列上各划分独立的端口,专供复制流量使用,不和业务I/O抢通道。如果一个复制对需要更高的带宽,还可以并行配置多个端口,让TC在多条链路上进行负载均衡。要给网络交换机划分专门的VSAN(或用其他厂商逻辑网络隔离),避免其它业务波动影响复制链路。另外强烈建议配置链路冗余,至少两条路径,当一个端口故障时自动切换到另一个端口。我遇到的实战案例里,有客户只拉了单根光纤,结果光缆被施工挖断,复制中断了六个小时,虽然没丢数据,但那一整天的RPO变成了无穷大,业务侧也是吓出一身冷汗。
4.3 阵列资源规划
TC复制对里的P-VOL和S-VOL原则上容量必须一致,至少S-VOL不能小于P-VOL。复制过程中TC不会做压缩,所有数据块原样传输。所以给S-VOL预留10%到20%的余量,用于应对后续的LUN扩充和快照预留。另外,S-VOL所在存储池(DP Pool)写性能如果太差,会直接拉高复制写延迟,严重时主机响应都会被拖慢。我一般建议从卷的磁盘类型和RAID策略不要低于主卷,宁可使用同样等级甚至更高等级的磁盘。
5. TC配置实操步骤解析
5.1 实验环境描述
为了避免麻烦,这里不写具体厂商型号,用某厂商高端存储作为样例。环境大致如下:
- 主阵列:某高端存储双控制器,存储池Pool_A,已有生产卷。
- 从阵列:另一台同系列高端存储,存储池Pool_B,用于放置从卷。
- 管理软件:某Storage Navigator管理界面(或命令行),用于配置复制对。
- 链路:通过两个交换机连接两台存储的复制端口,采用光纤通道。
5.2 第一步:创建数据卷
在管理界面的"存储池"菜单中,从Pool_B创建一块逻辑卷作为S-VOL。创建时注意:
- 容量按前面说的,等于P-VOL大小再加一点余量。
- 不映射给任何主机,S-VOL是专供复制使用的,不需要主机访问。
- 数据初始状态为空即可,TC建立后会做全量拷贝。
如果使用命令行,大概是这样的思路(具体命令因产品版本而异,这里只给逻辑):
# 在从存储上创建一个裸设备卷 create_lun -pool Pool_B -size 200G -name S_VOL_APP创建完成后,在管理界面上可以看到这个卷的状态是Normal、未绑定。
5.3 第二步:建立复制对
在TC菜单里选择“新建复制对”,填写:
- P-VOL:选择主机正在使用的那块生产卷。
- S-VOL:选择刚创建的从卷。
- 复制方式:选择Synchronous(同步)。
- 一致性组编号:如果有多个卷组成一个应用,则分配同一个一致性组ID。
- 初始复制模式:通常选“Full Copy”,就是先把主卷现有数据完整复制一遍到从卷。
确认之前再检查一遍两块卷的容量和Pool是否匹配。执行后系统会开始创建初始拷贝,状态会从SMPL变为COPY,再到PAIR。在拷贝期间,P-VOL的业务I/O不会中断,所以不用担心停机。拷贝完成后,TC才开始真正进入同步复制状态。
5.4 第三步:验证同步状态
用命令行查看复制对状态:
pairdisplay -g CGroup01输出结果里会看到复制对的名字、状态、一致性组号、IO状态等。常见的状态有:
- SMPL:还没有建立复制关系。
- COPY:正在初始全量复制。
- PAIR:复制对已建立,同步状态正常。
- PSUS:由于某种原因暂停复制,P-VOL和S-VOL有差异。
- PFUL / PSUE:表示复制对失败或发生异常。
看到PAIR说明TC已经正常工作。此时可以故意在主阵列上创建几笔数据,然后手动暂停、再恢复复制,观察从卷数据是否完全同步。这种验证建议在新环境上线前做一遍,避免用了好几个月才发现复制其实没生效。
5.5 第四步:配置监控与告警
一台TC复制对是否健康,单靠人工登录看状态是不够的。通常要把存储的SNMP告警关联到监控平台,告警规则主要关注几个点:
- 复制对状态从PAIR变为PSUS或PSUE。
- 一致性组中出现任何一个失败复制对。
- 复制链路带宽使用率超过70%。
- 复制延迟超过基线值。
有条件的话,还可以定期执行一致性校验,也就是把主卷和从卷的块数据进行比对,确保位图状态一致。虽然TC本身不会无故丢数据,但控制器微码bug、链路错误丢包、磁盘静默损坏,都可能破坏数据一致性,定期对账是很有必要的。
6. 日常运维、切换演练和常见问题
6.1 TC状态机速查
TC的状态切换并不是只有“复制”和“停止”两个状态。在故障和切换过程中还会出现其他关键状态。我做了一张速查表,方便日常排查:
| 状态 | 含义 | 常见触发条件 | 处理建议 |
|---|---|---|---|
| SMPL | 无复制关系 | 刚创建卷、删除复制对等 | 无需处理 |
| COPY | 初始复制中 | 建立复制对后 | 等待完成,注意监控带宽 |
| PAIR | 正常同步复制中 | 初始复制完成或恢复复制后 | 正常工作状态 |
| PSUS | 复制暂停,有差异 | 管理员暂停、链路中断告警 | 排查原因后恢复 |
| SSUS | 挂起且数据不完整 | 网络故障导致S-VOL数据未完整接收 | 务必先重新同步 |
| PSUE | 复制对异常 | 出现硬件错误或超时 | 立即查看错误日志 |
| PFUL | 复制等待初始同步 | 某些产品在初始化时 | 等待,勿强行操作 |
6.2 计划性的切换演练
容灾系统最怕“一次都没切过,真出事时不会切”。所以我强烈建议在非业务高峰期做切换演练。TC的切换逻辑可以分成“正常切换”和“故障切换”。正常切换步骤如下:
- 在应用层停掉写入,或通知DBA把数据库切到只读模式。
- 在TC管理界面执行复制暂停,让主卷和从卷保持一致。
- 确认P-VOL和S-VOL数据一致后,将S-VOL映射给灾备中心主机。
- 灾备主机挂载S-VOL,启动应用,完成切换。
- 后续如果生产中心恢复,可以把S-VOL反向设为P-VOL,再建立新的复制对,新变化逐步回传。
这中间最容易犯的错是“应用还没停就暂停复制”,这样S-VOL上的数据可能比P-VOL落后几个事务,切换后数据其实是迟到的。真正要演练的正是“应用停机那一刻和复制暂停那一刻”之间的衔接顺序。
6.3 链路中断怎么处理
网络抖动或者光模块故障都会导致TC链路中断。此时存储会按策略进入PSUS状态,也就是暂停复制,但P-VOL还是继续接收主机写操作。这样做是为了不让业务受损,但P-VOL和S-VOL的差异会越积越大。排查步骤一般是:
- 检查复制链路两端的端口状态,用命令行或管理界面查看“链路信息”,确认设备是否在线。
- 用ping或fcing测试物理连通性,但注意有些存储复制端口并不支持ICMP响应,得看具体产品。
- 如果网络恢复了,先不要急着恢复复制,先观察链路稳定几分钟。
- 执行复制对恢复,系统会先做差异同步,把链路中断期间P-VOL上产生的变更数据重新发到S-VOL。
- 完成后状态回到PAIR,然后立刻确认S-VOL上的数据完整性。
这里最关键的坑是:链路中断期间,如果P-VOL和S-VOL之间的位图记录溢出(比如差异超过位图容量),某些情况下TC可能会无法恢复,只能全量重新复制,这意味着可能需要把S-VOL清空再来一遍,耗时很长。所以日常监控里位图使用率也是一个指标,最好记录下来长期观察。
6.4 常见问题速查表
我在一线实际运维中总结过一些高频问题,整理成表格供参考:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 复制对一直处于COPY状态 | 初始复制带宽太小 / 远端写慢 | 扩容带宽或检查S-VOL缓存 |
| 业务IO延迟突然增高 | 复制链路拥塞 / 远端盘故障 | 查看两端端口速率,检查从卷磁盘状态 |
| 手工暂停后无法恢复 | 暂停前有写入未刷盘 | 检查P-VOL缓存,手动flush后再恢复 |
| 切换后应用起不来 | 一致性组范围不全 | 确认所有相关LUN都在同一CG内 |
| 复制链路频繁闪断 | 光模块老化或光纤接头脏 | 更换光模块,清洁光纤 |
| S-VOL容量不足报错 | 初始规划未留余量 | 扩展S-VOL或重建复制对 |
6.5 几个避坑心得
第一,TC的一致性组不是越多越好,也不是越少越好。太多组增加管理复杂度,太少组容易把无关卷绑在一起。一个业务系统一个组最合理。第二,千万不能为了性能关闭“write order”保护,一旦关了,远端顺序无法保证,数据库崩了神仙难救。第三,做复制恢复操作之前,一定要先拍个存储级快照,哪怕快照保留两小时,也会让你在误操作后能回到过去。第四,复用业务光纤链路跑TC是很冒险的,一旦业务流量峰值拥塞,复制流量会被挤掉,而业务自己感觉不到太大变化,实际上灾难恢复能力已经降级了。有条件就单独建复制网络。
7. 从实际项目中得到的体会
我在多个容灾项目里部署过TC,最大的感受是:TC本身很稳定,真正出问题的往往不是TC,而是人。比如有人把复制端口和业务端口插反了,有人把S-VOL的LUN归属设置错误导致主机在线扫描出了两个盘,有人误执行了删除复制对的命令,差点把灾备端数据清掉。所以操作任何存储复制功能前,建议先写一份变更脚本或操作票,列出要执行的每一步命令、预期状态,再找第二个人复核一遍。这种事听起来麻烦,但能挡掉九成以上的低级事故。
如果你所在环境还没有启用TC,但已经有了灾备规划,我建议先从一对测试卷开始做功能测试,把流程跑通、把命令记录好,再推广到生产。一次成功的TC配置,不是把所有按钮都点了就完事,而是你能在深夜两点被oncall叫醒时,还能冷静地通过几个命令判断出“链路断了”还是“从卷坏了”,这比背一百条命令都重要。