背景

2010年,G7正式为物流运输行业提供面向车队管理的SaaS服务,经过持续创新,通过软硬一体化的产品技术能力,致力于数字化每一辆货车,以实时感知技术创造智慧物流新生态。G7为客户提供全方位的数据服务、智能的安全和运营管理、手机管车、数字运力、以及ETC、油和金融等增值服务。

目前,G7连接了600,000辆货车,每天行驶6500万公里(可绕地球赤道1625圈),13.5 亿个轨迹点和2,200万次车辆事件触发,并且以直线速度飞速增长。G7每天产生的车辆行驶、状态、消费等数据超过2T,飞速增加的车辆、数据类型和复杂的金融业务,使得数据库的事务、分析、扩展和可用性面临巨大的挑战。

在大量的车辆信息和轨迹相关数据业务中,当前我们通过Spark、Hive等对大量原始数据进行分析后,存入阿里云DRDS,对外提供基础数据接口服务。由于清洗后的数据量依然很大,使用DRDS的存储成本非常高,且面对很多OLAP的查询时,效率不如人意。

而在金融和支付这种复杂业务场景中,面临CAP中C和P的挑战。在以往的工作中,支付系统由于面临强一致性事务的高峰值写入问题,采用了2PC+MySQLXA(单个MySQL作为参与者,上层增加Proxy作为协调者)完成了分布式事务数据库的方案。但是这种方案在 Partition中,极为麻烦。同时,运营和风控系统经常需要做相对复杂的查询,要么通过 MySQL+ETL+OLAP数据库(成本高),要么容忍查询的效率问题。



探索

G7的技术团队一直在寻找一种能解决上述问题的数据库。要找到这样一种数据库,除了需要满足上述需求以外,还需要满足另一个需求:可维护性和易迁移性。这要求该数据库具体需要满足如下几个要求:

  • 兼容MySQL协议,使得数据库的变更对上层业务透明,这个有多重要,做过基础架构升级落地的同学应该深有感触。

<!---->

  • 支持MySQL的主从同步机制,使得数据库的变更可以平滑逐步升级,降低变更风险。

<!---->

  • 必须是开源的。数据库的稳定需要付出很大的精力和时间,在这个过程中,或多或少都出现问题。出现问题不可怕,可怕的是无法定位和解决问题,只能依赖“他人”。数据库的一个BUG对“他人”来说,可能是一个小问题,对G7业务而言,可能是一个巨大的灾难。当“屁股”不在同一个板凳上时,我们需要对数据库有很强的掌控力。

<!---->

  • 开源的同时,背后一定需要有一个有实力的技术团队或商业公司的全力投入。在见识了不少“烂尾”和“政绩”的开源项目后,只有一个稳定全职投入的技术团队或商业公司,才能最终让这个数据库越来越好。

在这么多限制和需求的情况下,TiDB+TiSpark很快进入我们的视线,并且开始调研。通过和TiDB技术人员的交流,除了满足上述的需求外,如下技术细节使我们一致认为可以选择这样的方案:

  • 将MySQL架构中Server和StorageEngine概念进一步松耦合,分为TiDB和TiKV,水平扩展性进一步提升。

<!---->

  • 定位于Spanner的开源实现,但是没有选择Multi-Paxos,而是采用了更容易理解、实现和测试的Raft,使得我们在分布式一致性上少了很多担忧。

<!---->

  • 使用RocksDB作为底层的持久化KV存储,单机的性能和稳定性经过了一定的考验。

<!---->

  • 基于GooglePercolator的分布式事务模型,在跨区域多数据中心部署时对网络的时延和吞吐要求比较高,但我们目前没有这样的强需求。


初体验—风控数据平台

该风控数据平台是将众多的业务数据做清洗和一定复杂度的计算,形成一个客户在G7平台上金融数据指标,供后续的风控人员来查询客户的风险情况,同时支撑运营相对复杂的查询。由于数据量较大,传统的关系型数据库在扩展性和处理OLAP上不符合该业务的需求;同时该业务面向内部,在一开始不熟悉的情况下,不会影响到客户,因此,我们决定在这个业务上,选择使用TiDB。风控数据平台开始于2017年8月,2017年10月上线了第一个版本,对线上用户提供服务。最开始使用的TiDBRC4版本,后升级到Pre-GA,我们计划近期升级到GA版本。

系统架构如下所示,整个流程非常简洁高效。

TiDB在 G7 的实践和未来_github

在使用的过程中,我们还是遇到了不少兼容性相关的问题。为了增加我们对TiDB的理解,我们和TiDB技术团队取得联系,积极参与到TiDB项目中,熟悉代码和修复部分兼容性和 BUG相关的问题。以下是我们在实践过程中解决的问题:

  • 修复INFORMATION_SCHEMA.COLUMNS中,COLUMN_TYPE不支持UNSIGNED的兼容性问题。
  • https://github.com/pingcap/tidb/pull/3818

<!---->

  • 修复IGNORE关键字对INSERT、UPDATE和DELETE的兼容性问题。
  • https://github.com/pingcap/tidb/pull/4376
  • https://github.com/pingcap/tidb/pull/4397
  • https://github.com/pingcap/tidb/pull/4564

<!---->

  • 修复Set和Join中存在的PanicBUG。

        https://github.com/pingcap/tidb/pull/4326

        https://github.com/pingcap/tidb/pull/4613

  • 增加了对SQL_MODE支持ONLY_FULL_GROUP_BY的特性。
  • https://github.com/pingcap/tidb/pull/4613

这里仍然存在一个与MySQL不兼容的地方。当开启事务后,如果insert的语句会导致主键或者唯一索引冲突时,TiDB为了节省与TiKV之间的网络开销,并不会去TiKV查询,因此不会返回冲突错误,而是在Commit时才告知是不是冲突了。希望准备使用或关注TiDB的朋友能注意到这一点。后来我们咨询TiDB官方,官方的解释是:TiDB采用乐观事务模型,冲突检测在执行Commit操作时才会进行。

感谢在初体验过程中,TiDB团队非常认真、负责和快速的帮助我们排查和解决问题,提供了非常好的远程支持和运维建议。



在其它业务中的推广规划

2018年初,运维团队和每一个业务方进行了一次需求沟通,业务方对TiDB的需求越来越强烈。我们正沿着如下的路径,让TiDB发挥应用到更多的场景中。

  • 将TiDB作为RDS的从库,将读流量迁移到TiDB。

<!---->

  • 从内部业务开始,逐步将写流量迁移到TiDB。

<!---->

  • 将更多OLAP的业务的迁到TiSpark上。

<!---->

  • 合作开发TiDB以及TiDB周边工具。


参与TiDB社区的Tips

  • 善用GDB工具去了解和熟悉TiDB的代码结构和逻辑。

<!---->

  • 初始选择一些Issue,去分析和尝试修复。

<!---->

  • 利用火焰图去关注和优化性能。

<!---->

  • 如果没有读过周边的论文,可以试着去读一读,加深对系统原理的理解。

<!---->

  • 积极参与TiDB的社区活动,加深与TiDB核心研发的沟通。

<!---->

  • 有合适的业务场景,可以多试用TiDB,拓宽TiDB在不同场景下的应用实践。

**本文作者:**廖强,曾供职于百度,负责百度钱包的分布式事务数据库,基础架构和收银台。现G7汇通天下技术合伙人,负责金融产品研发、运维和安全。