100TB这个量级,放到数据库圈里是个很有代表性的分水岭。单机MySQL或者传统主从架构,真要把数据堆到100TB,扩容基本等于搬家,备份恢复能让人等到怀疑人生,一个慢查询就能把整个集群拖到告警。阿里云PolarDB走的是存算分离路线,计算节点和存储池各自独立扩展,这几年我陆陆续续跟过不少冲上100TB的PolarDB项目,从保险核心库到电商订单中台再到游戏行为分析,底层逻辑其实高度一致:先让存储不再成为瓶颈,才有资格谈超大规模数据管理。这篇文章我挑了三个有代表性的客户案例,把存算分离这套架构到底怎么帮他们解决问题、落地时有哪些关键动作,一步步拆开讲。
1. 存算分离架构拆解:为什么100TB级别要换思路
1.1 单机时代的三道墙:扩容、IO、复制
做数据库的人都知道,数据量一旦过了一个临界点,最先爆掉的往往不是磁盘空间,而是架构本身。传统“一机一库”模式下,计算和存储绑在同一台机器上,哪怕你用的是高端物理机,也逃不过三堵墙。
第一堵墙是扩容墙。单机的存储上限是实打实的物理约束。我见过不少客户,还没到100TB的时候数据盘就先见底了,然后就得提工单迁移、扩盘、换新规格,整个过程需要停机窗口,业务部门一听要停两个小时就开始跳脚。就算用云盘,单实例能挂载的容量也有上限,过了这个线只能拆库拆表,业务改造量立刻翻倍。
第二堵墙是IO墙。单机的网卡、磁盘队列、IO吞吐都是固定的。100TB的数据体量下,一个大批量查询可能瞬间打满所有IO,在线交易也跟着遭殃。很多团队在上PolarDB之前,都在用分库分表来“曲线救国”,把大表拆成几百个分片,但分片越多,跨库聚合查询越痛苦,一个简单的商家报表要拼好几轮数据。
第三堵墙是复制墙。传统主从复制走的是逻辑日志,主库压力一大,从库回放就落后,一落后只读流量就不敢切过去。数据量到100TB之后,复制延迟问题会成倍放大,因为一个稍大的事务产生的日志量可能让从库追几个小时。
1.2 计算与存储解耦,解开的到底是什么
PolarDB的存算分离,核心就是把“数据库实例”拆成两个平面:计算平面和存储平面。计算平面是一组数据库引擎节点,可以有一个主节点负责写入,挂多个只读节点分摊查询;存储平面是底层的分布式存储PolarStore,统一承载所有数据,容量按需扩展。
这句话听起来简单,但实际影响非常深远。最直接的变化是,扩容不再等于搬数据。以前数据量大了,要把整个实例迁移到更大的机器;现在存储空间不够,直接在存储池上扩容,计算节点连接的是同一个存储池,数据不需要重新拷贝。计算资源不够,加只读节点就行,节点挂上去之后立刻开始承接查询流量,不需要等几个小时的“初始化数据拷贝”。
这个架构很像把“自建仓库”换成了“公共云仓库”。以前每个门店(计算节点)背后都得跟着一个装满货的仓库(本地磁盘),仓库小了就得整个门店搬迁;现在门店只管做生意,仓库是统一的大型仓储中心,门店多了就多开几个柜台,仓库里的货是共享的,哪个柜台需要调货直接从仓库拉。
1.3 性能没打折:PolarStore与物理复制这两个关键设计
很多人一听存算分离,第一反应是“网络传输会不会很慢”。早期确实有不少这种架构的网络延迟问题,但PolarDB的存储访问走的是RDMA高速网络,计算节点和存储节点之间的通信延迟被压到了极低的水平。底层PolarStore是分布式块存储,默认多副本冗余,IOPS能到百万级,官方文档里对这个能力有明确说明。
另一个关键设计是日志下沉。PolarDB把Redo Log写入和存储副本同步的过程放到了存储层,计算节点只需要把日志发给存储层,由存储层在多个副本之间完成数据同步。这样一来,主节点不再需要等待本地磁盘完成所有落盘操作再返回,大大降低了写入延迟。
还有一个特别值得提的点是物理复制。PolarDB的只读节点和主节点之间用的是物理复制,不是MySQL传统的binlog逻辑复制。逻辑复制要把binlog解析成SQL再在从库上回放一遍,物理复制直接基于数据页做同步,效率和延迟都好了不止一个数量级。这也是为什么PolarDB挂多个只读节点之后,只读节点的数据延迟一般都能控制在非常低的水平,读流量可以放心分流过去。
2. 三个真实客户案例:把100TB数据真正用起来
2.1 保险客户:从Oracle一体机到PolarDB,用归档换成本
先讲一个保险行业的案例。这位客户的保单核心系统和历史理赔系统原本跑在Oracle一体机上,算上历史归档数据,整体量级在120TB以上,其中核心在线业务库大约10TB,理赔与历史档案库85TB左右,还有更早的数据一直躺在老旧的存储设备里。
痛点非常典型。其一,一体机的扩容和续保成本极高,存储容量扩一圈的价格能买几台小汽车。其二,监管要求保单数据保留期很长,数据只增不减,老系统每年都要面对容量告急。其三,备份和恢复太慢,85TB的库做一次物理备份要跑十几个小时,真碰到故障要做恢复,业务中断时间没法接受。
迁移方案最终选定了PolarDB for PostgreSQL,看中的是它对Oracle语法的高兼容性,存储过程、触发器和序列等核心对象改造量小。架构上,我们把在线核心库和档案库拆成了两套PolarDB集群,在线库保持10TB级别,负责交易和实时查询;档案库承载85TB左右的历史数据,用只读节点给风控、核保和数据团队提供准实时的查询能力。再往前的超冷数据,我们做了分区归档,定期把不再访问的旧分区导出到OSS对象存储,用的时候再加载。
最后的效果:85TB档案库的备份时间从十几个小时压缩到20分钟以内,存储成本大约是原来一体机方案的1/3。最关键的是,以前那种“盘满就慌、备份过夜”的焦虑感消失了,存储空间在控制台上点点就能扩,业务不用再跟着存储的物理上限走。
这个项目最值得复用的经验是:迁移之前一定要做好对象兼容性评估,特别是存储过程和大SQL。保险系统里几百个存储过程是常态,如果全部靠手工改,上线周期会变得不可控。我们提前用工具做了全库扫描,把所有不兼容的语法点梳理成清单,分批改造,比上线后边跑边修靠谱得多。
2.2 电商客户:大促弹性扩展,让计算跟着流量走
第二个案例是某电商平台的订单与支付数据中台。这个客户的订单表、支付流水表、库存流水表加起来超过100TB,行数在几十亿这个级别。早期这套系统是自建MySQL加分库分表,拆了两百多个分片,单分片的数据控制在几百GB以内。
这套方案撑过了早期业务增长,但到了后面问题越来越多。第一,分片太多导致跨分片查询非常难受,运营想看一个店铺的全链路订单数据,需要把几十个分片的数据聚合起来,写SQL就像做拼图。第二,大促之前扩容要提前两三天准备,申请新机器、初始化实例、迁移分片数据,压力全堆在运维团队身上。第三,分片集群的只读能力不足,商家端报表高峰时读流量一大,主库就会被拖住。
后来客户决定把核心订单链路迁到PolarDB for MySQL。迁移之后,分片逻辑保留了一部分,但每个分片不再是“一套MySQL实例”,而是一个PolarDB集群。底层存储池按需扩容,订单涨了不用再手工拆片;计算层,日常保留2个只读节点,大促前再加4个,加节点的操作从原来的提前3天准备变成了提前半天在控制台点几下。大促期间,商家端报表和用户端订单查询都走只读节点,写入走主节点,互不干扰。
这个案例里最惊艳的不是PolarDB某个单点性能有多猛,而是它的“弹性”真正落地了。计算资源跟着流量走,大促前加节点,大促后缩容,成本是弹性的,扩缩容窗口从“天”级缩到了“小时”级。对电商团队来说,这种按需扩容的能力,比单纯堆性能更值钱。
2.3 游戏客户:历史库也能分析,离线链路断舍离
第三个案例是一家游戏公司,场景是玩家行为分析平台。这个平台的埋点数据、行为日志、道具流水、充值流水全部汇总在一个库里,总数据量在110TB上下,每天新增数十亿条行为事件。自研游戏的运营同学每天都要看留存、付费转化、关卡通过率这些指标,对数据新鲜度的要求很高。
原来的架构是典型的“在线库 + Hive离线数仓”两条腿走路:在线MySQL只保留最近几天的热数据,历史数据全部落到Hadoop集群,分析任务要先把数据从Hive导出再加工,跑一次核心报表通常要等好几个小时,T+1已经算快的了。链路长、成本高、口径还容易对不上。
客户最终选了PolarDB for MySQL,并且用上了并行查询和列存索引。做法是,把行为明细表按照日期做RANGE分区,当天的数据进热分区,历史分区定期压缩并使用列存索引加速分析。在线业务继续用行存索引跑点查,分析团队直接在同一套集群上跑大查询,靠并行查询把大表的扫描能力拉起来。
改造后的结果是,核心指标报表从原来的小时级变成秒级到几十秒级,运营同学上午就能看到前一天的完整数据和今天的实时趋势,不再依赖T+1。ETL链路砍掉了一大截,之前统一的离线分析流程也简化了不少。对这家客户来说,PolarDB的存算分离让他们敢把原本“应该进数仓”的数据直接留在在线库上管理,少搬了一次数据,也就少了一堆麻烦。
3. 百TB数据落地路线:容量、分区、调优与容灾
3.1 容量规划:先算清三本账
数据量过了100TB,最容易犯的错误就是“先跑起来,有问题再说”。存算分离架构虽然帮你拆掉了存储瓶颈,但容量规划该做还是要做,而且要比传统架构做得更精细。我一般建议客户先算清三本账。
第一本账是存储池账。存储池大小不等于业务数据量。PolarDB存储层默认三副本,假设业务数据100TB,那底层存储池至少需要300TB的裸容量,还要再预留20%到30%的扩容buffer,避免存储空间使用率超过70%之后影响性能。也就是说,规划时你心里要有“400TB”这个概念,而不是“100TB”。
第二本账是计算节点账。OLTP场景下,节点的CPU和内存决定并发处理能力;OLAP分析型查询多,则要优先考虑并行查询能力和只读节点数量。通常我们会根据压测结果倒推节点规格,比如某条核心写链路在8C16G节点上能扛住多少QPS,再乘以峰值流量,得出主节点规格。只读节点的数量则取决于读流量占比,读多写少的场景多配几个只读节点,把读流量分散开。
第三本账是IO账。大事务、批量写入、DDL操作都会瞬间拉高IO压力。虽然PolarStore的IOPS能力很强,但IO也有天花板,峰值写入时如果发现存储延迟明显上升,要么拆分大事务,要么适当扩容存储性能层。IO排障的思路通常从慢SQL和存储监控两个入口同时下手。
3.2 分区和冷热分层:让100TB不是“100TB”
同样是100TB数据,处理方式不同,查询性能和运维成本差别巨大。我的经验是,数据量抵达这一级别时,一定要做分区设计,并且把冷热分层意识贯穿到架构里。
分区设计最常用的就是范围分区,按业务日期做RANGE分区。查询语句只要带上时间范围,优化器就能直接走分区裁剪,只扫相关分区,而不是整表扫描。分区粒度一般按天或按月,按天适合写入频率高、近实时查询多的场景;按月适合历史明细多、查询以月为单位的场景。分区数也不能无限加,单表单分区数量建议控制在合理范围内,分区太多之后,DDL、统计信息和备份管理都会变得臃肿。
冷热分层方面,以PolarDB的实际使用为例,在线库保留最近3到6个月的“热数据”,让业务查询和实时分析都能拿到好性能;更早的数据迁入归档库或者冷分区,使用压缩存储和列存索引降低成本;真正极少访问的过期数据,甚至可以直接导出到OSS,只保留元数据在库里。这样才能保证“100TB在线库”这个壳里,真正活跃的数据永远只有几十GB到几TB。
3.3 查询性能优化:别让大表拖死整个集群
100TB数据面前,一条没走索引的查询就可能让整个集群CPU狂飙。所以在落地PolarDB时,查询治理是必须做的前置工作。
并行查询是PolarDB面对大查询的核心利器。大表扫描、大聚合、大join这些操作会自动被拆分到多个并行线程执行,效果立竿见影。但在实际调优中,并行度并不是越高越好。并发查询一多,并行度太高会占满CPU,反而让在线事务性能下降。我的习惯是,先在测试环境压测出适合业务模型的并行度参数,再通过hint或者会话级参数对特定SQL做单独控制,避免全局一把梭。
索引设计上,覆盖索引是性价比很高的优化方式。对于查询字段和返回字段都比较固定的场景,把select的字段和where的条件都放进一个索引里,可以免去回表,查询性能会有几倍的提升。还要注意避免索引失效,比如在索引列上做函数运算、隐式类型转换之类,这些都是经典坑。
连接治理同样不能忽略。高并发场景下,应用一个劲儿地创建短连接,很容易把数据库的连接数打满。接上PolarDB Proxy或者应用侧连接池,把连接复用起来,效果非常明显。我见过不少客户,明明数据库规格不小,结果被几千个空闲连接压得喘不过气,加了连接池之后瞬间清爽。
3.4 备份恢复与高可用:越大的数据越怕丢
数据量越大,备份恢复的难度就越高。传统数据库备份100TB数据,光拷贝数据文件就要好几个小时,这还是没算上网络传输和日志回放的时间。PolarDB的备份基于存储层快照,天然有优势,备份速度非常快,恢复通常也能在分钟级完成,还支持按时间点恢复。
不过,备份快不代表高可用就自动达标。在超大规模场景下,容灾设计要分两层考虑:一层是同地域跨可用区的副本冗余,PolarDB默认三副本分布在多个可用区,单可用区故障不用人工切换;另一层是跨地域容灾,如果业务对容灾要求高,可以通过跨地域备份或者集群复制的方式,在异地建立一个备用集群,RPO和RTO都能控制在比较理想的范围内。
还有一件很多人容易忽略的事:恢复演练。数据到了100TB,恢复流程里面每个环节都可能出幺蛾子,比如网络带宽不够、目标集群规格偏小、权限配置有误。我一般建议客户每季度做一次完整的恢复演练,真的把备份恢复到一个临时集群上,跑几条核心SQL确认数据完整性。演练过的流程,出故障时才敢拍胸脯说能恢复。
4. 迁移与运维避坑指南:文档里没写的那些细节
4.1 存量库迁移PolarDB的完整路径
从自建库或者其他云数据库迁移到PolarDB,路径其实相对成熟,但每个环节都有不少细节值得注意。我复盘几个跑完的迁移项目,大致可以拆成五步。
第一步是评估。用工具把源库的对象、SQL、存储过程、数据类型等全部扫一遍,和PolarDB的兼容性清单做比对。千万别迷信“自动兼容99%”这句话,剩余的1%在百TB数据下可能是几百个SQL,逐个改也是一周起步。
第二步是压测。在PolarDB上搭建和源库等价的数据量,用压测工具模拟真实业务模型,把TPS、QPS、RT这些指标跑出来对比。存储过程和大SQL一定要单独拎出来压,这些往往是迁移后性能差异最大的部分。
第三步是同步。用DTS做全量加增量同步。全量阶段要特别关注源库的IO负载,别让数据传输把生产库压垮。建议同步任务放在业务低峰期开启,并且监控源库的延迟和慢查询。
第四步是切换。切换前做好校验,比如核心表行数比对、最大值最小值比对。切换窗口一般选在凌晨,业务停写后做最终增量追平,然后一键切换流量。回滚预案一定要提前写好,一旦切换后出现严重问题,能快速切回源库。
第五步是上线后观察。数据一致性、性能指标、慢SQL、连接数、存储增长,全部都要盯。新环境经常会暴露一些隐藏的性能问题,这是一个正常的“排雷期”,提前和业务方约定好一周到两周的观察窗口,比出了问题再解释要好得多。
4.2 高频问题排查速查表
在多个百TB项目维护过程中,有几类问题反复出现。我整理了一个问题排查速查表,基本覆盖了日常运维最常见的情况。
| 问题现象 | 可能原因 | 处理方式 |
|---|---|---|
| 写入高峰时存储延迟上升 | 大事务或批量任务导致Redo增长过快 | 拆分大事务、错峰跑批、必要时候扩容存储性能 |
| 只读节点延迟突增 | 主库大DDL或大事务导致回放压力大 | 错开大任务窗口、调整并行回放参数、临时增加只读节点 |
| 存储空间增长异常 | Undo膨胀、临时表过多、过期备份未清理 | 监控Undo和临时表空间、清理过期备份、定期归档冷分区 |
| 并行查询性能不升反降 | 并行度设置不合理或SQL未走分区裁剪 | 检查执行计划、按SQL级别调整并行度、补充分区键条件 |
| 连接数被占满 | 应用短连接过多或连接池参数不合理 | 启用Proxy、调整连接池、限制实例最大连接数 |
| 备份恢复时间偏长 | 备份文件过大或恢复目标规格不足 | 精简备份保留周期、提升恢复集群规格、分库恢复 |
这个表格看起来简单,但每一条背后都有真实的故障时间。关键是建立好监控告警体系,把存储使用率、IO延迟、只读节点延迟、慢SQL数量这些核心指标都配置上告警,不要等业务方来反馈才被动响应。
4.3 成本账怎么算才真的划算
很多人觉得PolarDB存算分离比自建MySQL贵,其实要看你怎么算这笔账。自建MySQL一套100TB的架构,光想想就头疼:打底一台高性能物理机或高配云主机跑主库,再来一两个从库,数据盘要挂大容量ESSD,备份要单独买存储,DBA人力成本还得算进去。最关键的是,这套架构平时用不满,大促或者业务高峰时又不够用,性能与成本的平衡非常难拿捏。
PolarDB的计费逻辑是存储和计算分开。存储按实际占用量计费,用得少就便宜,用得多也是透明的线性增长,不像买物理机那样一次砸一大笔钱。计算节点可以灵活启停和扩缩容,业务低谷期可以把不用的只读节点释放掉。备份空间单独计费,只要定期清理过期备份,就能控制住这块成本。
我之前和客户算过一笔账,客户原来的一体机方案,每年光硬件维保和扩容费用就是一辆中档车的价格;换成PolarDB之后,存储按量付费,计算按需扩容,加上不再需要单独采购备份设备,整体成本差不多压缩到原来的三分之一到二分之一。当然,具体数字会因业务模型、地域、计费方式不同而浮动,但方向是一致的:存算分离的成本优势,在百TB这个量级会非常明显。
还有一个特别容易忽略的成本点:迁移上线后,因为弹性能力和运维效率提升而节省的人力成本。以前大促扩容可能要连续熬夜好几个晚上,现在提前半天加节点就行。这部分节省的时间和精力,往往比直接省下的云资源费用更值钱。
这几个项目跑完之后,我最大的体会是,用PolarDB管理100TB数据,最该转变的不是工具选型,而是思维方式。别再把数据库看作一台台孤立的机器,而是看成“计算资源池 + 存储资源池”的组合。分区、归档、容量规划这些基本功,做得越早,后面越省心;等出了问题再来补课,付出的代价往往是几倍。如果你也在评估超大规模数据的落地方案,我建议先回去翻一翻自己的数据增长曲线和访问特征,把冷热数据和读写的真实比例摸清楚,再来对照这套架构,很多纠结自然就解开了。