从MySQL迁移到Scale-Out数据库,以服务2.9亿月度用户

2018-12-06 Meituan 互联网

工业:电子商务

作者:赵英刚(美团研究员),李坤(美团数据库专家),朴长军(美团数据库专家)

介绍

在中国,Meituan意思是“买的越多,生活越好”两家公司的合并在美国,该平台以内置折扣帮助数十亿人购买商品和服务。按商品总量计算,美团排名第一中国最大的团购网站.部分Groupon,部分Yelp,部分Uber Eats,我们提供一系列本地化服务和娱乐,如送餐、餐厅评论、理发和美甲、订票、自行车共享等。2018年4月,我们有2.9亿月度活跃用户,去年我们产生了超过58亿笔交易,总交易额超过510亿美元。2018年9月20日,我们公司该公司在香港交易所上市,发行价为每股69港元

随着业务的快速增长,我们的数据量也激增。这给后台的MySQL数据库系统带来了巨大的压力。由于处理如此庞大的数据负担沉重,我们开始探索更好的数据存储解决方案。幸运的是,我们发现TiDB,兼容mysql的NewSQL混合事务和分析处理(HTAP)数据库,由PingCAP构建并支持。现在,我们可以比以往任何时候都更有信心利用我们的数据,为我们的用户提供更好的服务,享受更好的生活。

2018年初,我们的DBA团队与架构存储团队合作,选择并实现了分布式数据库解决方案。自2018年11月以来,我们已经在生产环境中部署了10个TiDB集群,拥有近200个物理节点。这些集群部署在六个产品部门或平台:交付、运输、快速通、住宿、美团平台、核心开发平台。这些应用程序中的大多数都是纯粹的OLTP(在线事务处理)工作负载。我们很高兴地报告,自部署以来,所有集群都平稳运行。

在这篇文章中,我们将分享我们选择TiDB的两个场景,我们是如何使用它的,我们遇到的一些问题和相应的解决方案,以及我们与PingCAP合作的经验。

挑战

场景1:带有大量写和高读QPS的离线分析工作负载

在美团,用于分析的数据量最大的场景是每天写500GB的数据。这个场景功能:

  • 稳定写入,每个事务操作100到200行,每秒60,000次写入。
  • 每天写的数据300GB到500GB,未来会逐渐增加到3TB。
  • 每15分钟有5,000个QPS的常规读取作业(频率高但数据量小)。
  • 不规则查询(频率低但数据量大)。

以前,我们使用MySQL来存储数据,但是我们遇到了容量和性能的瓶颈,我们希望将来我们服务的数据量能增加十倍。我们测试了ClickHouse但是发现它不能很好地处理高并发情况下的高频SQL查询,尽管它满足了我们对存储容量和运行低频SQL语句的需求。此外,我们认为只使用ClickHouse进行完整的低频SQL查询有点过分了。

场景2:OLTP工作负载对响应时间敏感

除了需要分析和查询大量数据的离线服务外,我们还有大量的分片服务。尽管行业中使用了多种分片策略来克服独立机器性能和存储的瓶颈,但这些策略确实有一些缺点:

  • 没有应用程序友好的分布式事务。
  • 对于跨数据库的查询,查询的结果聚合在中间件上,这很麻烦。
  • 当单个数据库存储空间不足时,需要重新拆分数据库。
  • 应用程序应该考虑数据分发的规则,尽管应用了中间件,但问题并不能真正解决。

我们环境中的许多应用程序和服务都进行了分片,其中一些很快就会超过一台独立机器的存储容量,或者需要新的分片策略。所有这些服务都体现了以下特点:

  • 没有太多的SQL查询,但是SQL查询的执行非常频繁。
  • 他们呼吁数据的高度一致性。
  • 一般来说,一些数据具有时间属性。

探索

为了克服这些挑战,并为我们的基础设施的未来奠定基础,我们开始探索符合以下要求的数据库解决方案:

  • 与我们现有的软件堆栈和生态系统的兼容性,以最小化迁移成本和工作量。

    • 在美团,MySQL是我们主要的数据库解决方案,支持我们的大多数业务场景。因此,与支持二级索引的MySQL协议的兼容性是一个必须具备的特性。该解决方案还必须能够提供具有高并发性的高性能OLTP服务。
    • 美团有很多产品线。业务规模庞大,需要存储系统提供高质量的服务。我们需要对当前的软件栈进行最小程度的转换,例如服务访问、监视和警报系统以及自动化操作平台。
  • 网络可伸缩性。对在线业务来说,数据分片、合并和迁移需要是自动和透明的。解决方案应支持分片和数据分片自动迁移,数据迁移过程中不应中断业务。

  • 具有强一致性的分布式事务。事务可以跨分片和节点执行,并且必须是强一致性的。

  • 跨数据中心的服务可用性。任何数据中心宕机时,业务都可以自动切换。

  • 跨数据中心写入到跨数据中心的一个表中。尽管这是一个棘手的问题,但支持跨数据中心编写一个表是支持我们当前和下一阶段业务计划的重要需求。

在深入研究各种数据库解决方案之前,我们做了功课,通过不同的论文,特别是谷歌的以下论文,解开了适合的数据存储结构和事务处理算法的细节:

当然,TiDB,一个开放源代码,NewSQL,可伸缩的混合事务和分析处理(HTAP)数据库,由PingCAP团队和开源社区构建,引起了我们的注意。它最终成为我们选择的数据库,因为它与MySQL的兼容性,前沿的技术架构和远见,以及充满活力的社区。在TiDB Alpha发布到2018年7月底的近三年时间里,至少有200名用户在他们的生产环境中部署了TiDB。其中许多用户都是各自行业的龙头企业。

更具体地说,与行业中的传统解决方案相比,TiDB是对上述所有要求的完美匹配,它是:

  • 兼容MySQL协议;
  • 灵活的在线扩展和扩展;
  • 支持ACID事务,一致性强;
  • 支持跨数据中心部署和容错,支持多节点写入;
  • 处理TiDB上的服务就像在一个独立的MySQL。

因此,我们开始测试TiDB的这些特性。

评价

为了评估TiDB的性能和特性是否能够满足我们的需求,我们进行了定期的功能和性能测试,并与MySQL进行了比较。值得一提的一个特殊测试是验证每个数据中心是否有3个副本中的1个,以便一个数据中心崩溃不会导致大多数副本的数据丢失。我们是按照以下标准进行测试的:

  • 使用Raft的水平扩展支持学习节点,因此即使一个数据中心宕机,三分之二的数据副本仍然可用。
  • TiKV的优先级标签必须是可靠的,以确保数据副本在数据中心之间均匀分布,即使每个数据中心的机器数量不相等。
  • 当TiDB集群处于高并发状态时,如果数据中心发生故障,QPS、响应时间、报错次数不正常,数据不会丢失。
  • 手动将一个地区调度到其他数据中心进行数据均衡后,当原数据中心恢复后,可以自动将该地区迁移回原数据中心。

所有测试结果表明,TiDB完全符合我们的预期。

采用

美团对于采用新的解决方案总是很谨慎,TiDB也不例外。TiDB的实现经历了以下迁移阶段:离线分析场景、非关键工作负载,然后是关键任务工作负载。

美团有很多产品线。这些业务的业务量较大,对存储系统的性能要求较高。因此,做好存储系统的规划非常重要,包括监控和告警、上下游业务部署和数据同步等。

与当前生态系统的整合:

监控和警报

美团目前使用的是Mt-Falcon平台(一种定制的分布式监控系统Open-Falcon)作监察及警戒之用。在Mt-Falcon中配置了各种插件,以自定义监控多个组件,并与木偶部署后,可以识别不同用户的特权和不同文件的问题。这样,只要我们完成了插件脚本和必要的文件,就可以建立机器安装和特权控制。

监控体系结构

监控体系结构

监控体系结构

TiDB使用普罗米修斯+Grafana如上图所示的监控系统,集群中有超过700个指标。如下面的监控架构所示,每个组件将其指标推送到Pushgateway,而Prometheus从Pushgateway获取指标。

TiDB监控体系结构

TiDB监控体系结构

在TiDB集群中部署了一组Prometheus实例后,在原始TiDB监视体系结构中收集、分析和配置监视指标变得很不方便。因此,我们决定聚合监控组件。由于警报系统在Mt-Falcon上运行良好,所以没有必要在AlertManager上建立一个新的警报系统。

为了整合对Mt-Falcon的监控和警报,我们评估了三个政策:

  • 政策# 1:修改源代码并将指标直接推送到Mt-Falcon。

    评价:由于指标分散在TiDB代码中,迭代速度很快,因此经常调整监视跟踪代码非常耗时。

  • 政策# 2:在Pushgateway上聚合可以直接收集的指标。

    评价:Pushgateway是一个单入口点,数据维护比较麻烦。

  • 政策# 3:通过每个组件(TiDB, PD和TiKV)的本地API获取数据。

    评价:一个组件的崩溃不会影响其他组件,而且很容易实现这个策略。

我们采取了三号政策。对此存在一个挑战:我们需要将《普罗米修斯》中使用的度量类型转换为Mt-Falcon能够识别的类型。Prometheus支持Counter、Gauge、Histogram和Summary类型的度量,而Mt-Falcon只支持Counter和Gauge类型。Mt-Falcon的计算表达式很少,所以我们需要转换度量类型并在监控脚本中计算数据。

批量部署

在使用Ansible批量部署TiDB的过程中,我们遇到了一个问题:快速更新的TiDB版本带来了频繁更新的Ansible,我们只向Ansible添加新代码,而没有修改现有代码。因此,我们需要同时在线部署和维护多个版本的TiDB集群。如果每个集群只有一个Ansible目录,会浪费存储空间。

为了解决这个问题,我们在中心监控机器上为每个集群版本创建了一个Ansible目录,每个版本都使用一个特定的目录文件进行维护。

上下游异构数据同步

目前使用的是MySQL蜂巢,要用TiDB取代MySQL,我们需要解决两个问题:

  • 数据从MySQL迁移到TiDB。

    • 这包括数据迁移和增量数据(DTS)的实时同步。

      Mydumper+加载程序用于在MySQL中导出数据,然后导入到TiDB中;TiDB DM可以用来同步从MySQL到TiDB的增量数据。

    • MySQL使用大量的自动递增id作为主键。当分片MySQL的数据聚合到TiDB时,需要解决自动增量id的冲突问题。

      这个问题可以通过删除自动增量id并在TiDB上构建唯一的主键来解决。新的TiDB DM版本还具有在合并分片表过程中自动处理主键的功能。

  • 从Hive迁移到TiDB,从TiDB迁移到Hive。

    • 由于TiDB与MySQL高度兼容,因此很容易将数据从Hive迁移到TiDB。Insert语句不需要修改;我们只需要稍微调整一下。

    • 从TiDB向Hive迁移数据时,使用TiDB Binlog(泵+排水器)是PingCAP开发的企业工具,是一个很好的解决方案。排水器可以将数据导出到Kafka, MySQL和TiDB。我们目前正在考虑使用排水器输出数据到Kafka的模式,以便将数据从TiDB同步到Hive,如下图所示。

从TiDB同步数据到Hive

从TiDB同步数据到Hive

问题和解决方案

服务上线后,出现了一些问题。以下是一些典型的例子:

问题#1:在TiKV中写入停顿

在TiKV底层,有两层RocksDB实例作为存储引擎使用。将新数据写入L0 (Level 0),当L0中的数据达到一定的大小时,Write操作会变慢,甚至出于自我保护而停止。

TiKV的默认配置:

  • level0-slowdown-writes-trigger = 20
  • level0-stop-writes-trigger = 36

我们曾经遇到过Write stall问题,并发现L0中文件过多的原因可能是:

  • 写操作的数据太大,导致Compact操作无法完成。处理步骤
  • TiKV创建快照的速度比发送创建快照请求的速度要慢。因此,创建Regions的累积副本突然被释放,在rocksdb-raft中创建了大量的L0文件。

写摊位监控

写摊位监控

我们使用以下措施解决了Write stall问题:

  • 降低Raft Log Compact的频率(增加Raft - Log -gc-size-limit和Raft - Log -gc-count-limit的值)。
  • 加速快照操作(整体性能,包括硬件性能)。
  • 设置max-sub-compactions为3。
  • 设置max-background-jobs为12。
  • 将L0的三个触发器分别设置为16、32和64。

问题#2:删除的数据太多会导致GC崩溃

目前,TiDB的GC(Garbage Collection)在单线程框架中对每个kv实例执行操作。当一个事务删除了太多的数据时,GC就会变慢,花费的时间甚至比Write操作还要长。

目前,这个问题可以通过添加更多的TiKV实例来解决。从长远来看,GC需要能够以多线程方式工作。PingCAP已经在TiDB 2.1中实现了这个特性。

问题#3:Insert语句的响应时间变长了

开始时,H80的Insert语句的响应时间约为20ms。随着服务继续运行,响应时间逐渐增加到200ms以上。我们解决了这个问题,找到了原因:随着Regions数量的快速增长,Raftstore还有更多的工作要做。因为Raftstore是单线程的,而且每个Region定期发送一个心跳,所以性能下降了。

解决方案如下:

  • 临时解决方案

    将心跳周期从1s延长到2s。这一政策取得了积极成果,如下图所示:

    Insert语句优化前后的响应时间

    Insert语句优化前后的响应时间
  • 永久的解决方案

    • 减少region的数量并合并空region。TiDB 2.1实现了区域合并功能。
    • 将Raftstore更改为多线程。PingCAP的工程师们正在研究它,这个特性将在TiDB的下一个版本中发布。

结果

在我们将TiDB部署到生产环境的半年多时间里,我们对TiDB和PingCAP的信心不断增长,我们真的相信TiDB是一个很有前景的数据库。

更重要的是,PingCAP的工程师和支持团队非常专业、敬业和高度的积极性!他们对我们的问题反应迅速而有效。

接下来是什么

我们计划在越来越多的应用系统中部署TiDB,并与TiDB一起成长。目前,美团的三位dba和多位存储专家全力致力于与PingCAP在底层存储、中间层计算机制、服务层接入、存储方案的数据模型选择等方面的合作。

从长远来看,我们将与PingCAP一起构建一个更强大的生态系统。以下是我们的一些举措:

  • TitanDB

    TitanDB是TiDB的下一个大计划:下一代存储引擎。节省了Value占用的存储空间,解决了单行的大小限制问题,提高了单个TiKV的存储容量上限。有了TitanDB,大规模的TiDB部署将变得更加经济有效。

  • TiDB云(基于Docker & Kubernetes)

    适应云计算的发展趋势,PingCAP是开源的TiDB运营商2018年8月向社区发布。TiDB Cloud不仅为数据库提供高度自动化的操作,而且利用Docker提供基于硬件隔离的数据库多租户。

  • TiDB HTAP平台

    PingCAP工程师基于TiDB Server的原始计算引擎构建TiSpark这是一个薄层,用于在TiDB/TiKV之上运行Apache Spark,以回答复杂的OLAP查询。这使得TiDB平台成为一个完整的平台HTAP数据库。这种体系结构极大地减少了公司数据周期中核心服务的数据副本,从而节省了成本并提高了OLAP应用程序的成本效益。我们计划将一些具有实时或接近实时需求的分析查询系统迁移到TiDB。

    TiDB平台架构

    TiDB平台架构
  • 后续的物理备份策略和跨数据中心的多写

    我们将在更多的应用场景中采用TiDB,如物理备份和跨数据中心的多写。

我们期待着由TiDB和PingCAP引领的HTAP数据库的新时代!

准备好开始使用TiDB了吗?