这是伪代码:
case class IpDB(startIp: Long, endIp: Long, company: String)
def ipMap(line: Array[String]):
val Array(startIp, endIp, company) = line
IpDB(startIp.toLong, endIp.toLong, company)
// The ip-db is just 300M in raw format.
// format of ip-data from s3:
// 100000 200000 GOOGLE
val ipData = sc.broadcast(sc.textFile("s3://....").map(_.split("\t", -1)).map(ipMap).collect().sortWith(_.startIp < _.startIp)).value
val dataA = sc.textFile("s3://...").map((ip, 1)).reduceByKey(_+_)
val dataB = sc.textFile("s3://...").map((ip, 1)).reduceByKey(_+_)
// will do ip company lookup here
dataA.fullOuterJoin(dataB).map(doIpCompanyLookUp(ipData, _)).collect()
代码只是从输入源获取ip数据,然后在加入后找到它的公司。 这是我的问题:
此代码将在生产中运行2-3分钟,但在删除广播数据时(只需加入两个数据),只花费不到1分钟。当我看到火花的ui时,我发现了gc时间可能是问题。
以下是运行此作业的设置:
spark-submit --master yarn --deploy-mode client --driver-memory 4g --num-executors 10 --executor-memory 8800m --executor-cores 4 --class ... XX.jar
此作业在aws emr spark cluster
上运行spark version: 1.6.1
10 m3.xlarge.
更新
case class IpDB(startIp: Long, endIp: Long, company: String)
def ipMap(line: Array[String]):
val Array(startIp, endIp, company) = line
IpDB(startIp.toLong, endIp.toLong, company)
// The ip-db is just 300M in raw format.
// format of ip-data from s3:
// 100000 200000 GOOGLE
val dataA = sc.textFile("s3://...").map((ip, 1)).reduceByKey(_+_)
val dataB = sc.textFile("s3://...").map((ip, 1)).reduceByKey(_+_)
// will do ip company lookup here
val joinResult = dataA.fullOuterJoin(dataB)
val ipData = sc.broadcast(sc.textFile("s3://....").map(_.split("\t", -1)).map(ipMap).collect().sortWith(_.startIp < _.startIp)).value
joinResult.map(doIpCompanyLookUp(ipData, _)).collect()
在dataA.fullOuterJoin(dataB)
之后移动ip公司数据的生成和广播。运行时间减少了很多。
UPDATE2。 由于生产代码非常复杂,与上面的伪代码不同,在代码顺序稍有变化后,程序运行得更快,但我不确定问题的关键是初始化数据的位置。
答案 0 :(得分:0)
没有太多考虑你的代码:
val ipData = sc.broadcast(sc.textFile("s3://....").map(_.split("\t", -1)).map(ipMap).collect().sortWith(_.startIp < _.startIp)).value
让我很担心。
您正在使用sc.textFile
构建分布式RDD,只是通过collect()
将其设置为本地(驱动程序),然后再次分发,并由sc.broadcast
提供给执行程序( !)正如您所看到的,有很多来回发送数据。
你最好cache
IP数据,以便它保留在内存中,但这样做:
sc.textFile("s3://....").map(_.split("\t", -1)).map(ipMap).cache