13

我想知道是否有任何方法可以将 CSV 数据实际加载为二进制 Hive 格式 - 即与在关系数据库中加载数据所做的相同:解析和类型转换输入并将其存储为二进制格式(在另一个二进制如果是 Hive 文件)。Hive 参考说该load data inpath命令不执行“任何转换”,所以我怀疑类型没有转换,例如,从字符串到整数。我正在阅读有关 OCR 和 RCFile 格式的信息,但我无法确定,例如,来自 CSV 的字符串值是否被类型转换为机器整数值并存储在 HDFS 中。是这样吗?在 Hive 中创建 CSV 文件的二进制表示还有哪些其他可能性?

在相关说明中:我怀疑 Hive 在查询处理期间确实将字符串值转换为机器表示,而不是例如比较字符串值 - 这个假设是否正确?

4

1 回答 1

24

默认情况下,Hive 仅将文件存储为纯文本文件,并将记录存储为纯文本,全部未压缩。它确实使用 ASCII 0x1 作为字段分隔符,这对于某些输入来说比逗号更方便,但我相信您已经了解了如何让 Hive 使用逗号分隔值。如果您希望 Hive 使用不同的文件格式,以不同的方式序列化/反序列化,或压缩数据,您可以使用几个不同的选项。

开箱即用,Hive 支持几种不同的文件格式:TEXTFILESEQUENCEFILERCFILE. 两者之间的差异与文件的读取、拆分和写入方式有关。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/压缩编解码器,并进行一些性能测试来确定您的方法。

于 2013-05-06T18:03:41.823 回答