我试图在Scala-Spark中将一个较大的xml文件(1 TeraByte)拆分为较小的文件。这是一个示例XML,如下所示(test1.xml)。 “ LOG”是根标签,“ LgRec”是行标签,并且要求根据“ RecId”(LgRec的属性)值将其拆分为较小的文件。因此,在这种情况下,它将产生3个文件test1_AA.xml,test1_BB.xml,test1_CC.xml。
我使用DATABRICKS XML库编写了代码,并在一个较小的文件上进行了测试。当我为1 TB文件运行此程序时,我的问题是有更好的方法来执行此操作。 Spark是否将整个1 TB DF和较小的DF保留在内存中,这意味着我的Spark集群需要大约2TB +的内存?
欣赏您的想法
test1.xml (input file)
<?xml version="1.0" encoding="UTF-8"?>
<LOG>
<LgRec RecId="AA">
<UpdRec>
<field num="001">aaaa</field>
<field num="002">100</field>
<field num="003">100.10</field>
<field num="004">20181125</field>
<field num="005">101010.123</field>
</UpdRec>
</LgRec>
<LgRec RecId="BB">
<UpdRec>
<field num="001">xaaa</field>
<field num="002">1100</field>
<field num="003">1100.10</field>
<field num="004">20181125</field>
<field num="005">111111.123</field>
</UpdRec>
</LgRec>
<LgRec RecId="CC">
<UpdRec>
<field num="001">zaaaa</field>
<field num="002">3100</field>
<field num="003">3100.10</field>
<field num="004">20181225</field>
<field num="005">131313.123</field>
</UpdRec>
</LgRec>
</LOG>
test1_AA.xml (output file)
<LOG>
<LgRec RecId="AA">
<UpdRec>
<field num="001">aaaa</field>
<field num="002">100</field>
<field num="003">100.10</field>
<field num="004">20181125</field>
<field num="005">101010.123</field>
</UpdRec>
</LgRec>
test1_BB.xml (output file)
<LgRec RecId="BB">
<UpdRec>
<field num="001">xaaa</field>
<field num="002">1100</field>
<field num="003">1100.10</field>
<field num="004">20181125</field>
<field num="005">111111.123</field>
</UpdRec>
</LgRec>
test1_CC.xml (output file)
<LgRec RecId="CC">
<UpdRec>
<field num="001">zaaaa</field>
<field num="002">3100</field>
<field num="003">3100.10</field>
<field num="004">20181225</field>
<field num="005">131313.123</field>
</UpdRec>
</LgRec>
</LOG>
这是代码
import org.apache.spark.sql._
import org.apache.spark.sql.types._
import com.databricks.spark.xml._
object splitXML {
def main(args: Array[String]) = {
val spark = SparkSession
.builder()
.appName("splitXML")
.master("local")
.getOrCreate()
import spark.implicits._
val inputFile = "test1.xml"
val outputFilePrefix = "test1_"
val outputFileSuffix = ".xml"
val inputXMLDF = spark.read
.option("roottag", "LOG")
.option("rowTag" , "LgRec")
.xml(inputFile)
//get distinct recId's
val recTypeDF = inputXMLDF.select("_RecId").distinct()
//for each recid filter the DF by recId and output the file
recTypeDF.collect().map(row => {
println("row = " + row(0) )
inputXMLDF.filter(inputXMLDF("_RecId")===row(0))
.write
.option("roottag", "LOG")
.option("rowTag" , "LgRec")
.xml(outputFilePrefix + row(0) + outputFileSuffix)
})
spark.close()
}
}