TiDB + TiFlash : 朝着真 HTAP 平台演进

做者介绍:
韦万,PingCAP 数据库研发工程师,主要领域是数据库的存储引擎研发,以及系统性能优化。

1、为何咱们须要 HTAP 数据库?

在互联网浪潮出现以前,企业的数据量广泛不大,特别是核心的业务数据,一般一个单机的数据库就能够保存。那时候的存储并不须要复杂的架构,全部的线上请求(OLTP, Online Transactional Processing) 和后台分析 (OLAP, Online Analytical Processing) 都跑在同一个数据库实例上。后来渐渐的业务愈来愈复杂,数据量愈来愈大,DBA 们再也优化不动 SQL 了。其中一个显著问题是:单机数据库支持线上的 TP 请求已经很是吃力,没办法再跑比较重的 AP 分析型任务。跑起来要么 OOM,要么影响线上业务,要么作了主从分离、分库分表以后很难实现业务需求。算法

在这样的背景下,以 Hadoop 为表明的大数据技术开始蓬勃发展,它用许多相对廉价的 x86 机器构建了一个数据分析平台,用并行的能力破解大数据集的计算问题。因此从某种程度上说,大数据技术能够算是传统关系型数据库技术发展过程的一个分支。固然在过程当中大数据领域也发展出了属于本身的全新场景,诞生了许多新的技术,这个不深刻提了。数据库

由此,架构师把存储划分红线上业务和数据分析两个模块。以下图所示,业务库的数据经过 ETL 工具抽取出来,导入专用的分析平台。业务数据库专一提供 TP 能力,分析平台提供 AP 能力,各施其职,看起来已经很完美了。但其实这个架构也有本身的不足。安全

图 1 Tranditional Data Platform

<center>图 1 Tranditional Data Platform</center>性能优化

首先是复杂性问题。自己 ETL 过程就是一个很繁琐的过程,一个例证是 ETL 作的好,能够成为一个商业模式。由于是两个系统,必然带来更高的学习成本、维护成本和整合成本。若是你使用的是开源的大数据工具搭建的分析平台,那么确定会遇到各类工具之间的磨合的问题,还有因为各类工具参差不齐所致使的质量问题。网络

其次是实时性问题。一般咱们认为越接近实时的数据,它的价值越大。不少业务场景,对实时性有很高的要求,好比风控系统,它须要对数据不停的分析,而且在险情出现以后尽快响应。而一般的 ETL 是一个周期性的操做,好比一天或者一个小时导一次数据,数据实时性是没有办法保证的。
最后是一致性问题。一致性在数据库里面是很重要的概念,数据库的事务就是用来保证一致性的。若是把数据分表存储在两个不一样的系统内,那么很难保证一致性,即 AP 系统的查询结果没有办法与线上业务正确对应。那么这两个系统的联动效应就会受到限制,好比用户没办法在一个事务里面,同时访问两个系统的数据。架构

因为现有的数据平台存在的以上局限性,咱们认为开发一个HTAP(Hybrid Transactional/Analytical Processing)融合型数据库产品能够缓解你们在 TP or AP 抉择上的焦虑,或者说,让数据库的使用者不用考虑过分复杂的架构,在一套数据库中既能知足 OLTP 类需求,也能知足 OLAP 类需求。这也是 TiDB 最初设计时的初衷。异步

2、TiFlash 是什么?

TiDB 定位为一款 HTAP 数据库,但愿同时解决 TP 和 AP 问题。咱们知道 TiDB 能够看成可线性扩展的 MySQL 来用,自己设计是能够知足 TP 的需求的。在 17 年咱们发布了 TiSpark,它能够直接读取 TiKV 的数据,利用 Spark 强大的计算能力来增强 AP 端的能力。然而因为 TiKV 毕竟是为 TP 场景设计的存储层,对于大批量数据的提取、分析能力有限,因此咱们为 TiDB 引入了以新的 TiFlash 组件,它的使命是进一步加强 TiDB 的 AP 能力,使之成为一款真正意义上的 HTAP 数据库。分布式

图 2  What is TiFlash

<center>图 2 What is TiFlash</center>工具

TiFlash 是 TiDB 的一个 AP 扩展。在定位上,它是与 TiKV 相对应的存储节点,与 TiKV 分开部署。它既能够存储数据,也能够下推一部分的计算逻辑。数据是经过 Raft Learner 协议,从 TiKV 同步过来的。TiFlash 与 TiKV 最大的区别,一是原生的向量化模型,二是列式存储。 这是都是专门为 AP 场景作的优化。TiFlash 项目借助了 Clickhouse 的向量化引擎,所以计算上继承了它高性能的优势。oop

图 3 TiFlash Architecture

<center>图 3 TiFlash Architecture</center>

因为 TiFlash 节点和 TiKV 节点是分开部署的,因此即便咱们跑很重的计算任务,也不会对线上业务产生影响。

上层的计算节点,包括 TiSpark 和 TiDB,他们均可以访问 TiKV 和 TiFlash。后面会介绍咱们是如何利用这个架构的优点,在一个系统内同时服务 TP 和 AP 这两个场景,而且产生 1+1>2 的效果。

3、TiFlash 技术内幕

对于一个数据库系统,TP 和 AP 是有系统设计上的冲突的。TP 场景咱们关注的是事务正确性,性能指标是 QPS、延迟,它一般是点写、点查的场景;而 AP 更关心的吞吐量,是大批量数据的处理能力,处理成本。好比不少状况下 AP 的分析查询是须要扫描几百上千万条数据,join 十几张表,这种场景下系统的设计哲学和 TP 彻底不一样。TP 一般使用行式存储,例如 InnoDB,RocksDB 等;而 AP 系统一般使用列式存储。将这两个需求放在同一个系统里面实现,从设计上很难取舍,再加上 AP 的查询业务一般属于资源消耗型,隔离性作很差,很容易影响TP 业务。因此作一个 HTAP 系统是一件难度很是高的事情,很考验系统的工程设计能力。

1. 列式存储

图 4 Row Based vs Column Based

<center>图 4 Row Based vs Column Based</center>

通常来讲,AP 系统基本上都是使用列式存储,TiFlash 也不例外。列式存储自然能够作列过滤,而且压缩率很高,适合大数据的 Scan 场景。另外列式存储更适合作向量化加速,适合下推的聚合类算子也更多。TiFlash 相对于 TiKV,在 Scan 场景下性能有数量级的提高。

而行式存储显然更适合 TP 场景,由于它很适合点查,只读少许数据,IO 次数、粒度都更小。在绝大多数走索引的查询中,能够实现高 QPS 和低延迟。

因为咱们把 TiFlash 和 TiKV 整合在了 TiDB 内部,用户能够灵活选择使用哪一种存储方式。数据写入了 TiKV 以后,用户能够根据需选择是否同步到 TiFlash,以供 AP 加速。目前可选的同步粒度是表或者库。

2. 低成本数据复制

数据复制永远是分布式系统的最重要的问题之一。TiFlash 做为 TiDB 的另一个存储层,须要实时同步 TiKV 的数据。咱们采用的方案也很天然:既然 TiKV 节点内部使用 Raft 协议同步,那天然 TiKV 到 TiFlash 也是能够用 Raft 协议同步数据的。TiFlash 会把本身假装成一个 TiKV 节点,加入 Raft Group。比较不同的是,TiFlash 只会做为 Raft Learner,并不会成为 Raft Leader / Follower。缘由是目前 TiFlash 还不支持来自 SQL 端(TiDB/ TiSpark)的直接写入,咱们将在稍后支持这一特性。

图 5 Raft Learner Replication

<center>图 5 Raft Learner Replication</center>

你们知道,Raft 协议为了提升数据复制效率,Raft Log 从 Leader 到 Follower / Learner 的复制一般会优化成异步复制,只要记录被复制到了 Leader + Follower 的 “多数” 节点,就认为已经 commit 了。而且 Learner 是排除在 “多数” 以外的,也就是说更新不须要等待 Learner 确认。这样的实现方式,缺点是 Learner 上的数据可能有必定延迟,优势是大大减小了引入 TiFlash 形成的额外数据复制开销。固然若是复制延迟太大,说明节点之间的网络或者机器的写入性能出现了问题,这时候咱们会有报警提示作进一步的处理。

3. 强一致性

那既然是异步复制,如何保证读一致性呢?一般来讲,由于在 Leader 节点必定能够拿到最新的数据,因此咱们只会去 Leader 节点读数据。可是 TiFlash 只有 Learner,不可能这样读数据。咱们使用 Raft Follower / Learner Read 机制来实现直接在 TiFlash 节点读数据。原理是利用了 Raft Log 的偏移量 + 全局时间戳的特性。首先在请求发起的时候获取一个 read ts,那么对于全部的 Region(Region 是 TiDB 内部数据切割单位,也是 Raft Group 单位),只要肯定本地 Region 副本已经同步到足够新的 Raft Log,那么直接读这个 Region 副本就是安全的。能够利用 MVCC 的特性,对于每一条 unique key,过滤出 commit ts<= read ts 的全部版本,其中 commit ts 最大的版本就是咱们应该读取的版本。

这里的问题是,Learner 如何知道当前 Region 副本足够新呢?实时上 Learner 在读数据以前,会带上 read ts 向 Leader 发起一次请求,从而得到确保 Region 足够新的 Raft Log 的偏移量。TiFlash 目前的实现是在本地 Region 副本同步到足够新以前,会等待直到超时。将来咱们会加上其余策略,好比主动要求同步数据(如图 6 和图 7 所示)。

图 6 Learner Read (1/2)

<center>图 6 Learner Read (1/2)</center>

图 7 Learner Read (2/2)

<center>图 7 Learner Read (2/2)</center>

4. 更新支持

TiFlash 会同步 TiKV 上的表的全部变动,是两个异构的系统之间同步数据,会遇到一些很困难的问题。其中比较有表明性的是如何让 TiFlash 能实时复制 TiKV 的更新,而且是实时、事务性的更新。一般咱们认为列式存储的更新相对困难,由于列存每每使用块压缩,而且块相对于行存更大,容易增长写放大。而分列存储也更容易引发更多的小 IO。另外因为 AP 的业务特色,须要大量 Scan 操做,如何在高速更新的同时保证 Scan 性能,也是很大的问题。

图 8 Update Support

<center>图 8 Update Support</center>

目前 TiFlash 的方案是,存储引擎使用类 LSM-Tree 的存储架构,而且使用 MVCC 来实现和 TiDB 一致的 SI 隔离级别。LSM-Tree 架构能够很好的处理 TP 类型的高频小 IO 写入;同时又有的必定的局部有序性,有利于作 Scan 优化。

4、TiFlash 带来的想象空间

在新的业务纬度上让 TiDB 更加 Scalable。经过引入全新的 TiFlash AP 扩展,让 TiDB 拥有了真正的 AP 能力,即为 AP 专门优化的存储和计算。咱们能够经过增减相对应的节点,动态的增减 TiDB 系统的 TP 或者 AP 端的能力。数据再也不须要在两个独立的系统之间手动同步,而且能够保证明时性、事务性。

AP 与 TP 业务的隔离性,让 TiDB 的 AP 业务对线上的 TP 影响降到最低。由于 TiFlash 是独立节点,一般和 TiKV 分开部署,因此能够作到硬件级别的资源隔离。咱们在 TiDB 系统中使用标签来管理不一样类型的存储节点。

图 9  AP 与 TP 业务隔离

<center>图 9 AP 与 TP 业务隔离</center>

从 TiDB 的视角,TiFlash 和 TiKV 从层次上是一致的,都是存储节点。区别在于它们在启动时候给 PD (PD 为 TiDB 集群的 Coordinator)上报的节点标签。TiDB 就能够利用这些信息,把不一样类型的请求路由到相应的节点。好比咱们能够根据一些启发试算法,以及统计信息,了解到一条 SQL 须要 Scan 大量的数据而且作聚合运算,那么显然这条 SQL 的 Scan 算子去 TiFlash 节点请求数据会更合理。而这些繁重的 IO 和计算并不会影响 TiKV 侧的 TP 业务。

TiFlash 带来了全新的融合体验。TiFlash 节点并不仅是单纯的从 TiKV 节点同步数据,它们其实能够有进一步的配合,带来 1+1>2 的效果。上层的计算层,TiDB 或者 TiSpark,是能够同时从 TiFlash 和 TiKV 读取数据的。

图 10 Combination of TiFlash and TiKV

<center>图 10 Combination of TiFlash and TiKV</center>

如图 10 所示,好比咱们遇到一条 SQL,它须要 join 两份数据,其中一份数据须要全表扫描,另一份则能够走索引,那么很显然能够同时利用 TiFlash 强大的 Scan 和 TiKV 的点查。值得一提的是,用户一般会配置 3 或 5 份副本在 TiKV,为了节约成本,可能只部署 1 份副本到 TiFlash。那么当一个 TiFlash 节点挂掉以后,咱们就须要从新从 TiKV 同步节点。

图 11 SQL MPP Push Down

<center>图 11 SQL MPP Push Down</center>

咱们接下来计划让 TiFlash 节点成为 MPP 集群。即 TiDB 或者 TiSpark 接收到 SQL 以后,能够选择把计算彻底下推。MPP 主要是为了进一步提高 AP 的计算效率。

图 12  性能数据

<center>图 12 性能数据</center>

上图是 TiFlash 某一个版本的性能数据,咱们使用 TiSpark + TiFlash 来对比 Spark + Parquet。能够看到 TiFlash 在支持了实时 update 和事务一致性的状况下,仍然达到了基本一致的性能。TiFlash 目前还在快速迭代之中,最新版本相对于这里其实已经有很大幅度的提高。另外咱们目前正在研发一款专门为 TiFlash 全新设计的存储引擎,至少带来 2 倍的性能提高。能够期待一下以后出来的性能。

图 13 TiDB Data Platform

<center>图 13 TiDB Data Platform</center>

简单就是生产力。传统的数据平台因为技术的限制,企业须要作很是繁重的建设工做。须要把许多技术整合在一块儿才能实现业务需求,而系统之间使用复杂繁琐的 ETL 过程同步数据,致使数据链条很长,效果也不必定好。TiDB 但愿把系统的复杂性留在工具层面,从而大幅度简化用户的应用架构。

目前 TiFlash 正在与部分合做伙伴进行内部 POC,预计年末以前会发布一个 GA 版本,敬请期待。

(对 TiFlash 感兴趣的朋友欢迎私聊做者,交流更多技术细节~ weiwan@pingcap.com)

相关文章
相关标签/搜索