blob: b32ec72851da8fa86a3d226e0cee82f14d0dca85 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Apache Flink: Apache Flink 代码样式和质量指南 — 组件</title>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/flink.css">
<link rel="stylesheet" href="/css/syntax.css">
<!-- Blog RSS feed -->
<link href="/blog/feed.xml" rel="alternate" type="application/rss+xml" title="Apache Flink Blog: RSS feed" />
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<!-- We need to load Jquery in the header for custom google analytics event tracking-->
<script src="/js/jquery.min.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Main content. -->
<div class="container">
<div class="row">
<div id="sidebar" class="col-sm-3">
<!-- Top navbar. -->
<nav class="navbar navbar-default">
<!-- The logo. -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="navbar-logo">
<a href="/zh/">
<img alt="Apache Flink" src="/img/flink-header-logo.svg" width="147px" height="73px">
</a>
</div>
</div><!-- /.navbar-header -->
<!-- The navigation links. -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-main">
<!-- First menu section explains visitors what Flink is -->
<!-- What is Stream Processing? -->
<!--
<li><a href="/zh/streamprocessing1.html">What is Stream Processing?</a></li>
-->
<!-- What is Flink? -->
<li><a href="/zh/flink-architecture.html">Apache Flink 是什么?</a></li>
<!-- What is Stateful Functions? -->
<li><a href="/zh/stateful-functions.html">What is Stateful Functions?</a></li>
<!-- Use cases -->
<li><a href="/zh/usecases.html">应用场景</a></li>
<!-- Powered by -->
<li><a href="/zh/poweredby.html">Flink 用户</a></li>
&nbsp;
<!-- Second menu section aims to support Flink users -->
<!-- Downloads -->
<li><a href="/zh/downloads.html">下载</a></li>
<!-- Getting Started -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">教程<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11/zh/getting-started/index.html" target="_blank">With Flink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1/getting-started/project-setup.html" target="_blank">With Flink Stateful Functions <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="/zh/training.html">Training Course</a></li>
</ul>
</li>
<!-- Documentation -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">文档<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11" target="_blank">Flink 1.11 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-docs-master" target="_blank">Flink Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1" target="_blank">Flink Stateful Functions 2.1 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-master" target="_blank">Flink Stateful Functions Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
</ul>
</li>
<!-- getting help -->
<li><a href="/zh/gettinghelp.html">获取帮助</a></li>
<!-- Blog -->
<li><a href="/blog/"><b>Flink 博客</b></a></li>
<!-- Flink-packages -->
<li>
<a href="https://flink-packages.org" target="_blank">flink-packages.org <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Third menu section aim to support community and contributors -->
<!-- Community -->
<li><a href="/zh/community.html">社区 &amp; 项目信息</a></li>
<!-- Roadmap -->
<li><a href="/zh/roadmap.html">开发计划</a></li>
<!-- Contribute -->
<li><a href="/zh/contributing/how-to-contribute.html">如何参与贡献</a></li>
<ul class="nav navbar-nav navbar-subnav">
<li >
<a href="/zh/contributing/contribute-code.html">贡献代码</a>
</li>
<li >
<a href="/zh/contributing/reviewing-prs.html">审核 Pull Request</a>
</li>
<li >
<a href="/zh/contributing/code-style-and-quality-preamble.html">代码样式与质量指南</a>
</li>
<li >
<a href="/zh/contributing/contribute-documentation.html">贡献文档</a>
</li>
<li >
<a href="/zh/contributing/docs-style.html">Documentation Style Guide</a>
</li>
<li >
<a href="/zh/contributing/improve-website.html">贡献网站</a>
</li>
</ul>
<!-- GitHub -->
<li>
<a href="https://github.com/apache/flink" target="_blank">Flink on GitHub <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Language Switcher -->
<li>
<a href="/contributing/code-style-and-quality-components.html">English</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-bottom">
<hr />
<!-- Twitter -->
<li><a href="https://twitter.com/apacheflink" target="_blank">@ApacheFlink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<!-- Visualizer -->
<li class=" hidden-md hidden-sm"><a href="/visualizer/" target="_blank">Plan Visualizer <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<hr />
<li><a href="https://apache.org" target="_blank">Apache Software Foundation <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li>
<style>
.smalllinks:link {
display: inline-block !important; background: none; padding-top: 0px; padding-bottom: 0px; padding-right: 0px; min-width: 75px;
}
</style>
<a class="smalllinks" href="https://www.apache.org/licenses/" target="_blank">License</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/security/" target="_blank">Security</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/sponsorship.html" target="_blank">Donate</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
</div>
<div class="col-sm-9">
<div class="row-fluid">
<div class="col-sm-12">
<h1>Apache Flink 代码样式和质量指南 — 组件</h1>
<ul class="list-group" style="padding-top: 30px; font-weight: bold;">
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-preamble.html">
序言
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-pull-requests.html">
Pull Requests &amp; Changes
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-common.html">
常用编码指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-java.html">
Java 语言指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-scala.html">
Scala 语言指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-components.html">
组件指南
</a>
</li>
<li class="list-group-item">
<a href="/zh/contributing/code-style-and-quality-formatting.html">
格式指南
</a>
</li>
</ul>
<hr />
<div class="page-toc">
<ul id="markdown-toc">
<li><a href="#section" id="markdown-toc-section">组件特定指南</a> <ul>
<li><a href="#section-1" id="markdown-toc-section-1">配置更改</a></li>
<li><a href="#section-2" id="markdown-toc-section-2">连接器</a></li>
<li><a href="#section-3" id="markdown-toc-section-3">示例</a></li>
<li><a href="#sql-api" id="markdown-toc-sql-api">表和 SQL API</a></li>
</ul>
</li>
</ul>
</div>
<h2 id="section">组件特定指南</h2>
<p><em>关于特定组件更改的附加指南。</em></p>
<h3 id="section-1">配置更改</h3>
<p>配置选项应该放在哪里?</p>
<ul>
<li>
<p><span style="text-decoration:underline;">‘flink-conf.yaml’:</span> 所有属于可能要跨作业标准的执行行为的配置。可以将其想像成 Ops 的工作人员或为其他团队提供流处理平台的工作人员设置的参数。</p>
</li>
<li><span style="text-decoration:underline;">‘ExecutionConfig’</span>: 执行期间算子需要特定于单个 Flink 应用程序的参数,典型的例子是水印间隔,序列化参数,对象重用。</li>
<li><span style="text-decoration:underline;">ExecutionEnvironment (在代码里)</span>: 所有特定于单个 Flink 应用程序的东西,仅在构建程序/数据流时需要,在算子执行期间不需要。</li>
</ul>
<p>如何命名配置键:</p>
<ul>
<li>
<p>配置键名应该分层级。将配置视为嵌套对象(JSON 样式)</p>
<div class="highlight"><pre><code>taskmanager: {
jvm-exit-on-oom: true,
network: {
detailed-metrics: false,
request-backoff: {
initial: 100,
max: 10000
},
memory: {
fraction: 0.1,
min: 64MB,
max: 1GB,
buffers-per-channel: 2,
floating-buffers-per-gate: 16
}
}
}
</code></pre></div>
</li>
<li>
<p>因此生成的配置键应该:</p>
<p><strong>不是</strong> <code>"taskmanager.detailed.network.metrics"</code></p>
<p><strong>而是</strong> <code>"taskmanager.network.detailed-metrics"</code></p>
</li>
</ul>
<h3 id="section-2">连接器</h3>
<p>连接器历来很难实现,需要处理多线程、并发和检查点等许多方面。</p>
<p>作为 <a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-27%3A+Refactor+Source+Interface">FLIP-27</a> 的一部分,我们正在努力使数据源(source)的实现更简单。新的数据源应该不必处理并发/线程和检查点的任何方面。</p>
<p>预计在不久的将来,会有类似针对数据汇(sink)的 FLIP。</p>
<h3 id="section-3">示例</h3>
<p>示例应该是自包含的,不需要运行 Flink 以外的系统。除了显示如何使用具体的连接器的示例,比如 Kafka 连接器。数据源/数据汇可以使用 <code>StreamExecutionEnvironment.socketTextStream</code>,这个不应该在生产中使用,但对于研究示例如何运行是相当方便的,以及基于文件的数据源/数据源。(对于流,Flink 提供了连续的文件数据源读取数据)
示例也不应该是纯粹的玩具示例,而是在现实世界的代码和纯粹的抽象示例之间取得平衡。WordCount 示例到现在已经很久了,但它是一个很好的功能突出并可以做有用事情的简单代码示例。</p>
<p>示例中应该有不少的注释。他们可以在类级 Javadoc 中描述示例的总体思路,并且描述正在发生什么和整个代码里使用了什么功能。还应描述预期的输入数据和输出数据。</p>
<p>示例应该包括参数解析,以便你可以运行一个示例(使用 <code>bin/flink run path/to/myExample.jar --param1 … --param2</code> 运行程序)。</p>
<h3 id="sql-api">表和 SQL API</h3>
<h4 id="section-4">语义</h4>
<p><strong>SQL 标准应该是事实的主要来源。</strong></p>
<ul>
<li>语法、语义和功能应该和 SQL 保持一致!</li>
<li>我们不需要重造轮子。大部分问题都已经在业界广泛讨论过并写在 SQL 标准中了。</li>
<li>我们依靠最新的标准(在写这篇文档时使用 SQL:2016 or ISO/IEC 9075:2016 <a href="https://standards.iso.org/ittf/PubliclyAvailableStandards/c065143_ISO_IEC_TR_19075-5_2016.zip">[下载]</a>)。并不是所有的部分都能在网上找到,但可以通过网络查找确认。</li>
</ul>
<p>讨论与标准或厂商特定解释的差异。</p>
<ul>
<li>一旦定义了语法或行为就不能轻易撤销。</li>
<li>需要扩展或解释标准的贡献需要与社区进行深入的讨论。</li>
<li>请通过一些对 Postgres、Microsoft SQL Server、Oracle、Hive、Calcite、Beam 等其他厂商如何处理此类案例进行初步的探讨来帮助提交者。</li>
</ul>
<p>将 Table API 视为 SQL 和 Java/Scala 编程世界之间的桥梁。</p>
<ul>
<li>Table API 是一种嵌入式域特定语言,用于遵循关系模型的分析程序。
在语法和名称方面不需要严格遵循 SQL 标准,但如果这有助于使其感觉更直观,那么可以更接近编程语言的方式/命名函数和功能。</li>
<li>Table API 可能有一些非 SQL 功能(例如 map()、flatMap() 等),但还是应该“感觉像 SQL”。如果可能,函数和算子应该有相等的语义和命名。</li>
</ul>
<h4 id="section-5">常见错误</h4>
<ul>
<li>添加功能时支持 SQL 的类型系统。
<ul>
<li>SQL 函数、连接器或格式化从一开始就应该原生的支持大多数 SQL 类型。</li>
<li>不支持的类型会导致混淆,限制可用性,多次修改相同代码会增加负担。</li>
<li>例如,当添加 <code>SHIFT_LEFT</code> 函数时,确保贡献足够通用,不仅适用于 <code>INT</code> 也适用于 <code>BIGINT</code><code>TINYINT</code></li>
</ul>
</li>
</ul>
<h4 id="section-6">测试</h4>
<p>测试为空性</p>
<ul>
<li>几乎每个操作,SQL 都原生支持 <code>NULL</code>,并具有 3 值布尔逻辑。</li>
<li>确保测试每个功能的可空性。</li>
</ul>
<p>尽量避免集成测试</p>
<ul>
<li>启动一个 Flink 集群并且对 SQL 查询生成的代码进行编译会很耗时。</li>
<li>避免对 planner 测试或 API 调用的变更进行集成测试。</li>
<li>相反,使用单元测试来验证 planner 产生的优化计划。或者直接测试算子的运行时行为。</li>
</ul>
<h4 id="section-7">兼容性</h4>
<p>不要在次要版本中引入物理计划更改!</p>
<ul>
<li>流式 SQL 中状态的向后兼容性依赖于物理执行计划保持稳定的事实。否则,生成的 Operator Names/IDs 将发生变化,并且无法匹配和恢复状态。</li>
<li>导致流传输管道的优化物理计划改变的每个 bug 修复均会破坏兼容性。</li>
<li>因此,导致不同优化计划的此类更改目前仅可以合并到大版本中。</li>
</ul>
<h4 id="scala--java-">Scala / Java 互操作性(遗留代码部分)</h4>
<p>在设计接口时要牢记 Java。</p>
<ul>
<li>考虑一个类将来是否需要与 Java 类交互。</li>
<li>在接口中使用 Java 集合和 Java Optional,以便与 Java 代码平滑集成。</li>
<li>如果要将类转换为 Java,不要使用 .copy() 或 apply() 等 case class 的功能进行构造。</li>
<li>纯 Scala 面向用户的 API 应该使用纯 Scala 集合/迭代/等与 Scala 自然和惯用的(“scalaesk”)集成。</li>
</ul>
</div>
</div>
</div>
</div>
<hr />
<div class="row">
<div class="footer text-center col-sm-12">
<p>Copyright © 2014-2019 <a href="http://apache.org">The Apache Software Foundation</a>. All Rights Reserved.</p>
<p>Apache Flink, Flink®, Apache®, the squirrel logo, and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
<p><a href="/privacy-policy.html">Privacy Policy</a> &middot; <a href="/blog/feed.xml">RSS feed</a></p>
</div>
</div>
</div><!-- /.container -->
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.matchHeight/0.7.0/jquery.matchHeight-min.js"></script>
<script src="/js/codetabs.js"></script>
<script src="/js/stickysidebar.js"></script>
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-52545728-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>