class Cleaner {
def getDocumentData() = {
val conf = new SparkConf()
.setAppName("linkin_spark")
.setMaster("local[2]")
.set("spark.executor.memory", "1g")
.set("spark.rdd.compress", "true")
.set("spark.storage.memoryFraction", "1")
val CorpusReader = new Corpus()
val files = CorpusReader.getListOfFiles("/home/DATA/doc_collection/")
val sc = new SparkContext(conf)
val temp = sc.textFile(files(0).toString())
println(files(0).toString())
var count = 0
val regex = """<TAG>""".r
for (line <- temp ) {
line match {
case regex(_*) => {
println(line)
count += 1
println(count)
}
case _ => null //Handle error - scala.MatchError
}
}
println(s"There are " + count + " documents.") // this comes out to be 0
}
}
我有一个我必须阅读的文本文件列表。它们是类似XML的文件,所以我需要提取相关的文本。因为,它们不是标准的XML文件,我想用正则表达式来获取文本。每个文档都以<TAG>
标记开头。所以我试着算不了。文件中的文件等于否。 <TAG>
匹配文件中的匹配项。上面的功能做了同样的事情。最初该文件有264个文档但是当我运行该函数时,我得到127或137,这两个数字。它似乎没有读取整个文件。最后count
最后也是0.
我是Scala / Spark新手。
更新
var count = sc.accumulator(0)
val regex = """<TAG>""".r
for (line <- temp ) {
println(line)
line match {
case regex(_*) => {
count += 1
println(s"$line @ $count") //There is no "<TAG> @ 264" in the output
}
case _ => null
}
}
println(s"There are " + count.value + " documents.")
程序中的这一更改为我提供了count
的正确值,即264,但文件ID正确打印!!它似乎从中间开始,到中间的某个地方结束。
更新II:
这与线程有关。 SparkConf()
已经使用local[2]
初始化,这意味着2个线程,如果我没有错的话。一旦我将其更改为local[1]
,我得到了正确的答案,但我不能使用一个帖子。
文件如下所示:
<TAG>
<DOCNO> AP890825-0001 </DOCNO>
<FILEID>AP-NR-08-25-89 0134EDT</FILEID>
<TEXT>
Some large text.
</TEXT>
</TAG>
<TAG> // new doc started
我该如何纠正这个问题?
答案 0 :(得分:2)
这是一个关闭问题。每个节点都有自己的count
变量版本。您想使用accumulators
或只是执行reduce
创建者:
val tagCounter = sc.accumulator(0, "tagCount")
更新者:(节点上无法读取)
tagCounter += 1
可通过以下方式阅读驱动程序:
tagCounter.value
更新后:
var count = sc.accumulator(0)
val regex = """<TAG>""".r
val output = for (line <- temp ) yield {
//println(line)
line match {
case regex(_*) => {
count += 1
//println(s"$line @ $count") //There is no "<TAG> @ 264" in the output
line
}
case _ => "ERROR"
}
}
println(s"output size:{output.count}")
println(s"There are " + count.value + " documents.")
查看输入格式后的更新:
您最终会随心所欲地使用wholeTextFiles
来保证订购。否则分布式性质意味着通常无法保证订购,但如果您可以保证订购(可能是自定义分区程序或自定义InputFormat),那么这样的事情应该有效:
sc.parallelize(list)
.aggregate(Nil : List[String])((accum, value) => {
value match {
case regex(_*) => accum :+ value
case _ => {
accum match {
case Nil => List(value)
case _ => accum.init ++ (accum.tail :+ value)
}
}
}, _ ++ _)