借助TiDB的帮助,闪电战规模最大的无桩共享单车平台

2018-04-03 Mobike 互联网

工业:随意组合

数据增长速度:每天~ 30 tb

作者:丁成杰、胡明(摩拜基础设施平台工程师)

Mobike是全球第一家也是最大的无桩共享单车提供商,为全球200个城市的2亿多用户提供服务,运营着900多万辆智能自行车。这是一种经济实惠的短途城市交通方式,拥有专利自行车设计,智能锁系统和移动应用程序。我们每天为用户处理超过3000万次骑行。

摩拜应用背后的系统每天从装有GPS和物联网设备的自行车上收集超过30 TB的数据。数据量和并发性的空前增长给我们的后端系统,特别是数据库带来了巨大的挑战。多亏了TiDB,分布式混合事务和分析处理(HTAP)建立的数据库PingCAP团队们,我们不仅配备了一个可以弹性横向扩展的解决方案,而且我们还被授权从“新鲜”数据中获取见解,以支持实时决策。充满活力的TiDB开源社区还允许我们在世界各地部署和运行,而无需锁定供应商。现在,我们可以轻松地支持业务和数据的快速增长,而不必担心基础设施。

自2017年初以来,我们一直在生产环境中使用TiDB。现在,我们已经将TiDB部署在多个集群中,拥有近100个节点,为不同的应用场景处理数十个tb的数据。这篇文章将通过说明TiDB如何解决我们的痛点,深入探讨我们为什么选择TiDB而不是MySQL及其分片解决方案。

为什么TiDB ?

在我们选择TiDB之前,我们仔细评估了MySQL及其分片解决方案。作为一家快速成长的初创公司,我们发现MySQL分片解决方案不受欢迎,原因如下:

  • 独立的MySQL要求我们经常存档数据。当数据的大小超出了一个独立MySQL的容量时,我们不得不使用中间件解决方案对数据库和表进行分片,这很难管理;
  • 根据我们以前的分片经验,大量的数据通常会导致数据库挂起,因为它需要频繁的表结构更新来执行数据定义语言(data Definition Language, DDL)操作。这种情况会对应用程序的可用性产生负面影响,甚至导致数据不一致。另外,我们希望在业务量暴增、服务需求不断变化的情况下,更方便地升级应用逻辑,而这是分片无法做到的;
  • 如果我们采用分片解决方案,当要分片数据库时,我们必须停止正在进行的业务,重构应用程序代码,然后迁移数据。更糟糕的是,我们必须小心地手动指定分片键,因为它控制着数据应该如何在分片上分布,而更改现有的分片键可能会导致严重的问题。更不用说分片不支持跨分片分布式事务,也不保证事务的强一致性。

必须找到新的解决方案来满足以下要求:

  • 在线DDL:新业务不断涌现,DDL变化不断。我们需要能够在没有数据库停机的情况下添加新的列和索引。
  • 弹性可扩展性:我们需要应对随需应变营销活动带来的数据快速增长和临时流量激增,在高峰时增加容量,在活动结束时减少容量。
  • 支持运营团队的频繁相关查询和临时查询需求。

值得庆幸的是,TiDB完全符合这个要求。

TiDB简介

TiDB具有以下核心特性:

  • 兼容MySQL协议;
  • 水平可伸缩性;
  • 跨多个数据中心的分布式ACID事务;
  • 强一致性保证;
  • 自动故障转移和高可用性。

在TiDB项目内部,有几个组件:

  1. TiDB集群由无状态TiDB实例作为无状态SQL层,处理用户的SQL查询,访问存储层中的数据,并返回相应的结果。

  2. TiKV组成的集群,TiKV实例,是数据驻留的分布式事务性Key-Value存储。无论数据是否出现,最终都会存储在TiKV中。它使用复制协议,保证数据一致性和容灾。

  3. TiSpark位于TiKV之上,支持我们的数据科学家在现有Hadoop系统中进行实时分析或离线日常分析。

TiDB生态系统还拥有大量其他企业级工具,例如Ansible脚本用于快速部署的Syncer,用于从MySQL无缝迁移的Syncer,用于异构数据迁移的Wormhole,以及用于收集Binlog文件的TiDB Binlog。

四个生产中的应用

案例1:锁定解锁成功率

锁定和解锁智能自行车的成功率是摩拜单车的关键指标之一,因为解锁或解锁失败将导致糟糕的用户体验,甚至用户流失。为了提供流畅的体验,我们需要根据地区、应用版本、终端、用户、单车等不断了解锁/解锁成功率,以定位出问题的单车。每次用户上锁或解锁自行车时(通常是在高峰时段),都会生成大量的自行车日志信息。据估计,这个数据量每年有数百亿行。

我们部署TiDB直接帮助支持系统锁定解锁成功率,满足以上所有要求。TiDB是如何集成到我们的系统中的,请参见下图:

采用TiDB和TiSpark的实时数据分析系统

当系统检测到锁定和解锁的成功率在几分钟内下降时,就会向管理员发送警报。我们可以快速地从数据库中找到单个失败的骑行和相关的用户和自行车,这使我们能够快速地定位出故障的自行车。

案例二:实时数据分析

随着我们的数据量继续呈指数级增长,我们需要可访问的、准确的实时数据分析,以保持我们相对于其他共享单车平台的竞争优势。在我们实现TiDB之前,我们有几十个MySQL集群,其中一些是分片数据库,而另一些是独立的实例。但是MySQL并不是为处理针对海量数据集的复杂查询而设计的,这使得实时数据分析更加具有挑战性。

为了应对这个挑战,我们最初的计划是同步数据到Hive。我们想出了两种方法,但每一种都有明显的缺点:

  1. 每天进行全卷同步。这种方法会给在线数据库带来很大的压力,并且随着时间的推移会消耗大量的Hive资源。

  2. 每天的增量同步。这种方法很复杂,每天的差异应该与前一天的数据合并,因为HDFS不支持更新操作。这种方法的优点是,如果数据量很大,增量同步比全同步更快,节省更多空间。缺点是增量同步会占用Hadoop大量的计算资源,影响系统的稳定性。

相反,使用TiDB,实时数据同步可以通过为MySQL生态系统设计的工具从多个MySQL实例执行。我们之前提到过的Syncer使我们能够将TiDB集群与各种MySQL实例和分片MySQL集群进行同步。TiDB支持更新操作,不存在Hive存在的问题。TiSpark是一个用于在TiDB/TiKV之上运行Apache Spark的薄层,在TiDB导入数据后,我们可以利用Spark快速运行复杂的OLAP查询。

下图描述了我们使用TiDB和TiSpark实现的实时数据分析系统。在这个系统的支持下,我们可以随时轻松地执行各种各样的分析任务,这是Hadoop无法做到的。

采用TiDB和TiSpark的实时数据分析系统

目前,我们的TiDB集群拥有几十个具有多个tb数据的节点。得益于TiDB的高可用架构,我们的系统是稳定的,可以通过添加更多的x86服务器实现水平可伸缩性,同时提供实时数据分析能力,无论我们的数据集增长有多快。

案例3:摩拜商店的OLTP

摩拜商店是一个在线购物平台,用户可以使用摩拜币购买物品,这是一个创新的忠诚度奖励计划,在我们的骑行者中广受欢迎。用户可以根据自己的骑行历史、频率和特定行为,以各种方式收集这些摩拜币。

随着用户基础的快速增长,摩拜单车商店的数据飙升。我们估计,它的数据量将在年内轻松达到数千亿行。为了支持摩拜单车商店系统,我们需要一个数据库来满足以下要求:

  • 24 × 7 × 365可在线使用,在任何场景下均可稳定运行;
  • 所有数据都需要永久存储;
  • 在高峰期和特殊促销活动运行时处理高并发;
  • 即使我们的核心业务在增长和发展,也不会出现服务中断。

根据我们的内部测试结果,TiDB非常适合支持摩拜商店的基础设施需求。当一个表中的数据量超过5000万行时,TiDB比MySQL表现出更大的优势。TiDB的本地水平可伸缩性使我们能够弹性地增加容量。它还支持在线DDL,这很好地促进了摩拜商店等服务的不断迭代——即使当应用程序发生变化时,也没有必要停止服务。

自我们部署TiDB以来,在PingCAP团队及时专业的支持下,摩拜商城OLTP的数据量已达数百亿行,运营顺畅。

案例4:日志收集数据库

为了实现实时决策的即时洞察,摩拜会保存和分析来自各种数据源的日志,比如停车历史和自行车成功解锁时的通知。由于日志数据量很大,我们非常关心数据库的可伸缩性,以及跨数据库分析能力。

在TiDB之前,我们有以下问题:

  • 每当我们想要开发一项新的服务时,我们必须根据数据量、增长和并发需求,提前分别规划和设计一个MySQL分片解决方案;
  • 因为我们所有的服务都是相互关联的,所以很难从支持不同服务的独立数据库中聚合数据;
  • 对于其他复杂的实时数据分析需求,我们需要首先通过执行ETL将数据迁移到大数据平台,这是一项冗长且耗时的工作。

有了TiDB,所有这些问题都变得很容易解决:

  • 为了容纳来自新服务和应用程序的数据,我们只需添加更多TiKV节点。系统的并发性不再是一个问题,因为集群只是水平增长并变得更加分布式;
  • 将所有这些相互关联的服务放在我们的TiDB集群中,可以方便地访问特定类型和特定时间段的任何数据进行分析;
  • 使用TiSpark,我们可以直接对TiDB集群中的数据运行复杂的分析查询。通过这种方式,我们可以很容易地用一个数据库解决方案实现实时数据分析,而不需要执行ETL。

日志收集数据库

问题和优化

虽然TiDB是一个伟大的产品,但在使用它来适应我们复杂的用例时,存在一些问题和挑战。幸运的是,PingCAP的技术支持和开发团队总是乐于助人。在本节中,我将介绍我们一起遇到的(以及已经克服的)主要挑战,以及我们做的一些优化。

正如文章中提到的,TiDB内部(I) -数据存储, TiKV本质上是一个巨大的有序键值映射。数据按“地区”存储和分布。每个区域包含一个连续的数据范围。如果一个Region包含来自多个表的数据,或者多个热Region共存于一台机器上,就会出现资源瓶颈,从而出现资源隔离问题。

这就是为什么这个问题在TiDB的设计中被仔细考虑了HotRegionBalance被设计成驱动程序位置(PD),一个管理TiKV集群的独立组件,以避免它。但是,如果一个集群中有多个数据库,或者一个数据库中有多个表,仍然会增加资源瓶颈的概率,因为PD中的调度策略是基于以下假设的:

  • 各地区资源消耗相等;
  • 不同地区之间没有相关性;
  • 区域尽可能均匀地分布在各个商店之间。

为了解决这个问题,我们与PingCAP团队合作,完成了以下优化:

优化1:基于表的分割

基于表的分割优化对于TiKV中的协处理器,其目的是确保每个Region只包含一个表中的数据,以降低小表之间出现资源瓶颈的概率。现在,当新的表数据插入到一个Region时,TiKV根据当前Region的Key Range计算它的tableID。如果插入的Key不在Key范围内,该Region将提前分裂。

优化2:表级别的资源隔离

将TableID和NameSpace以及NameSpace和TiKV Store之间的映射关系添加到表目录在PD。映射关系被写入并持久化在etcd中,以确保安全性。现在,每当插入新数据时,我们都可以从TiDB层获取TableID,然后通过PD查找目标Region的TiKV地址,确保新数据没有被放置在其他TiKV节点中。此外,我们与PingCAP团队合作,构建了一个NameSpace调度程序,将非结构化区域重新调度到TiKV服务器,从而确保在表级没有数据干扰。

优化3:管理工具

为了管理NameSpace,我们开发了一个特定的管理工具。幸运的是,TiDB的设计很灵活,所以为了完成这个优化,我们只需要通过原始TiDB接口调用相关的API来通过表名获取TableID。我们添加了一个HTTP接口的命令目录pd-ctl,通过PD命令行管理工具,管理和验证“Table Name”和“Table ID”的关系。

结论

我们在生产环境中部署TiDB已经一年了。在过去的一年里,我们的用户数量增长了近10倍,每天的骑行数据增长了几十倍。多亏了TiDB的在线可扩展性,我们成功地扩展了我们的基础设施。我们终于可以专注于摩拜应用程序的开发和优化,为我们的用户提供惊人的体验,而不用担心MySQL的分片规则。这对于像我们这样快速增长的初创公司来说是非常有价值的,它让我们在竞争环境中领先。

TiDB的主要好处包括:

  • 灵活的可扩展性。其可扩展性可与NoSQL数据库相媲美。在数据量和访问流量不断增加的情况下,可以通过横向扩展提高系统的服务支撑能力,同时保持响应延迟稳定。
  • 可用性。TiDB与MySQL协议兼容,所以它是一个简单的解决方案,允许我们避免分片。它的界面是友好的,所以我们的技术人员可以很容易地执行操作和后台管理。
  • 企业级支持。我们可以与PingCAP支持人员沟通,并依靠他们为我们的任何问题提供快速响应和解决方案。

我们与PingCAP团队的密切合作以及与TiDB开源社区的互动也为我们带来了实质性的利益和反馈,大大降低了我们的代码维护成本。

未来,我们计划继续与PingCAP密切合作,加强我们正在开发的管理工具,将TiDB更深入地应用到我们的基础设施中,并在摩拜单车中更广泛地应用TiDB。

另一个案例研究:在易国捕捉易逝洞察力的混合数据库

准备好开始使用TiDB了吗?