ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从ECS自建到云原生数据库:架构演进与迁移实战

从ECS自建到云原生数据库:架构演进与迁移实战 在ECS上自己搭MySQL跑了两三年后来又换到RDS托管再到手上几个核心业务库迁到瑶池数据库PolarDB这中间踩过的坑和想明白的事我觉得值得单独写一篇。很多人一上来就问“ECS和RDS到底差在哪”其实这只是第一层问题真正关键的是为什么一旦业务进入核心交易、高并发读写、强一致的场景ECS自建和传统RDS都开始力不从心而瑶池数据库这种云原生架构才是更合理的归宿。这篇文章我就从架构差异讲起把ECS、RDS、瑶池数据库三者的底层逻辑掰开揉碎再结合我实际迁移和运维的经验聊聊选型和落地的关键点。适合正在做数据库选型、准备从自建迁云、或者被核心业务性能问题困扰的开发和运维同学。1. ECS自建数据库与RDS先搞清楚前面这对架构差异1.1 ECS自建数据库主机视角下的“什么都自己管”很多人最开始用数据库路子都很像在ECS上装一个MySQL或者PostgreSQL数据目录放在数据盘每天写个crontab跑mysqldump再配一主一从。这套方案在业务量小的时候确实够用毕竟ECS本身就是一台你可以完全掌控的云服务器操作系统、内核参数、数据库版本、存储布局全都可以自己定。但也正因为“全都可以自己定”所有问题也都落在你头上。我最开始就是这么干的生产环境一台4C8G的ECS跑MySQL 5.7另一台2C4G的ECS做从库中间用binlog复制同步。表面上看起来没问题实际上每一次内核小版本升级、OS补丁、磁盘扩容、慢查询优化、主从延迟处理都是手工活。尤其是主从复制一旦从库延迟追上不应用层读流量稍微大一点从库的Seconds_Behind_Master就开始往上飙而主库的IO压力也没法卸载因为从库还是要靠主库的binlog来同步。说白了ECS自建的架构是“以主机为中心”的数据库的可靠性、可用性、扩展性全部绑定在一台台具体的ECS上存储和计算没有分离瓶颈很早就出现了。还有一个容易被忽略的点ECS自建数据库的备份恢复完全依赖你对自己的“信任”。我之前就遇到过磁盘坏道导致数据文件损坏还好当时有物理备份否则恢复起来要花费大量时间。即使有云盘快照快照只是块级别的拷贝数据库崩溃恢复时可能还要依赖redo和undo日志处理不好就会丢数据。这类经验让我逐渐意识到ECS自建数据库适合的是“练手”、“学习”、“非核心业务”而不是把公司命脉压在几台云主机上。1.2 RDS的托管边界从主机运维到内核运维RDSRelational Database Service出现之后很多人才发现原来“数据库不用自己运维主机”是这么舒服。RDS把操作系统、数据库安装、高可用切换、自动备份、监控告警都托管了你只需要把连接串改一下业务就能跑起来。从架构上看RDS通常采用“主备高可用”模式一台主实例承载读写一台备实例同步数据主库故障时自动切换。存储层面用的是云盘或本地SSD计算和存储能力仍然绑定在单机上。RDS解决了ECS自建的“运维体力活”问题但它并没有改变数据库的“单机架构”本质。举个例子RDS的只读实例虽然可以扩展读能力但只读实例和主实例之间是通过binlog或redo进行异步/半同步复制主库的写压力、大事务、DDL操作都会在只读实例上产生延迟。你在ECS自建时遇到的主从延迟问题在RDS上依然存在只是阿里云帮你把切换、备份这些事做了。也就是说RDS的定位是“托管好一个单体数据库”而不是“改变数据库的架构形态”。从边界来看RDS帮你托管到了数据库内核这一层但参数调优、索引优化、慢查询分析、架构设计仍然需要你自己负责。很多团队把RDS当成“不用管运维的MySQL”却忘了RDS也有规格上限最大连接数、IOPS、存储容量都受限于你所购买的实例规格。比如一台4C8G的RDS MySQL即使开启了通用型性能也不代表你可以在上面跑几个T的数据和每秒几千的TPS还能保持稳定。这个时候真正的矛盾就出来了你想要的不是“托管一台数据库”而是“数据库本身能弹性扩展”。1.3 三张对比表资源隔离、性能上限、备份恢复为了让大家更直观地理解ECS自建和RDS的差异我梳理了三张对比表分别从资源隔离、性能上限、备份恢复三个角度看问题。资源隔离方面ECS自建数据库使用的是ECS的CPU、内存、磁盘同一台物理机上的其它ECS实例可能对你有影响需要自己处理超卖、邻居噪声等问题RDS则由云厂商通过虚拟化隔离计算和存储资源更可控你不需要关心宿主机上还有谁。性能上限方面ECS自建的上限取决于你选择的ECS规格、数据盘类型高效云盘、ESSD、网络带宽RDS的上限取决于实例规格和存储类型但整体上它仍然是一个单机数据库形态纵向扩展升配有一定上限横向只读扩展仍然依赖复制。备份恢复方面ECS自建需要自己写备份脚本、定期做恢复演练RDS提供自动备份、日志备份、按时间点恢复PITR明显更省心。但要注意RDS的备份恢复能力依然受限于单机数据库的物理粒度如果你有跨可用区容灾需求还需要额外购买“多可用区部署”。从这三张表能看出一条主线ECS自建和RDS都是在“单体数据库”框架内做文章只是运维责任的分配不一样。这个认知特别重要因为接下来聊瑶池数据库的架构时你会发现它直接跳出了这个框架。2. RDS与瑶池数据库的架构分水岭为什么传统托管扛不住核心业务2.1 传统主备复制与共享存储的本质区别传统RDS的“主备高可用”本质上还是“计算和存储不分离的复制架构”。主实例和备实例各自拥有独立的存储主库把binlog或redo传给备库备库在本地回放。这种架构的问题有两个第一主备切换时备库可能没有完全追上主库的日志导致少量数据丢失RPO不为0第二备库在正常情况下是“闲置”的只承担备份和故障切换的角色算力浪费。瑶池数据库PolarDB采用的则是“计算与存储分离”的架构底层存储是分布式共享存储PolarStore通过RDMA网络把多个存储节点连接起来数据在存储层多副本同步。计算节点主节点和只读节点不直接存数据而是通过存储协议访问共享存储。这样做最直接的好处是主备或者说主节点和只读节点看到的是同一份数据不需要通过binlog一层层回放数据一致性由存储层保证。打个比方传统RDS像是两个人都拿着一份文件的副本一个人改了内容后要把整个文件重新复印一份寄给另一个人瑶池数据库则像是两个人直接围着同一张桌子看同一份文件谁改了一笔另一个人马上就能看到。后者天然就省去了复制延迟的问题也为主备切换提供了更好的基础。在实际使用中这种区别感受非常明显。我原来用RDS MySQL时主库跑一个大事务只读实例的延迟能到几十秒甚至几分钟后来迁到瑶池数据库只读节点走的是存储层的物理复制主库提交完成的同时只读节点就能看到最新数据延迟基本在毫秒级甚至更低。对于读多写少、对一致性要求高的业务这个优势是压倒性的。2.2 一写多读、计算存储分离到底解决了什么瑶池数据库的“一写多读”架构简单说就是一个主节点负责读写多个只读节点负责读流量所有节点共享同一个分布式存储。主节点写入数据时redo日志直接写到存储层存储层负责把数据变更同步给所有只读节点。这样有两个核心收益。第一读扩展变得非常简单。传统RDS加只读实例本质上还是加一台“备库”你需要考虑复制延迟、连接数、资源规格瑶池数据库加只读节点就像“给同一个存储池增加计算能力”节点之间天然共享数据不需要等待数据拷贝。我曾经在一套瑶池数据库上挂了三四个只读节点业务读流量突增时直接在控制台加一个节点几分钟就能生效压力立刻被分摊。第二存储容量和计算规格解耦。在ECS自建或RDS架构下你想扩大存储就得升配整台实例CPU和内存可能用不完钱花得很冤枉瑶池数据库的存储是共享的独立资源池存储容量和计算节点是分开计费的计算节点不够就加节点存储不够就扩存储互不影响。这一点对于数据量大、增长快的业务尤其重要不用再为了一两TB的数据去购买一台昂贵的超大规格实例。当然一写多读也不是万能的。它优化的是“读多写少、主节点写压力不大”的场景。如果业务是超高并发写入、数据量极大、复杂分析查询你可能还需要考虑并行查询、列存索引等高级特性但这些就属于瑶池数据库产品能力层面的扩展了后面章节我再展开讲。2.3 从故障切换、备份恢复看“架构红利”架构决定了你在故障时能恢复多快、丢多少数据。传统RDS主备切换一般能做到秒级或分钟级RTO但RPO很难保证为0因为备库的日志回放总有一个“尾巴”。瑶池数据库的存储层是Multi-AZ多副本同步的主节点故障时只读节点或新的主节点可以直接从共享存储上继续读写数据不丢切换时间也能控制在秒级。我印象最深的一次是线上主节点所在机架出现硬件告警控制台触发了自动切换整个过程大概三十秒左右应用侧只是出现了一些重连和重试没有产生任何数据丢失的反馈。这个体验跟以前用ECS自建、RDS主备遇到故障时那种“心跳悬着”的感觉完全不同。不是因为运气好而是因为底层架构就是把“数据可靠性”下沉到了存储层计算节点反而变得“无状态”了。备份恢复方面瑶池数据库同样受益于存储层。自动备份基于存储快照技术速度快而且对业务影响小不像传统逻辑备份那样需要长时间锁表或占用大量IO。恢复时你可以把备份克隆成一个新的集群几十分钟就能拉起一个和线上几乎一致的环境这个能力在做数据回放、测试、分析时特别有用。我自己就经常用备份克隆出测试库来验证业务发版前的SQL变更。3. 核心业务为什么选择瑶池数据库性能、可用性、成本三维度拆解3.1 性能与扩展性从“升配”到“加节点”核心业务对数据库性能的要求通常不是“够用”而是“在流量高峰时依然稳定”。传统RDS在遇到性能瓶颈时最直接的手段是升配把CPU从8核升到16核内存从16G升到32G。升配本身不复杂但升配的过程中往往需要重启实例业务会有闪断而且升配解决不了“读流量持续增长”的问题最终还是要加只读实例。瑶池数据库的思路完全不同主节点和只读节点都支持独立扩展。读流量大了加只读节点主节点CPU吃紧可以单独给主节点升配不用动只读节点存储不够直接扩存储。更重要的是瑶池数据库可以把一些计算下推到存储层比如在并行查询、列存索引IMCI的帮助下复杂分析查询的速度提升非常明显。之前我做过一个压测同样一批聚合查询SQL在RDS MySQL上要跑十几秒的在瑶池数据库开并行查询后只需要两三秒这对报表类业务是质的改变。不过这里要提醒一句瑶池数据库的性能优势是建立在正确使用它的特性上的。如果你拿着一套为单机MySQL优化的慢SQL、不合理索引直接迁过来该慢还是慢。云原生架构解决的是“扩展性”和“资源弹性”的瓶颈而不是替你优化SQL。3.2 高可用能力RPO、RTO的差距到底在哪核心业务最怕的是数据丢失和长时间不可用。衡量高可用能力有两个核心指标RPO恢复点目标即最多丢多少数据和RTO恢复时间目标即多久恢复。传统RDS通过主备复制、自动备份能做到不错的RTO分钟级但RPO要视复制模式而定。在异步复制模式下主库宕机时可能丢失一小段事务在半同步复制模式下可以大幅减少丢失但对主库性能有影响而且备库宕机时主库写会受到阻塞。瑶池数据库从架构上改变了这个局面。数据在存储层通过多副本同步写入主节点事务提交时数据实际上已经在多个副本上持久化了。主节点如果发生故障系统从只读节点中提升一个新的主节点新的主节点访问的是同一份共享存储数据不会丢切换时间也能做到秒级。这意味着核心业务可以把RPO做到0、RTO做到秒级而这在传统RDS架构下是极难实现的目标。我还想在“高可用”这个话题下多说一句高可用不等于“多买一台备库”。如果你用的是ECS自建即使你搭了一主两从你还是得处理主从选举、日志同步、脑裂等一系列分布式问题如果你用传统RDS高可用由云厂商负责但它在架构上仍然绕不开复制延迟的约束。瑶池数据库把高可用做成了“架构自带”的能力这才是核心业务真正需要的。3.3 成本账ECS自建真的省钱吗很多人有这样一种直觉ECS自建数据库最便宜因为ECS按量付费便宜MySQL又不要License。这种“省钱”的想法在小业务、测试环境里是成立的但在核心业务上成本要算总账。首先人力成本。ECS自建意味着你要有人负责数据库的备份、监控、故障处理、版本升级、性能优化。一个专职DBA的年成本是多少大家心里都有数。哪怕不是专职DBA让开发兼任开发的精力也被分散了。其次风险成本。核心业务一次数据库故障造成的数据丢失或长时间停摆损失可能远超你省下的机器费用。再次资源成本。ECS自建为了应对峰值通常要预留不少冗余而这些资源在平时是浪费的RDS和瑶池数据库则可以按量伸缩或只读扩展资源利用率更高。瑶池数据库在价格上看起来比ECS自建高但它把“可靠性”和“扩展性”的成本包进去了。计算和存储分离的架构也让你不用为了存储扩容去升级整个实例这在大数据量场景下能省下相当可观的费用。我在一次方案评审中算过一笔账一个数据量3TB、读写都有明显峰值的业务用ECS自建主从两台的月成本大约是多少用RDS MySQL高可用的月成本是多少用瑶池数据库PolarDB的计算加存储组合又是多少。结果是瑶池数据库在提供更高可用性和扩展性的前提下综合成本并没有比RDS高多少甚至在某些规格组合下更划算。4. 迁移实操从ECS自建或RDS迁到瑶池数据库的关键步骤4.1 迁移前评估兼容性、规格、网络规划很多人觉得云数据库迁移就是“导出导入”直接跑个mysqldump就完事了。对于非核心业务这种粗暴的方式也许能接受对于核心业务迁移必须是一个严谨的项目。我建议把迁移前评估分成三步。第一步是兼容性评估。瑶池数据库的大版本分为MySQL兼容、PostgreSQL兼容、Oracle兼容等你需要先确定自己的数据库类型和版本。如果原来用的是MySQL 5.7迁到瑶池数据库的MySQL 8.0兼容版本要注意字符集utf8mb4、排序规则、sql_mode、事务隔离级别等参数差异。如果业务里用了大量存储过程、触发器、自定义函数更要提前在测试环境验证一遍因为这些对象往往最容易出现兼容性问题。第二步是规格规划。不要简单按原ECS或RDS的规格来选瑶池数据库的节点规格而是要根据实际的CPU使用率、内存使用率、QPS、TPS、连接数来评估。一般来说主节点规格可以参考原实例的峰值负载只读节点数量则根据读流量占比来定。存储容量要预留至少20%到30%的余量避免数据增长后频繁扩容。第三步是网络规划。瑶池数据库支持在VPC内网访问你需要提前规划好数据库所在的安全组规则、白名单、连接地址。如果原来的业务部署在ECS上迁移后ECS仍然通过内网连接数据库网络延迟基本可以忽略。但如果业务不在同一VPC就需要通过云企业网、公网或专线打通连接这一步最好在迁移前就完成测试避免割接时发现网络不通。4.2 DTS迁移的完整流程与参数设置迁移工具我强烈推荐使用DTS数据传输服务。它支持结构迁移、全量数据迁移、增量数据同步可以在不中断业务的情况下把数据从ECS自建或RDS平滑迁移到瑶池数据库。整个流程大概是这样的第一步创建迁移任务。在DTS控制台选择“数据迁移”源库类型选择MySQL或PolarDB兼容版本目标库选择瑶池数据库。填写源库和目标库的连接信息注意源库的账号需要有足够的权限至少需要SELECT、REPLICATION SLAVE、REPLICATION CLIENT等权限。第二步选择迁移类型。我建议“结构迁移全量数据迁移增量数据同步”一起勾选。结构迁移会自动创建表结构全量迁移负责历史数据增量同步会实时拉取源库的binlog把迁移过程中产生的新数据同步到目标库。这样做的好处是迁移过程中业务方基本不用停机只在最后割接时切换一下应用连接。第三步设置迁移对象。你可以选择迁移整个库也可以只迁移部分表。对于核心业务建议整库迁移避免遗漏外键、视图、存储过程等依赖关系。迁移前还会有一个预检查环节会检查源库和目标库的连通性、版本、权限、大表数量等预检查不通过时可以根据提示逐步修正。第四步启动并观察。全量迁移阶段DTS会按表并行迁移可以通过控制台查看迁移速度和进度。全量完成后会自动进入增量同步阶段此时源库和目标库的数据基本一致延迟通常在秒级以内。我习惯在增量同步稳定后对关键表做一次数据校验DTS本身也提供数据校验功能可以对比源库和目标库的行数、主键、校验和是否一致这一步不能省。4.3 割接与回滚方案设计增量同步稳定后真正的重头戏是割接。割接不是“把应用连接串改一下”这么简单而是要有一整套时间计划和回滚预案。我常用的割接流程是先在低峰期把应用流量切换一部分到新库观察一段时间确认新库的监控指标正常、没有报错再逐步切全部流量。如果是核心业务建议先切换只读流量再切换写流量。只读流量切换风险低如果新库有问题改回来也容易写流量切换后要更谨慎因为此时应用已经开始在新库上写入。切换前要确认几个点增量同步延迟是否已归零或接近零源库和目标库的数据校验是否通过新库的参数组、账号权限、白名单是否已经配置好监控告警是否已经覆盖CPU、内存、连接数、慢查询、主备切换等关键指标。这些问题没有全部确认前不要轻易切写流量。回滚方案同样重要。我的做法是在切换写流量后保留源库一段时间通常是24到72小时期间DTS增量同步不停继续把新库的变更反向同步回流回源库如果需要的话。如果新库出现严重问题可以快速把应用连接切回源库。当然反向同步需要额外配置你可以在迁移前就规划好双向同步或重建反向任务。这里想强调一点回滚不是“把连接串改回去”这么简单关键是数据不能丢。如果新库已经写入大量新数据而源库没有这些数据直接回滚会造成数据不一致。所以回滚决策要快窗口期越短越好。注意割接窗口尽量避免选在业务高峰和月底/年底结算日。我见过很多团队因为赶时间在业务高峰强行割接结果一个慢查询拖垮了整条链路最后连夜回滚。数据库迁移这种事宁可多花几天观察也不要赌运气。5. 常见问题与排查技巧实录5.1 连接数、事务隔离级别、大事务的几个坑迁移到瑶池数据库后最常见的问题往往不是数据库本身而是应用层还带着以前单机MySQL的使用习惯。我总结了三个高频“坑”。第一个坑是连接数。瑶池数据库默认的最大连接数是根据规格动态计算的但很多老代码里设置了固定连接池大小比如c3p0、Druid、HikariCP。如果应用侧连接池配置过大新库的连接数可能很快被打满。我建议迁移后先检查连接池的initialSize、minIdle、maxActive等参数再结合瑶池数据库的监控里的连接数指标合理调整。连接池不是越大越好连接数过多反而会消耗数据库内存和CPU。第二个坑是事务隔离级别。MySQL默认是REPEATABLE READ瑶池数据库的MySQL兼容版默认也是REPEATABLE READ但如果你之前的业务为了提升并发性能改成了READ COMMITTED迁移后要确认参数组里也做了同样设置。这种参数差异不会报错但会悄悄改变业务的行为比如出现不可重复读、幻读等问题排查起来非常隐蔽。第三个坑是大事务。ECS自建或RDS时代很多团队习惯了“用一个事务搞定所有更新”比如在循环里逐条update然后一次性提交。这种大事务在瑶池数据库上问题会被放大因为一写多读架构下大事务可能会对存储层产生较大的IO压力同时也会拖长redo日志的生成周期。我的建议是把大事务拆成小事务分批提交如果做批量更新控制每批的行数尽量避免在一个事务里同时操作多个大表。5.2 参数组与监控告警的配置经验瑶池数据库的参数组是一个很容易被忽略但又非常重要的配置项。和RDS一样瑶池数据库也支持通过参数组管理数据库参数但有些参数是“松散参数”比如以loose_开头的扩展参数以及一些云原生特有的参数比如并行查询parallel_query、列存索引imci相关的开关。迁移到新环境后我建议先对比原实例和瑶池数据库的参数组差异重点看sql_mode、max_allowed_packet、innodb_buffer_pool_size、innodb_flush_log_at_trx_commit、slow_query_log这些关键参数。监控告警方面除了基础的CPU、内存、磁盘使用率我强烈建议对以下指标设置告警活跃会话数、连接数使用率、慢查询数量、主备切换事件、只读节点延迟、存储水位。瑶池数据库控制台自带这些监控项也支持通过云监控配置告警规则。报警阈值不要设得太高比如连接数使用率到80%就要告警不要等到100%才处理存储水位建议70%就告警给扩容留出操作时间。在告警配置上还有一个容易被忽视的点只读节点的延迟。虽然瑶池数据库的只读节点走的是存储层复制延迟通常很低但如果有大查询、大批量导入、DDL操作仍然可能出现延迟升高。你需要在监控里单独查看每一个只读节点的延迟指标而不是只看主节点。延迟超过阈值时建议优先排查是否有慢查询在只读节点上执行而不是一上来就加节点。5.3 典型故障排查表我把运维过程中遇到的几类典型问题整理成一张速查表方便以后遇到同类情况时快速定位。故障现象可能原因排查与解决办法应用报连接超时或连接被拒连接数打满、白名单未配置、安全组拦截检查连接数使用率优化连接池检查数据库白名单和安全组规则读写延迟突然升高慢查询、大事务、存储IO抖动查看慢查询日志定位耗时SQL检查监控中的IOPS和延迟指标分析是否大事务引起主节点CPU 100%慢查询多、无索引或索引失效、并发过高开启慢查询日志分析TOP SQL检查执行计划是否走索引考虑对只读流量拆分到只读节点只读节点出现复制延迟大查询占用资源、DDL操作、大事务查看只读节点的活跃会话和慢查询错开大查询和DDL时间必要时临时增加只读节点数据校验不一致迁移过程中有DDL、增量同步中断重新校验迁移任务的预检查确认DDL已同步必要时重建增量同步任务备份恢复后数据少备份时间点选择不对、恢复到错误时间确认使用正确的备份集和时间点建议通过按时间点恢复PITR来恢复数据这张表不能覆盖所有场景但能帮你在遇到问题时先把排查方向定下来。核心原则是先看监控再查日志最后动参数。不要一上来就重启实例或者改大参数那样往往解决不了根本问题还会引入新的风险。在迁移和运维瑶池数据库的这段时间里我最大的体会是架构升级不只是换一个数据库产品而是要跟着调整自己的使用习惯和运维思路。ECS、RDS、瑶池数据库这三者从“自建主机”到“托管实例”再到“云原生分布式架构”每一次变化都解放了一部分人力但也对使用者提出了新的要求——你得理解底层是怎么运作的才能真正用好它。如果你也在规划核心业务上云数据库我的建议是先从兼容性评估和POC测试开始拿一个非核心业务先迁移一遍跑通整个流程再决定大范围推广。数据库没有绝对的好坏只有适合不适合。瑶池数据库在核心业务上的架构优势是实打实的但它也只适合你真正需要那种弹性和高可用能力的场景。
返回列表