使HTAP数据库成为现实:我从PingCAP的VLDB文件中学到的东西

2020-12-13 04:14:54

最近,VLDB 2020发布了PingCAP的论文TiDB:基于Raft的HTAP数据库。这是业界第一篇描述分布式混合事务/分析处理(HTAP)数据库的实现的论文。作为一个从开放式分布式SQL数据库TiDB中受益匪浅的DBA,我很高兴VLDB认可TiDB,并受到PingCAP工程团队的新颖思想的启发。

PingCAP的论文不是典型的理论研究论文,而是提出了一个永远无法实现的想法。相反,它清楚而实用地证明了可以实现分布式HTAP数据库。数据库研究人员可以使用此信息更自信地朝正确的方向前进。

在本文中,我将与大家分享我对TiDB实现HTAP数据库的想法,该数据库提供了强大的数据一致性和资源隔离性,以及我对TiDB的期望。

您可能知道,数据库分为两种类型:在线事务处理(OLTP)和在线分析处理(OLAP)。但是您是否想过为什么?

OLTP和OLAP描述了两种非常不同的数据处理方法,因此它们具有不同的数据库要求。

几年前,数据库在OLTP和OLAP之间几乎没有区别。相反,一个数据库处理两种类型的请求。但是,随着数据量的增长,在单个数据库中处理两种类型的工作负载变得很困难。最重要的是,不同的工作负载类型会相互干扰。

因此,为了满足OLAP工作负载的特殊需求,人们设计了一个单独的数据库,该数据库仅处理OLAP工作负载。他们将数据从OLTP数据库导出到OLAP数据库,并在那里处理OLAP工作负载。分离OLTP和OLAP工作负载可以解决两个工作负载之间的冲突,但同时也引入了外部数据复制。在复制期间,很难确保数据的一致性和实时性。

PingCAP的论文提出了一种解决此问题的新方法:复制应在数据库内部而不是数据库外部进行。

由于OLTP和OLAP是非常不同的工作负载,因此很难在单个数据库中完成两种工作。有两种通用模式:

设计适用于OLTP和OLAP的存储引擎。在存储引擎中,数据是一致且实时的,但是很难确保两个工作负载不会互相干扰。

在一个数据库中构建两组存储引擎。每个存储引擎将处理一种类型的工作负载,因此OLTP和OLAP不会相互影响。但是,由于数据是在两个引擎之间复制的,因此同时实现强大的数据一致性和资源隔离可能很困难。

TiDB选择了第二种方法。 TiKV(基于行的存储引擎)处理OLTP工作负载,而TiFlash(列式存储引擎)处理OLAP工作负载。但是它们如何提供强大的一致性和资源隔离性?

对于大多数分布式存储系统而言,强一致性和资源隔离是一个任择的问题。您不能同时拥有两者。但是TiDB有一个答案:通过添加学习者角色来扩展Raft共识算法。

在TiKV中,数据存储的基本单位是Region,它表示数据范围(默认为96 MB)。默认情况下,每个区域都有三个副本。相同区域的副本通过Raft共识算法将数据从Leader复制到Follower。这是同步复制。

假设TiFlash是Raft组中的关注者,则TiKV和TiFlash之间的复制是同步的。如果TiFlash的复制速度很慢,或者TiFlash节点出现故障,则大多数节点不太可能成功复制数据,从而影响TiKV的可用性。因此,TiFlash不能成为关注者,因为它会干扰TiKV,并且资源不是隔离的。

为了解决此问题,TiDB通过向其添加学习者角色来扩展Raft算法。学习者副本仅异步接收Raft日志。它不会提交日志或参加“领导者”选举。当学习者副本正在复制数据时,关注者'并且Leader的性能开销非常低。当TiFLash的Learner副本接收数据时,TiFlash会将行格式元组转换为列格式数据,并将其存储在列存储中。这样,数据同时处于行存储和列存储格式。

但是,如果TiFlash的Learner副本异步地从Raft组接收日志,那么如何确保数据高度一致?

当应用程序从TiFlash读取数据时,TiFlash保证了强大的一致性。与Raft的追随者读取机制类似,Learner副本提供快照隔离,因此我们可以使用指定的时间戳从TiFlash读取数据。当TiFlash收到读取请求时,学习者副本将ReadIndex请求发送到其领导者。根据收到的ReadIndex,Leader保留请求,直到将相应的Raft日志复制到学习者,然后按指定的时间戳过滤所需的数据。这就是TiFlash可以提供高度一致的数据的方式。

当应用程序从TiFlash读取数据时,TiFlash的Learner副本只需要对TiKV的Leader副本执行ReadIndex操作。此操作对TiKV的负担很小。根据该论文,当TiDB处理OLTP和OLAP工作负载时,OLAP吞吐量降低了不到5%,而OLTP吞吐量仅降低了10%。

而且,该论文记录了一个实验,其中从TiKV到TiFlash的异步数据复制产生了非常低的延迟。对于10个仓库的数据量,延迟通常在100毫秒以内,最大延迟小于300毫秒。对于100个仓库,延迟主要在500毫秒以内,最大延迟小于1500毫秒。最重要的是,延迟不会影响数据的一致性。它只会使TiFlash处理请求的速度变慢。

TiDB有两个存储引擎,用于OLTP的TiKV和用于OLAP的TiFlash,它们都支持强一致性数据复制并提供相同的快照隔离。

这对于在计算层优化查询是一个巨大的好处。当优化程序处理请求时,它具有三个选项:行扫描(TiKV),索引扫描(TiKV)或列扫描(TiFlash)。对于单个请求,优化器可以对数据的不同部分应用不同的扫描,这为优化提供了很大的灵活性。 PingCAP论文还证明,使用两个存储引擎的OLAP请求比使用两个引擎中的任何一个的请求都更好。

尽管较旧的数据库要求用户划分请求并将其发送到适当的数据库,但TiDB提供了不同的工作流程:该用户只有一个数据库。数据库分析请求并确定要使用哪个存储引擎。它会麻烦地划分数据库和请求,而这是更高层次的抽象。

在当前的分布式数据库行业中,不同的体系结构设计共存。一种杰出的设计是去中心化架构,例如Cassandra或CockroachDB。但是TiDB并不是严格分散的,因为它具有中央调度管理器Placement Driver(PD)。

分散式架构在容错性,抗攻击性和抗共谋性方面表现出色。但是,由于数据库部署在可靠的内部网络中,因此抵抗攻击或串通并不是问题。另一方面,容错也可以在集中式体系结构中进行处理。因此,不需要分散。

与分散式架构相比,集中式架构更易于调度。 HTAP数据库用于处理大量数据。当节点数量和数据量增长到前所未有的程度时,数据库必须能够弹性伸缩。数据库是否具有智能调度功能将成为决定其性能和稳定性的关键因素。但是,在分散式架构中,调度很困难,因为调度程序无法检测到集群中发生的所有事情,也无法轻松地协调多个节点之间的决策过程。

如此看来,集中式调度程序(在本例中为PD)具有独特的优势。它具有全局视图和多节点协调功能,以实现更好的调度。因此,对于分布式数据库,只要集中式调度程序不会成为系统瓶颈,那么收益将大大超过成本。在本文中,PingCAP还进行了严格的性能测试,以证明PD作为单一点不会限制整个系统的水平可扩展性。

在TiDB中,存储与计算完全分离。存储层具有两个引擎TiKV和TiFlash,计算层还具有两个引擎SQL引擎和TiSpark(用于运行Apache Spark的薄层)。将来,这两个层次都可以轻松扩展到其他生态系统。从用户的角度来看,我希望PingCAP将TiDB从数据库扩展到分布式存储生态系统。

HTAP在单个TiDB集群中非常高效。它提供了强大的一致性和资源隔离性,并消除了在不同数据库之间复制数据的过程。工程师可以编写代码而不必担心导入和导出数据。

但是,当您有多个TiDB集群时,情况会有些棘手。尽管TiDB提供了水平可伸缩性,但它不支持多租户。当前,由于应用程序和维护要求(例如备份和还原),公司不太可能将所有数据放在单个TiDB集群中。因此,如果OLAP请求所需的数据跨多个群集存储,则用户仍然必须将多个群集中的数据加载到处理OLAP请求的数据库中,这同样是导入和导出数据的麻烦过程。

一种解决方案是在TiDB群集之上添加类似于Google F1的层。在统一的F1层下,有多个TiDB集群。每个群集都是一个与其他群集完全隔离的租户。 F1层管理元数据,路由读取和写入请求,并跨集群处理OLAP请求。

另一个公式是在存储层中添加租户管理。每个租户对应于一组存储节点。在此体系结构中,租户隔离在存储层中,并且计算层可以处理跨租户OLAP请求。

简而言之,这是一个关于在存储层中隔离资源并在计算层中提供统一视图的问题。我期待看到TiDB将如何跟进此事。

HTAP数据库的PingCAP实现很好地解决了长达数十年的冲突:如何在单个数据库中处理两种类型的查询。他们的论文不仅提供了理论上的依据。它准确地显示了他们如何实现数据库,并通过可靠的测试来备份他们的声明。

作为行业中描述分布式HTAP数据库实现的第一篇论文,TiDB的论文证明了基于Raft的分布式HTAP数据库是可以实现的。它可以加快分布式HTAP数据库的开发和采用。在这方面,它是一个里程碑。