Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSON对象跨越多行,如何在Hadoop中拆分输入_Java_Json_Hadoop_Elephantbird - Fatal编程技术网

Java JSON对象跨越多行,如何在Hadoop中拆分输入

Java JSON对象跨越多行,如何在Hadoop中拆分输入,java,json,hadoop,elephantbird,Java,Json,Hadoop,Elephantbird,我需要接收大型JSON文件,这些文件的记录可能跨越多行(而不是文件)(完全取决于数据提供者是如何编写的) 大象鸟假设LZO压缩,我知道数据提供者不会这样做 Dzone文章假设JSON记录将位于同一行 任何想法,除了挤压JSON。。。文件将是巨大的。。。关于如何正确分割文件以使JSON不会中断 编辑:行,而不是文件缺少任何其他建议,并且取决于JSON的格式,您可能有一个选项 正如Dzone文章中指出的,问题在于JSON没有可以在跳转到拆分点时轻松定位的结束元素 现在,如果您的输入JSON具有“漂亮

我需要接收大型JSON文件,这些文件的记录可能跨越多行(而不是文件)(完全取决于数据提供者是如何编写的)

大象鸟假设LZO压缩,我知道数据提供者不会这样做

Dzone文章假设JSON记录将位于同一行

任何想法,除了挤压JSON。。。文件将是巨大的。。。关于如何正确分割文件以使JSON不会中断


编辑:行,而不是文件

缺少任何其他建议,并且取决于JSON的格式,您可能有一个选项

正如Dzone文章中指出的,问题在于JSON没有可以在跳转到拆分点时轻松定位的结束元素

现在,如果您的输入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反序列化器(或者只将多行文本传递给映射器)。

分割和解析多行JSON数据的最佳方法是扩展NLineInputFormat类,并定义您自己对什么构成InputSplit的概念。[例如:1000条JSON记录可能构成一个拆分]

然后,您将需要扩展LineRecordReader类,并定义您自己对什么构成一行的概念[在本例中为一条记录]

这样,您将得到定义良好的拆分,每个拆分都包含“N”个JSON记录,然后可以使用相同的LineRecordReader读取这些记录,并且您的每个映射任务一次将收到一条要处理的记录

Charles Mengay对的回答很好地解释了这种方法的细微差别

有关NLineInputFormat的此类扩展的示例,请查看

Hadoop的类似多行CSV格式可在此处找到:

更新:我在这里找到了Hadoop的相关多行JSON输入格式:

如果“验证”是您想要做的事情(即,建立一个上下文,让您知道JSON字符串何时按语法完成,而无需将整个内容加载到内存中),那么您可以查看基于事件的解析器(类似于SAX对XML的操作)。这个答案列出了一些。数据提供者将准备JSON格式的数据(不要问我为什么使用JSON,我想他们已经在他们的端上设置了该提要)。一些专有系统会将文件放入HDFS中,以通过M/R进程运行。其想法是,当读取输入文件时,我可以可靠地拆分它,这样顶级JSON对象就不会被破坏。问题是我无法控制文件本身,因此它可能会被一个跨多行的顶级对象转储到我身上。Chukwa应该有一个JSONInputFormat,但我不知道它是否读取多行。因此我的建议是通过一个简单的流式解析器(沿着的行,参见第2点)传递它。解析器只需做一件事:处理嵌套深度,观察正确的结束标记。这样,您就可以知道JSON对象何时完成(还有,FWIW,是否格式正确).不过,我无法为您创建这样的程序,所以这只是一个粗略的想法。Chukwa有一个JSONLoader,但没有一个用于JSON的InputFormat扩展类。提供程序的JSON格式非常简单。虽然我很欣赏响应并将其标记为书签以供将来参考,但我最终决定假设它是一个简单的没有深度的键值对(在本例中是这样的)。我的愿望是通过为未来的JSON提供者提供解决方案来“第一次就把它做好”……但在本例中,敏捷压倒了完美。