关于比较Hadoop中的存储格式:让我们从ORC开始

Hadoop包含可与各种格式的文件一起使用的产品。 我已经反复搜索,阅读并考虑过哪种格式更好。 当我相对随机地遇到ORC格式时,我变得感兴趣,阅读(甚至有点爱抚),这就是我的理解-比较这样的格式是不正确的。 更准确地说,我认为它们通常以不正确的方式进行比较。 实际上,有一篇关于此的文章,以及关于Apache ORC格式(在技术上)及其提供的机会的文章。


我将从一个问题开始:一个由1万行(每行两个整数字段)组成的关系表的大小(以字节为单位,非常近似)是多少? 通常他们在这里放一个小桶,答案放在小桶下-我在这里回答:628个字节。 并且细节和历史将在猫的控制下转移。


一切的开始:我建立了一个用于与Apache ORC一起使用的库(请参阅项目主页-https: //orc.apache.org ),并编译了自己的有关编写ORC的示例(打扰您了-我们从可行的方法开始) ,其中有2个字段和1万行。 我启动了它-我收到了orc文件,因为我是在办公室外的某个地方完成的-为了以防万一,我将库和文件重写了到闪存驱动器中(急着-我没看大小,我认为闪存驱动器可以处理它)。


但是我以某种方式迅速地做出了回应……我看着大小-628字节。 我以为这是个错误,我坐下来开始理解。 我启动了用于从同一编译库中查看ORC的实用程序-文件的内容表明一切都是诚实的-1万行。 在那之后,我想知道一万行可以容纳到628个字节中(当时我已经对ORC有所了解,并且意识到还存在元数据-格式是自给自足的)。 了解,分享。


关于ORC格式


图片


在这里,我将不重复有关格式的一般性文字-参见上面的链接,该链接写得很好。 我将从上面的图片中以出色的形式关注两个形容词(该图片来自项目的主页):让我们尝试弄清楚为什么ORC是“最快的”和“最紧凑的”。


速度


就数据而言,速度可能会有所不同-至少是读取或写入的速度(您可以更深入地了解,但现在让我们停下来)。 由于上面的标语中明确提到了Hadoop,因此我们将主要考虑读取速度。


要从ORC文档中引用更多信息:


它针对大型流读取进行了优化,但具有集成支持,可快速查找所需的行。 以列格式存储数据使阅读器仅可以读取,解压缩和处理当前查询所需的值。

我会翻译一点:


  • 优化格式以流式读取大量内容
  • 同时包含对必要行的快速搜索的支持
  • 允许您仅读取所需的数据

尺码


没有报价,我会用自己的话说


  • 格式可以最佳地存储元信息
  • 在流式读取速度和紧凑型存储之间取得平衡
  • 内置支持,以最紧凑的方式存储列值

提供机会


我想提请您注意上面引号中的措辞:“针对...进行了优化”,“包含支持...”,“允许您阅读...”-文件格式作为一种编程语言,是一种手段(在这种情况下,请确保有效存储和访问数据)。 存储和访问数据是否真正有效不仅取决于该工具,还取决于谁使用它以及如何使用它。


让我们看看该格式提供了哪种格式,以提高速度和紧凑性。


列存储和条带


ORC中的数据以列的形式存储,首先会影响大小。 为了确保流式读取的速度,将文件分为所谓的“条带”,每个条带都是自给自足的,即 可以分别读取(因此可以并行读取)。 由于存在条带,文件大小将增加(非唯一列值将存储多次-在出现此类值的那些条带中)-“速度-大小”的平衡相同(这是一个折衷)。


指标


ORC格式包含索引,这些索引使您可以确定条带(或更确切地说,每条1万行的条带部分,即所谓的“行组”)是否包含要查找的数据。 索引建立在每个列上。 这会影响读取速度,从而增加尺寸。 顺便说一句,在流式读取索引时,您无法读取。


压缩方式


所有元数据都以压缩形式存储,


  • 统计和描述性信息(该格式允许您重新创建存储在其中的表,包括字段的名称和类型)
  • 指标
  • 划分信息(分为条带和流)

(下面我们将看到元数据是文件的重要组成部分)


列值也以压缩形式存储。 同时,可以仅读取和解压缩所需的数据块(即,不压缩文件,也不压缩整个条带)。 压缩会影响大小和读取速度。


编码方式


列值以及文件正好存储了这些值,并以编码形式存储。 例如,在当前版本的整数格式(ORC v1)中,有4种编码选项可用。 同时,不是对整个列进行编码,而是对列的一部分进行编码,因此可以以最佳方式对此部分进行编码(在说明书中这些部分称为“运行”)。 因此,实现了所存储数据的总长度的最小化。 再次,对大小和速度的影响。


我们来看一下ORC文件


让我们非常简单地看一下ORC文件中的内容(一个文件本身是628个字节)。 对于那些对技术细节不太感兴趣的人,请向下滚动到下一部分(关于格式比较)。


这是在ORC的示例记录中定义表的方式:


图片


元数据


关于长度的信息(我给出了jupyter笔记本的屏幕截图,我认为它足够清楚)


图片


我们在这里看到的是:


  • 在“小腿”中(这就是后记+页脚+元数据)只有1 + 23 + 115 + 50 = 189字节
  • 在单个条带中,只有3 + 436 = 439个字节,总计628个字节
  • 带包含一个索引(73个字节),数据(276个字节),页脚(87个字节)

让我们在这里注意数据量和元数据的比例(276到352字节)。 但是这276个字节的数据不仅是数据,还包含一些“多余的”(为了简洁起见,我不提供屏幕截图-使用它们需要花费很长时间,我将只用我的注释进行管理),该数据包含在其中:


  • 每列的PRESENT流有3个(包括公用的伪列结构)-每列20个字节,共60个字节
  • 数据流(此处未表示伪列)-103和113字节(分别为“ x”和“ y”列)

PRESENT流是位字符串,可让您知道列为NULL的位置。 在我们的示例中,它们的出现看起来很奇怪(在我们文件的统计数据中清楚地写出数据中没有NULL-为什么要包含PRESENT?这似乎是一个缺陷...)


数据本身总共占用216字节元数据-352。


从元数据中还可以看出,这两列都是使用DIRECT_V2方法编码的(对于整数,它允许4种表示形式,有关详细信息,请参阅规范-位于项目网站上)。


资料


让我们来看看(为了简洁起见,同样没有截图),一万个数字如何容纳在103个字节中(对于“ x”列):


  • 使用增量编码,其中参数是初始值和步长(为简便起见略有简化)
  • 我们总是有1步,第一次运行的初始值为0,然后为511、1022等。
  • 在我们的案例中,运行(以一种单一方式编码的一组数据)包含511个值(增量编码的最大可能值)
  • 文件中每次运行的长度为4到6个字节(运行的长度会因使用Zigzag表示初始值而增加)
  • 我们在文件20个运行中得到“ x”列的总数,总长度为103个字节(我检查了-它们都适合在一起)

总结一下文件中的简单表的显示方式之后,我将说此示例中的索引是退化的-它们指示数据流的开始。 我将使用实际示例处理索引;我可能会在另一篇文章中对其进行描述。


对于那些感兴趣的人:在链接下可以找到jupyter笔记本,我在其中“理解”了格式的内部结构。 您可以使用它并重复(ORC文件也附加在此)。


我确信许多读者“迷路了”-是的,ORC格式并不简单(从理解细节和使用提供的功能方面而言)。


关于格式比较


现在,让我们继续讨论要点-格式比较不正确。


比较格式的频率:让我们比较格式A和B的文件大小,格式A和B的读取速度(不同的读取类型-随机,流式传输等)。比较,我们得出结论,格式A比格式B更好。


使用上面列出的最后一个紧凑性(编码)工具的示例:可以在ORC中以最佳方式编码数据吗? 是的,有机会-见上文。 但同样,您不能这样做! 这取决于“作者”(ORC术语中的作者):在上面的示例中,作者可以做到这一点。 但是他可以用1万个数字写下2次,这在格式上也是正确的。 “按大小”比较格式时,我们不仅会比较格式,而且不会比较使用这些格式的应用程序系统的算法质量


谁是Hadoop中的“作者”? 其中有很多-例如,Hive,它创建一个表以ORC格式将其数据存储在文件中。 例如,比较Hadoop中的ORC和Parquet,我们实际上评估了Hive中实现的数据转换算法的实现质量。 我们不比较格式(这样)。


Hadoop的重要功能


在经典的关系世界中,我们无法影响Oracle中表的大小-它以某种方式存储,只有Oracle知道如何。 在Hadoop中,情况略有不同:我们可以看到该表或该表的存储方式(例如,Hive对其进行“编码”的程度如何)。 而且,如果我们看到可以改进这一点,那么我们有一个真正的机会:创建我们自己的最佳ORC文件并将其作为外部表提供给Hive。


比较ORC和QVD


我最近描述了QlikVew / QlikSense正在积极使用的QVD格式 。 让我们根据它们提供的实现最大读取速度和最小尺寸的功能非常简要地说明这两种格式。 如QVD中所述,ORC的功能如上所述:


列存储


QVD可以被视为“列”格式,其中没有重复的列值-唯一值存储一次。 但是它不允许并行处理-首先,您需要完全读取所有列的值,然后才能并行读取行。


在行级别存在重复-行在字符表中存储重复的索引值。


压缩方式


我没有遇到压缩的QVD文件-我没有成功-元数据中有这样一个标签,也许每个元数据中都有偏移和长度的部分(这是每个字符表和整个字符串表)都可以被压缩。 在这种情况下,并行读取行是“再见” ...


指标


在QVD文件中无法理解需要读取其中的哪一部分。 实际上,您必须逐个字节地解析字符表,这不是一种非常有效的方法...


编码方式


不使用QVD中的编码,可以通过编码在字符串表中绘制位索引的类比,但是通过在字符表中用字符串复制数字来对这种类比进行``补偿''(有关详细信息,请参见本文的简要介绍-列值通常由数字AND字符串表示)。


我亲自得出的简短比较结论是-QVD格式实际上不包含允许紧凑存储和快速读取此格式文件中包含的数据的功能。


(听起来对QVD有点反感,我要补充一点-该格式是很久以前创建的,仅使用QlikView / QlikSense,它们将所有数据“存储”在内存中。我认为QVD文件只是按“原样”读取内存中的所有数据,然后这些方面在所有方面都非常出色,BI产品在此演示文稿中可以非常快速地工作-在这里他们是大师...)


而不是结论


他批评了,还没有提供任何东西...-我建议。


在我看来,不需要通过特定实现方式的示例来比较格式,而是需要根据格式中包含的工具以及使用这些工具解决特定问题的能力来比较格式。 处理器的速度在不断提高,现在我们几乎可以负担得起在读取数据转换后的所有数据转换算法-无论如何,从磁盘读取速度会变慢。 这就是为什么格式的“表达方式”很重要的原因。


在上面,我简要列出了有趣的ORC格式的可能性。 我仍然没有关于实际情况的统计信息(例如,Hive使用了哪些功能以及使用的程度)。 当它出现时-我会写。 近期计划是对另一种流行的存储格式-木地板进行类似的审查。


好吧,总而言之,在现代世界中,有很多信息,不幸的是,这些信息的一部分太肤浅了。 我们不会屈服,我们会看本质。

Source: https://habr.com/ru/post/zh-CN458552/


All Articles