追寻终极数据库 - 事务/分析混合处理系统的交付挑战 (3)

挑战:支持多个存储引擎

如下内容并非新发现:行优化存储适用于OLTP和运营工做负载,而列存储适用于BI和分析工做负载。频繁写入的工做负载适用于行式存储。对Hadoop而言,Hbase适合低延迟工做负载,列式ORC文件或Parquet适合BI和分析工做负载。业界(尤为是内存数据库厂商)宣称:列结构能够很好地为各类工做负载服务。实际上,当相同的数据结构用于处理不一样访问模式的工做负载时,一般存在性能折中。Cloudera承诺的Kudu存储引擎将能知足混合工做负载的要求,但它明确指出,低延时性能低于HBase,BI和分析工做负载性能低于Parquet。数据库

NoSQL技术革新已经代表,为了知足当今工做负载的不一样需求,支持多种数据模型是颇有必要的。可是,为了减小数据的复制和移动,理想方案是单个查询引擎能够支持多个存储引擎。数据能够驻留在数据结构/存储引擎中,对于所需的数据访问模式而言,这种状况是最理想的,并且查询引擎能够透明地支持全部这些操做。为此,Hive、Impala、Drill、Spark、Presto和其余SQL-on-Hadoop解决方案支持多种数据结构。可是,这些查询引擎还不支持OLTP或运营工做负载。缓存

问题不只在于存储引擎没法服务于多种工做负载,并且查询引擎也难以支持多个存储引擎。为了支持混合工做负载,可能须要将数据从一个存储引擎转换和迁移到另外一个存储引擎,但这存在许多挑战,接下来咱们讨论其中某些挑战。安全

统计

如前所述,为了生成优良的查询计划、或理解工做负载是运行型或分析型,咱们须要统计信息以支持全部类型的查询工做负载。所以,当添加新的存储引擎时,您还须要添加对收集统计信息的支持功能。存储引擎有高效机制来对行进行抽样吗?经过增量统计,计算它是否有一个简单的方法来查询新的数据?它是否收集行数和其余可用于快速统计收集的指标?为了使查询引擎决定什么时候对其统计信息作另外一次更新,它是否收集增删改查记录的计数量?您须要回答诸如此类的一系列问题来设置对统计数据的收集,与存储引擎高效地工做。服务器

键结构

对于运营工做负载而言,键入访问对亚秒级响应时间很是重要。单行访问须要经过键进行访问。因为事务或事实表老是具备多列键,理想状况下,键值应支持多列键。若是不支持多列键,则查询引擎须要将多个主键列映射到单个存储引擎键。此外,较短的运营查询一般须要汇集访问来检索少许行。汇集键的范围扫描有助于运营工做负载知足服务级别协议(SLA, Service Level Agreements)。为了实现最高效的访问,查询引擎须要了解存储引擎可用的键入访问选项,并为其支持的每一个存储引擎优化此访问。网络

分区

对于查询引擎而言,了解存储引擎如何跨磁盘和节点对数据进行分区,这一点很是重要。它是否支持哈希和/或范围分区,或这些分区的组合?如何肯定这种分区?为了平衡各个分区的负载和避免性能瓶颈,查询引擎是否须要对数据进行加盐(salt data)?若是须要,如何添加一个加盐键(salt key)(例如,表格键的最左边的列)而且仍然避免全表扫描?当集群在扩展或收缩时,存储引擎是否从新分区或从新平衡分区,或者由查询引擎来执行此操做?在对数据从新分区时,用户可能须要全盘读取和写入,因此这可能会变得很是复杂。若是查询引擎将对来自这些分区的数据执行并行处理,那么数据如何在分区间进行传播是很是重要的。它须要尝试将访问本地化,减小数据的再分区(也称为shuffle),或尽量多地跨节点分布数据。在未理解存储引擎的键和分区结构的状况下,不可能有效地处理查询数据。运营查询可能不会常常遇到并行处理数据的一些挑战,可是,如何对数据进行分区将影响是否能经过访问单个分区、磁盘或节点来处理快速运营查询,而没必要经过访问多个分区来知足具备严格服务级别的目标。数据结构

数据类型支持

查询引擎须要了解存储引擎支持哪些数据类型,以及存储引擎对这些类型实施的约束条件,以便查询引擎能够执行存储引擎不会执行的任何约束条件。例如,在某些状况下,若是存储引擎只支持字符串存储,那么查询引擎最好将数据存储在本身的编码数据类型中。或者,若是查询引擎会强制执行CHECK限制条件,那么它是否能够将CHECK约束转包给存储引擎,或由查询引擎来执行它们?固然,存储引擎通常不会支持引用约束检查。
若是存储引擎能提供完整的字符集支持,那么存储引擎和查询引擎便能经过UTF-8进行通讯;排序规则也是如此。并发

存储引擎是否提供压缩或加密支持,或由查询引擎提供上述支持?查询引擎极可能发出DDL语句(建立表格),它还需了解哪些选项用于数据块级别压缩和键压缩,以及须要向用户公开的其余表结构选项。在一些状况下,可能会将存储引擎表格映射到表的查询引擎视图。框架

投影和选择

大多数存储引擎支持投影,存储引擎只返回须要的列,不然查询引擎必须解压数据并进行投影。一样,须要了解存储引擎是否能够提供谓词求值的能力。 存储引擎可以为哪些谓词(=、<、>、<>、between、LIKE)求值?它能在多列上评估谓词或评估多列谓词((a,b)>(5,1))吗?它能处理IN列表吗?支持多长IN列表?通常来讲,它是否能处理ORs和ANDs的组合以及能处理何种复杂级别?它能自动肯定应用谓词的最有效的顺序(例如,首先评估能最大程度减小基数的列上的谓词,尤为是当存储引擎为列式存储时)吗? 它能处理涉及同一表格的多个列的谓词(例如,c1>c2)吗?除了文字,能处理字符串表达式(STR(c1,3,2)='10')或日期和时间表达式吗?这些表达式有多复杂?存储引擎如何处理缺省或缺失值(NULLs)?查询引擎须要了解存储引擎的全部这些方面,以肯定下推哪些谓词到存储引擎、哪些谓词由查询引擎评估。机器学习

内存价格的降低让咱们能为每一个节点配置大量的内存,非易失性存储器的普遍使用也即将实现。为了访问事务和分析工做负载的数据,存储引擎不只在内存中设计高效的结构,并且正在实施使投影和选择等操做更高效的技术。存储引擎利用L一、L2和L3 CPU高速缓存来处理数据,其速度甚至比主存储器处理数据的速度更快。经过矢量化方法同时处理多组行/列的数值,并提出其余的创新方式,例如,最小化或消除序列化/反序列化的成本,最大程度地提升数据处理速度的同时最大限度地利用硬件设施。这样,瓶颈将从磁盘移动到主内存,最终移动到CPU。高效地使用CPU很是重要,查询引擎必须挖掘存储引擎的效率,并尽量地减小CPU使用率。函数

可扩展性

为了在存储引擎/服务器端实现更多功能,一些存储引擎能够运行用户自定义的代码(例如,在HBase上的协处理器、前触发器或后触发器),从而减小信息流量开销并提升效率。

例如,若是优化器能将聚合下推到存储引擎,则它可能有处理积极聚合的能力。当数据在GROUP BY列汇集或分组数目较小时,该方法极为有效。若是存储引擎不支持该操做,则查询引擎能使用协处理器来执行相同操做。能够在此层级执行具备表达式和函数的复杂谓词求值、并发链接和索引维护、安全执行和某些ANSI触发器操做,甚至事务支持。

安全执行

安全处理是查询引擎和存储引擎之间的信息交互点。存储引擎可能有本身的底层安全实现方式,若是它能良好地与SQL模型进行集成,则查询引擎可使用它。不然,在细粒度访问控制的状况下,查询引擎必须管理schema、表、列和行的权限。它可能须要将本身的受权框架与存储引擎的受权框架进行集成(甚至映射)。考虑到其余安全问题,例如,Hadoop安全解决方案(Sentry或Ranger管理这些对象),查询引擎须要与该安全框架进行集成。根据对安全日志及其余安全信息和事件管理(Security Information and Event Management, SIEM)功能的支持,查询引擎必须能与存储引擎和平台功能进行集成,或自身提供相关功能。对于混合事务/分析处理(Hybrid Transaction / Analytical Processing,HTAP)而言,因为可能须要支持多个存储引擎,这将变得更加复杂。

事务管理

假设一个存储引擎提供某种级别的高可用复制、备份和恢复以及某种级别的多数据中心支持。可是,事务性支持能够彻底不一样。事务管理具备ACID模型(原子性 [Atomic]、一致性 [Consistent]、隔离性 [Isolated] 和持久性[Durable])以及BASE模型(基本业务可用性 [Basic Availability]、柔性状态[Soft-state] 和 [Eventual consistency])。根据搜索引擎提供的支持,查询引擎可能须要提供完整的多行、多表格和多语句的事务支持,任一时间点的在线备份和事务一致性恢复,以及为多数据中心提供双活同步更新和最终一致性的支持。查询引擎须要与预写式日志和存储引擎的其余机制集成,以便利用引擎的底层复制和其余高可用性功能。这些能够具备很大差异,例如Cassandra、HBase或Hive,它们各自都有本身的事务模型。

此外,回到存储引擎功能的可扩展性(例如,HBase的协处理器),查询引擎须要实现此事务功能,尽量地与查询引擎接近并进行集成,以得到可分布和最佳性能。不然,它最终只是一个更通用的、而不是可扩展的和高效的实现方式。

元数据支持

查询引擎须要为正在支持的存储引擎表添加元数据支持。存在可能映射(例如,目录、名称、位置和数据类型映射);针对存储引擎的特定扩展选项(例如,压缩选项);支持多列族 – 例如,将数据分区选项映射到底层存储引擎结构(例如,Hbase regions)等。当有人在外部更改存储引擎表时,如何更新该元数据?或者如何将其标记为无效,直到有人修复了差别?

实际上,若是数据库能访问外部存储引擎,那么须要处理大量不可预知的问题,例如,如何保证事务一致性和数据完整性?若是列中的数据与其应该具备的数据类型不一致、或包含无效数据(可能它已经过其余方式更新),那么查询引擎应如何操做?此外,您是否容许在此类表格上建立二级索引、视图、限制条件和物化视图等?上述状况不只须要提供元数据支持,并且必须解决可能由外部访问引发的潜在的不一致性问题。

运营工做负载与BI和分析工做负载所需的元数据支持存在差别。例如,运营功能须要参照完整性、触发器和存储过程,而BI不须要;运营工做负载不太须要物化视图。

性能、扩展和并发性考虑事项

查询引擎为了支持HTAP负载,在和不一样的存储引擎集成时,需考虑不一样存储引擎的性能、扩展性和并发性等关键因素。例如,是否有可用的批量加载机制,以及它在此类加载期间对事务一致性和可用性有什么影响?是否支持批量插入,从而能够有效地进行大量插入操做?批量提取功能是否可用,以在每一个缓冲区返回行集,而不是一次返回一行的接口?是否有更快的扫描选项(例如,快照扫描)?当查询引擎了解将会扫描大量数据时(多是针对数据抽取或大型复杂查询),能请求预取大块数据吗?查询引擎如何进行并行更新和访问存储引擎?若是查询引擎支持执行进程进行并行查询,那么它如何最高效地访问存储引擎文件/分区和区域?存储引擎能支持什么级别的并发访问?查询引擎如何最高效地利用存储引擎所支持的功能和填补其不支持的功能?这些都很难肯定,更难以实现。

错误处理

查询引擎可能须要支持HTAP,所以,每一个存储引擎的错误处理方式也不相同。存储引擎提供的错误处理机制是什么?如何记录这些错误?存储引擎记录错误吗?或者查询引擎须要解释每种错误类型并记录它吗?须要向用户提供某些重大错误消息和补救指导吗?

其余运营考虑事项

除了前文提到的错误处理,还须要考虑其余方面。例如,HBase的合并或拆分问题。这些对性能和用户工做负载很重要,对事务工做负载的影响更大。如何经过查询引擎管理这些以提供最佳客户体验?

简单地说,支持存储引擎并不是一项简单任务。固然,您能够走捷径,例如,支持 InputFormat或OutputFormat;甚至使用UDF或某些链接器技术来使查询引擎与存储引擎进行通讯。但要真正集成存储引擎,让其发挥最佳性能,并提供最高效的并行处理,须要投入大量的努力。若是您须要支持多个存储引擎,以获取在多个存储引擎之上的查询引擎的终极数据库,这是很是困难的。

IT行业齐心合力共同为查询引擎建立标准接口,例如,Java数据库链接(Java Database Connectivity, JDBC)和开放数据库链接(Open Database Connectivity , ODBC)。若是不一样的存储引擎能为查询引擎提供通用的接口,这将是一件很是好的事。查询引擎能经过接口快速省力地识别存储引擎的能力,再与存储引擎进行集成,并充分利用存储引擎的功能。若是能实现这个目标,IT行业将会到达发展的成熟阶段。但目前来看,各类存储引擎的API及其功能并不统一。

虽然某些挑战看起来与数据联邦引擎必须应对的挑战极为类似,但不一样的是,查询引擎使用标准JDBC / ODBC接口与数据联邦引擎链接,即将查询转包至另外一个查询引擎。这种抽象层次与更深层次的集成不一样,更深层次的集成能大幅提升效率和性能,它用于查询引擎和存储引擎之间。试想将一个专有RDBMS,例如,将Oracle拆分红一个查询引擎和一个存储引擎,该方法与联邦引擎链接至Oracle实例的过程不一样。

挑战:适于全部工做负载的相同数据模型

正如IT行业的许多其余模糊术语同样,data model这个术语包含不少不一样的含义。在RDBMS背景下,数据模型(data model)是实现的规范化级别。用于运营工做负载的数据是从第一范式到第六范式。对于BI和分析工做负载使用的历史数据,您须要不一样的数据模型,例如,星型schema或更复杂的包含维度表和事实表的雪花schema等。数据模型截然不同,以适应在OLTP和运营查询中的不一样访问模式,这些访问模式侧重于特定实体,(例如,客户、订单、供应商和产品),而不是侧重于BI或分析查询的大量历史数据。

HTAP是否无需描述数据模型?一些内存数据库供应商声称已经达到这种效果,但还没有撰写出任何性能基准报告——人工(TPC)或真实世界——即BI和分析工做负载在第三范式中性能良好。如今,尚未任何数据代表OLTP /运营系统能在星型schema中表现良好,无论是内存数据库仍是非内存数据库。除了基准外,性能还由客户运行的工做负载的种类决定,这些工做负载与TPC基准不一样,甚至不存在一点交集。

所以,您明白存在必定级别的数据重复、转换、聚合以及从一个数据结构、数据模型和存储引擎到另外一个数据结构、数据模型和存储引擎的移动,并且您但愿查询引擎能将全部都无缝集成。虽然这很难,但仍是能够实现。然而,彻底不一样的是,您不须要复制、转换、聚合或移动数据,也不须要为任何工做负载下降性能。随着Kudu的问世,Cloudera但愿市场上有须要单一数据副本、愿意下降高端运营和分析性能的需求,即为了提升设计、开发和运营简单性,他们愿意下降性能。最终结论尚待分晓,可是,若是IT行业在积极地追寻了NonSQL若干年后,又将钟摆摇回预期方向,这将很是有趣。现在,性能扩展和高并发不只是一项要求,而是惟一要求。

可是,如前所述,数据模型(data model)有不一样的定义:键值、有序键值、Bigtable、文档、全文搜索和图形数据模型。为了实现单个存储引擎的终极数据库,人们试图让这些数据模型处理它们原本不擅长的业务,从而充分挖掘它们的潜力。所以,文档中的整个父-子关系代表再也不须要RDBMS功能,而且文档的存储能知足全部工做负载要求。或者,如今是图形数据库的时代吗?咱们是否能够在边缘和顶点中填充各类参数以支持各类工做负载?事实上,即便每一个数据模型确实解决了某些问题,但它们并不能独立地支持当今企业须要解决的各类工做负载。

文档功能、文本搜索(必要时)、图形结构(须要快速访问的层级或网络类型关系)、支持半结构化或非结构化数据的基于键值的模型,和彻底结构化的关系数据库能针对不一样需求给出不一样的使人满意的结果。尽管一些查询引擎全力支持,但挑战是有效地将存储引擎与查询引擎进行集成。另外,为其余数据模型加入标准SQL API(实际上它并不是标准,由于每一个数据库有它特有的实施方式)和非标准API,这也是一项挑战。

不管您怎样理解“数据模型”一词,若是HTAP以相同的查询引擎来支持全部企业工做负载的多个(非所有)数据模型,那么它须要克服许多挑战。

挑战:企业级能力

大企业开始将BI工做负载扩展至分析工做负载,再扩展至高级分析引用(例如,数据挖掘和机器学习),他们最初在专有数据库和平台上运行BI和分析工做负载,在Hadoop上运行大数据的其余工做负载。但随后许多企业将某些在专有数据库中运行的部分工做负载迁移至Hadoop上运行,一些企业正在提供运行全面的RDBMS OLTP和在Hadoop上运行运营工做负载的能力,从而将工做负载类型向混合事务型和分析模型扩展。但要真正处理全部工做负载,包括关键任务工做负载,则HTAP数据库引擎须要提供企业级能力,咱们将在如下部分对此进行讨论。

高可用性

对任何数据库而言,可用性是一项重要指标。例如,您能够经过HBase获得99.99%(也被称为“4个9”)的可用性,即每一年有约52.56分钟的非计划停机时间。许多关键任务应用都努力实现99.999%(也被称为“5个9”),即每一年5.26分钟的停机时间。固然,可用性所增长的成本多是巨大的。如今的问题是:查询引擎与存储引擎结合在一块儿,能提供何种程度的高可用性?

一般,数据库很难实现高可用性。若是想要实现,须要解决如下问题:

  • 当须要读写数据,在不能停机的状况下,您能将底层OS、Hadoop发行版、存储或查询引擎升级至新的软件版本吗——即,支持滚动更新吗?
  • 您能够将数据从新分配到已添加进集群的新的节点或磁盘吗?或合并它们以减小节点或磁盘(彻底在线,不停机)?与此相关的问题是从新分区数据的能力。您是否能在线完成?在线意味着在操做期间仅读取数据、或同时读取和写入数据。
  • 能在线为数据库更改DDL吗?例如,在不影响读取和写入的前提下,更改列的数据类型?数据库能容易地添加和删除非键列。
  • 能在线建立和删除二级索引吗?
  • 支持彻底和增量在线备份吗?

您的应用程序须要上述哪些功能取决于运营和分析工做负载的混合程度,以及高可用性对这些工做负载的重要程度。

安全

运营和分析工做负载的安全实现不一样。对运营工做负载而言,一般在应用程序层管理安全性。应用程序与用户交互,并管理数据库的全部访问。另外一方面,BI和分析工做负载能使最终用户经过报告和分析工具直接访问数据库。在这种状况下,可能会将受权推送至数据库,查询和存储引擎须要管理安全性。

集成到SIEM系统也适用于分析工做负载,但不少运营工做负载须要更高程度的安全控制和可见性。

可管理性

管理数据库及其工做负载的能力很是重要。从图1-9中能够看出,可管理性须要不少功能,也许仅能实现部分功能

clipboard.png

图1-9 数据库管理任务

因为HTAP工做负载的混合特性,某些管理任务变得愈来愈具挑战性,特别是工做负载管理。衡量OLTP或运营工做负载时每每须要考虑事务或人机交互的能力。该理念是根据每秒完成的事务来评估服务水平目标。因为此类事务的延迟可能很小,因此跟踪每一条SQL语句的性能或每一事务的表现成本将很是高。所以,您须要以某个时间间隔来统计信息并计算出平均值。而BI和分析适用于报表或查复杂查询,这些查询一般耗时较长,它们采集自身的运行指标值,并基于查询级别统计信息进行监视和管理,以达到良好的性能。

根据优先级和/或资源分配,混合工做负载很难达到SLA的要求。分析工做负载的随机特性使其不能很好地融入运营工做负载,即便在负载峰值期间,运营工做负载也要求亚秒级的响应时间。

若是查询引擎正在与不一样的存储引擎进行集成,那么得到全部的运行指标也具挑战性。虽然查询引擎能够跟踪一些指标,例如,存储引擎服务一项请求所花费的时间,但可能没法查看底层存储引擎正在使用的资源。另外,很难在查询引擎和存储引擎之间细分出重要的CPU、内存和I / O指标以及诸如队列长度和内存交换等信息,例如,若是您想得到操做符(用于查询计划的每一步,例如,扫描、链接和聚合等)和被访问的表在查询中所使用资源的详细信息,特别是并发执行和表被分区时,这将是一项很是困难的工做,除非利用插桩和回调函数收集端到端信息。再例如,如何找出遇到数据倾斜或瓶颈的缘由?

在不久的未来,不一样类型的工做负载可能在单个平台上运行,但这篇报告并无详尽列举出与企业级运营能力相关的全部挑战。例如,与YARN或Mesos的集成,它们会尽量考虑如何管理跨集群的不一样应用工做负载的资源。但愿这些能帮助您理解目前的挑战。

相关文章
相关标签/搜索