本指南介绍了为 Apache Spark 做出各种贡献的最佳方式,包括提交代码更改之前需要做些什么。

为 Spark 贡献不仅仅意味着编写代码。在邮件列表上帮助新用户、测试版本和改进文档也同样受欢迎。事实上,提出重大的代码更改通常需要先通过其他方式帮助社区,从而积累经验和信誉。本指南也是成为有效贡献者的指南。

因此,本指南按顺序组织了贡献,这些贡献应该是新贡献者在打算长期参与时应该考虑的。建立一些帮助他人的记录,而不仅仅是打开拉取请求。

通过帮助其他用户来贡献

为 Spark 做出贡献的一个好方法是帮助回答用户在 [email protected] 邮件列表或 StackOverflow 上的问题。总是有很多新的 Spark 用户;花几分钟时间帮助回答一个问题是一项非常有价值的社区服务。

贡献者应该订阅此列表并关注它,以便了解 Spark 中发生的事情。回答问题是帮助社区的一种出色且可见的方式,这也展示了你的专业知识。

请参阅 邮件列表指南,了解有关如何在邮件列表以及 StackOverflow 等论坛上有效参与讨论的指南。

通过测试版本来贡献

Spark 的发布流程是面向社区的,社区成员可以在 [email protected] 邮件列表上对新版本进行投票。Spark 用户被邀请订阅此列表以接收公告,并在较新版本上测试他们的工作负载,并提供对在较新版本中发现的任何性能或正确性问题的反馈。

通过审查更改来贡献

对 Spark 源代码的更改是通过 GitHub 拉取请求(稍后描述)提出、审查和提交的。任何人都可以查看和评论这里正在进行的更改。审查他人的更改是了解更改流程如何工作以及了解代码各个部分活动的好方法。你可以通过审查更改并提出问题或指出问题来提供帮助——就像拼写错误或小的样式问题一样简单。还可以查看 https://spark-prs.appspot.com/,这是一个方便查看和过滤打开的 PR 的方法。

贡献文档更改

要提出对发布文档(即出现在 https://spark.apache.org/docs/ 下的文档)的更改,请编辑 Spark 的 docs/ 目录中的 Markdown 源文件,其 README 文件显示了如何在本地构建文档以测试你的更改。提出文档更改的过程与下面提出的代码更改过程相同。

要提出对其余文档(即出现在 https://spark.apache.org/docs/ 下的文档)的更改,请类似地编辑 spark-website 存储库 中的 Markdown 并打开拉取请求。

为 Spark 贡献用户库

就像 Java 和 Scala 应用程序可以访问大量库和实用程序一样,这些库和实用程序本身并不属于 Java 或 Scala,Spark 旨在支持丰富的库生态系统。许多新的有用实用程序或功能属于 Spark 之外,而不是核心。例如:语言支持可能必须是核心 Spark 的一部分,但是,有用的机器学习算法可以在 MLlib 之外愉快地存在。

为此,大型且独立的新功能通常会被拒绝包含在 Spark 本身中,但是,可以并且应该作为单独的项目和存储库托管,并包含在 spark-packages.org 集合中。

贡献错误报告

理想情况下,错误报告会附带一个建议的代码更改来修复错误。这并不总是可能的,因为发现错误的人可能没有修复错误的经验。可以通过创建 JIRA 来报告错误,但无需创建拉取请求(见下文)。

但是,错误报告只有在包含足够的信息来理解、隔离并理想地重现错误时才有用。仅仅遇到错误并不意味着应该报告错误;如下所示,首先搜索 JIRA 并搜索和询问 Spark 用户/开发邮件列表。无法重现的错误或简单的错误报告可能会被关闭。

如果错误报告包含有关错误是如何引入的以及通过哪个提交引入的描述,这将非常有帮助,这样审阅者可以轻松地理解错误。它还有助于提交者在合并拉取请求时决定应该将错误修复回溯到多远。修复错误的拉取请求应该将问题缩小到根本原因。

性能回归也是一种错误。修复性能回归的拉取请求必须提供基准测试来证明问题确实已修复。

请注意,数据正确性/数据丢失错误非常严重。确保相应的错误报告 JIRA 票证被标记为 correctnessdata-loss。如果错误报告没有得到足够的关注,请发送电子邮件至 [email protected],以引起更多关注。

也可以提出新功能。这些通常没有帮助,除非附带详细信息,例如设计文档和/或代码更改。大型新贡献应该首先考虑 spark-packages.org(见上文),或者首先在邮件列表上进行讨论。功能请求可能会被拒绝,或者在长时间不活动后被关闭。

为 JIRA 维护贡献

鉴于 Apache Spark JIRA 中提出的问题数量之多,不可避免地,一些问题是重复的,或者最终以其他方式变得过时并最终得到修复,或者无法重现,或者可以从更多细节中获益,等等。帮助识别这些问题并解决它们很有用,无论是通过推进讨论,甚至解决 JIRA。大多数贡献者能够直接解决 JIRA。在确定你是否非常有信心应该解决问题时,请使用判断,尽管更改可以轻松撤消。如有疑问,请在 JIRA 上留言。

在解决 JIRA 时,请遵守一些有用的约定

  • 如果存在可以指向的解决问题的更改,则将其解决为已修复
    • 仅当解决方案为已修复时,才设置修复版本
    • 将分配者设置为对解决方案贡献最大的人,这通常是打开解决问题的 PR 的人。
    • 如果几个人都做出了贡献,最好分配给更“初级”的非提交者贡献者
  • 对于无法根据报告在 master 上重现的问题,将其解决为无法重现
    • 如果很明显之前的哪个拉取请求解决了它,那么已修复也是合理的。链接到它。
  • 如果问题与另一个问题相同或是一个子集,则将其解决为重复
    • 确保链接到它重复的 JIRA
    • 最好将活动或讨论较少的问题解决为重复问题
  • 如果问题看起来明显过时,并且适用于自它打开以来已发生根本性变化的问题或组件,则将其解决为不是问题
  • 如果问题没有意义——例如,不可操作,非 Spark 问题,则将其解决为无效
  • 如果这是一个连贯的问题,但有明确的迹象表明没有支持或兴趣采取行动,则将其解决为不会修复
  • 如果它们只是不对应于自身可操作更改的容器问题,则伞形问题通常会被标记为已完成

准备贡献代码更改

选择要贡献的内容

Spark 是一个异常繁忙的项目,平均每隔几个小时就会出现一个新的 JIRA 或拉取请求。审查可能需要提交者花费数小时或数天的时间。如果贡献者专注于有用、清晰、易于评估且已通过基本检查的更改,每个人都会受益。

有时,贡献者已经有一个特定的新更改或错误。如果正在寻找想法,请咨询 JIRA 中的入门任务列表,或询问 [email protected] 邮件列表。

在继续之前,贡献者应该评估建议的更改是否可能相关、新颖且可操作

  • 是否清楚代码必须更改?仅当已识别出明确的问题或更改时,才适合提出 JIRA 和拉取请求。如果只是在使用 Spark 时遇到问题,请首先使用邮件列表,而不是考虑提交 JIRA 或提出更改。如有疑问,请先向 [email protected] 发送电子邮件,了解可能的更改
  • 搜索 [email protected][email protected] 邮件列表的 存档 以查找相关讨论。通常,问题之前已经讨论过,并且有一个不需要代码更改的解决方案,或者记录了哪些类型的更改不会被接受为解决方案。
  • 在 JIRA 中搜索现有问题:https://issues.apache.org/jira/browse/SPARK
  • 在右上角的搜索框中键入 spark [搜索词]。如果已经存在逻辑上类似的问题,那么请先参与现有 JIRA 和拉取请求的讨论,而不是创建一个新的问题。
  • 更改的范围是否与贡献者的经验水平相匹配?任何人都可以建议修复拼写错误,但重构核心调度逻辑需要对 Spark 有更多的了解。一些更改需要先积累经验(见上文)。

值得再次强调的是,对 Spark 核心的更改,或对 SQL 和 Catalyst 等高度复杂且重要的模块的更改,更难正确进行。它们将受到更多审查,并且将比对不太关键的代码的更改有更高的审查标准。

MLlib 特定的贡献指南

虽然丰富的算法集是 MLLib 的重要目标,但要扩展项目,可维护性、一致性和代码质量必须放在首位。新的算法应该

  • 广为人知
  • 被使用和接受(学术引用和具体用例可以帮助证明这一点)
  • 具有高度可扩展性
  • 有良好的文档
  • 具有与 MLLib 中其他完成相同任务的算法一致的 API
  • 对开发者支持有合理的预期。
  • 在公共类、方法和变量上使用 @Since 注解。

错误消息指南

Spark 中抛出的异常应该与标准化和可操作的错误消息相关联。

错误消息应该回答以下问题

  • 什么是问题?
  • 为什么问题会发生?
  • 如何解决问题?

编写错误消息时,您应该

  • 使用主动语态
  • 避免使用基于时间的陈述,例如对未来支持的承诺
  • 使用现在时描述错误并提供建议
  • 如果解决方案不清楚,请提供具体示例
  • 避免听起来指责、评判或侮辱
  • 直接
  • 不要在面向用户的错误中使用编程术语

有关更多详细信息,请参阅 错误消息指南

代码审查标准

在考虑如何贡献代码之前,了解代码是如何审查的以及为什么更改可能会被拒绝非常有用。请参阅 Google 工程实践文档中的 代码审查人员详细指南。简而言之,具有许多或大型积极因素,并且负面影响或风险很少的更改更有可能被合并,并且合并速度更快。风险较大和价值较低的更改极不可能被合并,并且可能直接被拒绝,而不是接受审查迭代。

积极因素

  • 修复现有功能中错误的根本原因
  • 添加大量用户需要的功能或修复问题
  • 简单、有针对性
  • 维护或改进 Python、Java、Scala 之间的一致性
  • 易于测试;有测试
  • 降低复杂性和代码行数
  • 更改已讨论过,提交者已知晓

负面因素、风险

  • 只对错误的症状进行临时修复
  • 引入复杂的新功能,尤其是需要支持的 API
  • 添加仅对利基用例有帮助的复杂性
  • 添加不需要在 Spark 中维护的用户空间功能,但可以托管在外部并由 spark-packages.org 索引
  • 更改公共 API 或语义(很少允许)
  • 添加大型依赖项
  • 更改现有依赖项的版本
  • 添加大量代码
  • 在一个“大爆炸”更改中进行大量修改

贡献代码更改

在提出代码更改之前,请查看上一节。本节介绍如何进行操作。

当您贡献代码时,您确认贡献是您的原创作品,并且您根据项目的开源许可证将作品许可给项目。无论您是否明确说明这一点,通过拉取请求、电子邮件或其他方式提交任何受版权保护的材料,您都同意根据项目的开源许可证许可该材料,并保证您有权这样做。

克隆 Apache Spark 源代码

如果您有兴趣使用最新的开发中代码或为 Apache Spark 开发做出贡献,您可以从 Git 中检出 master 分支

# Master development branch
git clone git://github.com/apache/spark.git

下载 Spark 后,您可以在 文档页面 上找到安装和构建它的说明。

JIRA

通常,Spark 使用 JIRA 来跟踪逻辑问题,包括错误和改进,并使用 GitHub 拉取请求来管理特定代码更改的审查和合并。也就是说,JIRA 用于描述应该修复或更改的内容以及高级方法,而拉取请求描述如何在项目的源代码中实现该更改。例如,主要的设计决策在 JIRA 中进行讨论。

  1. 找到与更改相关的现有 Spark JIRA。
    1. 如果要创建更改以解决 JIRA 中的现有问题,请不要创建新的 JIRA;而是添加到现有讨论和工作中
    2. 查找与 JIRA 链接的现有拉取请求,以了解是否有人已经在处理 JIRA
  2. 如果更改是新的,则通常需要一个新的 JIRA。但是,对于微不足道的更改,其中更改的内容与更改的方式几乎相同,则不需要 JIRA。例如:Fix typos in Foo scaladoc
  3. 如果需要,请创建一个新的 JIRA
    1. 提供描述性的标题。“更新 Web UI”或“调度程序中的问题”是不够的。“Kafka 流式处理支持无法在 YARN 集群模式下处理空队列”很好。
    2. 编写详细的描述。对于错误报告,理想情况下应该包括问题的简短重现。对于新功能,它可能包括设计文档。
    3. 设置必需字段
      1. 问题类型。通常,Bug、改进和新功能是 Spark 中唯一使用的类型。
      2. 优先级。设置为 Major 或以下;更高的优先级通常保留给提交者设置。主要例外是正确性或数据丢失问题,这些问题可以标记为 Blockers。JIRA 倾向于在其优先级字段值中不幸地混淆“大小”和“重要性”。它们的含义大致为
        1. Blocker:如果没有此更改,发布将毫无意义,因为发布对于大量用户来说将不可用。正确性和数据丢失问题应被视为其目标版本的 Blockers。
        2. Critical:如果没有此更改,大量用户将缺少重要功能,并且/或者解决方法很困难
        3. Major:一小部分用户在没有此更改的情况下将缺少重要功能,并且存在解决方法
        4. Minor:利基用例缺少一些支持,但它不会影响使用或很容易解决
        5. Trivial:一个不错的更改,但实际上不太可能出现任何问题
      3. 组件
      4. 影响版本。对于 Bug,至少分配一个已知存在问题或需要更改的版本
      5. 标签。使用不多,除了以下情况
        • correctness:正确性问题
        • data-loss:数据丢失问题
        • release-notes:更改的影响需要在发行说明中提及。JIRA 或拉取请求应包含适合包含在发行说明中的详细信息 - 请参阅下面的“文档文本”。
        • starter:适合新贡献者的简单的小更改
      6. 文档文本:对于需要在发行说明中添加条目的问题,这应该包含发行经理应该包含在发行说明中的信息。这应该包括对受影响行为的简要概述,以及对行为更改的详细信息。它可以在打开 JIRA 时临时填写,但在问题解决时可能需要使用最终详细信息进行更新。
    4. 不要设置以下字段
      1. 修复版本。这仅由提交者在解决时分配。
      2. 目标版本。这由提交者分配,以指示 PR 已被接受,以便在目标版本中进行可能的修复。
    5. 不要包含补丁文件;拉取请求用于提出实际更改。
  4. 如果更改是大型更改,请考虑在继续实施更改之前,先在 [email protected] 上邀请讨论该问题。

拉取请求

在 Apache Spark 中创建拉取请求之前,务必检查测试是否可以在您的分支上通过,因为我们的 GitHub Actions 工作流程会自动为您的拉取请求/后续提交运行测试,每次运行都会占用 Apache Spark 存储库中 GitHub Actions 的有限资源。以下步骤将引导您完成该过程。

  1. 如果您还没有,请 fork https://github.com/apache/spark 上的 GitHub 存储库
  2. 转到您分叉的存储库的“Actions”选项卡,并启用“Build and test”和“Report test results”工作流程
  3. 克隆您的分叉并创建一个新分支
  4. 考虑是否需要添加或更新文档或测试作为更改的一部分,并根据需要添加它们。
    1. 添加测试时,确保测试具有自描述性。
    2. 此外,您应该考虑在拉取请求针对修复特定问题时在测试中编写 JIRA ID。实际上,通常在 JIRA 类型是错误或 PR 向现有测试类添加了几个测试时添加它。请参阅以下示例
      • Scala
        test("SPARK-12345: a short description of the test") {
          ...
        
      • Java
        @Test
        public void testCase() {
          // SPARK-12345: a short description of the test
          ...
        
      • Python
        def test_case(self):
            # SPARK-12345: a short description of the test
            ...
        
      • R
        test_that("SPARK-12345: a short description of the test", {
          ...
        
  5. 考虑是否需要添加或更新基准测试结果作为更改的一部分,并通过 在您的分叉存储库中运行基准测试 来生成基准测试结果,根据需要添加它们。
  6. 使用 ./dev/run-tests 运行所有测试,以验证代码是否仍然可以编译、通过测试以及通过样式检查。如果样式检查失败,请查看下面的代码样式指南。
  7. 将提交推送到您的分支。这将在您的分叉存储库上触发“Build and test”和“Report test results”工作流程,并开始测试和验证您的更改。
  8. 打开一个拉取请求,针对 apache/sparkmaster 分支。(只有在特殊情况下,PR 才会针对其他分支打开)。这将触发“On pull request*”工作流程(在 Spark 存储库上),该工作流程将查找/观察“您的”分叉存储库上的成功工作流程运行(如果正在运行,它将等待)。
    1. PR 标题应采用 [SPARK-xxxx][COMPONENT] Title 的形式,其中 SPARK-xxxx 是相关的 JIRA 编号,COMPONENT spark-prs.appspot.com 上显示的 PR 类别之一,Title 可以是 JIRA 的标题或更具体的标题,描述 PR 本身。
    2. 如果拉取请求仍在进行中,尚未准备好合并,但需要推送到 GitHub 以便于审查,则在组件后添加 [WIP]
    3. 考虑识别已在更改的代码上工作的提交者或其他贡献者。在 GitHub 中找到文件,然后单击“Blame”以查看代码最后更改者的逐行注释。您可以在 PR 描述中添加 @username 以立即 ping 他们。
    4. 请说明贡献是您的原创作品,并且您根据项目的开源许可证将作品许可给项目。
  9. 如果有相关的 JIRA,它将被标记为“进行中”,您的拉取请求将自动链接到它。您无需成为 JIRA 的分配者即可对其进行处理,但欢迎您评论您已开始工作。
  10. 如果您的拉取请求中存在与 SparkR 相关的更改,AppVeyor 将自动触发以在 Windows 上测试 SparkR,这大约需要一个小时。与上述步骤类似,修复故障并推送新的提交,这将请求 AppVeyor 重新测试。

审查流程

  • 其他审阅者,包括提交者,可能会对更改发表评论并建议修改。只需将更多提交推送到同一个分支即可添加更改。
  • 鼓励社区中的每个人进行活跃、礼貌、快速的的技术辩论。结果可能是拒绝整个更改。
  • 请记住,对 Spark 更关键部分(如其核心和 SQL 组件)的更改将受到更多审查,并且可能需要比其他更改更多的测试和正确性证明。
  • 审阅者可以通过评论来表明更改看起来适合合并,例如:“我认为此补丁看起来不错”。Spark 使用 LGTM 约定来表示对补丁的最强技术签署:只需评论“LGTM”即可。它具体意味着:“我已经仔细查看了它,并承担了与我自己编写补丁相同的责任”。如果您评论 LGTM,则需要帮助解决补丁中的错误或后续问题。一致、明智地使用 LGTM 是在更广泛的社区中获得审阅者信誉的好方法。
  • 有时,其他更改将被合并,这些更改与您的拉取请求的更改冲突。在解决冲突之前,无法合并 PR。这可以通过以下方式解决,例如,通过 git remote add upstream https://github.com/apache/spark.git 添加远程以跟上上游更改,运行 git fetch upstream,然后运行 git rebase upstream/master 并手动解决冲突,然后将结果推送到您的分支。
  • 尽量对讨论做出响应,而不是让回复之间相隔几天。

关闭您的拉取请求/JIRA

  • 如果更改被接受,它将被合并,拉取请求将自动关闭,以及任何相关的 JIRA。
    • 请注意,在您被要求针对 master 以外的分支打开拉取请求的罕见情况下,您实际上需要手动关闭拉取请求。
    • JIRA 将分配给更改的主要贡献者,作为一种给予信用的方式。如果 JIRA 未及时关闭和/或分配,请在 JIRA 上发表评论。
  • 如果您的拉取请求最终被拒绝,请立即关闭它。
    • … 因为提交者无法直接关闭 PR。
    • 如果提交者发表了类似“介意关闭此 PR 吗?”的评论,拉取请求将在 Apache 自动处理后大约一周内自动关闭。这意味着提交者明确要求关闭它。
  • 如果拉取请求没有得到太多关注,请考虑改进描述或更改本身,并在几天后再次 ping 可能的审阅者。考虑提出更容易包含的更改,例如更小和/或侵入性更小的更改。
  • 如果它经过审查,但在几周后没有被采纳,在征求最相关审阅者的审查后,或者,遇到了中立的反应,结果可以被认为是“软否”。在这种情况下,撤回并关闭 PR 会很有帮助。
  • 如果拉取请求被关闭,因为它被认为不是解决 JIRA 的正确方法,则保持 JIRA 开启。但是,如果审查清楚地表明 JIRA 中识别的问题不会通过任何拉取请求解决(不是问题,不会修复),那么也解决 JIRA。

代码风格指南

请遵循现有代码库的风格。

  • 对于 Python 代码,Apache Spark 遵循 PEP 8,但有一个例外:行长可以达到 100 个字符,而不是 79 个字符。
  • 对于 R 代码,Apache Spark 遵循 Google 的 R 风格指南,但有三个例外:行长可以达到 100 个字符,而不是 80 个字符,函数名没有限制,但它有一个初始的小写字母,并且允许 S4 对象/方法。
  • 对于 Java 代码,Apache Spark 遵循 Oracle 的 Java 代码约定 和下面的 Scala 指南。后者优先。
  • 对于 Scala 代码,Apache Spark 遵循官方的 Scala 风格指南Databricks Scala 指南。后者优先。要格式化 Scala 代码,请在提交 PR 之前运行 ./dev/scalafmt。

如果有疑问

如果您不确定某件事的正确风格,请尝试遵循现有代码库的风格。查看代码中是否有其他使用您功能的示例。随时在 [email protected] 列表上提问,以及/或者询问提交者。

行为准则

Apache Spark 项目遵循 Apache 软件基金会行为准则。该 行为准则 适用于 Apache 软件基金会管理的所有空间,包括 IRC、所有公开和私人邮件列表、问题跟踪器、维基、博客、Twitter 以及我们的社区使用的任何其他通信渠道。针对面对面活动(即会议)的行为准则在已发布的 ASF 反骚扰政策中进行了编码。

我们希望所有正式或非正式地参与 Apache 社区,或声称与基金会有任何关联,在任何与基金会相关的活动中,尤其是在代表 ASF 时,在任何角色中,都遵守此行为准则。

此代码并非详尽无遗或完整。它旨在提炼我们对协作、共享环境和目标的共同理解。我们希望它在精神上和文字上都能得到遵循,以便它能够丰富我们所有人以及我们参与的技术社区。

有关更多信息和具体指南,请参阅 Apache 软件基金会行为准则

最新消息

存档