微众银行 TiDB HTAP 和自动化运维实践
作者:黄蔚
本文根据微众银行资深数据库架构师黄蔚在 DevCon 2022 上的分享整理,主要讲述了微众银行对于 HTAP 架构的探索和实践情况,以及提升大规模分布式数据库运维效率的经验。
内容将从四个方面展开:HTAP 技术的演进历程、微众银行在 HTAP 技术的选型以及实践、在大规模分布式数据库自动化运维的优化实践、TiDB 在微众银行的未来规划。
TiDB HTAP 架构的演进
我们知道一项新技术的出现和发展,其背后往往有两个原因:一是因为业务驱动,追求客户的极致体验;二就是技术的发展,通过一些新技术的创新和应用,进一步降低硬件成本、开发成本或整体维护成本。HTAP 其实也是在这样背景下诞生的。
我们首先来看传统的数据架构有哪些瓶颈或者有哪些优化点。我们知道,按照负载类型划分,系统一般分为 OLTP 和 OLAP,OLTP 在金融场景一般是包括像交易、转账、营销等,面向的是客户,追求的是极致体验,如果有问题很可能就会影响用户体验,甚至造成用户损失。所以 OLTP 要求的是耗时短,并且处理的数据量相对小。
而我们还要基于这些用户产生的数据做商业分析、数据挖掘,根据分析结果来进行决策,比如进行战略方向上的调整。所以衍生出来了 OLAP,通常专门用来做一些分析。而 OLTP 和 OLAP 的负载不一样,也就意味着技术底座是不一样的,所以一般是将两者分开,这个时候就需要通过 ETL 的方式把数据传输到 OLAP 上做分析,但是这个传输的过程在时效性上会比较差,同时架构也会比较复杂,但优势是这套架构非常成熟,尤其是自从大数据三驾马车的论文出来之后,大数据的整个生态变得更加成熟,使用也更广泛。
随着业务的发展,业务对于时效性的要求越来越高,比如希望实时对用户进行客群圈选、画像分析、实时洞察,或者做金融场景的风控,这时候就诞生出了 Kappa 架构。
Kappa 架构的核心就是流式处理, OLTP 系统产生的 CDC 或者 Message 通过 Kafka 消息队列传输到常见的流处理技术组件比如 Flink、Spark Streaming 进行处理,最终到 Serving DB 来存放这些数据并实时对外提供服务。而对于 Serving DB 的要求首先是扩展性要好,同时受限于流式处理暂时没法完全取代批处理,那就意味着在 Serving DB 上还需要做一定的 OLAP 分析。其实 TiDB 在这个架构里也有一定的使用量,比如 Flink 要存放一些中间态数据或者进行维表关联,对于 DB 也需要一定的扩展性,此时 TiDB 的扩展能力正好可以满足。
这个架构的核心特点就是准实时处理,而且在工程实践上非常丰富。而这个架构的劣势是组件很多,学习的成本相对高,并且整个链路很长,意味着在数据一致性的保证上会比较困难。所以,大家就在想能不能在一个数据库同时去承载 OLTP 跟 OLAP 业务呢?不需要去做额外的数据同步,不需要去学习额外的组件,所以就衍生出了 HTAP 数据库的概念。
它的架构很简洁,但是实现技术难度也非常高。虽然这几年 HTAP 非常火,但是工程实践相对较少,像传统的 Oracle 12c In-Memory Column Store、Google Spanner PAX 其实都算是行列混存的架构,TiDB 也有自己的 HTAP 实现。HTAP 架构的难度是怎样做资源隔离,怎样做一致性保证,如何做 OLTP 和 OLAP 的负载平衡等等。
接下来谈谈 TiDB HTAP 架构的演进,我们如何基于业务需求去做选型以及对应的实践情况。
图中,我们看到 TiKV 为了让数据均衡,容易做分布式调度,会把数据分成很多小片,也就是 Region,Region 在 TiKV 这一侧是强同步的,我们可以看到绿色线条是实线。而 TiFlash 的创新点就是没有打破原来 TiKV 的架构,而是新增一个列式引擎,直接通过 Raft Log 的方式同步到 TiFlash,因为列式存储天然对于 OLAP 场景是比较友好的,所以还要做一个行转列的处理。我们可以看到 TiKV 到 TiFlash 的同步线是一条虚线,意味着这是一个异步过程。那么又如何保证在 TiFlash 上的查询是强一致的呢?这里其实做了一些优化,每次收到读取请求,TiFlash 中的 Region 副本会向 Leader 副本发起进度校对(一个非常轻的 RPC 请求),只有当进度确保至少所包含读取请求时间戳所覆盖的数据之后才响应读取,所以如果有同步延迟,就会需要等待,甚至有可能在 TiFlash 的查询会超时,在实践中我们发现有些场景对于 OLAP 的一致性要求并没那么高,而在 6.0 版本的 TiFlash 提供了 Fast Scan 这个功能,降低一致性的保障,但可以提升读写速度。
我们看到 TiDB HTAP 架构隔离性非常好,因为列存跟行存完全独立,同时 TiFlash 借助了 MPP 并行计算框架,并且是基于 Clickhouse 底座,所以天然具备向量化计算引擎的一些 OLAP 特性。同时,TiDB HTAP 架构创新性地通过 Raft Log 来同步保证了一致性,同时也可以通过 Fast Scan 功能来降低一致性,提高读写速度。进一步的,TiDB 的产品迭代非常快,有一些特性是我们也非常期待,比如说低成本的硬盘支持、更准确的优化器等。
微服务分布式链路追踪和微服务治理场景下的 HTAP 实践
在银行场景下我们怎样选型 HTAP 技术呢?微众银行的基础架构是基于 DCN 的分布式架构,也就是单元化,一笔简单的交易可能涉及到几十甚至上百个微服务在背后支撑,所以微服务的调用量很大。那么我们怎样快速地进行定位异常问题呢?比如说一笔交易或者一个系统如果有异常,怎样快速地知道哪里出问题了?这里就需要借助可观测的方式。可观测一般都会谈到 Trace、Metrics、Log 这三个基本元素。
基于微众银行 DCN 的分布式架构,如果两个用户分属不同的 DCN,要进行交互比如转账,就需要通过 RMB 可靠消息总线来进行交互。我们为了保存完整全量的微服务调用关系,会旁路地消费一份服务之间的调用消息,把这些信息存到 TiDB。为什么存到 TiDB 呢?我们行内交易量特别大,TiDB 正好能提供扩展性,同时 TiDB 支撑的并发量也很大,每秒达到了 20 万+ 这样一个量级。
我们可以通过这些 Trace 信息去追踪这一笔交易涉及的不同服务、不同的子系统之间调用的详细信息,比如说源端、目标端调用的耗时,调用返回的状态,有没有报错等,这是微观层面的追踪。微服务场景下,服务数量非常多,种类也多,调用关系很复杂,我们怎样从全局的角度了解整个微服务的架构是否健康,是否存在问题,比如有没有流量突增,有没有系统性的问题?所以衍生出了服务治理这个系统。服务治理的要求是能够实时知道微服务整个调用关系的信息,所以我们就把 TiKV 存储的 Trace 信息实时同步到 TiFlash,同时我们预定义很多的度量指标,比如实时分析整个服务的健康度,整个子系统调用的次数排名,是否存在流量突增,耗时的变化等。
基于这些度量指标,我们再通过决策引擎去得到一个最优的治理策略。我们的决策可以分成两部分,第一个是自动决策,通过度量指标直接把需要去治理的动作下发到生产环境的微服务的应用或者容器。第二个是辅助决策,生成一个决策值,人工进行判断,根据经验或者根据一些特定的阈值触发相应的策略,再下发到真正的生产环境。我们看到整个系统形成了一个闭环,从生产环境产生消息,到分析消息,再通过度量产生决策,最后又反向去影响我们的生产环境,让整个微服务的精细化管理越来越好,这是我们在 HTAP 选型的一个场景。
当然我们也遇到了一些挑战,第一是集群非常大,第二是在这么大规模的集群下还要跟 TiFlash 结合。所以我们形成了相关的实践经验。首先,集群很大,如何稳定运行?我们从几个方面进行入手:第一,TiDB 的组件 PD 可能会存在个别单点瓶颈,所以我们把大集群 Region 总数控制在一定范围;第二,控制单个 TiKV 实例的 Region 数量,对于一些历史归档或者相对冷的数据,心跳维持不用太频繁,所以我们开启了 Hibernate Region 功能,减轻单个实例可能产生的瓶颈问题。
其次,TiDB 架构中 OLTP 的负载使用的是 TiKV,OLTP 往往面对的是客户,直接关系到用户体验的问题,我们认为在极端情况下 TiFlash 有异常的时候,不希望它影响到 TiKV,因此我们建立了一个快速熔断机制,目的是在 TiFlash 全部异常的情况下尽可能对 TiKV 的影响最小。我们还在超大集群 POC 时做了很多暴力验证,比如说把 TiFlash 全部直接关停,比如制造一些网络拥塞,IO、CPU 资源跑满等。在验证过程中我们也发现了很多问题,也相应都做了修复,我们认为未来在超大集群的使用上,HTAP 架构的健壮性会越来越好。
刚刚提到,TiKV 跟 TiFlash 需要联动,集群很大,又要做数据的生命周期管理。TiKV 是做链路追踪,我们希望它的数据保留的时间比较长,比如 7 天,7 天之外的就删掉,TiFlash 做的是实时分析,我们希望保存数据的天数少一点,比如 3 天,这两边的清理策略是不一样的。这时候就会有一个问题,TiKV 跟 TiFlash 虽然物理上是隔离的,但 PD 调度是共用的,很可能会产生相互影响。举个简单例子,我们在超大集群下往往需要去提前规避写入热点问题进行提前打散。我们发现在打散的时候会影响正常写入,发现本质原因是打散动作首先会在一个 Region 上进行打散,最终再会去 scatter 均衡,而均衡背后有 Remove Peer 动作,就是把本地的 Peer 删掉,再调到其他节点上,而 Remove Peer 会有资源的占用。
因为写入同样也会触发分裂,同样也会需要 Remove Peer 功能,这时候就产生了互斥。我们在整个实践中发现,各个调度参数之间可能会相互影响,所以需要找到参数之间的相互干扰的因素,再找到一个最佳的平衡点。最后,我们通过右下角这张图对相关参数进行了深入研究和调试,最终实现了超大集群下 TiKV+TiFlash 的稳定联动,可以确保 20 万+ 每秒的持续写入并不会产生明显抖动。
TiFlash 实际上也是一个 OLAP 的引擎,在很多场景里会拿 TiFlash 去跟一些 OLAP 传统组件去对比,比如拿 TiFlash 跟 Clickhouse 去对比。我们在真正的业务场景中发现用户的需求场景很多,对应的技术要求也不一样,所以细分下来发现像有些分析场景,可能对于实时性要求很高,有些场景可能计算量很大,维度很固定,希望做一些预计算,还有一些交互式的,希望灵活和快速返回,所以我们通过细分业务场景以及对应的技术要求的细化,最终找到了不同的 OLAP 组件所对应的场景和最佳实践。
我们也对 TiFlash 和 Clickhouse 做了一个简单对比,可以很明显地看到 Clickhouse 在硬件成本以及单表的性能上有很大优势,而 TiFlash 在运维成本、开发成本以及实时更新有不错的优势。所以我们认为 OLAP 组件没有银弹,我们可以通过这种组合的方式,通过在各个 OLAP组件之上增加一个中间层来统一来提供服务给业务,让业务不用感知具体的引擎或组件,对用户来说,只需要去满足业务需求就好了。
TiDB HTAP 的场景推荐有哪些呢?第一个肯定是 HTAP 型的交易系统,OLTP 是一定要用的,同时我们要结合 OLTP 把数据同步到 TiFlash 进行实时分析,这是第一种最经典的场景。第二种,我们知道 TiDB 有 DM 工具,可以把多个 MySQL 的数据快速地同步汇聚到一个 TiDB 集群,多源汇聚到 TiDB 后,TiDB 可以是一个数据中台、一个数据仓库或者是一个数据集市,再结合 TiFlash 的分析能力,快速地进行业务分析或业务监控,所以多源数据的汇聚和实时分析是第二个场景。第三个场景,就是上面提到的,把 TiDB 作为一个单纯的 OLAP 组件使用,当然成本会较高,因为如果只使用用 TiFlash,还是需要从 TiKV 进行数据同步。但是 TiDB 的好处就是开发成本比较低。
基于微信机器人的 TiDB 数据库运维优化
目前 TiDB 在微众银行的集群规模越来越大,从 2021 年开始的 20 多个集群到现在已经接近 60 个集群,数据的总容量也接近 800T,同样使用 TiDB DM 的量也非常大,应用的业务类型也特别多,包括贷款、存款、理财、科技管理、基础科技,应用的场景包括联机、批量、归档、管理平台等等。在数据增长快,应用规模大,业务场景类型多,重要性高的情况下,同时还要符合合规要求,因此在 TiDB 大规模分布式数据库的运维上,我们也进行了很多探索,比如怎样更高效地运维和使用分布式数据库。
我们有三个方面的总结:第一,做标准化的 SOP,对于业务接入,日常变更和故障处理,我们都需要一些标准化的流程;第二,这么大规模的集群量,我们希望运维工作可以 Work Smart,也就是更加高效地处理遇到的问题,我们引进了微信机器人,把集群诊断、巡检这些工作都自动化了;最后,开源有一个最大的好处就是能看到源码,所以我们希望可以从源码侧去解析,这样有些疑难问题我们可以更加深入,更加快捷地去发现问题,同时提供更理想的优化方案。
接下来看看我们基于微信机器人的 Smart 运维工作。可以看到,我们的 DBA 只需要通过微信,通过一部手机就可以对一些场景进行快速处理。以往,在银行,对于遇到一些生产的告警,我们需要去登陆 VPN,输入 Token,在其他的内部系统又要做二次登录校验,整个过程耗时比较长。而针对一些比较紧急的告警,登录到服务器,已经过去了不少时间,所以我们希望针对一些特定合适的告警场景,快速地去响应,所以我们基于微信机器人的方式进行了优化,分成几个层次。
第一,通过 TiDB 自带的 TiUP 工具来做一些数据采集,包括集群信息和主机的 CMDB 信息,把这些信息全量入库。每天定时去把收集的信息进行分析巡检,输出一个报告。第二,在自动诊断这块,我们在 TiDB 上会遇到一些常见高频的问题,比如内存高、OOM、热点、慢查询、执行计划突变等,我们把这些问题处理会形成一个知识库,并且生成对应的分析引擎,如果触发了对应告警,就会自动地触发根因分析,并且生成推荐根因。在生成推荐根因的时候,我们还会模拟爬虫在 Grafana 上把最近的半小时的 Overview,包括一些监控视图、实例信息截图生成一个图片,结合刚才的推荐根因一起推送到我们的手机微信上。DBA 立马就可以看到告警发生可能的原因是什么,并且我们还可以快速地进行执行,处理相应问题。
我们在微信机器人上提供了一个交互的快速执行方式。比如可以对一些慢查询进行 Kill,比如 restart TiDB Server,当然前提一定是安全合规,我们对一些高危命令会增加预审批流程,同时我们会预定义一些白名单的命令。最终可以看到,我们从巡检、数据采集、自动诊断以及交互式的快速执行四个维度来整体提升数据库的运维效率。
这里是 Smart 运维的效果图,可以看到像 tiup display、show processlist,以及 kill 慢查询,restart server 等一系列动作,都可以通过一部手机去完成,我们内部称为微信机器人的运维方式,这种方式提升了数据库的运维效率。
最后做一个简单的展望,我们希望未来继续沉淀 HTAP 技术在金融场景的探索和落地经验,形成金融场景的最佳实践。同时,我们希望未来能够把内部的一些运维工具,比如 DM 自动化校验平台、自动诊断平台等开源出去,能够和大家进行深入的交流和共创。 最后,随着国产化的进程,我们也会推动 TiDB 在国产 ARM 服务器上的进一步扩大使用。