大家好,我是数据库小学妹 👋
上个月一个客户找我帮忙看账单。说实话我有点心虚。之前精力全放在性能优化和故障排查上,没做过系统性的成本优化。打开客户账单那一刻我确实惊了。每月数据库费用接近5万元。主要分布在RDS实例、云盘存储、只读实例这几项。备份存储、DTS同步、Redis实例也占了不少。
客户说能降多少降多少,前提是不能影响业务。我当时真没把握,只能先拉监控数据摸底。两周后月账单降到了3.5万出头,降幅约30%。客户那边没有任何性能反馈,监控里的慢查询反而比之前还少了一些。
今天把这六个关键步骤完整拆解出来,每步都附具体操作和成本数据。希望给遇到同样问题的你带来解决思路,可以少走弯路少踩坑。
一、实例规格重新选型:最大的浪费是过度保险
我排查的第一个动作是把所有RDS实例的配置清单拉出来。对照监控数据看实际使用率。
结果很扎眼。线上有3台RDS实例,配置是16核64G。但CPU平均使用率长期在8%到15%之间,内存使用率42%。这是典型的过度保险。当初按大促峰值选了高配,平时根本用不到。还有一台只读实例配置8核32G,实际TPS不到50,CPU使用率3%。这些实例加起来原费用每月约26500元。
降本方案:先把CPU使用率长期低于20%的实例降配。16核64G降到8核32G。CPU平均使用率从12%涨到28%,内存使用率从42%涨到65%。仍然有充足余量应对日常波动。大促前临时升配,大促后降回来。
成本变化:3台16核64G按年付费,每月单台约8000元。降到8核32G后每月约4000元。三台共省12000元/月。只读实例从8核32G降到4核16G,每月省约2500元。实例降配总共每月省14500元,优化后这部分费用降到约12000元。
这里的关键判断标准是:CPU使用率持续低于20%就是降配候选。内存使用率低于50%的也是。云数据库实例价格随规格是阶梯式跳跃的,16核到8核通常就是减半,性价比差异非常明显。
二、冷热数据分层:别把历史数据全放在SSD上
这是降本效果最明显的一招。我先把客户所有数据库的存储清单拉出来。总占用约4TB,其中订单表占了800GB。
我把订单表按create_time做了分区。近90天的数据定义为热数据,90到365天的定义为温数据,365天以上的定义为冷数据。
热数据留在RDS实例上。用SSD存储支撑日常查询。温数据通过DTS同步到另一个低配RDS实例,存储从SSD换成高效云盘,单价只有SSD的一半左右。冷数据导出到对象存储做归档,成本几乎可以忽略。
导出冷数据的做法有两种。一是用mysqldump按月份拆分导出。二是MySQL 8.0支持LOAD DATA和SELECT INTO OUTFILE直接按分区导出。导出的SQL文件压缩后上传到OSS。需要查历史数据时,用临时实例加载查询,用完释放。
成本变化:订单表原来占SSD约800GB,每月存储费用约800元。冷热分层后热数据留200GB在SSD上,约200元/月。温数据300GB在高效云盘,约150元/月。冷数据300GB在OSS,不到40元/月。加上其他几张历史表的分层处理,这一项总共每月省约1200元。
需要注意一个坑。冷数据导出脚本一定要做数据校验。我曾经导出一批冷数据后发现checksum不一致。排查下来是导出过程中有新数据写入。正确的做法是:导出前先锁定对应分区,或者在低峰期操作。导出后做checksum比对,确认无误再删除RDS中的冷数据。
三、存储压缩:InnoDB自带的压缩能力被忽视了
很多人不知道InnoDB原生支持行级压缩。不需要修改表结构,只需要ALTER一下。
ALTER TABLE orders ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
这个操作对以TEXT和BLOB字段为主的大表效果最好。压缩主要针对的就是这些大字段。我的订单表里有几个JSON字段存了详细的订单明细。每个JSON平均3KB,压缩后平均1.2KB,压缩比接近2.7:1。订单表存储从800GB降到约450GB。加上日志表和附件表的压缩,总体存储从4TB降到约2.5TB,每月存储费用从约4000元降到约2500元,每月省1500元左右。
压缩的代价是CPU开销增加。读写数据时需要解压和重新压缩,CPU使用率会上升5%到10%。但在我降配后的8核实例上,这个开销完全在可接受范围内。CPU从28%涨到35%,仍然远低于60%的警戒线。
压缩操作建议只在非高峰时段做。因为ALTER TABLE会锁表,可以用pt-online-schema-change做到在线变更。另外压缩后的表不支持在线DDL的某些操作。如果需要频繁变更表结构,压缩策略要和DDL计划协调。
四、备份存储优化:全量备份的存储策略太粗放
云数据库的备份存储费经常被忽视。它藏在账单的角落里。我查了一下,每月备份存储费用接近6000元。其中全量备份占了大头。
问题出在备份策略上。之前的配置是每天一次全量备份,保留30天。这意味着同一时间存在30份全量备份,每份大约120GB。30天乘120GB等于3600GB的备份存储,费用自然不低。
优化后的方案:每天一次全量备份,但只保留最近7天。7天前的全量备份转存到OSS冷归档,单价只有云存储的十分之一。增量备份保持每天一次,保留30天。因为增量备份体积小,平均每天15GB,存储成本很低。恢复时如果需要回到15天前的状态,先恢复7天内的全量备份,再回放增量binlog到目标时间点。
成本变化:云盘上备份存储从3600GB降到840GB。也就是7乘120GB。加上450GB增量备份,约1300GB。费用从6000元降到约2000元。OSS冷归档存储2760GB,约140元/月。这一项每月省3860元。
五、清理无用实例和僵尸资源:被遗忘的成本黑洞
这一步最让我惊讶。我在账单里翻到了一台只读实例。费用每月4000元。但监控显示它的QPS为零,连接数为零。查了一下,这是半年前做读写分离测试时创建的。测试完忘了释放。
还有一套DTS同步任务在持续运行。费用每月约2000元。这个同步任务是把一个废弃的老项目数据库同步到新数据库的。但老项目已经下线两个月了,同步任务一直在空转。
Redis实例也有类似问题。两台Redis实例,一台内存使用率长期为零。另一台只有12%的命中率。说明要么没有缓存数据写入,要么写入的数据永远不被读取。
这类僵尸资源的排查方法是:列出所有数据库相关资源。RDS、Redis、DTS、DMS、DBS等,逐个对照监控的QPS、连接数、内存使用率。QPS长期为零或低于阈值的,确认业务方不再使用后释放。
释放1台只读实例每月省4000元。1套DTS任务每月省2000元。2台Redis实例每月省3000元。共省9000元每月。这是最大的一刀,也是最不需要技术含量的一刀。很多团队都有类似问题。
六、预留实例与按量付费的组合策略
最后这步需要一点财务规划的意识。云数据库的付费模式有三种。包年包月预付费、按量付费后付费、预留实例承诺用量换取折扣。
我的策略是基线用量走预留实例。波动部分走按量付费。具体做法是分析过去6个月的用量数据,找出保底用量。也就是不管什么时段都稳定使用的实例和存储量。这部分走预留实例通常能拿到30%到50%的折扣。
超出保底的部分走按量付费。比如大促期间的临时升配,测试环境临时实例。用完即释放,不产生长期费用。
3台常驻RDS实例从包年包月切换为预留实例。这部分原费用每月约24000元,切换后每月约18000元,省了6000元。加之前各项优化,总月度账单从5万降到约3.5万。
七、优化汇总与避坑清单
把六个步骤的成本变化汇总:
| 优化项 | 原费用(月) | 优化后(月) | 节省 |
|---|---|---|---|
| 实例降配 | 26500元 | 12000元 | 14500元 |
| 冷热分层 | 1500元 | 390元 | 1110元 |
| 存储压缩 | 4000元 | 2500元 | 1500元 |
| 备份优化 | 6000元 | 2140元 | 3860元 |
| 清理僵尸资源 | 9000元 | 0元 | 9000元 |
| 预留实例策略 | 24000元 | 18000元 | 6000元 |
| 合计 | 约5万元 | 约3.5万元 | 约1.5万元 |
避坑方面有几个必须注意的点。
降配前务必确认CPU和内存的使用率峰值。平均值低不代表峰值不高。如果一个实例平时CPU 8%,但每天有两个时段会飙升到95%,直接降配到8核可能在高峰期扛不住。正确的做法是看P95或P99分位数据。确保降配后峰值仍在安全线以内。降配时选业务低峰操作,并提前告知业务方可能有短暂抖动。
冷热分层做之前一定要和业务确认数据访问模式。有些数据虽然365天没被查询过,但监管要求随时可查。这种数据就不能归档到OSS。我的做法是先拉出各表各分区的查询频率统计。从slow query log和performance_schema里提取。再和业务方逐表确认保留策略。确认后再操作。
僵尸资源清理前必须和业务方逐一确认。我吃过一个亏。有一台只读实例确实QPS为零,但我差点把它释放了。后来一问,这是给外部审计团队用的。他们每季度才查一次。这种低频但刚需的资源,降配保留比释放更合适。
你在云数据库上踩过哪些成本相关的坑?或者你还有什么降本妙招?欢迎交流,一起避坑。
我是数据库小学妹,咱们下篇见 👋