内容来源:http://mp.weixin.qq.com/s?__biz=MzI3NDIxNTQyOQ==&mid=2247489941&idx=1&sn=c962c794a78d3a1988da3a14c94dc2b2&chksm=eb163effdc61b7e964f8a48abbd37e31aff506530285368862136dd415c3ebfe9f8659fb43c0#rd
李文杰,网易互娱计费组,高级数据库管理工程师,TiDB User Group Ambassador。
计费组是为网易互娱产品提供统一登录和支付高效解决方案的公共支持部门,对内是互娱的各个游戏工作室,对外是国内外数百个渠道。由于业务场景的特殊性,我们为各个游戏产品部署了不同的应用服务,其中大产品环境独立,小产品集中部署。随着部门业务量的激增,单机 MySQL 在容量、性能、扩展性等方面都遇到了瓶颈,我们开始对其他数据库产品进行调研选型。本文将详细介绍网易互娱计费组针对自己场景的数据库选型对比方案,以及使用 TiDB 后解决的问题,并分享使用 TiDB 过程中集群管理、监控和数据迁移等方面的最佳实践,以供大家参考和交流。网易互娱计费组线上 MySQL 的基本使用架构,如下图所示,其中箭头方向表示数据或请求的指向:- 线上应用 Application 通过 Keepalive + 多机部署,流量经过负载均衡,可以有效保障应用服务的高可用;
- 数据库层架构是 Keepalive + 主从结构,利用半同步复制特性可以有效解决延迟和数据一致性的问题;
- Application 通过 VIP 访问后端数据库,在数据库主节点宕机后通过 VIP 飘移到从节点,保证服务正常对外提供;
- 通过 Slave 节点进行数据备份和线上数据采集,经过全量和增量同步方式导出数据到数据中心,然后进行在线和离线计算任务;
- 类似这样的架构组合线上大概有 50+ 套,涉及服务器 200~400 台,日均新增数据 TB 级。
随着业务的发展,部门内各应用服务产生的数据量也在快速增长。业务落地数据量不断激增,导致单机 MySQL 不可避免地会出现性能瓶颈。主要体现在以下几个方面:
- 单机 MySQL 实例存储空间有限,想要维持现有架构就得删除和轮转旧数据,达到释放空间的目的;
- 网易互娱某些场景单表容量达到 700GB 以上,订单数据需永久保存,同时也需要保持在线实时查询,按照之前的存储设计会出现明显的瓶颈。
- 最大单表 15 亿行,行数过大,导致读写性能受到影响。
- 大表轮转后出现多个分表,联合查询时需要 join 多个分表,SQL 非常复杂并难以维护;
- 当进行跨产品计算时,需要维护多个异构数据源,访问方式复杂。数据分散在不同的数据孤岛上会增加数据分析难度,不利于共性价值的挖掘。如下图:
针对目前存储架构存在的问题,有需要使用其他存储方案的可能。考虑到目前的业务与 MySQL 高度耦合,对数据库选型的主要要求有:一开始仍然是倾向使用基于 MySQL 的解决方案,比如 MySQL InnoDB Cluster 或 MySQL + 中间件的方案。我们测试了 MySQL 集群 5.7.25 版本对比 8.0.12 版本,在 128 并发写各 1000 万行的 10 个表,比较单节点、3 节点和 5 节点下的情况,如下图所示:在测试中发现,使用 MySQL InnoDB 集群的方案写性能比单机 MySQL 差约 30%,其他的读写测试结果也不甚满意。之后陆续测试 MySQL InnoDB Cluster 或 MySQL + 中间件的方案,不是测试结果性能不达要求,就是需要修改大量代码。因此我们得出了基于 MySQL InnoDB Cluster 或 MySQL + 中间件的方案的不满足我们的业务场景的结论。总结来说,我们不使用 MySQL 分库分表、中间件或 MySQL 集群,原因主要是以下两点:仔细分析来看,其实基于 MySQL InnoDB Cluster 或 MySQL + 中间件的方案,本质上是 MySQL 主从结构的延伸,并非真正的分布式拓展,像是以打“补丁”的方式来实现横向扩展,很多功能特性自然也难以让人满意。2.3.2 CockroachDB VS TiDB
在开源的分布式 NewSQL 领域,知名的有 TiDB 和 CockroachDB(简称 CRDB),二者都是基于 Google Spanner 论文的开源实现。我们对这两种数据库的功能和性能做了大量的调研和测试。- TiDB 天然兼容 MySQL 协议,而 CRDB 兼容 *** ;
- 如果业务以 MySQL 为主,那 TiDB 可能是比较好的选择;如果是 ***,那CRDB 可能是优先的选择。
测试方面,我们也进行了全面地对比和测试。这里说其中一个测试案例:10 台机器 5 存储节点,160 并发访问单表 2 亿行,我们于 2018 年 7 月,对 CRDB-v2.1.0 版本和 TiDB-v2.0.5 版本进行了读写测试(CRDB 和 TiDB 集群均使用默认配置,未进行调优)。 SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?
SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?
SELECT c FROM sbtest WHERE id BETWEEN ? AND ? ORDER BY c
SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c
SELECT id, k, c, pad FROM sbtest1 WHERE k IN (?)
SELECT count(k) FROM sbtest1 WHERE k BETWEEN ? AND ? OR k BETWEEN ? AND ?
UPDATE sbtest%u SET k=k+1 WHERE id=?
UPDATE sbtest%u SET c=? WHERE id=?
1. CRDB 和 TiDB 在性能表现上不相上下;图 7 TiDB 2.1.15 vs 3.0.3:OLTP 峰值比较
图 8 TiDB 2.1.15 vs 3.0.3:TPC-C2. CRDB 兼容 ***,如果需要迁移则需要转协议,需 MySQL → *** → CRDB。迁移过程复杂,成本高;3. TiDB 兼容 MySQL,代码修改量不多,迁移成本低。2.3.3 最终选型
- 整个集群分为 TiDB、TiKV 和 PD 3 个模块分层部署;
业务
集群
规模
41 台服务器,88 个实例节点,38 个 Syncer 实时同步流(将升级为 DM);
存储:20TB/总 50TB,230 万个 Region;
QPS 均值 4k/s,高峰期万级 QPS,读写比约 1:5;
延迟时间:80% 在 8ms 以内,95% 在 125ms 以下,99.9% 在 500ms 以下。
官方集成了 Prometheus + Grafana 的实时监控平台,从集群的各个方面进行了完善的监控,包括:PD 监控示意图如下,集群管理员可以很方便地掌握集群的最新状态,包括集群的空间 Region 等所有情况。图 11 最佳运维实践:Prometheus 实时监控如果集群运行过程出错,在监控面板上很容易就发现,下图是使用过程中的一个案例:应用访问 TiDB 写入数据时发现特别慢,读请求正常。排查后,根据 TiKV 面板发现 Raft Store CPU 这项指标异常。深入了解原因是因为数据库副本复制是单线程操作,目前已经到了集群的瓶颈。解决办法有以下两点:- Region 数量过多,Raft Store 还要处理 heartbeat message。
- Raft Store 单线程处理速度跟不上集群写入速度。
解决方法:从 2.1.5 升级到 2.1.15,开启自动 Region Merge 功能。
4.2.2 部分运维问题及解决方案
以前部分业务遍历全网数据库获取所需数据,需要维护多个源,而且是异构源,非常复杂和繁琐。使用 TiDB 很好地解决了这个问题,只需要访问一个源就可以获取到所有想要的数据。
4.4.1 MySQL 到 TiDB
图 14 数据从 MySQL 迁移到 TiDB
MySQL 数据库迁移到 TiDB 分为两个部分:全量和增量。- 使用工具 (Mydumper 或 MySQL Dump 等)从 MySQL 导出数据,并且记录当前数据的 binlog 位置;
- 使用工具(Loader 或 Lightning 等)将数据导入到 TiDB 集群;
- TiDB 伪装成为上游 MySQL 的一个 Slave,通过工具(Syncer 或 DM)实时同步 binlog 到 TiDB 集群;
- 通常情况上游一旦有数据更新,下游就会实时同步过来。同步速度受网络和数据量大小的影响。
4.4.2 数据迁出 TiDB
图 15 数据迁出 TiDB
如果数据需要反向导入或同步,可以利用 TiDB Binlog 工具将 TiDB 集群的 binlog 同步到 MySQL。TiDB Binlog 支持以下功能场景:- 实时备份和恢复:备份 TiDB 集群数据,同时可以用于 TiDB 集群故障时恢复。
- 全量:TiDB 兼容 MySQL 协议,在 MySQL 容量足够大的情况下,也可用工具将数据从 TiDB 导出后再导入 MySQL。
- 增量:打开 TiDB 的 binlog 开关,部署 binlog 收集组件(Pump+Drainer),可以将 binlog 数据同步到下游存储架构(MySQL、TiDB、Kafka、S3 等)。
图 16 去分库分表举例
举例:一个超级大表按天分表,现在打算查询某个账号一年间的信息。目标:利用 TiDB 的水平扩展特性,解决容量瓶颈和系统吞吐量瓶颈。使用 DM 或者 Syncer 将上游 MySQL 的数据同步到 TiDB 集群。同步流搭建后注意需要检查上下游数据一致性。观察一段时间,同步无误后,可以根据业务需要迁移部分读流量到 TiDB 集群。这一阶段是验证应用访问 MySQL 和访问 TiDB 可以得到相同的结果,验证业务访问的准确性问题。停止数据同步,使用流量复制工具将线上流量完全拷贝出来,同时读写 MySQL 和 TiDB。将两边的访问结果进行对比,核查 TiDB 是否可靠和可信。根据需要,这个阶段可以测试较长时间。将步骤 2 的双写停止,即关双写,同时拉起上游的 DM 同步。把访问部分非核心业务的库表写操作迁移到 TiDB,打开 TiDB 的 Binlog 开关对线上 MySQL 进行反向同步。这个操作,保证只写 MySQL 的数据同步到 TiDB ,只写 TiDB 的数据也可以反向同步到 MySQL,保证出了问题,随时可以回滚。当业务长时间访问正常,可以增加切换流量,进行灰度切换。建议观察一段时间,至少一个月。当流量完全迁移完成,保持 TiDB 反同步到 MySQL 过程,继续观察一段时间,确认无误后,断开反向同步,100% 迁移完成。TiDB 兼容 MySQL 协议,支持 TP/AP 事务且扩展性好,能很好地解决网易互娱计费组业务大容量、高可用等问题。目前我们的业务在不断深入和扩大规模使用 TiDB。因为看好它,所以这里提出一些使用中的问题以帮助原厂持续打磨产品:- 集群数据备份:希望提供集群更高效地备份和恢复 SST 文件的方式;
- 事务限制:希望可以放宽大事务的限制,现在仍需要人工切分大事务,比较复杂;
- 客户端重试:目前客户端代码需要封装重试逻辑,对用户不友好,希望可以改进。
最后,根据网易互娱计费组已有的使用情况,我们计划继续加大、加深 TiDB 的使用场景,丰富业务类型和使用规模,期待 TiDB 给我们的业务带来更多便利。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。