TiDB在网易游戏的应用实践

北京中科医院 https://wapyyk.39.net/bj/zhuanke/89ac7.html

作者介绍:李文杰,网易互娱高级数据库工程师,TUG年度和年度MVA。主要负责大数据研发和数据分析工作,为产品提供精细化运营指导;同时在部门内推广使用TiDB,为业务上云及数据库分布式化积累经验和探索最优方案,目前是TiDB管理小组负责人。

本文整理自TUG网易线上企业行活动,由网易游戏高级数据库工程师李文杰老师分享,主要介绍分布式数据库TiDB在网易游戏的应用实践经验。

网易游戏最开始引入TiDB是从AP的角度来进行使用的。在第一次使用TiDB时,我们把跑批业务这种计算量比较大的任务迁移到TiDB上面。在迁移过程中,如果跑的任务量比较大,相信很多人会遇到“transactiontoolarge”报错这个问题。

TiDB事务限制

经过一番排查发现,由于分布式事务要做两阶段提交,并且底层还需要做Raft复制,如果一个事务非常大,会使得提交过程非常慢,并且会卡住下面的Raft复制流程。为了避免系统出现被卡住的情况,TiDB对事务的大小做了限制,具体限制的内容有单事务的SQL语句数、KV键值对数目和大小、单KV键值对大小等。

知道这个限制后,我们就可以找到了解决办法,即把大的事务按业务的需求切分为多个小事务分批执行,这样之前跑失败的SQL就能成功运行了,而且在MySQL/Oracle中的跑批程序,也都成功迁移到了TiDB。

同时,我们不得不思考,在没有问题的时候,程序可以跑得非常顺畅,但是当机房中出现网络问题,或是出现其他的故障时,就会出现一部分数据写入到了TiDB中,而另外一部分数据是没有写入的。在场景中的表现是一个事务的执行没有能够保证其原子性,只执行了其中一部分,有一部分成功,有一部分失败了。

经排查发现,这是因为我们手动开启了事务切分,这种情况下大事务的原子性就无法保证,只能保证每个批次的小事务原子性,从整个任务的全局角度来看,数据出现了不一致。

那么该如何解决这个问题呢?

TiDB大事务优化

通过向官方反馈问题之后,TiDB4.0对大事务进行了深度优化,不仅取消了一些限制,而且将单事务大小从MB直接放宽限制到10GB,直接优化了倍。但与此同时也带来了另一个问题,在进行t+1的跑批业务时,前一天可能会有几百甚至上千万的数据量,如果用程序JDBC+TiDB方式处理,效率其实不高,处理时长往往需要持续数小时,甚至几十小时以上。

那么该如何提高计算任务的整体吞吐量?答案是TiSpark。

TiSpark:高效处理复杂OLAP计算

TiSpark是在Spark基础上开发的一个插件,它可以高效地从TiKV读取数据。同时支持索引查找和计算下推策略,有很高的查询性能。我们在实践过程发现,使用TiSpark读取TiKV的方式,5分钟可以完成2亿行数据读取。同时它也有很高的写入性能。有了TiSpark,我们可以直接通过Spark工具访问TiKV数据。经过时间证明,TiSpark读、写TiKV都有着非常好的性能表现,通过TiSpark我们可以处理比较复杂、数据量比较大的运算。

TiSpark实践

在实践中,使用TiSpark主要有两种方式:

方式一:TiSpark+JDBC写入

TiSpark+JDBC写入方式能够自动切分大事务,但不一定能保证事务的原子性和隔离性,且故障恢复时需要人工介入。这种方式写入速度可以达到万行/min,通过TiDB处理SQL再写入TiKV,速度一般。

方式二:TiSpark批量写入TiKV

TiSpark批量写入TiKV不会自动切分大事务。通过TiSpark直接读写TiKV,相当于直接通过大事务读写TiKV的数据,可以保证事务的原子性和隔离性,同时拥有良好的写入性能,写入速度可以达到万行/min。经过TiSpark的应用,解决了我们大数据量批处理任务的问题,但是也存在一定的隐患。TiSpark在进行读、写TiKV的时候,由于TiKV是作为整个TiDB架构的存储引擎,如果存储引擎层的数据读写压力大,对于线上的其他业务将会产生明显的影响。此外,在TiSpark读写TiKV时,如果没有对IO进行限制,很容引发性能抖动,导致访问延迟上升,也会对其他线上业务产生影响。

怎么样才可以做到有效隔离?或许TiFlash列式存储引擎能提供答案。

TiFlash:列式存储引擎

TiFlash作为TiKV行式存储引擎的补充,它是TiKV数据的raft副本,TiFlash作为在TiKV基础上的列式副本,经过raft协议保证数据同步的一致性和完整性。这样同样的一份数据就可以存储在两个存储引擎里面。TiKV保存的是行存数据,TiFlash保存的是列式数据。

在做Spark的计算分析时,我们可以直接从TiFlash集群进行读取,计算效率会非常高。用列式数据做AP分析,对于行式数据来说,简直就是降维打击。

TiFlash:TPC-H性能分析

TiSpark+TiFlash的结合应用使计算效率取得了量与质的提升。TPC-H性能分析显示,在与TiKV的横向对比中,几乎全部query场景下TiFlash执行效率都高于TiKV,且部分场景的效率远高于TiKV。用了TiFlash以后,既不影响TiKV的集群性能,也不影响线下的集群业务,而且在做离线大数据分析时,依然能够保持很好的性能与吞吐量。

经过实践证明,TiFlash可以解决我们的诸多问题,是非常棒的一个工具。

TiFlash应用:计算更高效

在网易游戏用户画像的部分指标计算场景中,使用上TiSpark+TiFlash后,不同业务内容的SQL处理速度相比TiSpark+TiKV快了至少4倍。所以使用TiFlash之后,离线批处理效率有了质的提升。

JSpark:跨源离线计算

随着业务规模和应用场景的增加,不同数据分布存储在不同的存储引擎。比如日志数据存储在Hive,数据库数据存储在TiDB,跨数据源访问需要大量数据迁移,耗时且费力。能否直接打通不同数据源,实现跨源互访?针对这个问题网易游戏采用了JSpark工具。JSaprk是为了打通底层不同存储,实现跨源访问目标而实现的一个离线计算工具。这个工具核心是TiSpark+Spark组件,Spark作为桥梁,可以实现不同数据源的访问。

JSpark基于TiSpark和JDBC进行封装,在TiKV可以进行数据读写,在TiFlash可以进行列式AP计算,在TiDB可以做常规的SQL计算,目前我们已经封装实现了TiDB和Hive的相互读写功能,后续JSpark工具将会支持TiDB与ES的读写互访,实现TiDB、Hive、ES多源数据访问。

目前JSpark工具,主要是实现了以下功能:

支持TiSpark+JDBC方式读写TiDB和读写Hive,这种方式效率一般。应用场景:在TiDB宽表中只操作业务需要的部分列。支持读TiDB表数据,Spark计算结果写入Hive目标表。读推荐使用TiSpark读取TiKV或TiFlash的方式,写推荐使用TiSpark写入TiKV的方式,效率会更高。应用场景:定期轮转TiDB分区表过期分区,备份永久保留副本到Hive,避免TiDB表过大。支持读Hive表数据,Spark计算结果写入TiDB目标表。推荐使用TiSpark写入TiKV的方式,效率高。应用场景:分析Hive数据产出用户画像指标并写入线上TiDB,提供线上业务TP查询。另一个实践场景是恢复Hive备份到TiDB。支持前端web或业务发起


转载请注明:http://www.aierlanlan.com/grrz/4808.html