运维成本降低 90%,存储成本降低 3 倍:多点利用 TiDB 资源管控功能将 100+ 套 MySQL 集合到一个 TiDB 实践
作者: jiaxin 原文来源:https://tidb.net/blog/e960ba2d
多点介绍
多点 DMALL 是一站式全渠道数字零售解决方案服务商,提供端到端的商业 SaaS 解决方案。多点 DMALL 通过 Dmall OS 提供零售联合云一站式解决方案,帮助零售商和品牌商数字化转型,实现线上线下一体化;同时通过多点 App 等工具赋能全渠道经营能力,并提供各类增值服务。
多点 DMALL 不仅是中国最大的零售数字化解决方案服务商,也在积极拓展海外市场,2023 年除中国内地以外市场的贡献的营收已达数亿元。多点 Dmall 已成功打入欧美市场,与惠康、万宁、SM 集团等世界知名零售商建立合作,推动了香港等地零售业的数字化转型。截至 2023 年底,多点 Dmall 的业务已覆盖 8 个国家和地区,展现了其在全球 SaaS 市场中的竞争力和影响力。多点 Dmall 的成功,体现了中国 SaaS 企业在全球市场的突破和成长。
相关介绍:境外业务持续加持 多点 DMALL 喜提“世界独角兽”
背景
在当前快速发展的大环境下,多点 Dmall 正积极推进零售 SaaS 私有化项目,以实现系统的高效简化。我们的目标是通过整合应用和数据库,显著降低系统的复杂性,并有效减少硬件成本与运维管理开支。
目前,我们已经将 Docker 应用实例从 300 个优化减少至 150 个,同时将数据库集群数量从 200 个精简至 100 个。在数据库方面,我们主要采用 MySQL 技术,其中最大的生产环境包含了上千个 MySQL 集群。现在我们已经成功地将多个 MySQL 集群合并为一个 TiDB 集群(多库合一)。我们将利用现有的 TiDB 集群,借助其动态扩缩容和高效压缩存储的能力,进一步优化数据库合并流程。TiDB 的这些优势使其在处理大量数据合并时,比传统的 MySQL 到 MySQL 合并更具效率和灵活性。我们的合并策略包括将源端 MySQL 中的库表数据完全迁移到目标 TiDB 集群中。通过更新配置中心并重启业务应用,我们能够顺利完成数据迁移和系统切换。尽管整个流程可能会遇到一些挑战和复杂情况,需要我们不断地调整和优化。通过这一私有化项目的实施,我们能够大幅提升系统的性能和稳定性,同时实现成本效益的最大化。
MySQL 合库到 TiDB 前提条件
二八原则的适用性在每个行业都很普遍,80% 的业务高 QPS 流量是由 20% 的数据库产生的。某私有化项目生产有 170 个 MySQL v8.0 集群, QPS 高的一般就 30 个库左右,大部分 MySQL 是属于长尾 QPS 较低,我们计划是长尾的这些全合并至一套 TiDB 集群。经过内部讨论合并 MySQL 至 TiDB 需满足几个条件:
高 QPS 业务不合并
QPS 比较高的业务往往对读写延迟有更高的要求,受限于本次改造硬件资源和 TiDB 分布式事务,部分业务读写延迟没有单机 MySQL 好,基于硬件资源本次选择 QPS 小于 100 的业务做合并。和业务方沟通遂对所有生产 MySQL 集群统计了周末两天(零售行业大多周末是高峰期)的峰值 QPS (规则是一段时间内,每隔一分钟取一次 prometheus 监控数据计算出主库的峰值 QPS + 从库的峰值 QPS 即为集群的峰值 QPS ,当然这也是参考数据,不能代表绝对,真实数据是做大促活动时的峰值 QPS )
经过第一轮条件筛选后,有 154 个 MySQL 集群可以合并
有 DDH 同步下有的 MySQL 不合并
Dmall Data Hub 数据同步系统(简称 DDH),同步 MySQL 的 binlog 至下游 kafka 给大数据或业务系统使用。 TiDB 自身也有 TiCDC 能同步自身的变更 changelog 至下游 kafka,但 TiCDC 同步 kafka 中格式和我们已有 DDH 同步 kafka 格式(内部自研的 kafka 消费格式)是完全不同的,为避免下游大数据或业务系统改造适配 kafka 新格式的成本风险,我们决定不合并有 DDH 的 MySQL 集群。
在第一轮筛选后的基础上,经过第二轮筛选,剩余 148 个集群可以合并
无主键表 / 非数值主键表 / 联合主键表不合并
这三种类型表我们 DRC 同步(支持全量 + 增量同步 MySQL 至 TiDB )不支持,况且非标准无数值主键表目前我们工单审核也是禁止提交的。 TiDB 自身 TiCDC 同步变更至 kafka 也是要求表有主键。
在第二轮筛选后的基础上,经过第三轮筛选,剩余 131 个集群可以合并
有特殊用法外键 / 视图 / 存储过程等不合并
由于历史原因有几种非标准用法 MySQL 还有小部分需要排除,标准工单审核也已经禁止提交, TiDB 里是不支持这几种用法,主要是外键、存储过程、物化视图、特殊函数等功能。
第三轮筛选后,剩余 128 个集群可以合并
有分库 & 基础组件服务 & 可下线等不合并
MySQL 里有物理分库,库名一样如都是 dmall_xxx,分布在多个 MySQL 集群里,合并至 TiDB 的话库名有冲突需要排除;中间件基础服务有小部分是没有接入配置中心(应用从配置中心拿数据库连接信息)如果合并需要改代码对业务上不透明,接入配置中心标准的我们的 DBA 刷配置中心把 MySQL 连接信息改为 TiDB 后业务方就只重启应用;经过几轮的筛选后再找业务方二次检查筛选,标记了 30 个老 MySQL 集群无用可以下线的,再减去有物理分库、基础服务,能合并至 TiDB 的减少至 75 个 MySQL 集群
104 个 MySQL 集群(75 个合并至 TiDB ,29 个下线)一主一从共可释放资源 212G 内存,1.1T 磁盘
合库目标 TiDB 版本升级至 7.5
已有一套老版本 v5.4 TiDB 集群,有几个库在里面,升级 TiDB 版本至 v7.5(官方长期支持 LTS)一是连接协议兼容 MySQL v8.0(@@version 8.0.11- TiDB -v7.5.0 我们源要合并的都是 MySQL v8.0,目标是让业务方不做任何改动把 MySQL 合并至 TiDB ),二是 v7.x 版本是新特性如RU 资源管控、TTL 自动清理无用数据,性能提升等
升级版本先必须在测试环境跑通后一段时间再做生产
升级前最好做好备份作为兜底
tiup 进行升级还是比较顺畅
升级前后读写延迟有降低 40-50% 左右,性能有一定提升。
升级前
升级后
同步 MySQL 账号信息至 TiDB
循环多次分别导出要合库 MySQL 账号信息还原至 TiDB
TiDB 计算节点新扩容 2 台
我们现有的 TiDB 集群,在配置较低的情况下,已经成功支撑了多个只读业务的平稳运行,实现了从 MySQL 到 TiDB 的无缝迁移。该集群由 3 台 2 核 8GB 的计算节点和 3 台 4 核 32GB 的高性能存储节点组成,确保了数据处理的高效性。
为了进一步提升性能并满足日益增长的业务需求,我们在现有的 MySQL 服务器上扩展了 2 个计算节点。这一策略不仅利用了 MySQL 服务器上未充分利用的内存资源,还通过分散新增计算节点的负载,有效减轻了写入操作的延迟,特别是在处理高并发数据库操作时。
通过这种优化,我们不仅提升了集群的计算能力,还通过智能分配资源,确保了数据同步和合库操作的流畅性,为业务的持续增长和稳定性提供了坚实的基础。
TiDB 新建合库 MySQL 专用域名
刷配置中心时使用该域名
ti4000i- TiDB -xxxx.com
同步 MySQL 数据至 TiDB
先手动同步表结构加上 auto_id_cache 配置(为什么加这后面 TiDB 配置参数有说明)
Check TiDB 数据一致情况
业务应用方自助在数据查询平台抽查数据情况
dba 批量统计源 MySQL 逻辑库行数和目标 TiDB 里逻辑库行数对比
刷配置中心数据后业务研发重启应用验证
配置中心里有应用 app 对应 key, value 是多少,应用启动拿配置中心 key,读取 value
DBA 把涉及合库老 MySQL 连接信息刷成 TiDB 后,应用重启后,读取 TiDB 连接生效
Check TiDB 集群连接数 & 慢查询情况
应用重启后新连接进 TiDB
合库后 TiDB 事务 OPS 在 400 左右
迁移 MySQL 集群元数据至 TiDB 集群
数据库管理平台里有权限控制,不同业务方看到的 MySQL , TiDB 库是不一样的,就需要把 MySQL 数据库管理平台中依赖元数据表迁移至 TiDB 集群。
主要梳理涉及元数据库里几张表关联迁移, MySQL 集群表,集群实例表,集群 DNS 表,集群对于系统应用表(当时迁移生成的 SQL 也有 30 行)
如下示例为另一生产环境 MySQL 、 TiDB 应用列表
MySQL 应用
TiDB 应用
对 TiDB 有压力库进行资源隔离(Resource Control)
TiDB 资源管控特性提供了两层资源管理能力,包括在 TiDB 层的流控能力和 TiKV 层的优先级调度的能力。两个能力可以单独或者同时开启,TiDB 提供用户、会话级、语句级别设置资源组,可将压力大的应用绑定到某个资源组后,TiDB 层会根据用户所绑定资源组设定的配额对用户的读写请求做流控,TiKV 层会根据配额映射的优先级来对请求做调度。通过流控和调度这两层控制,可以实现应用的资源隔离,满足服务质量 (QoS) 要求。
TiDB 资源隔离不是分配 IO CPU 具体多少,而是通过配置 RU(Request Unit (RU) 是 TiDB 对 CPU、IO 等系统资源的统一抽象的计量单位,读写请求消耗不同的 RU)
一共 85 个数据库,其中 3 个大库超过 100GB(大库有大 DML、SQL 查询会消耗大量硬件资资源,引起整个 TiDB 集群血崩),其中有 1 个 库存在慢查询多,其它 81 个业务资源使用量低,没有开启资源管控能力。
TiDB 集群通过硬件配置预估可用 RU 2.7 万个,按 70% 安全资源利用算(用最大额 RU 的话服务器压力会很大),可使用 RU 约 2 万个,分配 70% 的 RU 给 4 个大库(约 1.4 万,当前 TiDB 集群 IO、CPU 已有些压力 70%~80%,因此分别对 4 个大压力库配置 RU 避免引起雪崩。)
RU 形式隔离对大的业务慢查询相对暴力些,RU 用完后 SQL 会报错,而不单纯是执行变慢,需要评估好设置好 RU。
当前 7.5 ga 功能下,是超过分配 RU 会预估等待一定时间,预估时间较长还没有执行就报错。这个时间是动态可调的,默认 30s,可以调整 ltb-max-wait-duration 控制。
Runaway Queries 可以避免报错问题,但是 7.5 是实验特性,因此需要等升级 8.x 版本解决。
如图所示,针对空间占用大、慢查询多的两类数据库进行资源隔离限制,保障资源充足。
通过 TiDB 提供的 Dashboard 面板可以看到 TiDB 对 RU 的容量估算情况以及用户分配使用情况,监控粒度以及评估实现可视化。
配置 RU 后,在 Grafana 的监控面板中可以看到不同资源组 RU 消耗使用情况
Grafana 中 TiDB -Resource-Control 面板可以检测到 RU 更详细监控数据,包括 RU、Query、RRU 和 WRU 等监控。
值得注意的是,RU 分配不合理情况下,可能因 RU 资源不足,导致业务 SQL 查询报错的情况,需要调整 RU 分配情况。
在 Grafana 的 RU 监控面板中,Available RU 监控数据显示有为 0 情况,实际业务写入数据正常,可能监控数据采集有点异常。(官方已知问题:这个监控和 RU_PER_SEC 这个流速的概念是不对等的,这里显示的只是令牌桶瞬时的一个状态,后面会去掉。)
全链路压测
虽然 MySQL 合库至 TiDB 已经在测试环境跑过一段时间,但测试环境无法模拟真实生产环境,有些应用没使用或业务流量 QPS 都很小。在 MySQL 合并到 TiDB 落地生产合库上线后,本次私有化项目的商家临近大促活动前,进行一次非常有意义的全链路压测,业务测试人员模拟发起前端请求高并发 QPS ,经过应用层,压力传导到后端数据库 MySQL 、TiDB 、MongoDB、Redis,来验证技术架构方案面对高并发场景的支撑能力。
扩容计算节点和存储节点
若平峰期该 TiDB 集群是能支持业务,不用扩容。
3 台低配计算 2Core 8GB 升级至 4Core 16GB 服务器( MySQL -> TiDB 只读业务库使用计算节点)
3 台低配存储 4Core 32GB 升级至高配 16Core 64GB nvme 3.7TB 本地盘服务器
高配 16Core 64GB nvme 本地盘服务器上新扩容 3 台计算节点给直接读写 TiDB 业务使用(主要用计算资源, MySQL 合库至 TiDB )
3 台 2C 8G pd, TiDB 计算 +3 台 4C 32G 高性能存储支撑不了压测流量,并发一上来写入 TiDB 延迟时间飙升(P99 到了 7s 多,tikv cpu 压力最高 70% 左右,IO 压力 75% 左右)
扩容前:
3 台 16C 64G nvme 本地盘计算 + 存储扩容好后,并发压测上来, TiDB 延迟时间明显比之前提升近非常大(P99 64ms,P999 稍微高些 3s 多,tikv cpu 压力最高 30% 左右,IO 压力低),大多数业务压测是通过,有活动任务业务压测还是没通过(并发更新高,遂回滚到了 MySQL )
扩容后:
TiDB 配置参数
AUTO_ID_CACHE
中心化自增 ID 分配,auto_increment MySQL 兼容模式(TiDB 的 v7.5.1 版本存在使用 auto_id_cache 可能有 bug https://asktug.com/t/topic/1025153)
确保多个 TiDB 计算节点生成的自增列是单调递增( MySQL 中可能有依赖主键 id 做分页排序用法 select xxx from t order by id where id>? limit n),v6.4.0 版本之前存在自增 id 不连续问题
不支持在已有表增加 auto_id_cache,只能新建表设置
生产环境保险起见,需手动导出 MySQL 表结构加上 auto_id_cache 后再导入表结构到目标 TiDB
sql_mode
TiDB sql_mode 修改为和 MySQL 一致,避免对业务应用产生不可预期的错误,如
其它参数
支持设置默认校对规则,兼容 MySQL8.0,default_collation_for_utf8mb4
no utf8mb3,TiDB 里不支持 utf8mb3,源 MySQL 表有这字符集需要转化为 utf8mb4
合并后资源以及人效收益
上百个 MySQL 实例(一主一从)合并至 TiDB 后(有部分 MySQL 下线),数据库集群数量的大幅减少(175 套 MySQL +1 套 TiDB 减少至 74 套 MySQL +1 套 TiDB ),为整个系统简化助力(系统简化:运维、DBA、产研多方努力协作成果);
动态扩缩容能力(迁移扩容 3 人天降为 0.5 人天),有大促活动时新加服务器水平扩展,低峰时缩容,更好有效利用资源;
降低存储成本, TiDB 相比 MySQL 5 倍左右压缩率,整体能降 3 倍左右存储( MySQL 一主一从两副本, TiDB 三副本);
整体收益
通过将 100+ 套 MySQL 实例合并至 1 套 TiDB ,系统运维得到显著简化,数据库集群数量减少从运维 100+ 套 MySQL 到运维一套 TiDB 集群,整体的运维成本降低了 90%;这一整合大幅降低了运维、DBA 和产研的协作成本; TiDB 的动态扩缩容特性使得资源管理更加高效,从迁移扩容的 3 人天降至仅需 0.5 人天,整体提高了 6 倍;此外, TiDB 相比 MySQL 5 倍左右压缩率, MySQL 一主一从两副本, TiDB 三副本的情况下存储成本降低了 3 倍。除此之外,具体收益如下:
简化系统架构:通过减少数据库实例的数量,简化了整体系统架构,降低了系统的复杂性,使得运维工作更为集中和高效。
降低硬件成本:由于 TiDB 的高性能和良好的资源使用效率,可以用更少的硬件资源支撑相同的业务负载,减少了服务器的采购和运行成本。
减少运维人力:管理一个 TiDB 集群比管理上百个 MySQL 实例所需的运维人员更少,因为 TiDB 提供了更为自动化的管理工具和流程。
提高资源利用率: TiDB 的计算和存储分离架构允许更灵活的资源分配,可以在业务高峰期间快速扩展资源,低峰期间缩减资源,从而提高资源的利用率。
降低存储成本: TiDB 具有高效的数据压缩能力,相比 MySQL 可以显著减少存储空间的使用,降低了存储相关的成本。
提升备份效率:虽然 TiDB 的备份空间占用可能较大,但通过优化备份策略和忽略冗余数据,可以减少备份所需的存储空间,同时提升备份和恢复的效率。
增强数据安全性: TiDB 提供了多副本和自动故障转移机制,增强了数据的安全性和可靠性,减少了因数据丢失或损坏导致的运维成本。
减少业务中断风险:通过资源隔离和动态扩缩容, TiDB 可以更好地应对业务流量波动,减少因资源不足导致的业务中断风险。
性能提升: TiDB 的优化器和执行引擎针对现代硬件进行了优化,可以提供比传统 MySQL 更优的性能,减少了因性能问题导致的运维干预。
统一监控和管理:使用 TiDB 后,可以通过统一的监控和管理界面来观察整个数据库集群的状态,简化了监控系统的部署和维护工作。
降低升级和迁移成本: TiDB 兼容 MySQL 协议,减少了从 MySQL 迁移到 TiDB 的复杂性和成本,同时 TiDB 的持续升级和优化可以减少未来的升级工作。
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/2729f1b71f4707963cd8e4d0a】。文章转载请联系作者。
评论