代码之家  ›  专栏  ›  技术社区  ›  KayV

何时使用CountByValue以及何时使用Map()。ReduceByKey())

  •  -1
  • KayV  · 技术社区  · 7 年前

    我对spark和scala以及一个简单的wordcount示例不熟悉。

    为此,我使用CountByValue,如下所示:

    val words = lines.flatMap(x => x.split("\\W+")).map(x => x.toLowerCase())
    val wordCount = words.countByValue();
    

    很好用。

    同样的事情也可以实现,比如:

    val words = lines.flatMap(x => x.split("\\W+")).map(x => x.toLowerCase())
    val wordCounts = words.map(x => (x, 1)).reduceByKey((x, y) => x + y)
    val sortedWords = wordCounts.map(x => (x._2, x._1)).sortByKey()
    

    也可以。

    现在,我的问题是何时使用哪些方法? 哪一个比另一个更受欢迎?

    3 回复  |  直到 7 年前
        1
  •  2
  •   Ged    7 年前

    这里的例子-不是单词,而是数字:

    val n = sc.parallelize(List(1,2,3,4,5,6,7,8,2,4,2,1,1,1,1,1))
    val n2 = n.countByValue
    

    返回本地映射:

    n: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[4] at parallelize at command-3737881976236428:1
    n2: scala.collection.Map[Int,Long] = Map(5 -> 1, 1 -> 6, 6 -> 1, 2 -> 3, 7 -> 1, 3 -> 1, 8 -> 1, 4 -> 2)
    

    这就是关键的区别。

    如果你想从盒子里拿出一张地图,那么这就是你要走的路。

    另外,要点是减少是隐含的,不受影响,也不需要像reducebykey中那样提供。

    当数据大小较大时,ReduceByKey具有优先权。地图全部加载到驱动程序内存中。

        2
  •  0
  •   DarkZero    7 年前

    至少在派斯帕克,它们是不同的东西。

    countByKey 是用 reduce 这意味着驱动程序将收集分区的部分结果并进行合并。如果您的结果很大,那么驱动程序将不得不合并大量的大型字典,这将使驱动程序疯狂。

    reduceByKey 将密钥随机分配给不同的执行者,并对每个工作人员进行减少,因此如果数据很大,则更为有利。

    总之,当您的数据很大时,请使用 map , 按键还原 collect 会让你的司机更快乐。如果你的数据很小, 倒计时键 将引入较少的网络流量(少一个阶段)。

        3
  •  0
  •   KayV    7 年前

    在以上所有答案的基础上,我进一步发现:

    1. CountByValue返回不能以分布式方式使用的映射。

    2. ReduceByKey返回一个RDD,该RDD可以进一步以分布式方式使用。

    推荐文章