写在前面
这篇paper是老板推荐给我看的,感觉对在TP和AP之间徘徊的工程师们具有很好的指导意义,因此细读一遍,并进行翻译,并分享给大家。本文非原创,是对于论文的理解和翻译,有不正确的地方,请指正。
摘要
大规模实时分析应用越来越火(主要应用在实时库存/定价,移动应用程序推荐,欺诈检测,风险分析,物联网等)。 这些应用场景,需要存在一个既可以快速处理大量并发事务(OLTP)又能够支持对最近数据的分析(OLAP)。有时还需要在事务中进行一些OLAP的操作。但是OLAP和OLTP的优化手段和架构设计是完全不同的。对于需要同时处理OLAP和OLTP的数据管理系统,Gartner将其定义为:混合交易/分析处理(HTAP)系统。许多HTAP解决方案都来自于对大规模实时数据分析应用行业的工业或者学术探索。这些解决方案中有些是单独的系统解决方案,有些则是以松耦合的方式混合搭配使用OLTP数据库、NoSQL系统和如Spark一样的大数据平台。本文的目的就是:
1)快速回顾OLTP和OLAP系统的历史进展
2)讨论HTAP的驱动因素
3)对现有和新兴的HTAP解决方案进行深入的技术分析,详细介绍关键的架构差异和权衡取舍。
1. 简介
本文,我们将会分析现有的新兴HTAP(混合事务和分析处理)解决方案。 HTAP是由Gartner创造的术语,用于描述可在单个事务中同时支持OLTP(联机事务处理)和OLAP(联机分析处理)的系统。但是即使在OLAP与非事务性插入混合使用的解决方案中也被广泛使用。这些系统中,有一些系统能够对最近的数据运行分析查询,而其他系统在查询最新数据则存在一定的延时。
要理解HTAP,我们首先需要研究OLTP和OLAP系统以及它们的发展历程。关系数据库已被用于事务处理和分析很长时间。但是,OLTP和OLAP系统具有非常不同的特性。 OLTP系统的主要特点是:支持单条记录插入/删除/更新,并且可以利用索引进行快速的点查询。而索引是OLTP系统的核心,没有索引,人们根本不会去使用OLTP系统,因为性能太差。而OLAP系统主要用于批量更新,并且经常需要进行全表扫描。对OLAP系统的执行插入通常通过ETL(提取、转换、加载)系统来完成,ETL系统将事务数据从OLTP系统整合、转换并最终加载到OLAP环境,用于后续分析。
Stonebraker [34]针对多种专业性系统进行了长期的研究、讨论,并产生了大量的优秀和具有创意的论文,在这之后,数据库领域出现了大量专门的面向列的OLAP系统,如BLU [30],Vertica [23],ParAccel,GreenPlumDB,Vectorvise等。还出现了很多基于内存的OLTP系统,包括VoltDB [35],Hekaton [13],MemSQL [24]等。驱动数据库引擎变革的主要动力就是现代硬件的进步。第二代OLAP和OLTP系统更好地利用了多核,多级内存缓存和大量的内存。
与此同时,在过去十年中,新一代应用推动了许多大数据技术的爆炸式增长。 以Voldemort [32],Cassandra [8],RocksDB [31]为代表的NoSQL或键值存储提供了快速插入和查找,以及非常高的扩展性,但对Query语句的支持有限,并且只提供比较低的事务保证(参见Mohan的教程[25]);还有许多SQL-on-Hadoop [10]的产品,包括:Hive [36],Big SQL [15],Impala [20]和Spark SQL [3],它们提供大数据的分析功能,仅关注OLAP查询,但是不支持事务。虽然所有这些系统都支持对文本和CSV文件的查询,但它们的重点都放在列式存储上,如ORCFile [27]和Parquet [1]。
近几年,出现了越来越多的实时分析产品。此外,移动和物联网领域也已经产生了新一代的应用程序,这些应用程序会采集大量数据,它们在短时间内产生大量数据,并且需要实时分析。各大企业也正在大力推动对数据更加实时的分析以提高其竞争力,因此他们需要能够尽快对其运营数据进行分析。
现在有很多组织和机构都在研究如何在在大数据集上提供HTAP解决方案。在本文中,我们会快速的对不同的技术的发展历程进行说明,并且讨论当前的各种HTAP解决方案。我们将研究当前HTAP解决方案的不同架构,比较不同解决方案的优势和劣势。从不同的技术维度对这些解决方案进行分类,并且对几个解决方案进行说明。最后,我们将讨论实现一个真正的HTAP系统所面临的挑战,其中单个事务可以包含插入/更新/删除语句,也可以包含复杂的OLAP查询。
2. HTAP 解决方案: 设计选型
目前已经形成了多种HTAP的解决方案。本章将会分别介绍工业界和学术界的多种实现方案,并说明各个方案之间的不同权衡和抉择。 HTAP系统必须要做出的主要设计决策之一是:是否对OLTP和OLAP请求使用相同的引擎。
2.1 针对OLAP和OLTP采用同一个引擎
传统的关系数据库(例如,DB2,Oracle,Microsoft SQL Server)通过使用单一的数据组织方式(主要是行存储)在一个引擎中同时支持OLTP和OLAP。但是,这种方式对于OLAP和OLTP的性能都不是很好。因此,遵循the one size doesn’t fit all[34]的原则,过去十年中,利用现代硬件(更大的主存储器,多核等)的进步,分别针对于OLTP和OLAP的专用引擎大行其道。大量的工业界和学术团体使用内存优化的行存储(例如,VoltDB [35],Hekaton [13],MemSQL [24], Silo [37],...)和列存储(例如,MonetDB [7],Vertica [23],BLU [30],SAP HANA [14],...)分别专门用于OLTP和OLAP。这些系统脱离传统的关系数据库的编码和开发模式,从头开始构建更精简的引擎。这些系统一开始针对一种类型进特定开发和优化,后来再开始添加对其他类型的支持以支持HTAP。这些系统的区别主要在于其数据组织的形式。
2.1.1 针对OLAP和OLTP采用不同的数据存储格式
SAP HANA [14]或Oracle的TimesTen [22]的引擎主要针对内存中的列式处理进行了优化,这种优化更有利于OLAP。这些系统还支持ACID事务。但是,他们使用不同的数据组织进行数据提取(逐行)和分析(列式)。相反,MemSQL [24]的设计初衷是用于内存OLTP可扩展的引擎,但现在它也支持快速分析查询。它以行格式摄取数据,并以行格式保存数据的内存部分。但是将数据写入磁盘时,会将其转换为列式格式以便更快地进行分析。同样,IBM dashDB [11]也是传统行存储向HTAP系统的演进产品,分别用于OLTP和OLAP工作负载的混合行和列数据组织。
另一方面,HyPer [19]从一开始就旨在使用一个引擎同时支持AP和TP。最初它使用行式存储同时支持OLTP和OLAP,现在它还提供了列式存储来保证OLAP的高效性。
最后,最近发起的学术项目Pelaton[28]旨在构建一个自研的内存HTAP系统。该系统提供自适应数据组织结构[4],它能够根据请求的类型在运行时自动更改数据格式。
所有这些系统都需要将数据在行式和列式存储之间不停的转换从而分别满足TP和AP的需要。由于数据存储格式之间的转换,最新提交的数据可能无法立即用于分析查询。
2.1.2 针对 OLTP 和 OLAP采用相同的数据存储格式
学术项目H2TAP [2],该项目旨在构建运行在异构硬件并且能显著提高单节点硬件使用率的HATP系统。该系统对TP和AP只提供一种数据存储格式:行存储。
在SQL-on-Hadoop系统中,还有HTAP解决方案可以扩展现有的OLAP系统,并能够更新数据。从版本0.13开始,Hive在ORCFile(列式存储)的行级[18]引入了事务支持(insert,update和delete)。但是,主要还是更新维度表和流数据摄取。 Impala [20]与Kudu [21]的集成也可以同时支持SQL-on-Hadoop引擎的事务性更新和删除以及OLAP。
由于这些系统不需要从一种数据存储格式转换到另一种数据格式以同时支持TP和AP,因此OLAP查询可以读取最新提交的数据。但是,它们可能面临传统关系型数据库所面临的相同问题。这些系统没有同时最适合AP和TP的数据存储方式。因此,对于列式存储的数据,他们可能会依赖于批量请求处理的方式来实现快速事务处理。对于行式存储的数据进行AP的时候,性能可能不是太好。
2.2 采用不同引擎的OLTP 和 OLAP 系统
此类系统可以根据他们底层数据的存储方式:是否为OLAP和OLTP提供相同的存储方式,进一步进行区分。
2.2.1 分别为OLTP 和 OLAP提供不同的存储格式
许多应用程序将单独的OLTP系统和OLAP系统松耦合的集成在一起以提供HTAP服务。应用程序负责维护这套混合架构。 通过标准的ETL过程将OLTP系统中的数据周期性地同步到OLAP系统中,当然这时OLAP中的数据已经不再是最新数据了。实际上,这种做法在大数据领域中非常普遍,应用程序使用类似Cassandra这样的快速键值存储来进行OLTP,并将其中将Cassandra中的数据ETL到HDFS上的Parquet或ORC文件中,以支持SQL-On-Hadoop系统的查询(OLAP)。因此,OLAP系统可以查询的数据与OLTP系统看到的数据之间存在一定的滞后性。
2.2.2 为OLTP 和 OLAP提供相同的存储格式
一些数据库供应商通过将传统产品与Spark生态系统相结合实现了大规模HTAP。 SAP HANA Vora [16]就是一个例子。在HANA Vora中,事务处理通过HANA执行,而分析请求由Spark SQL处理,子查询下推到数据库。最近开发的几个数据管理引擎也采用了类似的方法。例如,SnappyData [26]使用事务引擎GemFire来支持OLTP并利用Spark生态系统进行OLAP。
诸如HBase [17]和Cassandra [8]之类的键值存储的优势在于快速更新。由于其缺少OLAP功能,键值存储通常与SQL-on-Hadoop引擎一起使用。在这种方法中,键值存储系统和SQL-on-Hadoop引擎看到的数据是完全一样的,这要求SQL-on-Hadoop系统能直接查询键值存储中的数据。目前已经开发了许多对现有SQL-on-Hadoop系统的扩展来实现这种集成。通过使用类似于Spark SQL中的Data Source API:Spark HBase连接器[38]和Spark Cassandra连接器[12],Spark SQL可以直接查询HBase和Cassandra数据。这种方法的主要缺点就是性能较差。每次查询(通常是分析查询)都需要扫描大量数据(通常是分析查询)。
另一种方法,SQL-on-Hadoop系统如:HIVE [36],Impala [20],IBM Big SQL [15]和Actian VectorH [9],使用HBase作为可更新的存储引擎来存储那些需要频繁更新的表。用户可以将事务更新和分析请求发送到SQL-on-Hadoop系统中的同一接口。这些发送给HBase表的请求在底层统一由HBase的处理引擎执行。
像Splice Machine [33]和Phoenix [29]这样的系统在HBase之上提供了一个SQL层。通过这些系统还可以对存储在HBase表中的数据进行事务性更新和操作,而这些所有的操作均依赖于HBase。 Splice Machine甚至还支持ACID事务。由于直接对HBase表扫描效率低下,因此无论是直接访问HBase表的SQL-on-Hadoop系统还是Splice Machine或者Phoeni在进行OLAP的时候性能都比较差。 由于HBase是专门为快速插入和单记录查找而设计的。因此基于HBase之上构建的SQL引擎的OLAP查询性能都会比较差。
Wildfire [5]是IBM Research最近发起的一个项目,它构建了一个HTAP引擎,在wildfire中数据采用Parquet [1]列式存储。并且OLAP和OLTP的请求统一在Parquet存储的数据上进行处理,因此Wildfire可以立即对最新写入的数据进行分析。 Wildfire还利用Spark生态系统实现大规模分布式分析。通过Spark SQL接受OLAP请求,并尽可能地下推到Wildfire引擎。
此类系统中,由于OLTP和OLAP共享相同的底层存储,因此最新提交的事务(对数据的修改)可被立即用于OLAP。
3. 实现HTAP的正确方式
在给出答案之前,我们需要首先明白HTAP以及HTAP用户在今天仍然面临的一些挑战。
虽然有许多系统都将自己标榜为HTAP解决方案(如第2节所述),但它们都没有真正地支持HTAP。现有的解决方案确实提供了一个可以同时支持OLAP和OLTP的平台。但是,现有解决方案都不能同时高效执行OLAP和OLTP。为了完全支持HTAP,系统不仅应该在TP之后进行AP,而是应该可以在一个请求中同时处理TP和AP。
此外,如今大多数HTAP解决方案都使用多个系统和产品来提供所有所需的功能。但是这些不同的系统和产品通常由不同的人群维护。因此,保持这些组件的兼容性并为最终用户提供单个系统的错觉确实是一项具有挑战性的任务。
最后,索引分布式的数据并在大规模集群中进行高效的点查询之间存在一定的矛盾性。此外,大多数这些系统都部署在公共云或私有云上,这些云使用对象存储以及HDFS等共享文件系统。需要细粒度索引才能实现高效的点查找和更丰富的OLTP。快速OLTP引擎将索引保留在内存中,但是对于大规模数据和HTAP来说,这些索引不能仅保留在内存中。可以只缓存最频繁访问的数据的缓存,以降低索引数据的访问成本。但是,大规模分布式OLAP系统使用主要针对扫描进行优化的共享文件系统和数据存储方式,这些系统和存储方式不能快速访问单个行或列。对这些共享文件系统和对象存储的快速点访问仍然是一个未解决的问题。