Hive中ORC文件格式详解

这是一个非常重要且高性能的数据存储格式,对于大数据处理来说,理解 ORC 是至关重要的。

一、ORC 是什么?

ORC,全称为 Optimized Row Columnar,即“优化的行列式”存储格式。

  • 它不是数据库:而是一种专门为 Hadoop 生态系统设计的、用于高效存储和处理大量数据的文件格式
  • 它是列式存储:与传统的按行存储(如 CSV、文本文件)不同,ORC 将数据按列而不是按行进行存储。这是其高性能的核心所在。
  • 它是优化的:它在早期的 RC(Record Columnar)文件格式基础上进行了大量优化,提供了更好的压缩和读写性能。

你可以把它想象成大数据领域的“高度压缩且带有索引的 Excel 表格”,但数据是按列存放的。


二、为什么需要 ORC?列式存储的优势

假设你有一张巨大的表,有 100 亿行数据,包含 user_id, name, age, city, purchase_amount 等字段。

现在要执行一个查询:SELECT AVG(purchase_amount) FROM sales WHERE city = 'Beijing';

1. 行式存储(如 TextFile)的做法:
数据库必须逐行读取每一行数据(所有列),然后检查 city 字段是否为 ‘Beijing’,如果是,再取出 purchase_amount 字段。它会读取大量不相关的数据(如 user_id, name, age),导致 I/O 效率极低。

2. 列式存储(ORC)的做法:

  • 数据在磁盘上是这样组织的:所有 user_id 的值存储在一起,所有 city 的值存储在一起,所有 purchase_amount 的值也存储在一起。
  • 执行上述查询时,Hive 只需要:
    • 只读取 city 这一列:快速扫描这一列,找到所有值为 ‘Beijing’ 的位置(行索引)。
    • 只读取 purchase_amount 这一列:根据上一步找到的位置,直接去 purchase_amount 列的对应位置取出数值进行计算。
  • 优势立即显现
    • 极高的 I/O 效率:避免了读取不必要的列,大大减少了磁盘 I/O 数据量。
    • 出色的压缩率:同一列的数据类型相同,重复值多(例如 city 列会有大量重复城市名),列式存储更利于使用高效的压缩算法(如 Run-length Encoding,字典编码),显著减少存储空间。
    • 向量化处理:列式数据布局非常适合现代 CPU 的向量化计算指令,可以一次性处理一批数据,而不是一次一个值,极大地提高了计算性能。

三、ORC 的核心结构与高级特性

ORC 文件不仅仅是简单地把列数据堆在一起,它内部包含了许多“元数据”和“索引”,使其异常强大。

一个 ORC 文件由以下部分组成:

1. Stripe(条带)

  • 这是 ORC 文件的主体数据块,相当于一个“数据单元”。
  • 通常每个 Stripe 的大小为 256MB。
  • 每个 Stripe 内部包含多行的数据,并且每个列的数据在 Stripe 内是独立存储的
  • 这使得读取操作可以在一个 Stripe 内高效地进行。

2. File Footer(文件脚注)

  • 这是文件的“目录”,包含至关重要的元信息:
    • Stripes 列表:文件中每个 Stripe 的信息(如行数、位置等)。
    • Schema 信息:表的结构(列名、数据类型)。
    • 统计信息(Statistics):这是 ORC 的王牌特性——谓词下推(Predicate Pushdown) 的基础。
      • 每个 Stripe 的每一列,都存储了其最小值、最大值、计数、求和等聚合信息。
      • 在执行 WHERE city = 'Beijing' 时,Hive 可以先检查每个 Stripe 的 city 列的统计信息。如果一个 Stripe 的 max(city) 是 ‘Shanghai’ 而 min(city) 是 ‘Guangzhou’,那么这个 Stripe 里根本不可能有 ‘Beijing’,Hive 就会跳过整个 Stripe 的读取!
      • 这极大地减少了需要扫描的数据量,提升了查询速度。

3. Postscript(后记)

  • 位于文件末尾,记录了文件本身的元数据,如压缩格式(ZLIB, SNAPPY, NONE)、压缩参数、文件脚注的长度等。

4. Index Data(索引数据)

  • 在 Stripe 级别,还包含了行级索引(Row Index),为 Stripe 中的每一万行左右记录一次偏移量, enabling more precise seeking within a stripe.

四、如何在 Hive 中使用 ORC?

1. 创建 ORC 表

-- 创建一个内部表,存储格式为 ORC
CREATE TABLE my_orc_table (
  user_id INT,
  name STRING,
  age INT,
  city STRING
) STORED AS ORC;

-- 创建表时可以指定压缩算法(例如使用 Snappy 压缩)
CREATE TABLE my_compressed_orc_table (
  ...
) STORED AS ORC
TBLPROPERTIES ("orc.compress"="SNAPPY"); -- 可选值:NONE, ZLIB, SNAPPY

2. 从其他表插入数据到 ORC 表
这是最常见的将文本数据转换为 ORC 格式的方式。

INSERT OVERWRITE TABLE my_orc_table
SELECT * FROM my_source_text_table;

3. 查询 ORC 表
查询方式与任何其他 Hive 表完全一样,但速度会快得多,尤其是聚合查询和带条件的查询。

SELECT city, AVG(age) FROM my_orc_table WHERE age > 20 GROUP BY city;

Hive 会自动利用 ORC 的统计信息和列式存储特性来优化这个查询。


五、优点总结

  1. 查询性能快:基于列式存储、谓词下推和统计信息,大大减少了磁盘 I/O。
  2. 压缩率高:节省大量存储空间(通常比文本格式节省 70%-90% 的空间)。
  3. 支持复杂类型:完美支持 Hive 的复杂数据类型(Array, Map, Struct)。
  4. 事务支持:ORC 是 Hive 实现 ACID 事务的基础文件格式。
  5. 内置索引:包含文件级和 Stripe 级的统计信息,用于加速查询。

六、缺点与注意事项

  1. 不适合单行频繁更新:ORC 是为大规模数据分析(OLAP)设计的,不适合频繁的单行写入、更新(OLTP)场景。写入成本较高。
  2. 不适合小数据量:由于其结构开销(Footers, Indexes),存储非常小的数据时可能不如文本格式高效。
  3. 非人类可读:无法直接用文本编辑器查看内容,必须通过 Hive、Spark、Presto 等工具查询。

七、与其他格式对比

格式存储方式压缩率查询性能可读性适用场景
TextFile/CSV行式数据交换,初始数据加载,小数据量
SequenceFile行式中间存储,二进制键值对数据
RCFile列式较快ORC 的前身,现已较少使用
ORC列式非常高非常快(Hive最佳)Hive 数据仓库的主力存储格式
Parquet列式非常高非常快(Spark最佳)Spark 生态的主力存储格式,跨生态系统支持更好

ORC vs Parquet:两者都是优秀的列式存储格式。ORC 与 Hive 的集成更紧密、优化更深(尤其是谓词下推和事务支持),而 Parquet 的设计更通用,被 Spark、Impala、Presto 等众多引擎广泛支持。选择通常取决于你的主要计算引擎。

结论

ORC 是 Hive 中高性能数据存储的事实标准。 对于任何使用 Hive 构建数据仓库的场景,都强烈建议将原始文本数据转换为 ORC(或 Parquet)格式,这将为你带来巨大的存储节省和查询性能提升,是数仓优化中最具性价比的操作之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值