作者:朱博帅,爱奇艺资深数据库架构师
爱奇艺,中国高品质视频娱乐服务提供者,2010 年 4 月 22 日正式上线,推崇品质、青春、时尚的品牌内涵如今已深入人心,网罗了全球广大的年轻用户群体,积极推动产品、技术、内容、营销等全方位创新。企业愿景为做一家以科技创新为驱动的伟大娱乐公司。我们在前沿技术领域也保持一定的关注度。
随着公司业务的快速发展,原来普遍使用的 MySQL 集群遇到了很多瓶颈,比如单机 MySQL 实例支撑的数据量有限,只能通过不停删除较旧的数据来维持数据库的运转。同时单表的数据行数不断增大导致查询速度变慢。急需一种可扩展、高可用同时又兼容 MySQL 访问方式的数据库来支撑业务的高速发展。
我司从 2017 年年中开始调研 TiDB,并且在数据库云部门内部系统中使用了 TiDB 集群。从今年 TiDB 推出 2.0 之后,TiDB 愈发成熟,稳定性与查询效率都有很大提升。今年陆续接入了边控中心、视频转码、用户登录信息等几个业务,这几个业务背景和接入方式如下详述。
边控中心存储的是机器的安全统计信息,包括根据 DC、IP、PORT 等不同维度统计的流量信息。上层业务会不定期做统计查询,其业务页面如下:
在选型过程中,也考虑过时序型数据库 Apache Druid(http://druid.io),但是 Druid 聚合查询不够灵活,最终放弃 Druid 选择了 TiDB 数据库。TiDB 几乎完全兼容 MySQL 的访问协议,可以使用现有的 MySQL 连接池组件访问 TiDB,业务迁移成本低,开发效率高。
边控中心是爱奇艺第一个在线业务使用 TiDB 的项目,所以我们制定了详细的上线计划。
第一,部署单独的 TiDB 集群。然后,为了数据安全,部署了 TokuDB 集群,用作 TiDB 集群的备份数据库。
第二,我们通过 TiDB-Binlog 将 TiDB 集群的数据变更实时同步到 TokuDB 集群中,作为 TiDB 的灾备方案。
第三,前端部署了自研的负载均衡中间件,以最大化利用多个 TiDB 节点的计算能力,同时保证 TiDB 节点的高可用。
第四,部署 Prometheus 和 Grafana 监控 TiDB 集群健康状况,同时 Grafana 接入了公司的告警平台,会及时将告警信息通过短信、邮件等方式通知到运维值班同事。
边控中心上线过程中,也遇到了一些问题,都比较顺利的解决了:
最常见的问题是连接超时。经过仔细排查发现是统计信息严重过时导致执行计划无法选择最优解造成的,这个问题其实是关系型数据库普遍存在的问题,普遍的解决思路是手工进行统计信息收集,或者通过 hint 的方式来固定执行计划,这两种方式对使用者都有一定的要求,而最新版本的 TiDB 完善了统计信息收集策略,比如增加了自动分析功能,目前这个问题已经解决。
还遇到了加索引时间较长的问题。这一方面是由于 DDL 执行信息更新不及时,造成查询 DDL 进度时看到的是滞后的信息。另一方面是由于有时会存在 size 过大的 Region,导致加索引时间变长。这个问题反馈给 PingCAP 官方后得到比较积极的响应,大 Region 已经通过增加 Batch split 等功能在新版的 TiDB 中修复了。
边控中心上线以后,在不中断业务的情况下成功做过版本升级,修改 TiKV 节点内部参数等操作,基本对业务没有影响。在升级 TiKV 节点过程中会有少量报错,如“region is unvailable[try again later]、tikv server timeout”等。这是由于缓存信息滞后性造成的,在分布式系统中是不可避免的,只要业务端有重试机制就不会造成影响。
边控中心上线以后,数据量一直在稳定增长,但查询性能保持稳定,响应时间基本保持不变,能做到这点殊为不易,我个人的理解,这个主要依赖 TiDB 底层自动分片的策略,TiDB 会根据表数据量,按照等长大小的策略(默认 96M)自动分裂出一个分片,然后通过一系列复杂的调度算法打散到各个分布式存储节点上,对一个特定的查询,不管原表数据量多大,都能通过很快定位到某一个具体分片进行数据查询,保证了查询响应时间的稳定。
边控中心数据量增长情况如下:
TiDB 底层自动分片策略:
视频转码业务是很早就接入 TiDB 集群的一个业务。视频转码数据库中主要存储的是转码生产过程中的历史数据,这些数据在生产完成后还需要进一步分析处理,使用 MySQL 集群时因为容量问题只好保留最近几个月的数据,较早的数据都会删掉,失去了做分析处理的机会。
针对业务痛点,在 2017 年年底部署了 TiDB 独立集群,并全量+增量导入数据,保证原有 MySQL 集群和新建 TiDB 集群的数据一致性。在全量同步数据过程中,起初采用 Mydumper+Loader 方式。Loader 是 PingCAP 开发的全量导入工具,但是导入过程总遇到导入过慢的问题,为解决这个问题,PingCAP 研发了 TiDB-Lightning 作为全量同步工具。TiDB-Lightning 会直接将导出的数据直接转化为 sst 格式的文件导入到 TiKV 节点中,极大的提高了效率,1T 数据量在 5-6 个小时内就能完成,在稳定运行一段时间后将流量迁移到了 TiDB 集群,并且扩充了业务功能,迄今稳定运行。
TiDB-Lightning 实现架构图:
3. 用户登录信息
用户登录信息项目的数据量一直在稳定增长,MySQL 主备集群在不久的将来不能满足存储容量的需求。另外,由于单表数据量巨大,不得不在业务上进行分表处理,业务数据访问层代码变得复杂和缺乏扩展性。在迁移到 TiDB 后,直接去掉了分库分表,简化了业务的使用方式。另外,在 MySQL 中存在双散表并进行双写。在 TiDB 中进一步合并成了一种表,利用 TiDB 的索引支持多种快速查询,进一步简化了业务代码。
在部署增量同步的过程中使用了官方的 Syncer 工具。Syncer 支持通过通配符的方式将多源多表数据汇聚到一个表当中,是个实用的功能,大大简化了我们的增量同步工作。目前的 Syncer 工具还不支持在 Grafana 中展示实时延迟信息,这对同步延迟敏感的业务是个缺点,据官方的消息称已经在改进中,同时 PingCAP 他们重构了整个 Syncer,能自动处理分表主键冲突,多源同时 DDL 自动过滤等功能,总之通过这套工具,可以快速部署 TiDB “实时”同步多个 MySQL,数据迁移体验超赞。
在我们公司业务对数据库高可用有两个需求:一个是机房宕机了,服务仍然可用。另一个是,多机房的业务,提供本机房的只读从库,提升响应速度。针对这些不同的需求,TiDB 集群采用了多机房部署的方式,保证其中任一个机房不可用时仍然正常对外提供服务(如下图)。对每个 TiKV 节点设置 label 后,TiDB 集群在每个机房都有一份数据的副本,PD 集群会自动调度到合适的副本进行读操作,也可以满足第二个要求。为了满足迁移过程中的高可用性,会在流量迁移完成后部署 TiDB 到 MySQL 的实时同步。Drainer 支持指定同步开始的时间戳,有力支持了反向同步功能。
在整个运维过程中,PingCAP 的小伙伴们提供了及时的帮助,帮助我们定位问题并提出建议,保证了业务的有序运行。在此表示由衷的感谢!
在实践过程中感受到 TiDB 解决的痛点主要是横向扩展和高可用。单机数据库支撑的数据量有限,如果采用分库分表 + proxy 的方式,无论 proxy 是在客户端还是服务端都增加了运维的成本。同时 proxy 的查询效率在很多场景下不能满足要求。另外,proxy 对事务的支持都比较弱,不能满足数据强一致性的要求。TiDB 可以直接替代 proxy+MySQL 的架构,服务高可用性、数据高可用性、横向扩展性都由 TiDB 集群完成,完美解决了数据量增量情况下出现的很多问题。而且,TiDB 在数据量越大的情况下性能表现得比 MySQL 越惊艳。
我司仍有其它业务在接入 TiDB 服务,目前正在评估测试中。一些业务场景是 OLTP+OLAP 混合的场景,TiSpark 正好可以大展身手。目前在测试集群发现 TiSpark 查询时对 OLTP 业务的影响还是比较大的,必须限制 TiSpark 对 TiDB 集群造成的压力。还部署了单独 TiDB 集群做 OLAP 场景的测试,对内部参数做了针对性的优化。未来计划会继续加大对 TiDB 的投入,贡献一些 PR 到社区,其中很大的一部分工作是增强 TiDB-Binlog 的功能,和现有的一些数据同步组件整合起来,支持 TiDB 到 Kudu、HBase 等的同步。