HashPartitioner 是如何工作的?

2024-05-13

我阅读了文档HashPartitioner http://spark.apache.org/docs/1.3.1/api/java/index.html?org/apache/spark/HashPartitioner.html。不幸的是,除了 API 调用之外,没有任何解释。我假设HashPartitioner根据键的哈希值对分布式集进行分区。例如,如果我的数据是这样的

(1,1), (1,2), (1,3), (2,1), (2,2), (2,3)

因此分区器会将其放入不同的分区,相同的键落在同一分区中。但是我不明白构造函数参数的意义

new HashPartitoner(numPartitions) //What does numPartitions do?

对于上面的数据集,如果我这样做,结果会有什么不同

new HashPartitoner(1)
new HashPartitoner(2)
new HashPartitoner(10)

那么如何HashPartitioner实际上工作吗?


好吧,让你的数据集变得更有趣:

val rdd = sc.parallelize(for {
    x <- 1 to 3
    y <- 1 to 2
} yield (x, None), 8)

我们有六个要素:

rdd.count
Long = 6

无分区器:

rdd.partitioner
Option[org.apache.spark.Partitioner] = None

和八个分区:

rdd.partitions.length
Int = 8

现在让我们定义一个小助手来计算每个分区的元素数量:

import org.apache.spark.rdd.RDD

def countByPartition(rdd: RDD[(Int, None.type)]) = {
    rdd.mapPartitions(iter => Iterator(iter.length))
}

由于我们没有分区器,我们的数据集在分区之间均匀分布(Spark 中的默认分区方案 https://stackoverflow.com/q/34491219/1560062):

countByPartition(rdd).collect()
Array[Int] = Array(0, 1, 1, 1, 0, 1, 1, 1)

现在让我们重新分区我们的数据集:

import org.apache.spark.HashPartitioner
val rddOneP = rdd.partitionBy(new HashPartitioner(1))

由于参数传递给HashPartitioner定义我们期望一个分区的分区数量:

rddOneP.partitions.length
Int = 1

由于我们只有一个分区,因此它包含所有元素:

countByPartition(rddOneP).collect
Array[Int] = Array(6)

请注意,随机播放后值的顺序是不确定的。

如果我们使用同样的方式HashPartitioner(2)

val rddTwoP = rdd.partitionBy(new HashPartitioner(2))

我们将得到 2 个分区:

rddTwoP.partitions.length
Int = 2

Since rdd按关键数据分区将不再均匀分布:

countByPartition(rddTwoP).collect()
Array[Int] = Array(2, 4)

因为 with 具有三个键并且只有两个不同的值hashCode mod numPartitions这里没有什么意外的:

(1 to 3).map((k: Int) => (k, k.hashCode, k.hashCode % 2))
scala.collection.immutable.IndexedSeq[(Int, Int, Int)] = Vector((1,1,1), (2,2,0), (3,3,1))

只是为了确认以上内容:

rddTwoP.mapPartitions(iter => Iterator(iter.map(_._1).toSet)).collect()
Array[scala.collection.immutable.Set[Int]] = Array(Set(2), Set(1, 3))

最后与HashPartitioner(7)我们得到七个分区,其中三个非空,每个分区有 2 个元素:

val rddSevenP = rdd.partitionBy(new HashPartitioner(7))
rddSevenP.partitions.length
Int = 7
countByPartition(rddTenP).collect()
Array[Int] = Array(0, 2, 2, 2, 0, 0, 0)

总结和注释

  • HashPartitioner采用一个定义分区数量的参数
  • 使用以下方法将值分配给分区hash的钥匙。hash函数可能因语言而异(Scala RDD 可能使用hashCode, DataSets使用 MurmurHash 3、PySpark、portable_hash https://github.com/apache/spark/blob/330c3e33bd10f035f49cf3d13357eb2d6d90dabc/python/pyspark/rdd.py#L59-L87).

    在像这样的简单情况下,其中 key 是一个小整数,您可以假设hash是一个身份(i = hash(i)).

    Scala API 使用nonNegativeMod https://github.com/apache/spark/blob/4e27578faa67c7a71a9b938aafbaf79bdbf36831/core/src/main/scala/org/apache/spark/util/Utils.scala#L1663-L1666根据计算的哈希值确定分区,

  • 如果密钥的分布不均匀,您可能会遇到部分集群空闲的情况

  • 键必须是可散列的。你可以查看我的回答作为 PySpark 的 reduceByKey 的键的列表 https://stackoverflow.com/a/31404405/1560062阅读有关 PySpark 特定问题的信息。另一个可能的问题突出显示HashPartitioner 文档 https://spark.apache.org/docs/1.4.0/api/scala/index.html#org.apache.spark.HashPartitioner:

    Java 数组的 hashCode 是基于数组的身份而不是其内容,因此尝试对 RDD[Array[]] 或 RDD[(数组[], _)] 使用 HashPartitioner 将产生意外或不正确的结果。

  • 在 Python 3 中,您必须确保散列是一致的。看异常:应通过 PYTHONHASHSEED 禁用字符串哈希的随机性在 pyspark 中意味着什么? https://stackoverflow.com/q/36798833/1560062

  • 哈希分区器既不是单射的也不是满射的。可以将多个键分配给单个分区,并且某些分区可以保留为空。

  • 请注意,当前基于哈希的方法在与 REPL 定义的案例类结合使用时在 Scala 中不起作用(Apache Spark 中的案例类相等 https://stackoverflow.com/q/35301998/1560062).

  • HashPartitioner(或任何其他Partitioner) 打乱数据。除非在多个操作之间重用分区,否则它不会减少要洗牌的数据量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HashPartitioner 是如何工作的? 的相关文章

随机推荐

  • Windows Azure 远程站点“Microsoft.ACE.OLEDB.12.0”提供程序未在本地计算机上注册[重复]

    这个问题在这里已经有答案了 以下代码在我的本地开发计算机上可以正常运行 但是当我部署它时 我收到以下错误消息Azure 远程网站 我已经查看了SO答案和谷歌搜索结果 但我仍然不清楚我必须在本地计算机上安装什么 这样当我将代码推送到Azure
  • 如何阻止 Django 中发生级联删除?

    我的 Django 应用程序中有三个模型类 class Folder models Model folder models ForeignKey Folder null True blank True related name folder
  • 您的手机中未安装应用程序

    我在模拟器中运行该应用程序 它成功运行 并且应用程序的图标显示在模拟器菜单中 但是当我尝试从模拟器菜单再次运行该应用程序时 它不允许我从中运行并显示 Toast 您的手机中未安装应用程序 在图像中 红色圆形是我的应用程序图标 如果您有您的M
  • “初始化 MCI 时出现问题”播放声音问题

    我正在尝试使用 Playsound 播放代码文件夹中的文件 但是每次运行代码时 它似乎都能够调用该文件 但我总是收到以下输出 playsound PlaysoundException Error 277 for command open p
  • 图像魔法叠加图像

    我有两个图像 一个是叠加图像 比如说具有透明度的图像 A 另一个是图像 B 我必须将叠加图像 A 放在图像 B 上 以便通过图像 A 的透明部分可以看到图像 B 的某些部分 我还必须根据一些参数移动图像B 我怎样才能用image magic
  • WebPack 源映射令人困惑(重复文件)

    我决定在我今天正在启动的一个新项目上尝试 WebPack 并且我从源映射中得到了非常奇怪的行为 我在文档中找不到任何相关信息 在浏览 StackOverflow 时也找不到其他人遇到此问题 我目前正在查看由以下公司制作的 HelloWorl
  • Scala 的代码覆盖率工具 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • FF 和 Webkit 中边框折叠的差异

    我有一个包含以下规则的表 table cellspacing 0 cellpadding 0 style width 100 并且单元格具有以下 CSS td padding 4px height 22px border 1px solid
  • JavaScript 原型继承和 html canvas

    我是一名 Ruby 开发人员 最终决定认真学习 JavaScript 所以我买了一些书 开始深入研究 但当我试图理解原型继承时 我很快就陷入了困境 这本书的例子之一如下 给定一个 Shape 其原型有一个绘制方法 以及两个子形状 一个 Tr
  • Heroku 上重启后 Better-SQLite3 数据库重置

    我有一个 Discord 机器人better sqlite3 https github com JoshuaWise better sqlite3硬币和 XP 数据库 直到两周前它一直工作得很好 现在 每次重新启动后 它只会恢复 XP 和硬
  • 支持 API 28(Android Pie) 上的 Android StrongBox 的 Android 智能手机列表

    我需要 Android 9 中支持安全元件和 StrongBox 的 Android 手机列表 在哪里或如何找到该列表 我在 Samsung Galaxy S9 和 AVD Google Pixel XL API 28 上尝试了下面的代码
  • Java 7u51/7u55 带星号的清单变量

    我正在部署一个小程序 其中包含清单中的下一个变量 Manifest Version 2 0 Ant Version Apache Ant 1 8 2 Trusted Library true Permissions all permissi
  • 在 TypeScript 中推断函数参数

    我正在尝试创建一个类型安全的映射函数 不是下面的函数 但我坚持让函数参数正确推断 export type Mapper u mapped Mapped u export type Unmapped name string args any
  • 在 ionic 2 应用程序中使用 iframe 播放 YouTube 视频

    在 Ionic 2 应用程序中 我尝试使用 iframe 嵌入一个 YouTube 视频 代码如下所示 但是 当我导航到该页面时 我收到此错误 我找不到如何解决这个问题的好答案 XMLHttpRequest 无法加载https google
  • 将 num 的签名键入 double?

    我才刚刚开始为你学习 Haskell 以获得伟大的好处 并且我在类型类方面遇到了一些麻烦 我想创建一个接受任何数字类型并强制其为双精度的函数 我的第一个想法是定义 numToDouble Num gt Double 但我认为这不起作用 因为
  • Sublime 2,如何自动关闭HTML标签并将光标放在标签内

    我试图弄清楚如何让 Sublime 2 创建以下行为 Type strong Sublime 然后会立即打印 strong strong 然后你的光标将被放置在标签内 我觉得它在不超过几个月前自动执行了此操作 或者也许我只是产生幻觉 或者正
  • 如何用水豚填充日期时间本地字段?

    我正在使用 Cocoon 添加记录 ID 看起来像workshop instance sessions attributes 1477654140 start time 目前 我正在遍历 DOM 并获取动态生成的 ID 这很好用 这样我就可
  • ASP.NET MVC 3 Razor DisplayFor 委托

    我收到此错误 模板只能与字段访问 属性访问 一维数组索引或单参数自定义索引器表达式一起使用 这是我的代码 自定义 HTML 帮助程序 包装 DisplayFor 以便我可以选择模板 public static string DisplayL
  • 仅将 Firesharp 用于 Windows 桌面推送通知

    我想在 Windows 桌面应用程序中使用 Firesharp 该应用程序只会接收来自 Firebase 的通知 并且不会有任何类型的数据库交互 Firebase Cloud Messaging FCM 是 Firebase 唯一使用的东西
  • HashPartitioner 是如何工作的?

    我阅读了文档HashPartitioner http spark apache org docs 1 3 1 api java index html org apache spark HashPartitioner html 不幸的是 除了