我正在尝试将一些数据从 Hbase 移植到 ORC 以提高写入性能。在 Hbase 中,我的数据针对一个行键存储在总共 10 列中。现在,当我们使用 Hbase 时,我们不必担心这些列的稀疏性。即使大多数行只有两列具有非零值,也可以,因为 Hbase 只会存储 2 列。
我在移植数据时的第一反应是将上述列限定符转换为与地图相关的值。但是,这对于检索不是很有效。我试图了解 ORC 如何解释空值 - 如果我将值存储为 10 个单独的列而不是地图会更好吗?在最坏的情况下,该矩阵将非常稀疏。
来自ORC 文档:
在 ORC 文件中,每一列都存储在多个流中,这些流在文件中彼此相邻存储。例如,一个整数列表示为两个流:PRESENT,如果值为非空,则使用一个每个值记录一个位,以及 DATA,它记录非空值。如果条带中的所有列值都不为空,则从条带中省略 PRESENT 流。
这意味着,在最坏的情况下,每个空值都会花费您一位。在一般情况下,如果您指定压缩算法,ORC 会进一步压缩这些流。因此,您最终可能会遇到空值花费不到一位的情况。
话虽如此,很难说这对您的特定应用程序是否更有效。如果您需要从每一行中读取特定值(即:列),那么您的读取性能可能会提高很多。如果您的读取是有条件的,则 I/O 可以进一步改进,例如:如果 COL2 == "someValue" 因为 ORC 具有支持跳过列块的索引。
ORC 的写入性能可能比 Hbase 差,ORC 用于读取繁重的用例,并且针对存储大量排序数据进行了优化。这是它发光的时候。大多数情况下,如果它的功能是围绕加快读取查询来组织的,例如谓词下推。我认为在不了解您的数据的情况下,Hbase 可能是编写繁重操作的更好解决方案。回答您的问题:由于 ORC 是面向列的格式,因此几乎必须将数据拆分为单独的列。它确实可以很好地处理稀疏数据。