ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

数据库高可用与容灾实战(10):架构实战:为一个 500GB 生产库设计高可用方案

数据库高可用与容灾实战(10):架构实战:为一个 500GB 生产库设计高可用方案 题目一张要能过评审的答卷第 9 篇里演练把纸面架构锤成了一串实测数字切换 93 秒、客户端收敛 257 秒、优化后全链路约 150 秒。这一篇做终章收束把前九篇攒下的所有零件、参数与教训装进一道典型的综合题——某核心业务 MySQL 库数据量 500GB、写峰值 1500 TPS、读峰值 20000 QPS、年增 40%部署在两个可用区SLA 承诺 99.99%、RPO0、RTO 不超过 5 分钟团队只有三名 DBA。方案文档要能过评审标准只有一条每个承诺都指向一个数字每个数字都有来源每个组件都写清故障语义每条没达到的项都挂在明面上。本篇用两个确定性模拟完成这次总装模拟的意义不在于替你真跑 MySQL而在于把前九篇实测过的口径切换秒数、收敛秒数、降级窗口、备份耗时放进同一本年度账里看它们合起来能不能兑现 SLA。先把 SLA 翻译成预算再翻译成旋钮99.99% 不是态度是预算一年 8760 小时里只允许中断 53 分钟。可用性写成乘积的形式最好算账可用性 f(年故障次数 x 单次中断时长)其中单次中断时长 判定 切换 客户端收敛第 9 篇的实测口径。这个式子告诉你降本只有两个旋钮——次数和单次时长自动切换与仲裁压的是时长与误报次数短 TTL 与连接池参数压的是收敛尾巴多数派共识干脆把两者同时按下去。RPO 同理它不由副本有没有数据决定而由每笔事务在几个持久化落点落了盘才被允许提交决定——这正是第 3 篇半同步与第 2 篇 durability 矩阵的全部意义。有了这两个分解候选架构的比较就退化成一门算术。实验一三个候选架构的年度账单YEAR_S365*86400CAND{A 异步人工切换:(6,4560*600,1800),B 半同步自动切换BinlogServer:(10,93257,0.5),C 跨AZ多数派共识:(6,3020,0),}SLA_AVAIL0.9999print(SLA 目标: 可用性 %.2f%% (年度中断预算 %.0f 分钟), RPO 目标: 金融场景 0%(SLA_AVAIL*100,YEAR_S*(1-SLA_AVAIL)/60))forname,(n,mttr,rpo)inCAND.items():downn*mttr avail1-down/YEAR_S verdict达标ifavailSLA_AVAILelse超预算 %.0f 分钟%((down-YEAR_S*(1-SLA_AVAIL))/60)print(%-28s: 年中断 %5.0f 分钟, 可用性 %.4f%%, RPO%ss - %s%(name,down/60,avail*100,rpo,verdict))print(\n把 B 推到 99.99% 的三个补丁:)budgetYEAR_S*(1-SLA_AVAIL)print( 1) 客户端收敛 257s - 153s(短TTL连接池参数, 476 实验B): 单次中断 %.0fs, 全年 %.0f 分钟%(9360,10*(9360)/60))print( 2) 降级探测误报(471 实验A): 仲裁fencing 防不必要的切换, 切换次数 10 - 6: 全年 %.0f 分钟%(6*(9360)/60))print( 3) 年度预算 %.0f 分钟: 剩余余量留给备份恢复演练与硬件维护窗口%(budget/60))运行输出SLA 目标: 可用性 99.99% (年度中断预算 53 分钟), RPO 目标: 金融场景 0 A 异步人工切换 : 年中断 364 分钟, 可用性 99.9307%, RPO1800s - 超预算 312 分钟 B 半同步自动切换BinlogServer : 年中断 58 分钟, 可用性 99.9889%, RPO0.5s - 超预算 6 分钟 C 跨AZ多数派共识 : 年中断 5 分钟, 可用性 99.9990%, RPO0s - 达标 把 B 推到 99.99% 的三个补丁: 1) 客户端收敛 257s - 153s(短TTL连接池参数, 476 实验B): 单次中断 153s, 全年 26 分钟 2) 降级探测误报(471 实验A): 仲裁fencing 防不必要的切换, 切换次数 10 - 6: 全年 15 分钟 3) 年度预算 53 分钟: 剩余余量留给备份恢复演练与硬件维护窗口三个候选的输入参数全部来自前九篇的实测口径A 案的 453600 秒是人工值守一小时的诚实写照它输得毫无悬念——异步复制加人肉切换在数学上就够不着 99.99%RPO 更是分钟级欠账B 案把单次中断压到 350 秒数据库侧 93 秒 收敛尾巴 257 秒却在次数上吃了亏——探测越敏感、误报切换越多第 4 篇实验里那种 720 笔脑裂写错的代价就以不必要的切换形式回到账单里58 分钟对 53 分钟超支恰好 6 分钟C 案跨 AZ 多数派共识Paxos/Raft 谱系MySQL 生态里对应组复制一类方案5 分钟达标但它要把整个读流量迁到共识组里重新做容量评估500GB 规模下改造成本最高。评审的结论因此非常工程化不选最漂亮的选差距最小的再用旋钮补齐——B 案距目标只差 6 分钟而两个旋钮各值十几分钟收敛优化后单次 153 秒全年 26 分钟仲裁加 fencing 把年切换次数从 10 压到 6全年 15 分钟15 分钟对 53 分钟预算余量留给维护窗口和恢复演练。需要点明这是把参数按固定值累加的确定性模拟不含随机数也不读时钟它验证的不是 MySQL 而是这笔账的算术。实验二最终方案总装与逐项验收选骨架B 案 两个补丁之后把七件套参数逐条装配每条都注名出处篇号最后输出一张不留情面的验收清单——没有出处和验收动作的架构描述在评审会上等于没说。plan{拓扑:主(AZ1) 半同步副本(AZ1,读) 异步副本(AZ2,读) binlog server(AZ2) ProxySQL x3 归档实例(AZ2),复制:GTIDROWbinlog_row_imageFULL; 半同步 wait_count1 指向 AZ1 副本, ACK 兜底 binlog server(AZ2),持久化:sync_binlog1 innodb_flush_log_at_trx_commit1(全节点),切换:自动: 多探测点仲裁 fencing relay/binlog 补账; 季度机房级演练验收,路由:ProxySQL: 写组主库, 读组 max_replication_lag1s, 写后 N 秒粘主,备份:XtraBackup 日全量(低峰0.5h窗口) binlog 连续归档(独立存储) 季度 PITR 真恢复,治理:大表建表即按月分区; 清理走分块归档限流; 在线变更优先 gh-ost,}fork,vinplan.items():print(%-4s: %s%(k,v))print(\n容量核算(500GB, 年增 40%, 三年后):)size500.0foryinrange(1,4):size*1.4print( 第%d年末 %.0fGB: 磁盘按 %.0f%% 水位购 %dGB; 日 binlog 按 6GB/100GB数据 经验值估 %.0fGB%(y,size,70,int(size/0.7/100)*100,size*0.06))peak_w,peak_r1500,20000# 写TPS / 读QPSper_replica_r12000print(\n读能力核算: 峰值 %d QPS, 单副本可扛 %d - 在线读副本 %d 台 主库兜底 20%%%(peak_r,per_replica_r,-(-peak_r//per_replica_r)))print( 主库回退余量: 全员熔断时主库要独扛 %d QPS 读 —— 主库规格必须按写全量读预算%peak_r)checks[(RPO0,半同步binlog server 双落点, 降级窗口配 P1 告警(470),True),(RTO5min,93s 数据库侧 收敛优化后 ~150s 全链路(476 优化参数),True),(可用性99.99%,年中断预算 53 分钟, 依赖仲裁降切换次数(实验A),False),(误删可救,ROWFULL 镜像闪回 PITR 双路径(474),True),(单表治理,月分区 DROP PARTITION 清理(475),True),]print(\n验收清单(未达项必须挂改进工单):)forname,basis,okinchecks:print( [%s] %-12s 依据: %s%(PASSifokelse未达,name,basis))print(未达项动作: 接入机房级多数派读能力(第 C 案)前, 用双写窗口补偿对账兜底, 并在季度演练中复测。)运行输出拓扑 : 主(AZ1) 半同步副本(AZ1,读) 异步副本(AZ2,读) binlog server(AZ2) ProxySQL x3 归档实例(AZ2) 复制 : GTIDROWbinlog_row_imageFULL; 半同步 wait_count1 指向 AZ1 副本, ACK 兜底 binlog server(AZ2) 持久化 : sync_binlog1 innodb_flush_log_at_trx_commit1(全节点) 切换 : 自动: 多探测点仲裁 fencing relay/binlog 补账; 季度机房级演练验收 路由 : ProxySQL: 写组主库, 读组 max_replication_lag1s, 写后 N 秒粘主 备份 : XtraBackup 日全量(低峰0.5h窗口) binlog 连续归档(独立存储) 季度 PITR 真恢复 治理 : 大表建表即按月分区; 清理走分块归档限流; 在线变更优先 gh-ost 容量核算(500GB, 年增 40%, 三年后): 第1年末 700GB: 磁盘按 70% 水位购 1000GB; 日 binlog 按 6GB/100GB数据 经验值估 42GB 第2年末 980GB: 磁盘按 70% 水位购 1400GB; 日 binlog 按 6GB/100GB数据 经验值估 59GB 第3年末 1372GB: 磁盘按 70% 水位购 1900GB; 日 binlog 按 6GB/100GB数据 经验值估 82GB 读能力核算: 峰值 20000 QPS, 单副本可扛 12000 - 在线读副本 2 台 主库兜底 20% 主库回退余量: 全员熔断时主库要独扛 20000 QPS 读 —— 主库规格必须按写全量读预算 验收清单(未达项必须挂改进工单): [PASS] RPO0 依据: 半同步binlog server 双落点, 降级窗口配 P1 告警(470) [PASS] RTO5min 依据: 93s 数据库侧 收敛优化后 ~150s 全链路(476 优化参数) [未达] 可用性99.99% 依据: 年中断预算 53 分钟, 依赖仲裁降切换次数(实验A) [PASS] 误删可救 依据: ROWFULL 镜像闪回 PITR 双路径(474) [PASS] 单表治理 依据: 月分区 DROP PARTITION 清理(475) 未达项动作: 接入机房级多数派读能力(第 C 案)前, 用双写窗口补偿对账兜底, 并在季度演练中复测。七件套里最容易被评审放过的是两条隐性预算。第一条是主库回退预算读能力按稳态算只要 2 台副本加主库兜底两成就够但第 5 篇实验算过熔断的账——所有副本同时超延迟时20000 QPS 全砸回主库这要求主库规格按写 全量读买而不是按稳态的 1500 TPS 买绝大多数副本压测通过、回退当天主库被打爆的事故都源于这笔账没算。第二条是未达项管理可用性一项在验收清单上是 [未达] 而不是 [PASS]——因为补丁生效的前提是仲裁与收敛优化全部落地并被季度演练复测在复测通过之前它就欠着改进工单兜底动作双写窗口加补偿对账写在清单尾巴上。容量那三行同样诚实1.4 的三次方意味着第三年 1372GB、购盘 1900GB架构再好也救不了不扩容的磁盘binlog 日增 82GB 时第 6 篇的连续归档与第 3 篇的追平速度都要跟着重新压测。设计评审前过一遍的坑把 SLA 写成形容词没有拆成次数 x 单次时长预算的 99.99%出了事才知道差在哪个环节。只压数据库侧秒数不管客户端收敛尾巴第 9 篇的账摆着257 秒对 93 秒尾巴比头长。读扩展按稳态峰值算副本数熔断回退、批量任务错峰、报表日这些全员回主场景才是主库的真实考题。备份策略里没有恢复XtraBackup 文件躺在异地不等于能回来季度 PITR 真恢复是唯一可信的证据。未达项用形容词兜底“基本满足”“风险可控”必须写成工单、写清兜底动作、写死复测时间。方案文档没有出处列每个参数要么是自己演练测的要么注明来自哪次实验否则评审现场无法质疑也无法采信。系列收官清单十条承诺对十篇文章复制链路看得懂binlog dump、IO/SQL 双线程、MTS 并行组第 1 篇——延迟曲线异常时知道去查哪个队列。切换用 GTID 不用位点集合代数可校验、errant 与洞要清零第 2 篇。RPO0 靠协议不靠运气AFTER_SYNC 加超时降级告警1/1 持久化打底第 3 篇。自动化带刹车多点仲裁、fencing、relay 与 binlog server 补账第 4 篇。代理层明白钱花在哪熔断回退的流量放大、复用的会话污染、DNS 收敛第 5 篇。备份按边界选工具dump 管逻辑、XtraBackup 管物理、快照管时间点3-2-1 与恢复演练缺一不可第 6 篇。误删有两条路事务边界截断的 PITR 加 ROW 镜像闪回第 7 篇。大表不裸删分块归档限流、gh-ost 与分区裁剪各就各位第 8 篇。演练可回滚稳态假设、爆炸半径、三级回滚预案、RTO 实测第 9 篇。方案能过评审预算分解、参数装配、未达项挂账就是本篇第 10 篇。十篇走完这套系列其实只反复说了一件事高可用不是组件清单而是数字账本——每一条 SLA 承诺都要能被追溯到一次切换耗时、一个 ACK 语义、一次恢复演练容灾也不是有备份而是恢复过一次并且还能再恢复。下次评审会上不妨就拿本篇那道 500GB 的题当模板先问预算再看旋钮最后检查有没有把未达项写进清单。答案在数据里不在架构图的方框里。参考来源MySQL 8.0 半同步复制https://dev.mysql.com/doc/refman/8.0/en/replication-semisync.htmlMySQL 8.0 GTID 概念https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-concepts.htmlPercona XtraBackup 8.0 文档https://docs.percona.com/percona-xtrabackup/8.0/GitHubsysown/proxysqlhttps://github.com/sysown/proxysqlGitHubgithub/gh-osthttps://github.com/github/gh-ostWikipediaHigh availabilityhttps://en.wikipedia.org/wiki/High_availability本系列已结集为免费专栏数据库高可用与容灾实战从主从复制到机房级演练进阶推荐付费专栏Python 自动化接单实战从脚本到第一单限时 ¥9.9首篇免费试读
返回列表