贝壳金服 TiDB 在线跨机房迁移实践

做者介绍李振环,贝壳金服数据基础架构负责人,目前负责数据平台和企业级数据仓库开发。sql

公司介绍

贝壳金服是专一居住场景的金融科技服务商,起步于2006年成立的链家金融事业部,并于 2017年3月正式独立运营。shell

贝壳金服聚焦于居住场景,在租赁、买卖、家装、安居等场景中为用户提供定制化的居住金融服务。贝壳金服以独家大数据与场景风控能力见长,致力于解决居住金融需求,以Fintech驱动产业升级,让每一个家庭都能享受高品质的居住生活。数据库

截至2018年末,贝壳金服业务已覆盖全国90多个城市及地区,为超过130万用户提供了金融服务。网络

项目背景

贝壳金服数据中台使用 TiDB 和 TiSpark 平台,基于 Syncer 将业务数据实时从 MySQL 备库抽取到 TiDB 中,并经过 TiSpark 对 TiDB 中的数据进行数据分析处理,供上游业务消费,现已服务于 70 多名数据开发人员。现有集群已经使用 100 多个 Syncer 同步上游 MySQL 数据,目前已经达到 4.7TB 热数据,上百张离线和实时报表。因为机房调整,数据中台也须要同步迁移到新机房,结合 TiDB 的特性,咱们探索了一种在线不停机迁移机房的方式。架构

TiDB 是一个分布式 NewSQL 数据库。它支持水平弹性扩展、ACID 事务、MySQL 语法,具备数据强一致的高可用特性,是一个不只适合 OLTP 场景还适合 OLAP 场景的混合数据库。而 TiSpark 是为解决较重的 OLAP 需求而推出的产品。它借助 Spark 平台,同时融合 TiKV 分布式集群的优点,和 TiDB 一块儿为用户一站式解决 HTAP 的业务需求。TiSpark 依赖于 TiKV 集群和 PD 组件,使用同一个数据源,减小对于 ETL 工具的维护,而且可使用 Spark 进行复杂查询计算。并发

<center>图 1 贝壳金服总体数据架构图</center>运维

业务类型

因为原有 MySQL 数据库提供服务很是吃力,使用 100 多个 Syncer 同步上游的 MySQL 数据,而 TiDB 做为一个数据中台,主要使用 TiSpark 在作查询。分布式

集群规模

<center>图 2 集群拓扑图</center>工具

迁移实践

迁移业务挑战

本次数据迁移主要有两个关键因素:性能

  1. 尽量减小对业务的影响,业务方但愿服务不能中断超过 1 小时。

  2. 因为跨机房网络带宽有限,而且与线上业务共用跨机房网络专线,在迁移过程当中须要能控制迁移速度,在白天线上业务繁忙时以较慢的速度迁移,等到晚上业务空闲时加快迁移速度。另外网络运维同事若是发现流量过载,为了避免影响其余业务正常网络资源使用,可能随时限制正在迁移的网络带宽,切断迁移网络链接,所以迁移方案必需要支持“断点续传功能”。

迁移方案设计

本次迁移最初设想了三套方案(以下),最终经过技术考察和验证,采用了技术上更有优点的第三套方案。

方案一:只使用 Syncer 在新机房同步 ODS(Operational Data Store 操做性数据存储)数据,而后从 ODS 数据再次所有计算 DW 和 ADM 层等数据。此方案须要迁移的数据最小,可是只从 ODS 计算出全部的其它数据是不现实的。其中不少拉链表(拉链表是数据仓库的数据模型设计中经常使用的数据模式,该模型记录历史,一般记录一个事务从开始,一直到当前状态的全部变化的信息)的数据都是基于历史时间点计算出来的结果,因为 TiDB 目前版本刚刚开始支持部分分区表功能,不能立刻用于生产。而且历史数据没有分区备份,历史的拉链数据没法真实还原。另外此方案业务迁移成本也很高,两边须要不断校准数据,查漏补缺,从新计算全部非 ODS 层数据计算量也过大,致使迁移时间和大量人力投入。

方案二:在某个时间点将老机房数据 Dump 出来,全量导入到新机房。以后再开启 TiDB 集群的 Binlog 增量同步老集群数据,待新集群慢慢追上老集群以后再迁移业务。这个方案中 Dump 数据没法实现单库 Dump。由于 Dump 出来的 Position 值不同,并且有的表没有主键,屡次导入会致使数据重复。所以全量 Dump 全部数据是一个很“重”的操做,Dump 后的大文件传输也存在没法断点续传的问题。具体存在问题以下:

  • 锁问题:全量备份时,须要对库进行加锁操做,若是数据量很大,备份时间较长,可能会影响业务。

  • 备份失败可能性较高:若是数据量较大,好比对 2T 的数据进行备份,可能会达到 3h 以上的备份时间,若是备份失败,那么此次备份就至关于不可用。

  • Binlog 增量同步延迟问题:若是上游 MySQL 压力较大,或者跨机房的网络带宽成为了瓶颈,那么增量同步可能追不上,Binlog 同步没法控制速度,断点续传也须要人工参与。

  • 最终数据校验任务较重:数据迁移完成以后,须要对上下游数据进行校验,最简单的方式是业务校验和对比上下游标的行数。或者使用 pt-toolkit 工具进行数据校验。

  • 停业务风险:在机房迁移完成后,业务须要中止,等待同步和数据校验完成才能够启动。

方案三:采用 TiDB 原生的 Raft 三副本机制自动同步数据。在新机房添加 TiKV 节点,待数据均衡以后再下线老机房 TiKV 节点。老机房 TiKV 下线完成则表示数据迁移完成。此方案操做简单,业务影响在分钟级别。网络层面能够经过 PD 调度参数控制 TiKV 迁移速度,Raft 副本迁移若是网络中断会自动从新传输。具体优势以下

  • 迁移数据期间不会影响线上业务,整个迁移过程都是在线提供服务的。

  • 迁移效率很是高。一个机房内部 balance 3T 的数据只须要 10 小时左右,跨机房迁移通常受限于网络。

  • 容错性高,没有不少的人工干预,集群高可用依然保留。

机房迁移实施过程

操做描述:

  1. 配置防火墙,将两个机房所需端口开通。

  2. 新机房扩容 3+ 个 TiKV,3 个 PD,2+ 个 TiDB。

  3. 执行下线 TiKV 命令,一次性下线全部旧机房的 TiKV。

  4. PD Leader 手动切换到新机房,业务迁移到新机房,等待 TiKV balance 完成以后,下线旧机房的 TiKV、PD 和 TiDB。

整个过程人为操做较少,耗时较长的只有 TiKV balance 数据的过程,能够调整调度并发度来加速整个过程。

注意事项:

  1. 新机房的 TiKV 节点尽可能要多于旧机房,不然在下线过程当中,可能因为集群 TiKV 实例数比之前要少,致使 TiKV 压力较大。

  2. 跨机房迁移,网络延迟不能高于 3ms。

  3. TiKV 下线过程当中, Region Leader(s) 会逐渐迁移到新机房,这时业务已经能够并行的迁移,将压力转移到新机房去。

在 TiDB 中的二次开发

  1. Syncer 二次开发:在贝壳金服,有 100 多个 Syncer 实时同步线上数据,因为 TiDB 语法与 MySQL 语法不是 100% 兼容,特别是上游修改 DDL 操做,好比从 INT 改为 VARCHAR,会致使 Syncer 同步失败。在贝壳金服实战中,优化了失败恢复工做,监控程序会监控失败缘由并自动化恢复 Syncer 错误。

  2. TiSpark 二次开发:TiSpark 没法实现 TiDB 数据插入和删除。贝壳金服基于 TiSpark 二次开发封装了 TiSpark,所以能够实现 TiSpark 直接原生 SparkSQL 执行 Insert 、Create 操做。实现新增 executeTidbSQL 实现 delete、update、drop 操做。增长 TiSpark View 的功能,弥补现阶段 TiDB 不支持 View 的问题。

  3. TiSpark 权限控制:TiDB 和 TiSpark 都没法实现基于组和大量用户的权限控制。贝壳金服基于 Catalyst 自研了一套兼容 TiSpark SQL 和 TiDB SQL 的 SQL 解析引擎,并基于此引擎之上开发权限验证、权限申请、权限审批、数据发现等功能。

趟过的坑

  1. Region 过多:因为 TiDB 目前版本暂不支持 Partition 功能,咱们的 job 都是须要支持能够重复跑,所以有一些业务会直接先 drop table 而后再建立 table。默认状况下每次建立 table 都会申请一套 Region,致使如今单台 TiKV Region 数过载。

  2. DDL 排队执行:有一次对一个 2 亿级别的大表添加索引,但愿提升基于时间查询的效率,结果致使集群业务中全部 drop table 、create table 相关 job 所有卡住。最终了解到 DDL 是串行化操做。Add index 大操做让其余 DDL 操做 pending,手动 kill add index 操做后集群恢复。目前 TiDB 2.1 版本已经将添加索引操做和其余的 DDL 操做分开,这个问题已经解决。

  3. Syncer 恢复自动化:TiDB 如今对某些 alter column sql(字段从 INT 改成 VARCHAR 的跨类型修改操做)依然不兼容,所以在上游执行不兼容 SQL 以后,Syncer 同步会失败。修复过程须要使用到 Syncer 同步 position,DB name,table name。获取这些信息以后能够一个 shell 自动恢复 Syncer 同步,可是上面的三个信息输出不够友好,须要人为查看才能获取到。若是在失败 Syncer 日志中能够格式化输出以上三个信息,Syncer 恢复能够更自动化。目前新版本的 Syncer 已经解决这个问题。

  4. Decimal Hash Join 结果不正确:在使用两个 Decimal 字段作表 join 时,发现使用 limit 能够查询出来数据,不 limit 返回无结果。查看执行计划发现 limit 以后改变了执行计划,将 HashLeftJoin 改成了 IndexJoin。调查以后发现 Decimal 在计算 hash 值时返回结果不正确,致使相同 Decimal 没法 join 上。可使用 hint 强制使用 IndexJoin 来解决此问题。目前 TiDB 2.0.11 及以上版本已经解决了这个问题。

  5. 列式存储:因为如今 TiDB 是行存,即便是 TiSpark 读取 TiDB 一个字段也会在底层取出此记录全部值,致使性能问题。在 OLAP 大宽表场景中使用列式存储性能会显著提高。

后续计划

机房顺利迁移完成后,后续计划升级到 TiDB 3.0,利用 TiDB 3.0 产品路线图中提供的新功能来优化和提高使用效果:

  • 开启 Region merge 功能,自动在后台合并空 Region 从而减小 Region 的数量。

  • 使用 3.0 所提供的视图 View 和分区 Partition 功能。

  • 尝试 PingCAP 新一代的列计算/存储引擎 TiFlash ,提高 OLAP 宽表查询性能。

此外,在应用 TiDB 支持业务的过程当中,贝壳金服的技术团队也经过自身对数据中台的业务理解和技术实践,打磨出了如下配套工具及平台:

  • 基于 TiDB 的数据发布平台

  • 基于 TiDB 的元数据管理平台

  • 支持 TiSpark+TiDB 的权限管理系统

  • 基于 Flink + TiDB 的在线 SQL 流式处理平台

在上面这些技术成果的基础上,贝壳金服的技术团队正在作将来的数据中台技术栈演进规划,即基于 TiDB + Azkaban + 自研的数据质量平台。

相关文章
相关标签/搜索