我需要摄取大型JSON文件,这些文件的记录可能跨越多行(而不是文件)(完全取决于数据提供程序是如何编写的)。
Elephant Bird假设LZO压缩,我知道数据提供商不会这么做。
Dzone文章http://java.dzone.com/articles/hadoop-practice假设JSON记录将在同一行上。
任何想法,除了挤压JSON之外...文件会很大..。关于如何正确拆分文件,以便JSON不会中断。
编辑:行,而不是文件
发布于 2012-08-14 09:10:04
如果没有其他建议,并且根据JSON的格式化方式,您可能有一个选择。
正如Dzone文章中所指出的,问题在于JSON没有可以在跳到拆分点时轻松定位的end元素。
现在,如果您的输入JSON具有“漂亮”或标准格式,则可以在自定义输入格式实现中利用这一点。
例如,取Dzone示例中的示例JSON:
{
"results" :
[
{
"created_at" : "Thu, 29 Dec 2011 21:46:01 +0000",
"from_user" : "grep_alex",
"text" : "RT @kevinweil: After a lot of hard work by ..."
},
{
"created_at" : "Mon, 26 Dec 2011 21:18:37 +0000",
"from_user" : "grep_alex",
"text" : "@miguno pull request has been merged, thanks again!"
}
]
}使用这种格式,您知道(希望如此?)每条新记录都从一行开始,该行有6个空格和一个左括号。一条记录以类似的格式结尾--6个空格和一个右括号。
因此,本例中的逻辑是:使用行,直到找到包含6个空格和一个左方括号的行。然后缓冲内容,直到找到6个空格和一个右括号。然后使用您想要将其转换为java对象的任何JSON反序列化程序(或者只是将多行文本传递给您的映射器。
发布于 2015-11-07 12:04:48
拆分和解析多行JSON数据的最好方法是扩展NLineInputFormat类,并定义自己的InputSplit组成概念。[例如: 1000个JSON记录可以构成1个拆分]
然后,您需要扩展LineRecordReader类并定义您自己的概念,即本例中的1行,即1条记录。
这样,您将获得定义良好的拆分,每个拆分包含'N‘条JSON记录,然后可以使用相同的LineRecordReader读取这些记录,并且每个映射任务一次将接收一条要处理的记录。
Charles Menguy对How does Hadoop process records split across block boundaries?的回复很好地解释了这种方法的细微差别。
有关NLineInputFormat的此类扩展的示例,请查看http://hadooped.blogspot.com/2013/09/nlineinputformat-in-java-mapreduce-use.html
Hadoop的类似多行CSV格式可以在这里找到:https://github.com/mvallebr/CSVInputFormat
Hadoop :我在这里找到了一种相关的多行输入格式:https://github.com/Pivotal-Field-Engineering/pmr-common/blob/master/PivotalMRCommon/src/main/java/com/gopivotal/mapreduce/lib/input/JsonInputFormat.java
https://stackoverflow.com/questions/11938792
复制相似问题