Spark,grep /搜索非常长的字符串/数据块

时间:2018-04-20 08:32:48

标签: apache-spark

我有一个非常长的字符串/数据块,我想在其中搜索/ grep。

示例:...AAABBAAAAVAACCDE...

在这个例子中,我想搜索AVA。

字符串的长度是GB的百分之

我的问题是,当我将字符串拆分为xxMB块(以允许并行执行)时,搜索将在边界上失败。

示例

 [Block 1] ...AAABBAAAA 
 [Block 2] VAACCDE... 

在上面的例子中,我永远找不到字符串AVA。

方法或辅助函数是否能解决这个边界问题?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

在Spark中,并不是每个人都能阅读这些自定义格式,特别是那些没有被换行符分隔的文件,非常高效的开箱即用。

从本质上讲,你需要原始文件中的FileInputStream(带有大字符串的文件),并且对于每个块,你希望每条记录都作为流读取

例如,您可以保留每个chuck / record中最后一个 n 字符的缓存,并将其连接到下一条记录,从而有效地创建重叠。

例如:

val fileIn = "hugeString.txt"
val fileOut = "sparkFriendlyOutput.txt"
val reader = new FileInputStream(fileIn)
val writer = new BufferedOutputStream(new FileOutputStream(fileOut))

val recordSize = 9
val maxSearchLength = 3

val bytes = Array.fill[Byte](recordSize)(0)
val prefix = Array.fill[Byte](maxSearchLength)(' ')

Stream
  .continually((reader.read(bytes),bytes))
  .takeWhile(_._1 != -1)
  .foreach{
    case (_, buffer) =>   {
      writer.write(prefix ++ buffer :+ '\n'.toByte)
      Array.copy(buffer.toList.takeRight(maxSearchLength).toArray,0,prefix,0,maxSearchLength)
    }}

writer.close()

reader.close()

这会变成这个字符串

  

... 1234567890123456789012345678901234567890123456789012345

进入此文件:

  

123456789

     

789012345678

     

678901234567

     

567890123456

     

...

这确实需要您选择您想要搜索的最大长度,因为这是重叠的目的。

这个文件很容易在Spark中读取

另一方面,如果您没有足够的奢侈品将其存储在磁盘(或内存)中,也许您可​​以考虑创建自定义火花流解决方案,您可以在其中实现自定义流媒体源(结构化流媒体) )或通过类似的FileInputStream +缓冲前缀解决方案读取文件的自定义接收器(Dstream)。

PS。你可以用重叠做更聪明的事情(至少除以2,所以不是整个可能的长度重复,

PS我认为你不关心绝对位置。如果这样做,那么我会将原始偏移量存储为每行旁边的长