车好多团体系国内领军的汽车生产服务一站式平台,旗下领有瓜子二手车、毛豆新车、车好多车后三大外围业务。
业务挑战
车好多团体关注 TiDB 始于 2018 年初,像大多数公司一样,公司倒退初期为了疾速适配业务开发,大部分数据都存储在 MySQL 中。但随着业务疾速倒退,存量数据越来越多,咱们在 MySQL 面临着如下痛点:
业务拆分简单
公司业务倒退快,单实例的 QPS 和数据存储会超出预期,这时候须要对业务线实例进行拆分。每次业务线拆分须要从数据产生端 (APP) 到数据流转端 (CDC) 最初到数据仓库 (DW) 一起配合调整; 如果波及到多方同时应用雷同库表,还须要多个利用的负责人协调; 同时一些脚本类程序可能在迁徙时被疏忽,局部业务数据会受到影响。每次业务线拆分的周期大略在 2-4 周,消耗人力。
分库分表侵入业务
业务倒退到肯定水平之后,一些数据表的数据量超过千万级别,惯例做法是分库分表。这里有几个可能遇到的问题:
- 分布式事务不好解决;
- 二级索引无奈创立;
- 分库分表的设计是否反对二次扩容;
- 跨库 join 无奈操作;
- 后果集的排序合并难度大。
大表构造批改艰难
咱们公司的业务模式变动快,为了疾速响应业务,表构造常常调整。在对一些数据在百万级别以上的大表做 DDL 的时候,会借助第三方工具,如 pt-osc。批改过程中须要先复制一份长期表,这种形式批改的工夫较长,对存储空间、IO、业务有肯定的影响。
为什么抉择 TiDB
面对以上痛点,咱们开始思考对数据库的架构进行降级革新,咱们依据业务方的诉求,将一些常见数据库技术计划,做了一些比照:
数据库类型 | 长处 | 毛病 |
---|---|---|
MySQL 分库分表 | 1. 依据 ID 查问的层面基本上无多余工作量。2. 短期技术实现成本低。 | 1. 库表数量线性增长,运维压力大,按百万级别数据量分表计算,每年增长表的数量至多 30 张,且单表容量依然较大。2. 分库分表在代码层实现需改变代码。3. 如引入分库分表中间件,则须要投入专门人员。 |
MongoDB | 1. 技术比拟成熟。2. 大数据量下,可通过分片进行扩大。 | 1. 业务须要全副重构,短期内无奈实现。2. 文档型数据库,须要业务来控制数据较验。 |
ElasticSearch | 搜寻功能强大(多二级索引)。 | 1. ElasticSearch 写入性能稍差,遇到大量写入操作时候,可能提早。2. 无 schema 治理,长期保护老本较高。 |
HBase | 1. 技术比拟成熟。2. 一般依据 rowkey 查问,无工作量。3. 可横向扩大。 | 1. 无奈通过 rowkey 间接获取数据的场景,都须要额定开发,接口通用性较低。2. 不反对二级索引。3. 协定与现有程序不统一,须要从新开发相干读写程序。 |
HBase+phoenix | 1. 底层 kv 存储复用 HBase,存储引擎的稳定性强。2. 可横向扩大。 | 1. SQL 语法小众。比方只有 upsert,没有独自的 insert 和 update。2. Phoenix 的事务性能依赖开源的 percolator 实现,可信度略低。事务还是一个比拟谨严的技术,Phoenix 社区和 Google 也没能查到太多事务相干的信息。 |
HBase+ES | 1. HBase 作为 OLTP 的记录存储,ES 作为 HBase 的二级索引。2. 兼顾了 HBase 的长处(疾速的 kv 能力,海量存储能力,可变字段能力)和 ES 的长处(弱小的二级索引能力)。 | 1. 不反对事务。2. HBase 和 ES 两端的数据统一保障难度高。 |
TiDB | 1. 齐全兼容 MySQL 协定,业务层简直不须要改变。2. 分布式存储,节点有限扩容,高可用。3. 完满代替 MySQL 分库分表。4. 大表 DDL 不影响业务。5. 反对事务,隔离级别为 ’ 快照级别隔离 ’ [见附录]。6. 可兼容 CDC 链路。 | 1. 资源需要较高。2. 无触发器、存储过程、某些语法不兼容。 |
TiDB 具备程度弹性扩大,高度兼容 MySQL,在线 DDL,一致性的分布式事务等个性,合乎车好多局部数据量大,业务变更频繁,数据保留周期长等场景。 咱们通过 TiDB 的内部测试后,确认能够满足现有业务需要。咱们最终抉择了 TiDB 做为这类需要的数据存储。
首次摸索
业务场景
综合 TiDB 的个性和车好多团体的业务场景,咱们比拟适宜引入 TiDB 的场景有: 工单调配 / 流转、电话销售零碎、业务中台 - 账务零碎等业务。首先这些业务积攒的数据量比拟大,在此基础上一部分业务会有频繁减少字段的需要,也有一部分业务会应用到事务,这些场景都十分实用于 TiDB。
面临问题
与指标业务方进行了一轮沟通之后,业务方给咱们介绍了一些数据的现状和业务上的需要:
- 上线之前存量数据靠近 3 亿条,每日新增 170 万条,单月约 5000 万增量。MySQL 中热数据即便只存储最新 2 个月,也面临单表数据破亿的场景。
- 因为车好多团体的业务特殊性,车的周转周期比拟长,一些冷数据可能会转变为热数据,归档逻辑与业务需要强绑定,一些所谓的 ” 冷数据 ” 可能会有更新操作。
- 这些数据针对线上用户提供服务,对数据库的实时性读写性能要求较高。
- 同一份数据有多方在应用,针对不同需要查问重点不同,业务查问条件简单。
- 当数据产生变更时,有相应的业务逻辑解决,须要配置 CDC 数据链路监控数据变动。
接入要求
因为 TiDB 的资源要求较高,咱们对接入的业务提出了以下要求:
- 存量数据在千万以上,将来 MySQL 的单机存储和性能会成为瓶颈。
- 业务波及到事务 / 分库分表 / 常常在线减少字段等非凡场景。
- 数据价值较高,提供针对用户的在线服务。
接入过程
面对一个新的数据库,大部分外围业务还是放心数据库的稳定性和数据的可靠性,不敢间接尝试。咱们优先选择一些数据量比拟大并且实时性需要绝对较低的场景进行试点,然而业务方依然放心服务的稳定性和性能等诸多问题。咱们屡次与业务方沟通,制订和施行了分段落地的打算:
第一步,将 TiDB 作为 MySQL 的从库应用,通过 DM 工具同步数据。业务方应用这套 TiDB 集群作为从库,验证数据的准确性 / 服务的稳定性 / 查问的性能等是否合乎业务需要,测试失常后灰度小比例的线上流量到该集群上进行查问,确认数据失常后逐渐放大灰度的比例直至全流量。这一步充沛的验证了 TiDB 的数据同步和数据查问,业务方对 TiDB 有了初步的认知,也逐步积攒了对 TiDB 和保护人员的信赖。
第二步,业务方革新程序,对 MySQL 和 TiDB 进行双写,断开 DM 同步。业务方将 TiDB 作为主库间接读写,但依然保留了 MySQL 中的数据写入,将 MySQL 作为 TiDB 产生异样之后的降级计划。这个阶段继续了 2 个季度左右。在这期间读写 TiDB 的程序运行失常,每天的数据校验保持一致。
第三步,下线双写,仅保留间接操作 TiDB 的局部。通过第一步和第二步的验证和积攒的信赖,TiDB 正式作为独立的数据库投入到生产环境应用.
新车业务接入 TiDB 之后,业务上将原先只反对近期三个月的查问扩大到反对全量查问,这部分数据对用户行为精细化治理带来了肯定的帮忙。随着业务倒退,存量数据从千万级别逐渐回升到亿级别,到当初将近十亿,在 1000 QPS 下查问的 99.9th 提早低于 128 毫秒,用户体验良好。通过了整个接入过程后,新车打算将存在数据库瓶颈的业务逐渐迁徙到 TiDB 中来。通过一年的倒退,目前车好多的二手车收售车治理、台账、领取网关、用户社群等业务逐渐尝试 TiDB,并且在试用之后缓缓从 MySQL 中迁徙更多的业务模块到 TiDB 中。
遇到的问题
在推动 TiDB 的过程中,咱们也遇到了各种问题,除了一些常见的慢 SQL、热点读写、DM 同步数据异样等问题外,咱们在车好多的业务背景下,遇到了一些绝对非凡的问题:
版本的抉择
TiDB 是一项比拟新的技术,社区的版本在一直的迭代更新,有很多 bugfix 和新个性在继续集成到 TiDB 中。咱们从开始调研到当初,经验了 2.X 到 4.0.X 的多个版本。咱们抉择了一些比较关心的内容进行跟进,如: Lightning 导入数据 bug 修复、乐观锁、TiFlash、TiUP 管理工具、TiCDC 等等。有一次咱们从 2.1.x 的版本升级到 3.0.x 版本,未留神到 sql mode 变更,恰好业务上正好有 SQL 被 ONLY_FULL_GROUP_BY 规定影响,紧急批改 SQL 后从新上线。咱们增量的业务抉择版本的时候,通常会抉择一些曾经安稳运行一段时间的版本,上线之后,如果没有重大的 bug 或者急需的个性,通常不再进行降级,以保障业务不因为数据库的降级受到影响。
SQL 执行打算 & SQL binding
应用 TiDB 一段时间后,某个业务线单表存量数据数据曾经超过 5 亿,QPS 也超过了 200。某天业务方反馈,线上零碎产生大量查问超时,后果无返回,TiDB-admin 帮助排查问题。察看监控数据,发现 CPU 被打满,IO 回升显著。持续察看慢 SQL 日志,发现在 analyze 收集统计信息的开端阶段,有一类 SQL 索引的抉择产生了扭转,每次扫描的 key 从失常索引下的百级别到异样索引下的百万到千万的级别。为了疾速复原业务,联合 TiDB 承载的业务的个性,将影响优化器抉择的未应用到的索引删除,同时将主动 analyze 操作设置为业务低谷时间段执行。
咱们以这个案例征询了 PingCAP 官网,因为 TiDB 应用的是基于老本的优化器(CBO),在统计信息变更的时候,有可能抉择与之前不统一的索引,倡议通过 SQL binding 解决此类问题。不久工夫后,另一条业务线的 SQL 因为相似问题,应用了 SQL binding 进行了绑定,在程序应用到 prepare statement 的时候遇到了另一个 bug [见附录],上报社区后曾经退出到修复打算中。
资源隔离
随着 TiDB 技术在车好多团体的推动,和第一批吃了螃蟹的业务方的举荐,越来越多的业务线心愿尝试 TiDB。受机房设备洽购周期的限度,咱们很难短期内凑出多套独立的 TiDB 集群,服务忽然回升的需求量。联合这些新增需要的业务个性: 大部分是增量比拟高然而没有存量数据的业务,后期对资源的需要并不是十分高,于是咱们 TiDB-admin 开始调研在同一组机器中混和部署多套集群,并且进行过程之间的资源隔离。TiDB 分为多个组件,PD 对资源的需要不高,临时疏忽;TiKV 能够通过软件层配置最大的 CPU 和内存,IO 的隔离咱们抉择在同一台机器部署多块 SSD 进行物理隔离,也比拟好管制;TiDB 尽管能够通过软件层配置最大的 CPU 和内存,然而无奈阻止刹时的内存暴增,调研后发现在通过 TiUP 部署的时候,能够设置 systemd 的参数 memory_limit,通过零碎的 cgroup 限度最大应用内存,这也催生了咱们通过 K8s+Docker 来全面管制资源的想法。咱们在混合部署之后,提供给了业务方进行验证,确认能够隔离某一方的异样 SQL 对通物理机下其余 TiDB 集群的影响,新业务逐渐用上了 TiDB。
TiDB 将来工作
- 尝试 TiDB 在车好多云上的实际:随着云原生技术的一直倒退,TiDB 作为一款为云原生设计的分布式数据库,能够通过 TiDB Operator 在云上工具化部署,自动化解决资源分配,晋升 TiDB 的资源利用率,同时也升高了 TiDB 的保护老本。
- 摸索 TiKV 笼罩到的场景:广告投放的业务对服务的拜访延迟时间十分敏感,如果提早过高用户的体检会大大降落,随同车好多五年来的数据积攒,咱们用作广告投放所积攒的数据量也十分大,因而咱们将 TiKV 作为可长久化的低提早的 KV 服务,提供给广告投放的业务来应用,技术计划曾经通过了线上流量的考验,因为汽车的交易周期较长,该我的项目依然处于业务初期阶段。在将来咱们将摸索更多的 TiKV 的应用场景,提供可长久化的、低提早的 KV 服务。
- CDC 的利用:车好多的数据流服务在 MySQL 数据库上是基于 Binlog 进行建设的,切换到 TiDB 后,应用过 Pump+drainer 的形式同步 binlog。在 TiDB 4.0 版本后退出了 CDC 服务,能够更不便的部署和集成多数据格式的输入,将来咱们会逐渐接入 CDC 的数据到现有零碎中。
- 接入车好多数据库运维平台:随同车好多的成长,咱们的 DBA 团队开发并保护了一套治理 MySQL 的零碎,管理员和开发的共事都能够很不便的在此零碎上实现日常工作,为了保护入口的对立,TiDB 将逐渐接入该零碎,便于 TiDB 运维的自动化。
- 提供更不便的接入形式:咱们现有的几条业务线的接入,大多是先通过 DM 同步数据,而后与业务方一起配合做一次迁徙。咱们心愿将来能够更不便地服务业务方,通过一个 SQL proxy 的代理层辅助,业务方只须要连贯到 proxy 层,后端是 MySQL 或者 TiDB 对于业务方不须要关怀,真正做到对业务 0 侵入。
附录:
- TiDB 事务隔离级别:
https://docs.pingcap.com/zh/t…
- prepare statement 形式 + limit 导致 SQL binding 失败:
https://github.com/pingcap/ti…