如何在不使用Hadoop的情况下读取HDFS上的Snappy压缩文件?

11
我正在使用Snappy压缩格式在HDFS上存储文件。我希望能够检查这些文件是否被创建的Hadoop进程正确执行,因此想将它们复制到本地Linux文件系统上进行检查。
当我将它们复制到本地并尝试使用Google标准库对其进行解压缩时,它告诉我该文件缺少Snappy标识符。当我试图通过插入Snappy标识符来绕过此问题时,它会破坏校验和。
有什么方法可以在不编写单独的Hadoop程序或通过类似Hive的方式传递文件的情况下读取这些文件吗?
4个回答

26

我终于发现我可以使用以下命令读取HDFS上Snappy压缩文件的内容:

hadoop fs -text /path/filename

使用Cloudera或HDP上的最新命令:

hdfs dfs -text /path/filename

如果想要以文本格式下载文件,以进行额外的检查和处理,则该命令的输出可以通过管道传输到本地系统上的文件中。您还可以使用head命令只查看文件的前几行。


我该如何在Scala或Java中以编程方式实现这个? - Bunder
要以编程方式写入Snappy文件,您需要导入Snappy编解码器类并获得该类的一个实例作为Mapper或Reducer设置的一部分。您需要通过编解码器的“createOutputStream”函数传递输出流以获取编码后的输出流。以下是代码片段。反向读取相同。codec =(CompressionCodec)ReflectionUtils.newInstance(codecClass,conf); fileOut = fs.create(targetPath,false); thiswriter = new LineRecordWriter <EtlKey,EtlValue>(new DataOutputStream(codec.createOutputStream(fileOut))); - Robert Rapplean

3
请查看Cloudera博客上的这篇文章。它解释了如何使用Snappy与Hadoop。基本上,原始文本上的Snappy文件是不可分割的,因此您无法跨多个主机读取单个文件。
解决方案是使用容器格式的Snappy,因此您实际上正在使用带有压缩设置为Snappy的Hadoop SequenceFile。正如在这个答案中描述的那样,您可以将属性mapred.output.compression.codec设置为org.apache.hadoop.io.compress.SnappyCodec,并将作业输出格式设置为SequenceFileOutputFormat
然后要读取它,您只需要使用SequenceFile.Reader,因为编解码器信息存储在文件头中。

1
谢谢,Charles,但我不认为这回答了我的问题。让我简化一下。我使用hadoop fs -get filename将文件从HDFS移动到Linux上的本地目录。既然我已经把它放在这里了,为什么不能使用snappy java库对其进行解压缩呢? - Robert Rapplean

0

这是因为Hadoop使用的Snappy压缩格式包含了一些元数据,这些元数据无法被像https://code.google.com/p/snappy/这样的库所理解。你需要使用Hadoop原生的Snappy解压你下载的数据文件。


你能具体一点吗?如果可能的话,我想从Hadoop FS接口来完成这个任务。 - Robert Rapplean

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接