Scala spark作业对于一个键只能获得一个结果

Scala spark作业对于一个键只能获得一个结果,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我现在有很多键值对(key,value) 现在对于一个键,我不想得到值的平均值或其他聚合,我只需要一个值。(获取不同的键) 我举个例子 ("1","apple") ("1","apple") ("2","orange") ("2","orange") ("1","apple") ("1","pear") 结果可能是 ("2","orange") ("1","apple") 或 我可以使用reduceByKey(((a,b)=>a))来获得这个,但是因为有很多键,所以时间很长 有谁有更好的建议

我现在有很多键值对(key,value)

现在对于一个键,我不想得到值的平均值或其他聚合,我只需要一个值。(获取不同的键)

我举个例子

("1","apple")
("1","apple")
("2","orange")
("2","orange")
("1","apple")
("1","pear")
结果可能是

("2","orange")
("1","apple")

我可以使用
reduceByKey(((a,b)=>a))
来获得这个,但是因为有很多键,所以时间很长

有谁有更好的建议吗


谢谢

Yiling,您可以使用distinct转换在RDD中保留不同的元素

实际上这是一个典型的map-reduce类问题。但您只希望每个键只有一个值,所以您可以简单地在reduce阶段进行操作,尽管这不是最好的方法。现在您知道,仅使用reduceByKey将花费大量时间进行无用的洗牌,这意味着您应该在Mapper中预先减少数据。所以答案对您来说是显而易见的:使用组合器

在spark中,可以在reduceByKey之前使用combineByKey删除重复值

=====================

除了合并器,您还可以更改洗牌方法。Spark 1.2+的默认洗牌是SortShuffle。您可以将其更改为HashShuffle,这可以降低对密钥进行排序的成本

试着在你的sparkConf中设置这个

spark.shuffle.manager = hash
spark.shuffle.consolidateFiles = true

但您必须注意,太多的映射核心可能会产生太多的随机文件,这将影响性能。
spark.shuffle.consolidateFiles
用于合并映射器输出文件。

您可以使用数据帧的
dropDuplicates()

val df = sc.parallelize(
  List(
      ("1", "apple"),
      ("1", "apple"),
      ("2", "orange"),
      ("2", "orange"),
      ("1", "apple"),
      ("1", "pear")
  )
).toDF("count", "name")

df.show()
+-----+------+
|count|  name|
+-----+------+
|    1| apple|
|    1| apple|
|    2|orange|
|    2|orange|
|    1| apple|
|    1|  pear|
+-----+------+
按名称删除重复项

val uniqueDf = df.dropDuplicates("name")
现在选择前两个唯一的行

uniqueDf.limit(2).show()

+-----+------+
|count|  name|
+-----+------+
|    2|orange|
|    1| apple|
+-----+------+
无限制的唯一记录

uniqueDf.show()
+-----+------+
|count|  name|
+-----+------+
|    2|orange|
|    1| apple|
|    1|  pear|
+-----+------+
编辑:


您可以在数据帧上使用
collect()
,将值放入列表中

谢谢!但是,看起来您的distinct将只区分相同的元素。对我来说,如果我碰巧有(“1”,“苹果”)和(“1”,“橙色”),我只希望结果中存在一个样本。啊,在这种情况下,使用distinct不是正确的转换。根据讨论,在元组RDD中,元组作为一个整体被考虑。嗨,Yiling,如果我没弄错的话,你实际上要求的是“按键区分”。你能修改你的问题描述吗?正如我所引用的,“我假设同一个键将具有相同的值”,这确实是误导。谢谢你,我刚刚修改了我的问题谢谢,但由于我有很多键,即使使用了组合器,仍然需要大量时间进行无用的洗牌。我正在考虑使用散列映射…但不知道..我已经更新了我的答案,您可以尝试使用散列洗牌,而不是使用默认的排序洗牌。但您必须注意,过多的映射核可能会产生过多的无序文件,这将影响性能。是否只需要
(“2”、“橙色”)(“1”、“苹果”)
或任何样本对?我希望结果包含所有键,对于具有不同值的键,仅一个样本值就足够了。
uniqueDf.show()
+-----+------+
|count|  name|
+-----+------+
|    2|orange|
|    1| apple|
|    1|  pear|
+-----+------+