Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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
Apache spark Spark/Scala:解析多行记录_Apache Spark - Fatal编程技术网

Apache spark Spark/Scala:解析多行记录

Apache spark Spark/Scala:解析多行记录,apache-spark,Apache Spark,什么是正确的spark | scala技术来解析多行日志文件条目? SQL跟踪文本文件: # createStatement call (thread 132053, con-id 422996) at 2015-07-24 12:39:47.076339 # con info [con-id 422996, tx-id 47, cl-pid 50593, cl-ip 10.32.50.24, user: SAPABA, schema: SAPABA] cursor_14048179715276

什么是正确的spark | scala技术来解析多行日志文件条目? SQL跟踪文本文件:

# createStatement call (thread 132053, con-id 422996) at 2015-07-24 12:39:47.076339
# con info [con-id 422996, tx-id 47, cl-pid 50593, cl-ip 10.32.50.24, user: SAPABA, schema: SAPABA]
cursor_140481797152768_c22996 = con_c22996.cursor()

# begin PreparedStatement_execute (thread 132053, con-id 422996) at 2015-07-24 12:39:47.076422
# con info [con-id 422996, tx-id 47, cl-pid 50593, cl-ip 10.32.50.24, user: SAPABA, schema: SAPABA]
cursor_140481797152768_c22996.execute("SELECT DISTINCT  blah blah blah")
# end PreparedStatement_execute (thread 132053, con-id 422996) at 2015-07-24 12:39:47.077706
每条记录由三行组成;每种记录类型的属性(例如
createStatement
PreparedStatement
)不同。 我想逐行读取文件,确定记录类型,然后为每条记录创建一个数据帧行:

示例

insert into prepared_statements values (132053,422996, '2015-07-24 12:39:47.076422','SELECT DISTINCT  blah blah blah')

为了实现这一点,我需要检查每一行以确定它是哪种记录类型,然后读取下两行以获取该记录类型的属性。此外,行格式因记录而异,因此我需要有条件地检查三行中每个块的开头,以确定记录类型。是否有一种spark技术可以解析多行记录?

这里有一个有效的解决方案,它将每一行与下一个空行的索引进行匹配,然后根据这些索引进行分组,将每个“逻辑记录”的行分组在一起。 假设输入位于
rdd

val indexedRows: RDD[(String, Long)] = rdd.zipWithIndex().cache()
val emptyRowIndices = indexedRows.filter(_._1.isEmpty).values.collect().sorted

val withIndexOfNextGap: RDD[(String, Long)] = indexedRows
  .filter(!_._1.isEmpty)
  .mapValues(i => emptyRowIndices.find(_ > i).getOrElse(0)) // finds lowest index of empty line greater than current line index

val logicalRecords: RDD[Iterable[String]] = withIndexOfNextGap.map(_.swap).groupByKey().values

logicalRecords.map(f) // f maps each Iterable[String] into whatever you need
请注意,此解决方案有几个注意事项:

  • 它假设“逻辑记录”(多行条目)的数量不太多,无法将其索引收集到驱动程序内存中
  • 它不是超高效的,因为我们将每行扫描这些索引

您是否可以假设两个“逻辑记录”之间总是有这一空行,或者这是为了示例的清晰性而添加的?嗨,Tzach,是的,每个逻辑记录之间都有一条空行。只需使用
\n\n
作为记录分隔符即可。