Scala 源RDD中的subtractByKey修改值
我在Scala 2.11.x中使用Spark 2.0.2时遇到了Scala 源RDD中的subtractByKey修改值,scala,apache-spark,Scala,Apache Spark,我在Scala 2.11.x中使用Spark 2.0.2时遇到了subtractByKey问题(它也在Spark 1.6.2和Scala 2.10中复制): 相关代码: object Types { type ContentId = Int type ContentKey = Tuple2[Int, ContentId] type InternalContentId = Int } val inverseItemIDMap: RDD[(InternalContentId, C
subtractByKey
问题(它也在Spark 1.6.2和Scala 2.10中复制):
相关代码:
object Types {
type ContentId = Int
type ContentKey = Tuple2[Int, ContentId]
type InternalContentId = Int
}
val inverseItemIDMap: RDD[(InternalContentId, ContentKey)] = itemIDMap.map(_.swap).cache()
logger.info(s"Built an inverse map of ${inverseItemIDMap.count()} item IDs")
logger.info(inverseItemIDMap.collect().mkString("I->E ", "\nI->E ", ""))
val superfluousItems: RDD[(InternalContentId, Int)] = .. .cache()
logger.info(superfluousItems.collect().mkString("SI ", "\nSI ", ""))
val filteredInverseItemIDMap: RDD[(InternalContentId, ContentKey)] =
inverseItemIDMap.subtractByKey(superfluousItems).cache() // <<===!!!
logger.info(s"${filteredInverseItemIDMap.count()} items in the filtered inverse ID mapping")
logger.info(filteredInverseItemIDMap.collect().mkString("F I->E ", "\nF I->E ", ""))
多余项(SI)中没有键为830071的元素,因此它不会从源RDD中删除。但是,由于某种原因,它的值被键829911中的值替换。这怎么可能?我无法在本地复制它-仅当在多机集群上运行时。这是一个bug还是我遗漏了什么?问题是我假设缓存和强制RDD保证它永远不会被重新评估
inverseItemIDMap
是使用非确定性操作构建的,多次使用它也会产生不同的结果:
val itemIDMap: RDD[(ContentKey, InternalContentId)] =
rawEvents
.map(_.content)
.distinct
.zipWithUniqueId()
.map(u => (u._1, u._2.toInt))
.cache()
logger.info(s"Built a map of ${itemIDMap.count()} item IDs")
val inverseItemIDMap: RDD[(InternalContentId, ContentKey)] =
itemIDMap.map(_.swap).cache()
我通过在
.zipWithUniqueId()之前添加.sortBy(c=>c)
使操作稳定,这就解决了问题。这里的类型,比如type InternalContentId=Int
是代码中使用的实际类型吗?通过查看代码(),我看不出这是如何发生的,除非该键的hashkey有某种缺陷(对于Int
),是的,键类型完全相同。我尝试用Int
替换类型别名,但也没有成功。
val itemIDMap: RDD[(ContentKey, InternalContentId)] =
rawEvents
.map(_.content)
.distinct
.zipWithUniqueId()
.map(u => (u._1, u._2.toInt))
.cache()
logger.info(s"Built a map of ${itemIDMap.count()} item IDs")
val inverseItemIDMap: RDD[(InternalContentId, ContentKey)] =
itemIDMap.map(_.swap).cache()