默认情况下,Hive 仅将文件存储为纯文本文件,并将记录存储为纯文本,全部未压缩。它确实使用 ASCII 0x1 作为字段分隔符,这对于某些输入来说比逗号更方便,但我相信您已经了解了如何让 Hive 使用逗号分隔值。如果您希望 Hive 使用不同的文件格式,以不同的方式序列化/反序列化,或压缩数据,您可以使用几个不同的选项。
开箱即用,Hive 支持几种不同的文件格式:TEXTFILE
、SEQUENCEFILE
和RCFILE
. 两者之间的差异与文件的读取、拆分和写入方式有关。TEXTFILE
是默认值,对普通文本文件进行操作。SEQUENCEFILE
是一种二进制键值对格式,很容易被 Hadoop 生态系统的其他部分使用。并且RCFILE
是一种面向列的方式来保存 Hive 表。除了这种文件格式,您还可以编写自己的文件或查找其他人编写的文件格式,以满足不同的需求。
除了保存数据的文件格式之外,您还可以通过指定 SerDe 来决定如何序列化和反序列化表中的记录。Hive 0.9.1 及更高版本包含一个AvroSerDe
, Avro 以二进制格式保存数据(它本身也有一个模式,这引入了一些复杂性)。谷歌搜索“hive binary SerDe”显示了LazyBinarySerde
一种听起来更直接的二进制格式保存方式。如果您找不到任何适合您需要的东西,您可以随时编写自己的 SerDe。
我想您的问题适合如何使 Hive 表更小和/或更高性能的大背景。为此,您可以在我上面提到的所有内容之上应用压缩。为此,只需告诉 Hive 压缩它的输出,并使用以下命令告诉它要压缩哪个编解码器:
hive> set hive.exec.compress.output=true;
hive> set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
如果您希望这些设置在会话之外持续存在(如果您正在共享集群,则包括其他人的 Hive 和 MapReduce 作业),您可以在配置文件中更改此设置。我使用 SnappyCodec 是因为它可以与 Hive 一起使用,开箱即用,可拆分,并为所花费的 CPU 时间提供良好的压缩/解压缩。您可能会决定不同的编解码器更适合您的需求。
现在,如果您的所有数据都是 CSV 格式,您将如何应用所有这些选项?最简单的方法是在 CSV 文件之上创建一个表,然后使用所需的文件格式和 SerDe 创建另一个表,然后将 CSV 支持的表中的数据插入到新表中(确保压缩 Hive 输出使用您选择的编解码器)。在后台,Hive 将负责从一种格式 (CSV) 读取数据并写入另一种格式(无论您决定如何)。在此之后,您将拥有数据的副本,并且您可以根据需要删除 CSV 文件。
CREATE EXTERNAL TABLE csv_table (id INT, name STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ","
LOCATION /user/muehlbau/yourData;
CREATE TABLE binary_table (id INT, name STRING)
ROW FORMAT SERDE org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDe
STORED AS SEQUENCEFILE;
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
INSERT OVERWRITE TABLE binary_table
SELECT * FROM csv_table
上面的示例演示了如何利用所有可用的选项,但不要将其视为默认的、合理的用例。阅读不同的文件格式/SerDes/压缩编解码器,并进行一些性能测试来确定您的方法。