提交 fcde1692 编写于 作者: W wizardforcel

2019-02-17 15:28:30

上级 3b1314ea
......@@ -17,7 +17,7 @@ JobManager协调每个Flink部署。它负责_调度_和_资源管理_。
例如,请考虑以下三个JobManager实例的设置:
![](https://flink.sojb.cn/fig/jobmanager_ha_overview.png)
![](img/jobmanager_ha_overview.png)
### 配置
......
......@@ -45,7 +45,7 @@
此持续时间是在最新检查点结束和下一个检查点开始之间必须经过的最小时间间隔。下图说明了这对检查点的影响。
![插图检查点之间的最小时间参数如何影响检查点行为。](https://flink.sojb.cn/fig/checkpoint_tuning.svg)
![插图检查点之间的最小时间参数如何影响检查点行为。](img/checkpoint_tuning.svg)
_注意:_可以配置应用程序(通过`CheckpointConfig`)以允许多个检查点同时进行。对于Flink中具有大状态的应用程序,这通常会将太多资源绑定到检查点。当手动触发保存点时,它可能正在与正在进行的检查点同时进行。
......@@ -186,7 +186,7 @@ Flink为所有检查点和保存点提供可选压缩(默认:关闭)。目
请注意,根据所选的状态后台和检查点策略,每个检查点可能会产生一些额外费用,用于创建和存储辅助本地状态副本。例如,在大多数情况下,实现将简单地将对分布式存储的写入复制到本地文件。
![检查点的例证与任务地方恢复的。](https://flink.sojb.cn/fig/local_recovery.png)
![检查点的例证与任务地方恢复的。](img/local_recovery.png)
### 主(分布式存储)和辅助(任务 - 本地)状态SNAPSHOT的关系
......
......@@ -1611,5 +1611,5 @@ Flink通过将程序拆分为子任务并将这些子任务调度到处理槽来
启动Flink应用程序时,用户可以提供用于该作业的默认插槽数.因此调用命令行值`-p`(用于并行).此外,可以为整个应用程序和各个算子[设置编程API中的插槽数](https://flink.sojb.cn/dev/parallel.html).
![](https://flink.sojb.cn/fig/slots_parallelism.svg)
![](img/slots_parallelism.svg)
......@@ -13,7 +13,7 @@
为了获得更大的灵活性,可以单独启用和配置内部和外部连接的安全性。
![内部和外部连接](https://flink.sojb.cn/fig/ssl_internal_external.svg)
![内部和外部连接](img/ssl_internal_external.svg)
#### 内部连接
......
......@@ -32,7 +32,7 @@ Flink的Web界面提供了一个监视作业检查点的选项卡。作业终止
检查点历史记录保存有关最近触发的检查点的统计信息,包括当前正在进行的检查点。
<center>![检查点监控:历史](https://flink.sojb.cn/fig/checkpoint_monitoring-history.png)</center>
<center>![检查点监控:历史](img/checkpoint_monitoring-history.png)</center>
* **ID**:触发​​的检查点的ID。每个检查点的ID都会增加,从1开始。
* **状态**:检查点的当前状态,_正在进行中_(),_完成_(),或_失败_()。如果触发的检查点是保存点,您将看到一个 符号。
......@@ -62,7 +62,7 @@ web.checkpoints.history: 15
摘要计算在对齐期间缓冲的端到端持续时间,状态大小和字节的所有已完成检查点的简单最小/平均/最大统计数据(有关这些含义的详细信息,请参阅[历史记录](#history))。
<center>![检查点监控:摘要](https://flink.sojb.cn/fig/checkpoint_monitoring-summary.png)</center>
<center>![检查点监控:摘要](img/checkpoint_monitoring-summary.png)</center>
请注意,这些统计信息不会在JobManager丢失后继续存在,并在JobManager故障转移时重置为。
......@@ -81,13 +81,13 @@ web.checkpoints.history: 15
单击检查点的“ _更多详细信息”_链接时,将获得所有 算子的“最小/平均/最大”摘要以及每个子任务的详细数字。
<center>![检查点监控:详细信息](https://flink.sojb.cn/fig/checkpoint_monitoring-details.png)</center>
<center>![检查点监控:详细信息](img/checkpoint_monitoring-details.png)</center>
#### 每个算子摘要
<center>![检查点监控:详细信息摘要](https://flink.sojb.cn/fig/checkpoint_monitoring-details_summary.png)</center>
<center>![检查点监控:详细信息摘要](img/checkpoint_monitoring-details_summary.png)</center>
#### 所有子任务统计
<center>![检查点监控:子任务](https://flink.sojb.cn/fig/checkpoint_monitoring-details_subtasks.png)</center>
<center>![检查点监控:子任务](img/checkpoint_monitoring-details_subtasks.png)</center>
......@@ -17,7 +17,7 @@ Flink的Web界面提供了一个选项卡来监控正在运行的作业的背压
背压监测通过反复获取正在运行的任务的堆栈跟踪样本来工作。JobManager会触发对作业`Thread.getStackTrace()`任务的重复调用。
![](https://flink.sojb.cn/fig/back_pressure_sampling.png)
![](img/back_pressure_sampling.png)
如果示例显示任务线程卡在某个内部方法调用中(从网络堆栈请求缓冲区),则表示该任务存在背压。
......@@ -47,13 +47,13 @@ Flink的Web界面提供了一个选项卡来监控正在运行的作业的背压
请注意,单击该行可触发此 算子的所有子任务的样本。
![](https://flink.sojb.cn/fig/back_pressure_sampling_in_progress.png)
![](img/back_pressure_sampling_in_progress.png)
### 背压状态
如果您看到任务的状态**正常**,则表示没有背压指示。另一方面,**HIGH**意味着任务被加压。
![](https://flink.sojb.cn/fig/back_pressure_sampling_ok.png)
![](img/back_pressure_sampling_ok.png)
![](https://flink.sojb.cn/fig/back_pressure_sampling_high.png)
![](img/back_pressure_sampling_high.png)
......@@ -17,6 +17,6 @@
您可以单击图中的组件以了解更多信息。
<center>![Apache Flink:Stack](https://flink.sojb.cn/fig/stack.png)</center>
<center>![Apache Flink:Stack](img/stack.png)</center>
<map name="overview-stack"><area id="lib-datastream-cep" title="CEP: Complex Event Processing" href="https://flink.sojb.cn/dev/libs/cep.html" shape="rect" coords="63,0,143,177"> <area id="lib-datastream-table" title="Table: Relational DataStreams" href="https://flink.sojb.cn/dev/table_api.html" shape="rect" coords="143,0,223,177"> <area id="lib-dataset-ml" title="FlinkML: Machine Learning" href="https://flink.sojb.cn/dev/libs/ml/index.html" shape="rect" coords="382,2,462,176"> <area id="lib-dataset-gelly" title="Gelly: Graph Processing" href="https://flink.sojb.cn/dev/libs/gelly/index.html" shape="rect" coords="461,0,541,177"> <area id="lib-dataset-table" title=" Table API and SQL" href="https://flink.sojb.cn/dev/table_api.html" shape="rect" coords="544,0,624,177"> <area id="datastream" title="DataStream API" href="https://flink.sojb.cn/dev/datastream_api.html" shape="rect" coords="64,177,379,255"> <area id="dataset" title="DataSet API" href="https://flink.sojb.cn/dev/batch/index.html" shape="rect" coords="382,177,697,255"> <area id="runtime" title="Runtime" href="https://flink.sojb.cn/concepts/runtime.html" shape="rect" coords="63,257,700,335"> <area id="local" title="Local" href="https://flink.sojb.cn/tutorials/local_setup.html" shape="rect" coords="62,337,275,414"> <area id="cluster" title="Cluster" href="https://flink.sojb.cn/ops/deployment/cluster_setup.html" shape="rect" coords="273,336,486,413"> <area id="cloud" title="Cloud" href="https://flink.sojb.cn/ops/deployment/gce_setup.html" shape="rect" coords="485,336,700,414"></map>
\ No newline at end of file
......@@ -29,7 +29,7 @@ Flink的容错机制的核心部分是绘制分布式数据流和算子状态的
Flink分布式SNAPSHOT的核心数据元是_流障碍_。这些障碍被注入数据流并与记录一起作为数据流的一部分流动。障碍永远不会超过记录,流量严格符合要求。屏障将数据流中的记录分为进入当前SNAPSHOT的记录集和进入下一个SNAPSHOT的记录。每个屏障都带有SNAPSHOT的ID,该SNAPSHOT的记录在其前面推送。障碍不会中断流的流动,因此非常轻。来自不同SNAPSHOT的多个障碍可以同时在流中,这意味着可以同时发生各种SNAPSHOT。
![数据流中的检查点障碍](https://flink.sojb.cn/fig/stream_barriers.svg)
![数据流中的检查点障碍](img/stream_barriers.svg)
流障碍被注入流源的并行数据流中。注入SNAPSHOT_n_的障碍(我们称之为_S &lt;sub&gt;n&lt;/sub&gt;_)的点是源流中SNAPSHOT覆盖数据的位置。例如,在Apache Kafka中,此位置将是分区中最后一条记录的偏移量。该位置_S &lt;sub&gt;n&lt;/sub&gt;_被报告给_检查点协调员_(Flink的JobManager)。
......@@ -37,7 +37,7 @@ Flink分布式SNAPSHOT的核心数据元是_流障碍_。这些障碍被注入
一旦完成SNAPSHOT_n_,作业将永远不再向源请求来自_S &lt;sub&gt;n&lt;/sub&gt;_之前的记录,因为此时这些记录(及其后代记录)将通过整个数据流拓扑。
![在具有多个输入的 算子处对齐数据流](https://flink.sojb.cn/fig/stream_aligning.svg)
![在具有多个输入的 算子处对齐数据流](img/stream_aligning.svg)
接收多个输入流的 算子需要在SNAPSHOT屏障上_对齐_输入流。上图说明了这一点:
......@@ -60,7 +60,7 @@ Flink分布式SNAPSHOT的核心数据元是_流障碍_。这些障碍被注入
* 对于每个并行流数据源,启动SNAPSHOT时流中的偏移/位置
* 对于每个 算子,指向作为SNAPSHOT的一部分存储的状态的指针
![检查点机制的例证](https://flink.sojb.cn/fig/checkpointing.svg)
![检查点机制的例证](img/checkpointing.svg)
### 完全一次与至少一次
......
......@@ -13,7 +13,7 @@ Flink中的执行资源通过_任务槽_定义。每个TaskManager都有一个
下图说明了这一点。考虑一个带有数据源,_MapFunction_和_ReduceFunction的程序_。源和MapFunction以4的并行度执行,而ReduceFunction以3的并行度执行。管道由序列Source - Map - Reduce组成。在具有2个TaskManagers且每个具有3个插槽的群集上,程序将按如下所述执行。
![将任务管道分配给插槽](https://flink.sojb.cn/fig/slots.svg)
![将任务管道分配给插槽](img/slots.svg)
在内部,Flink限定通过[SlotSharingGroup](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobmanager/scheduler/SlotSharingGroup.java)[CoLocationGroup](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/jobmanager/scheduler/CoLocationGroup.java) 哪些任务可以共享的狭槽(许可),分别哪些任务必须严格放置到相同的时隙。
......@@ -25,7 +25,7 @@ Flink中的执行资源通过_任务槽_定义。每个TaskManager都有一个
JobManager将JobGraph转换为[ExecutionGraph](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/)。ExecutionGraph是JobGraph的并行版本:对于每个JobVertex,它包含每个并行子任务的[ExecutionVertex](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/ExecutionVertex.java)。并行度为100的 算子将具有一个JobVertex和100个ExecutionVertices。ExecutionVertex跟踪特定子任务的执行状态。来自一个JobVertex所有ExecutionVertices都保存在 [ExecutionJobVertex中](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/ExecutionJobVertex.java),它跟踪整个算子的状态。除了顶点之外,ExecutionGraph还包含[IntermediateResult](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/IntermediateResult.java)[IntermediateResultPartition](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/IntermediateResultPartition.java)。前者跟踪_IntermediateDataSet_的状态,后者是每个分区的状态。
![JobGraph和ExecutionGraph](https://flink.sojb.cn/fig/job_and_execution_graph.svg)
![JobGraph和ExecutionGraph](img/job_and_execution_graph.svg)
每个ExecutionGraph都有一个与之关联的作业状态。此作业状态指示作业执行的当前状态。
......@@ -35,8 +35,8 @@ Flink作业首先处于_创建_状态,然后切换到_运行,_并在完成
与_完成_,_取消_和_失败_的状态不同,它表示全局终端状态,因此触发清理作业,_暂停_状态仅在本地终端。本地终端意味着作业的执行已在相应的JobManager上终止,但Flink集群的另一个JobManager可以从持久性HA存储中检索作业并重新启动它。因此,到达_暂停_状态的作业将不会被完全清除。
![Flink工作的状态和转型](https://flink.sojb.cn/fig/job_status.svg)
![Flink工作的状态和转型](img/job_status.svg)
在执行ExecutionGraph期间,每个并行任务都经历多个阶段,从_创建_到_完成_或_失败_。下图说明了它们之间的状态和可能的转换。可以多次执行任务(例如,在故障恢复过程中)。因此,在Execution中跟踪[ExecutionVertex执行](https://github.com/apache/flink/blob/master//flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/Execution.java)。每个ExecutionVertex都有一个当前的Execution和先前的Executions。
![任务执行的状态和转变](https://flink.sojb.cn/fig/state_machine.svg)
\ No newline at end of file
![任务执行的状态和转变](img/state_machine.svg)
\ No newline at end of file
......@@ -34,7 +34,7 @@ Flink 在流处理节目中支持不同的_时间_概念。
在内部,_摄取时间_与_事件时间_非常相似,但具有自动时间戳分配和自动水印生成函数。
![](https://flink.sojb.cn/fig/times_clocks.svg)
![](img/times_clocks.svg)
### 设定时间特征
......@@ -112,11 +112,11 @@ Flink中用于衡量事件时间进度的机制是**水印**。水印作为数
下图显示了具有(逻辑)时间戳的事件流,以及内联流水印。在该示例中,事件按顺序(关于它们的时间戳),意味着水印仅是流中的周期性标记。
![包含事件(按顺序)和水印的数据流](https://flink.sojb.cn/fig/stream_watermark_in_order.svg)
![包含事件(按顺序)和水印的数据流](img/stream_watermark_in_order.svg)
水印对于_无序_流是至关重要的,如下所示,其中事件不按时间戳排序。通常,水印是一种声明,通过流中的该点,到达某个时间戳的所有事件都应该到达。一旦水印到达算子,算子就可以将其内部_事件时钟_提前到水印的值。
![包含事件(乱序)和水印的数据流](https://flink.sojb.cn/fig/stream_watermark_out_of_order.svg)
![包含事件(乱序)和水印的数据流](img/stream_watermark_out_of_order.svg)
请注意,事件时间由新生成的流数据元(或多个数据元)继承,这些数据元来自生成它们的事件或触发创建这些数据元的水印。
......@@ -130,7 +130,7 @@ Flink中用于衡量事件时间进度的机制是**水印**。水印作为数
下图显示了流经并行流的事件和水印的示例,以及跟踪事件时间的 算子。
![具有事件和水印的并行数据流和 算子](https://flink.sojb.cn/fig/parallel_streams_watermarks.svg)
![具有事件和水印的并行数据流和 算子](img/parallel_streams_watermarks.svg)
请注意,Kafka源支持每分区水印,您可以[在此处](https://flink.sojb.cn/dev/event_timestamps_watermarks.html#timestamps-per-kafka-partition)详细了解。
......
......@@ -343,5 +343,5 @@ val stream: DataStream[MyType] = env.addSource(kafkaSource)
![生成具有Kafka分区感知的水印](https://flink.sojb.cn/fig/parallel_kafka_watermarks.svg)
![生成具有Kafka分区感知的水印](img/parallel_kafka_watermarks.svg)
......@@ -9,7 +9,7 @@
Flink提供不同级别的抽象来开发流/批处理应用程序。
![编程抽象级别](https://flink.sojb.cn/fig/levels_of_abstraction.svg)
![编程抽象级别](img/levels_of_abstraction.svg)
* 最低级抽象只提供**有状态流**。它 通过[Process Function](https://flink.sojb.cn/dev/stream/operators/process_function.html)嵌入到[DataStream API中](https://flink.sojb.cn/dev/datastream_api.html)。它允许用户自由处理来自一个或多个流的事件,并使用一致的容错_状态_。此外,用户可以注册事件时间和处理时间回调,允许程序实现复杂的计算。[](https://flink.sojb.cn/dev/stream/operators/process_function.html)
......@@ -29,7 +29,7 @@ Flink程序的基本构建块是**流**和**转换**。(请注意,Flink的Da
执行时,Flink程序映射到**流数据流**,由**流**和转换 **算子组成**。每个数据流都以一个或多个**源**开头,并以一个或多个**接收器**结束。数据流类似于任意有**向无环图** _(DAG)_。尽管通过_迭代_结构允许特殊形式的循环 ,但为了简单起见,我们将在大多数情况下对此进行掩饰。
![DataStream程序及其数据流。](https://flink.sojb.cn/fig/program_dataflow.svg)
![DataStream程序及其数据流。](img/program_dataflow.svg)
通常,程序中的转换与数据流中的 算子之间存在一对一的对应关系。但是,有时一个转换可能包含多个转换 算子。
......@@ -41,7 +41,7 @@ Flink中的程序本质上是并行和分布式的。在执行期间,_流_具
算子子任务的数量是该特定 算子的**并行**度。流的并行性始终是其生成 算子的并行性。同一程序的不同 算子可能具有不同的并行级别。
![并行数据流](https://flink.sojb.cn/fig/parallel_dataflow.svg)
![并行数据流](img/parallel_dataflow.svg)
流可以_以一对一_(或_转发_)模式或以_重新分发_模式在两个算子之间传输数据:
......@@ -57,7 +57,7 @@ Flink中的程序本质上是并行和分布式的。在执行期间,_流_具
Windows可以是_时间驱动的_(例如:每30秒)或_数据驱动_(例如:每100个数据元)。一个典型地区分不同类型的窗口,例如_翻滚窗口_(没有重叠), _滑动窗口_(具有重叠)和_会话窗口_(由不活动的间隙打断)。
![时间和计数Windows](https://flink.sojb.cn/fig/windows.svg)
![时间和计数Windows](img/windows.svg)
更多窗口示例可以在此[博客文章中](https://flink.apache.org/news/2015/12/04/Introducing-windows.html)找到。更多详细信息在[窗口文档中](https://flink.sojb.cn/dev/stream/operators/windows.html)
......@@ -71,7 +71,7 @@ Windows可以是_时间驱动的_(例如:每30秒)或_数据驱动_(例
* **处理时间**是执行基于时间的 算子操作的每个算子的本地时间。
![事件时间,摄取时间和处理时间](https://flink.sojb.cn/fig/event_ingestion_processing_time.svg)
![事件时间,摄取时间和处理时间](img/event_ingestion_processing_time.svg)
有关如何处理时间的更多详细信息,请参阅[事件时间文档](https://flink.sojb.cn/dev/event_time.html)
......@@ -81,7 +81,7 @@ Windows可以是_时间驱动的_(例如:每30秒)或_数据驱动_(例
状态 算子操作的状态保持在可以被认为是嵌入式键/值存储的状态中。状态被分区并严格地与有状态算子读取的流一起分发。因此,只有在_keyBy()_函数之后才能在_被Key化的数据流_上访问键/值状态,并且限制为与当前事件的键相关联的值。对齐流和状态的Keys可确保所有状态更新都是本地 算子操作,从而保证一致性而无需事务开销。此对齐还允许Flink重新分配状态并透明地调整流分区。
![状态和分区](https://flink.sojb.cn/fig/state_partitioning.svg)
![状态和分区](img/state_partitioning.svg)
有关更多信息,请参阅有关[状态](https://flink.sojb.cn/dev/stream/state/index.html)的文档。
......
......@@ -862,7 +862,7 @@ dataStream.rebalance();
|
| **重新调整**
DataStream→DataStream | 分区数据元,循环,到下游 算子操作的子集。如果您希望拥有管道,例如,从源的每个并行实例扇出到多个映射器的子集以分配负载但又不希望发生rebalance()会产生完全Rebalance ,那么这非常有用。这将仅需要本地数据传输而不是通过网络传输数据,具体取决于其他配置值,例如TaskManagers的插槽数。上游 算子操作发送数据元的下游 算子操作的子集取决于上游和下游 算子操作的并行度。例如,如果上游 算子操作具有并行性2并且下游 算子操作具有并行性6,则一个上游 算子操作将分配元件到三个下游 算子操作,而另一个上游 算子操作将分配到其他三个下游 算子操作。另一方面,如果下游 算子操作具有并行性2而上游 算子操作具有并行性6,则三个上游 算子操作将分配到一个下游 算子操作,而其他三个上游 算子操作将分配到另一个下游 算子操作。在不同并行度不是彼此的倍数的情况下,一个或多个下游 算子操作将具有来自上游 算子操作的不同数量的输入。请参阅此图以获取上例中连接模式的可视化:![数据流中的检查点障碍](https://flink.sojb.cn/fig/rescale.svg)
DataStream→DataStream | 分区数据元,循环,到下游 算子操作的子集。如果您希望拥有管道,例如,从源的每个并行实例扇出到多个映射器的子集以分配负载但又不希望发生rebalance()会产生完全Rebalance ,那么这非常有用。这将仅需要本地数据传输而不是通过网络传输数据,具体取决于其他配置值,例如TaskManagers的插槽数。上游 算子操作发送数据元的下游 算子操作的子集取决于上游和下游 算子操作的并行度。例如,如果上游 算子操作具有并行性2并且下游 算子操作具有并行性6,则一个上游 算子操作将分配元件到三个下游 算子操作,而另一个上游 算子操作将分配到其他三个下游 算子操作。另一方面,如果下游 算子操作具有并行性2而上游 算子操作具有并行性6,则三个上游 算子操作将分配到一个下游 算子操作,而其他三个上游 算子操作将分配到另一个下游 算子操作。在不同并行度不是彼此的倍数的情况下,一个或多个下游 算子操作将具有来自上游 算子操作的不同数量的输入。请参阅此图以获取上例中连接模式的可视化:![数据流中的检查点障碍](img/rescale.svg)
&lt;figure class="highlight"&gt;
......@@ -926,7 +926,7 @@ dataStream.rebalance()
|
| **Rescaling**
DataStream → DataStream | Partitions elements, round-robin, to a subset of downstream operations. This is useful if you want to have pipelines where you, for example, fan out from each parallel instance of a source to a subset of several mappers to distribute load but don't want the full rebalance that rebalance() would incur. This would require only local data transfers instead of transferring data over network, depending on other configuration values such as the number of slots of TaskManagers.The subset of downstream operations to which the upstream operation sends elements depends on the degree of parallelism of both the upstream and downstream operation. For example, if the upstream operation has parallelism 2 and the downstream operation has parallelism 4, then one upstream operation would distribute elements to two downstream operations while the other upstream operation would distribute to the other two downstream operations. If, on the other hand, the downstream operation has parallelism 2 while the upstream operation has parallelism 4 then two upstream operations would distribute to one downstream operation while the other two upstream operations would distribute to the other downstream operations.In cases where the different parallelisms are not multiples of each other one or several downstream operations will have a differing number of inputs from upstream operations.&lt;/p&gt; Please see this figure for a visualization of the connection pattern in the above example: &lt;/p&gt;![Checkpoint barriers in data streams](https://flink.sojb.cn/fig/rescale.svg)
DataStream → DataStream | Partitions elements, round-robin, to a subset of downstream operations. This is useful if you want to have pipelines where you, for example, fan out from each parallel instance of a source to a subset of several mappers to distribute load but don't want the full rebalance that rebalance() would incur. This would require only local data transfers instead of transferring data over network, depending on other configuration values such as the number of slots of TaskManagers.The subset of downstream operations to which the upstream operation sends elements depends on the degree of parallelism of both the upstream and downstream operation. For example, if the upstream operation has parallelism 2 and the downstream operation has parallelism 4, then one upstream operation would distribute elements to two downstream operations while the other upstream operation would distribute to the other two downstream operations. If, on the other hand, the downstream operation has parallelism 2 while the upstream operation has parallelism 4 then two upstream operations would distribute to one downstream operation while the other two upstream operations would distribute to the other downstream operations.In cases where the different parallelisms are not multiples of each other one or several downstream operations will have a differing number of inputs from upstream operations.&lt;/p&gt; Please see this figure for a visualization of the connection pattern in the above example: &lt;/p&gt;![Checkpoint barriers in data streams](img/rescale.svg)
&lt;figure class="highlight"&gt;
......
......@@ -70,7 +70,7 @@ A `WindowAssigner`负责将每个传入数据元分配给一个或多个窗口
一个_翻滚窗口_分配器的每个数据元分配给指定的窗口_的窗口大小_。翻滚窗具有固定的尺寸,不重叠。例如,如果指定大小为5分钟的翻滚窗口,则将评估当前窗口,并且每五分钟将启动一个新窗口,如下图所示。
![](https://flink.sojb.cn/fig/tumbling-windows.svg)
![](img/tumbling-windows.svg)
以下代码段显示了如何使用翻滚窗口。
......@@ -136,7 +136,7 @@ val input: DataStream[T] = ...
例如,您可以将大小为10分钟的窗口滑动5分钟。有了这个,你每隔5分钟就会得到一个窗口,其中包含过去10分钟内到达的事件,如下图所示。
![](https://flink.sojb.cn/fig/sliding-windows.svg)
![](img/sliding-windows.svg)
以下代码段显示了如何使用滑动窗口。
......@@ -200,7 +200,7 @@ val input: DataStream[T] = ...
在_会话窗口_中按活动会话分配器组中的数据元。与_翻滚窗口_和_滑动窗口_相比,会话窗口不重叠并且没有固定的开始和结束时间。相反,当会话窗口在一段时间内没有接收到数据元时,_即_当发生不活动的间隙时,会关闭会话窗口。会话窗口分配器可以配置静态_会话间隙_或 _会话间隙提取器_函数,该函数定义不活动时间段的长度。当此期限到期时,当前会话将关闭,后续数据元将分配给新的会话窗口。
![](https://flink.sojb.cn/fig/session-windows.svg)
![](img/session-windows.svg)
以下代码段显示了如何使用会话窗口。
......@@ -289,7 +289,7 @@ val input: DataStream[T] = ...
一个_全局性的窗口_分配器分配使用相同的Keys相同的单个的所有数据元_全局窗口_。此窗口方案仅在您还指定自定义[触发器](#triggers)时才有用。否则,将不执行任何计算,因为全局窗口没有我们可以处理聚合数据元的自然结束。
![](https://flink.sojb.cn/fig/non-windowed.svg)
![](img/non-windowed.svg)
以下代码段显示了如何使用全局窗口。
......
......@@ -39,7 +39,7 @@ stream.join(otherStream)
当执行翻滚窗口连接时,具有公共Keys和公共翻滚窗口的所有数据元以成对组合的形式连接并传递给`JoinFunction``FlatJoinFunction`。因为它的行为类似于内连接,所以不会发出一个流的数据元,这些数据元在其翻滚窗口中没有来自另一个流的数据元!
![](https://flink.sojb.cn/fig/tumbling-window-join.svg)
![](img/tumbling-window-join.svg)
如图所示,我们定义了一个大小为2毫秒的翻滚窗口,这导致了窗体的窗口`[0,1], [2,3], ...`。镜像显示了每个窗口中所有数据元的成对组合,这些数据元将被传递给`JoinFunction`。请注意,在翻滚窗口中`[6,7]`没有任何东西被发射,因为绿色流中不存在与橙色数据元⑥和⑦连接的数据元。
......@@ -96,7 +96,7 @@ orangeStream.join(greenStream)
执行滑动窗口连接时,具有公共键和公共滑动窗口的所有数据元都是成对组合并传递给`JoinFunction``FlatJoinFunction`。不会释放当前滑动窗口中没有来自其他流的数据元的一个流的数据元!请注意,某些数据元可能在一个滑动窗口中连接而在另一个滑动窗口中不连
![](https://flink.sojb.cn/fig/sliding-window-join.svg)
![](img/sliding-window-join.svg)
在这个例子中,我们使用大小为2毫秒的滑动窗口并将它们滑动一毫秒,从而产生滑动窗口`[-1, 0],[0,1],[1,2],[2,3], …`。x轴下方的连接数据元是传递给`JoinFunction`每个滑动窗口的数据元。在这里,您还可以看到橙色②如何与窗口中的绿色③ `[2,3]`连接,但未与窗口中的任何内容连接`[1,2]`
......@@ -153,7 +153,7 @@ orangeStream.join(greenStream)
在执行会话窗口连接时,具有相同键的所有数据元在_“组合”_满足会话条件时以成对组合方式连接并传递给`JoinFunction``FlatJoinFunction`。再次执行内连接,因此如果有一个会话窗口只包含来自一个流的数据元,则不会发出任何输出!
![](https://flink.sojb.cn/fig/session-window-join.svg)
![](img/session-window-join.svg)
这里我们定义一个会话窗口连接,其中每个会话除以至少1ms的间隙。有三个会话,在前两个会话中,两个流的连接数据元都传递给`JoinFunction`。在第三阶段,绿色流中没有数据元,所以⑧和⑨没有连接!
......@@ -221,7 +221,7 @@ orangeStream.join(greenStream)
注意间隔连接当前仅支持事件时间。
![](https://flink.sojb.cn/fig/interval-join.svg)
![](img/interval-join.svg)
在上面的例子中,我们连接两个流'orange'和'green',下限为-2毫秒,上限为+1毫秒。缺省情况下,这些界限是包容性的,但`.lowerBoundExclusive()``.upperBoundExclusive`可以应用到改变行为。
......
......@@ -11,7 +11,7 @@
下图中的示例数据流由五个子任务执行,因此具有五个并行线程。
![算子链接到任务](https://flink.sojb.cn/fig/tasks_chains.svg)
![算子链接到任务](img/tasks_chains.svg)
## TaskManager,JobManager,客户端
......@@ -29,7 +29,7 @@ JobManagers和TaskManagers可以通过多种方式启动:作为[独立集群](
**客户端**是不运行时和程序执行的一部分,而是被用来准备和发送的数据流的JobManager。之后,客户端可以断开连接或保持连接以接收进度报告。客户端既可以作为触发执行的Java / Scala程序的一部分运行,也可以在命令行进程中运行`./bin/flink run ...`
![执行Flink数据流所涉及的过程](https://flink.sojb.cn/fig/processes.svg)
![执行Flink数据流所涉及的过程](img/processes.svg)
## 任务槽和资源
......@@ -39,7 +39,7 @@ JobManagers和TaskManagers可以通过多种方式启动:作为[独立集群](
通过调整任务槽的数量,用户可以定义子任务如何相互隔离。每个TaskManager有一个插槽意味着每个任务组在一个单独的JVM中运行(例如,可以在一个单独的容器中启动)。拥有多个插槽意味着更多子任务共享同一个JVM。同一JVM中的任务共享TCP连接(通过多路复用)和心跳消息。它们还可以共享数据集和数据结构,从而Reduce每任务开销。
![具有任务槽和任务的TaskManager](https://flink.sojb.cn/fig/tasks_slots.svg)
![具有任务槽和任务的TaskManager](img/tasks_slots.svg)
默认情况下,Flink允许子任务共享插槽,即使它们是不同任务的子任务,只要它们来自同一个作业。结果是一个槽可以保存作业的整个管道。允许此_插槽共享_有两个主要好处:
......@@ -47,7 +47,7 @@ JobManagers和TaskManagers可以通过多种方式启动:作为[独立集群](
* 更容易获得更好的资源利用率。如果没有插槽共享,非密集 _源/ map()_子任务将阻止与资源密集型_窗口_子任务一样多的资源。通过插槽共享,将示例中的基本并行性从2增加到6可以充分利用时隙资源,同时确保繁重的子任务在TaskManagers之间公平分配。
![具有共享任务槽的TaskManagers](https://flink.sojb.cn/fig/slot_sharing.svg)
![具有共享任务槽的TaskManagers](img/slot_sharing.svg)
API还包括可用于防止不期望的时隙共享的_[资源组](https://flink.sojb.cn/dev/stream/operators/#task-chaining-and-resource-groups)_机制。
......@@ -57,7 +57,7 @@ API还包括可用于防止不期望的时隙共享的_[资源组](https://flink
存储键/值索引的确切数据结构取决于所选的[状态后台](https://flink.sojb.cn/ops/state/state_backends.html)。一个状态后台将数据存储在内存中的哈希映射中,另一个状态后台使用[RocksDB](http://rocksdb.org)作为键/值存储。除了定义保存状态的数据结构之外,状态后台还实现逻辑以获取键/值状态的时间点SNAPSHOT,并将该SNAPSHOT存储为检查点的一部分。
![检查点和SNAPSHOT](https://flink.sojb.cn/fig/checkpoints.svg)
![检查点和SNAPSHOT](img/checkpoints.svg)
## 保存点
......
......@@ -17,7 +17,7 @@
与数据库的异步交互意味着单个并行函数实例可以同时处理许多请求并同时接收响应。这样,可以通过发送其他请求和接收响应来覆盖等待时间。至少,等待时间在多个请求上摊销。这导致大多数情况下流量吞吐量更高。
![](https://flink.sojb.cn/fig/async_io.svg)
![](img/async_io.svg)
_注意:_通过仅扩展`MapFunction`到非常高的并行度来提高吞吐量在某些情况下也是可能的,但通常会产生非常高的资源成本:拥有更多并行MapFunction实例意味着更多任务,线程,Flink内部网络连接,网络连接到数据库,缓冲区和一般内部副本记录开销。
......
......@@ -398,11 +398,11 @@ bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wiki-result
您还可以查看应在[http:// localhost:8081上](http://localhost:8081)运行的Flink仪表板。您将获得群集资源和正在运行的作业的概述:
[![JobManager概述](https://flink.sojb.cn/page/img/quickstart-example/jobmanager-overview.png)](https://flink.sojb.cn/page/img/quickstart-example/jobmanager-overview.png)
[![JobManager概述](img/quickstart-example/jobmanager-overview.png)](img/quickstart-example/jobmanager-overview.png)
如果单击正在运行的作业,您将获得一个视图,您可以在其中检查各个 算子操作,例如,查看已处理数据元的数量:
[![作业视图示例](https://flink.sojb.cn/page/img/quickstart-example/jobmanager-job.png)](https://flink.sojb.cn/page/img/quickstart-example/jobmanager-job.png)
[![作业视图示例](img/quickstart-example/jobmanager-job.png)](img/quickstart-example/jobmanager-job.png)
这就结束了我们对Flink的小游览。如果您有任何疑问,请随时询问我们的[邮件列表](http://flink.apache.org/community.html#mailing-lists)
......@@ -60,7 +60,7 @@ $ ./bin/start-cluster.sh # Start Flink
检查**分派器的web前端**[HTTP://localhost:8081](http://localhost:8081),并确保一切都正常运行。Web前端应报告单个可用的TaskManager实例。
[![调度员:概述](https://flink.sojb.cn/page/img/quickstart-setup/jobmanager-1.png)](https://flink.sojb.cn/page/img/quickstart-setup/jobmanager-1.png)
[![调度员:概述](img/jobmanager-1.png)](img/jobmanager-1.png)
您还可以通过检查`logs`目录中的日志文件来验证系统是否正在运行:
......@@ -231,7 +231,7 @@ Starting execution of program
程序连接到套接字并等待输入。您可以检查Web界面以验证作业是否按预期运行:
[![调度员:概述(续)](https://flink.sojb.cn/page/img/quickstart-setup/jobmanager-2.png)](https://flink.sojb.cn/page/img/quickstart-setup/jobmanager-2.png)[![调度程序:运行作业](https://flink.sojb.cn/page/img/quickstart-setup/jobmanager-3.png)](https://flink.sojb.cn/page/img/quickstart-setup/jobmanager-3.png)
[![调度员:概述(续)](img/jobmanager-2.png)](img/jobmanager-2.png)[![调度程序:运行作业](img/jobmanager-3.png)](img/jobmanager-3.png)
* 单词在5秒的时间窗口(处理时间,翻滚窗口)中计算并打印到`stdout`。监视TaskManager的输出文件并写入一些文本`nc`(输入在点击后逐行发送到Flink &lt;return&gt;):&lt;/return&gt;
......
......@@ -40,7 +40,7 @@ Flink程序通过定义**步进函数**并将其嵌入到特殊的迭代 算子
**迭代 算子**覆盖所述_迭代简单形式_:在每次迭代中,**阶梯函数**消耗**整个输入**(在_先前的迭代的结果_,或在_初始数据集_),并且计算**该部分解决方案的下一个版本**(例如`map``reduce``join`,等等。)。
![迭代 算子](https://flink.sojb.cn/fig/iterations_iterate_operator.png)
![迭代 算子](img/iterations_iterate_operator.png)
1. **迭代输入**:来自_数据源_或_先前 算子_的_第一次迭代的_初始输入。
2. **步骤函数**:步进函数将在每次迭代中执行。它是由像算子的任意数据流`map``reduce``join`等,取决于手头的特定任务。
......@@ -74,7 +74,7 @@ setFinalState(state);
在以下示例中,我们**迭代地递增一组数字**
![迭代 算子示例](https://flink.sojb.cn/fig/iterations_iterate_operator_example.png)
![迭代 算子示例](img/iterations_iterate_operator_example.png)
1. **迭代输入**:初始输入从数据源读取和由五个单字段记录(整数`1``5`)。
2. **步进函数**:步进函数是单个`map` 算子,它将整数字段从`i`增加到`i+1`。它将应用于输入的每个记录。
......@@ -102,7 +102,7 @@ map(5) -> 6 map(6) -> 7 ... map(14) -> 15
在适用的情况下,这会导致**更高效的算法**,因为解决方案集中的每个数据元都不会在每次迭代中发生变化。这样可以**专注于**解决方案**的热部件**,并**保持冷部件不受影响**。通常,大多数解决方案相对较快地冷却,后来的迭代仅在一小部分数据上运行。
![Delta迭代算子](https://flink.sojb.cn/fig/iterations_delta_iterate_operator.png)
![Delta迭代算子](img/iterations_delta_iterate_operator.png)
1. **迭代输入**:从_数据源_或_先前的 算子_读取初始工作集和解决方案集作为第一次迭代的输入。
2. **步骤函数**:步进函数将在每次迭代中执行。它是由像算子的任意数据流`map``reduce``join`等,取决于手头的特定任务。
......@@ -136,7 +136,7 @@ setFinalState(solution);
在以下示例中,每个顶点都有一个**ID**和一个**着色**。每个顶点将其顶点ID传播到相邻顶点。该**目标**是_最小ID分配给子图的每个顶点_。如果接收的ID小于当前的ID,则它将变为具有接收到的ID的顶点的颜色。其中一个应用可以在_社区分析_或_连通组件_计算中找到。
![Delta迭代 算子示例](https://flink.sojb.cn/fig/iterations_delta_iterate_operator_example.png)
![Delta迭代 算子示例](img/iterations_delta_iterate_operator_example.png)
**初始输入**被设置为**两个工作集和溶液组。**在上图中,颜色可视化**解决方案集****演变**。每次迭代时,最小ID的颜色在相应的子图中展开。同时,每次迭代,工作量(交换和比较顶点ID)都会Reduce。这对应于**工作集的大小减小**,其在三次迭代之后从所有七个顶点变为零,此时迭代终止。在**重要的观察**是,_较低的子收敛上半之前_不和增量迭代能够与工作集抽象捕捉到这一点。
......@@ -154,5 +154,5 @@ setFinalState(solution);
我们将迭代 算子的阶梯函数的每次执行称为_单次迭代_。在并行设置中,在迭代状态的不同分区上**并行评估步骤函数的多个实例**。在许多设置中,对所有并行实例的步骤函数的一个评估形成所谓的**超级步骤**,其也是同步的粒度。因此,迭代的_所有_并行任务都需要在初始化下一个超级步骤之前完成超级步骤。**终止标准**也将在超级障碍评估。
![超级步](https://flink.sojb.cn/fig/iterations_supersteps.png)
![超级步](img/iterations_supersteps.png)
......@@ -37,7 +37,7 @@ _动态表_是Flink的 Table API和SQL支持流数据的核心概念。与表示
下图显示了流,动态表和连续查询的关系:
<center>![动态表格](https://flink.sojb.cn/fig/table-streaming/stream-query-stream.png)</center>
<center>![动态表格](img/stream-query-stream.png)</center>
1. 流转换为动态表。
2. 在动态表上评估连续查询,生成新的动态表。
......@@ -65,7 +65,7 @@ _动态表_是Flink的 Table API和SQL支持流数据的核心概念。与表示
下图显示了click事件流(左侧)如何转换为表(右侧)。随着更多点击流记录的插入,生成的表不断增长。
<center>![追加模式](https://flink.sojb.cn/fig/table-streaming/append-mode.png)</center>
<center>![追加模式](img/append-mode.png)</center>
**注意:**在流上定义的表在内部未实现。
......@@ -77,13 +77,13 @@ _动态表_是Flink的 Table API和SQL支持流数据的核心概念。与表示
第一个查询是一个简单的`GROUP-BY COUNT`聚合查询。这组`clicks`对表`user`字段和计数访问的网址的数量。下图显示了在`clicks`使用其他行更新表时,如何评估查询。
<center>![连续非窗口查询](https://flink.sojb.cn/fig/table-streaming/query-groupBy-cnt.png)</center>
<center>![连续非窗口查询](img/table-streaming/query-groupBy-cnt.png)</center>
查询启动时,`clicks`表(左侧)为空。当第一行插入表中时,查询开始计算结果`clicks`表。`[Mary, ./home]`Insert第一行后,结果表(右侧,顶部)由一行组成`[Mary, 1]`。当第二行`[Bob, ./cart]`Insert`clicks`表中时,查询将更新结果表并插入新行`[Bob, 1]`。第三行`[Mary, ./prod?id=1]`产生已更新的已计算结果行的`[Mary, 1]`更新`[Mary, 2]`。最后,`[Liz, 1]`当第四行附加到`clicks`表时,查询将第三行插入到结果表中。
第二个查询类似于第一个查询,但`clicks`除了`user`属性之外还在[每小时滚动窗口](https://flink.sojb.cn/sql.html#group-windows)上对表进行分组,然后计算URL的数量(基于时间的计算,例如窗口基于特殊[时间属性](#time-attributes),这将在下面讨论) )。同样,该图显示了不同时间点的输入和输出,以显示动态表的变化性质。
<center>![连续组窗口查询](https://flink.sojb.cn/fig/table-streaming/query-groupBy-window-cnt.png)</center>
<center>![连续组窗口查询](img/table-streaming/query-groupBy-window-cnt.png)</center>
和以前一样,输入表`clicks`显示在左侧。查询每小时连续计算结果并更新结果表。点击表包含四行,时间戳(`cTime`)位于`12:00:00`和之间`12:59:59`。查询从此输入计算两个结果行(每个一行`user`)并将它们附加到结果表。对于`13:00:00`和之间的下一个窗口`13:59:59`,该`clicks`表包含三行,这导致另外两行被追加到结果表中。结果表已更新,`clicks`随着时间的推移会附加更多行。
......@@ -140,11 +140,11 @@ FROM (
* 撤消**流:**撤消流是具有两种类型的消息的流,_添加消息_和_撤消消息_。通过将`INSERT`更改编码为添加消息,将`DELETE`更改编码为收回消息,将`UPDATE`更改编码为更新(先前)行的收回消息和更新(新)行的添加消息,将动态表转换为收回流。下图显示了动态表到回收流的转换。
<center>![动态表格](https://flink.sojb.cn/fig/table-streaming/undo-redo-mode.png)</center>
<center>![动态表格](img/table-streaming/undo-redo-mode.png)</center>
* **Upsert流:** upsert流是一种包含两种消息,_upsert消息_和_删除消息的流_。转换为upsert流的动态表需要(可能是复合的)唯一键。具有唯一键的动态表通过编码转换为动态表,`INSERT``UPDATE`更改为upsert消息并`DELETE`更改为删除消息。流消耗 算子需要知道唯一键属性才能正确应用消息。与收回流的主要区别在于,`UPDATE`使用单个消息对更改进行编码,因此更有效。下图显示了动态表到upsert流的转换。
<center>![动态表格](https://flink.sojb.cn/fig/table-streaming/redo-mode.png)</center>
<center>![动态表格](img/table-streaming/redo-mode.png)</center>
`DataStream`[Common Concepts](https://flink.sojb.cn/common.html#convert-a-table-into-a-datastream)页面上讨论了将动态表转换为a的API 。请注意,将动态表格转换为a时,仅支持附加和撤消流`DataStream`[TableSources和TableSinks](https://flink.sojb.cn/sourceSinks.html#define-a-tablesink)页面`TableSink`讨论了向外部系统发出动态表的接口。[](https://flink.sojb.cn/sourceSinks.html#define-a-tablesink)
......
......@@ -248,7 +248,7 @@ class CustomTypeSplit extends TableFunction[Row] {
用户定义的聚合函数(UDAGG)将一个表(一个或多个具有一个或多个属性的行)聚合到标量值。
<center>![UDAGG机制](https://flink.sojb.cn/fig/udagg-mechanism.png)</center>
<center>![UDAGG机制](img/udagg-mechanism.png)</center>
上图显示了聚合的示例。假设您有一个包含饮料数据的表格。该表由三列的`id``name``price`5行。想象一下,您需要找到表中所有饮料的最高价格,即执行`max()`聚合。您需要检查5行中的每一行,结果将是单个数值。
......
......@@ -9,7 +9,7 @@ Flink的Table&SQL API可以处理用SQL语言编写的查询,但是这些查
在_SQL客户端_旨在提供编写,调试,并提交表格程序到Flink集群的一个简单的方法没有的Java或Scala代码一行。在_SQL客户端CLI_允许检索和命令行中运行分布式应用可视化实时结果。
[![在群集上运行表程序的Flink SQL Client CLI的动画演示](https://flink.sojb.cn/fig/sql_client_demo.gif)](https://flink.sojb.cn/fig/sql_client_demo.gif)
[![在群集上运行表程序的Flink SQL Client CLI的动画演示](img/sql_client_demo.gif)](img/sql_client_demo.gif)
注意 SQL客户端处于早期开发阶段。即使应用程序还没有生产就绪,它可以是一个非常有用的工具,用于原型设计和Flink SQL。在未来,社区计划通过提供基于REST的[SQL客户端网关](sqlClient.html#limitations--future)来扩展其函数。
......
......@@ -48,7 +48,7 @@ println(env.getExecutionPlan())
完成这些步骤后,将显示详细的执行计划。
![flink作业执行图。](https://flink.sojb.cn/fig/plan_visualizer.png)
![flink作业执行图。](img/plan_visualizer.png)
**Web界面**
......
......@@ -465,7 +465,7 @@ val graph: Graph[Long, Long, Long] = ...
![过滤转换](https://flink.sojb.cn/fig/gelly-filter.png)
![过滤转换](img/gelly-filter.png)
* **Join**:Gelly提供了将顶点和边缘数据集与其他输入数据集连接的专用方法。`joinWithVertices`使用`Tuple2`输入数据集连接顶点。使用顶点ID和`Tuple2`输入的第一个字段作为连接键来执行连接。该方法返回一个新的`Graph`,其中顶点值已根据提供的用户定义的转换函数进行更新。类似地,输入数据集可以使用三种方法之一与边连接。`joinWithEdges`期望的输入`DataSet``Tuple3`,并关联对源和目标顶点ID的组合键。`joinWithEdgesOnSource`期望一个`DataSet``Tuple2`并关联上边缘和输入数据集的所述第一属性的源Keys和`joinWithEdgesOnTarget`期望一个`DataSet``Tuple2`并连接边的目标键和输入数据集的第一个属性。所有这三种方法都在边缘和输入数据集值上应用变换函数。请注意,如果输入数据集多次包含键,则所有Gelly连接方法将仅考虑遇到的第一个值。
......@@ -508,7 +508,7 @@ val vertexOutDegrees: DataSet[(Long, LongValue)] = network.outDegrees
* **Union**:Gelly的`union()`方法对指定图形的顶点和边集以及当前图执行并集 算子操作。从结果中删除重复的顶点`Graph`,而如果存在重复的边,则将保存这些顶点。
![Union转型](https://flink.sojb.cn/fig/gelly-union.png)
![Union转型](img/gelly-union.png)
* **差异**:Gelly的`difference()`方法对当前图形和指定图形的顶点和边集进行差异。
......@@ -624,7 +624,7 @@ Graph<K, VV, EV> removeEdges(List<Edge<K, EV>> edgesToBeRemoved)
例如,假设您要在下图中为每个顶点选择所有外边的最小权重:
![reduceOnEdges示例](https://flink.sojb.cn/fig/gelly-example-graph.png)
![reduceOnEdges示例](img/gelly-example-graph.png)
以下代码将收集每个顶点的外边缘,并`SelectMinWeight()`在每个结果邻域上应用用户定义的函数:
......@@ -666,7 +666,7 @@ val minWeights = graph.reduceOnEdges(new SelectMinWeight, EdgeDirection.OUT)
![reduceOnEdges示例](https://flink.sojb.cn/fig/gelly-reduceOnEdges.png)
![reduceOnEdges示例](img/gelly-reduceOnEdges.png)
类似地,假设您想为每个顶点计算所有进入邻居的值的总和。以下代码将收集每个顶点的进入邻居,并`SumValues()`在每个邻域上应用用户定义的函数:
......@@ -708,7 +708,7 @@ val verticesWithSum = graph.reduceOnNeighbors(new SumValues, EdgeDirection.IN)
![reduceOnNeighbors示例](https://flink.sojb.cn/fig/gelly-reduceOnNeighbors.png)
![reduceOnNeighbors示例](img/gelly-reduceOnNeighbors.png)
当聚合作用是不关联的,并且交换或当期望返回每个顶点多于一个的值,可以使用更一般的 `groupReduceOnEdges()``groupReduceOnNeighbors()`的方法。这些方法每个顶点返回零个,一个或多个值,并提供对整个邻域的访问。
......
......@@ -13,7 +13,7 @@ Gelly利用Flink的高效迭代 算子来支持大规模迭代图处理。目前
计算模型如下图所示。虚线框对应于并行化单元。在每个超级步骤中,所有活动顶点并行执行相同的用户定义计算。超级步骤是同步执行的,因此保证在一个超级步骤期间发送的消息在下一个超级步骤的开始时传递。
![以顶点为中心的计算模型](https://flink.sojb.cn/fig/vertex-centric supersteps.png)
![以顶点为中心的计算模型](img/vertex-centric supersteps.png)
要在Gelly中使用以顶点为中心的迭代,用户只需要定义顶点计算函数,`ComputeFunction`。该函数和最大运行迭代次数作为Gelly的参数给出`runVertexCentricIteration`。此方法将在输入Graph上执行以顶点为中心的迭代,并返回具有更新顶点值的新Graph。`MessageCombiner`可以定义可选的消息组合器以降低通信成本。
......@@ -246,7 +246,7 @@ Gelly提供了分散 - 聚集迭代的方法。用户只需要实现两个函数
让我们考虑在下图中使用散射 - 聚集迭代计算单源最短路径,并让顶点1成为源。在每个超级步骤中,每个顶点向其所有邻居发送候选距离消息。消息值是顶点的当前值与连接此顶点与其邻居的边缘权重之和。在接收候选距离消息时,每个顶点计算最小距离,并且如果已发现较短路径,则其更新其值。如果顶点在超级步骤期间没有改变其值,则它不会为其下一个超级步的邻居生成消息。当没有值更新时,算法收敛。
![Scatter-gather SSSP superstep 1](https://flink.sojb.cn/fig/gelly-vc-sssp1.png)
![Scatter-gather SSSP superstep 1](img/gelly-vc-sssp1.png)
* [**Java**](#tab_java_2)
* [**Scala**](#tab_scala_2)
......@@ -584,7 +584,7 @@ final class VertexUpdater extends GatherFunction {...}
让我们考虑在下图中用GSA计算单源最短路径,并让顶点1成为源。在该`Gather`阶段期间,我们通过将每个顶点值与边缘权重相加来计算新的候选距离。在`Sum`,候选距离按顶点ID分组,并选择最小距离。在`Apply`,将新计算的距离与当前顶点值进行比较,并将两者中的最小值指定为顶点的新值。
![GSA SSSP超越1](https://flink.sojb.cn/fig/gelly-gsa-sssp1.png)
![GSA SSSP超越1](img/gelly-gsa-sssp1.png)
请注意,如果顶点在超级步骤期间未更改其值,则在下一个超级步骤期间不会计算候选距离。当没有顶点改变值时,算法收敛。
......
......@@ -88,7 +88,7 @@ Graph<String, String, Long, Long, Double> graph = BipartiteGraph.fromDataSet(top
* **Projection**:Projection是二分图的常见 算子操作,可将二分图转换为常规图。有两种类型的Projection:顶部和底部Projection。顶部Projection仅保存结果图中的顶部节点,并且仅当顶部节点在原始图中连接到中间底部节点时才在新图中创建它们之间的链接。底部Projection与顶部Projection相反,即仅保存底部节点并连接一对节点(如果它们在原始图形中连接)。
![二分图Projection](https://flink.sojb.cn/fig/bipartite_graph_projections.png)
![二分图Projection](img/bipartite_graph_projections.png)
Gelly支持两种子类型的Projection:简单Projection和完整Projection。它们之间的唯一区别是数据与结果图中的边相关联。
......
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?)</nobr>
# 快速入门指南
......@@ -108,7 +107,7 @@ val astroTest: DataSet[(Vector, Double)] = astroTestLibSVM.map(normalizer).map(x
一旦我们转换了数据集,我们就可以训练一个`Predictor`诸如线性SVM分类器。我们可以为分类器设置许多参数。这里我们设置`Blocks`参数,用于通过底层CoCoA算法[[2]](#jaggi)使用来分割输入。正则化参数确定&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?l)&lt;/nobr&gt;的量&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?2)&lt;/nobr&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;msub&gt;&lt;mi&gt;&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;应用正则化,用于避免过度拟合。步长确定权重向量更新对下一个权重向量值的贡献。此参数设置初始步长。
一旦我们转换了数据集,我们就可以训练一个`Predictor`诸如线性SVM分类器。我们可以为分类器设置许多参数。这里我们设置`Blocks`参数,用于通过底层CoCoA算法[[2]](#jaggi)使用来分割输入。正则化参数确定 ![](http://latex.codecogs.com/gif.latex?l) 的量 ![](http://latex.codecogs.com/gif.latex?2) &lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;msub&gt;&lt;mi&gt;&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;应用正则化,用于避免过度拟合。步长确定权重向量更新对下一个权重向量值的贡献。此参数设置初始步长。
......
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?)</nobr>
# 如何贡献
......
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?)</nobr>
# 交叉验证
......@@ -22,7 +21,7 @@
最简单的分裂方法是`trainTestSplit`。此拆分采用DataSet和参数_分数_。该_分数_表示应分配给所述训练集合中的数据集的部分。这种拆分还需要两个额外的可选参数,_精确_和_种子_。
默认情况下,通过随机决定是否使用probability = _fraction_为训练DataSet分配观察来完成拆分。当_精确_是`true`然而,采取额外的步骤,以保证训练集是尽可能接近到DataSet的长度 &lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?%E2%8B%85)&lt;/nobr&gt;&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?)&lt;/nobr&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;mo&gt;&lt;/mo&gt;&lt;/math&gt; _分数_。
默认情况下,通过随机决定是否使用probability = _fraction_为训练DataSet分配观察来完成拆分。当_精确_是`true`然而,采取额外的步骤,以保证训练集是尽可能接近到DataSet的长度 ![](http://latex.codecogs.com/gif.latex?%E2%8B%85) ![](http://latex.codecogs.com/gif.latex?) &lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;mo&gt;&lt;/mo&gt;&lt;/math&gt; _分数_。
该方法返回一个新`TrainTestDataSet`对象,该对象具有`.training`包含训练DataSet的`.testing`属性和包含测试DataSet 的属性。
......
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?)</nobr>
# k-Nearest Neighbors关联
......@@ -7,9 +6,9 @@
## 描述
实现精确的k近邻连接算法。给出训练集&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?A)&lt;/nobr&gt;&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?)&lt;/nobr&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;mi&gt;一个&lt;/mi&gt;&lt;/math&gt;和测试集&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?B.)&lt;/nobr&gt;&lt;nobr aria-hidden="true"&gt;![](http://latex.codecogs.com/gif.latex?)&lt;/nobr&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;mi&gt;&lt;/mi&gt;&lt;/math&gt;,算法返回
实现精确的k近邻连接算法。给出训练集 ![](http://latex.codecogs.com/gif.latex?A) 和测试集 ![](http://latex.codecogs.com/gif.latex?B),算法返回
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?%C4%B7%20N%20%20N%20%C4%B4%EF%BC%88A%20%EF%BC%8CB%20%EF%BC%8Ck%EF%BC%89%3D%20%7B%20%EF%BC%88b%20%EF%BC%8CK%20N%20%20N%20%EF%BC%88b%20%EF%BC%8CA%20%EF%BC%8Ck%EF%BC%89%EF%BC%89%20%C2%A0%EF%BC%8C%E5%85%B6%E4%B8%AD%C2%A0b%E2%88%88%E4%B9%99%C2%A0%E5%92%8C%C2%A0%C4%B7%20N%20%20N%20%EF%BC%88b%20%EF%BC%8CA%20%EF%BC%8Ck%EF%BC%89%C2%A0%E6%98%AFk%E6%9C%80%E8%BF%91%E7%82%B9%C2%A0%20b%20%C2%A0%E5%9C%A8%C2%A0%20%E4%B8%80%E4%B8%AA%7D)</nobr><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mi>ķ</mi> <mi>N</mi><mi>N</mi> <mi>Ĵ</mi><mo stretchy="false"></mo><mi>一个</mi><mo></mo><mi></mi><mo></mo><mi>ķ</mi><mo stretchy="false"></mo><mo>=</mo><mo fence="false" stretchy="false">{</mo><mrow><mo></mo><mrow><mi>b</mi><mo></mo><mi>ķ</mi> <mi>N</mi><mi>N</mi> <mo stretchy="false"></mo><mi>b</mi><mo></mo><mi>一个</mi><mo></mo><mi>ķ</mi><mo stretchy="false"></mo></mrow><mo></mo></mrow><mtext> 哪里 </mtext><mi>b</mi><mo></mo><mi></mi><mtext> 和 </mtext><mi>ķ</mi> <mi>N</mi><mi>N</mi> <mo stretchy="false"></mo><mi>b</mi><mo></mo><mi>一个</mi><mo></mo><mi>ķ</mi><mo stretchy="false"></mo><mtext> 是最近的k点 </mtext><mi>b</mi><mtext> 在 </mtext><mi>一个</mi><mo fence="false" stretchy="false">}</mo></math>
![](http://latex.codecogs.com/gif.latex?%C4%B7%20N%20%20N%20%C4%B4%EF%BC%88A%20%EF%BC%8CB%20%EF%BC%8Ck%EF%BC%89%3D%20%7B%20%EF%BC%88b%20%EF%BC%8CK%20N%20%20N%20%EF%BC%88b%20%EF%BC%8CA%20%EF%BC%8Ck%EF%BC%89%EF%BC%89%20%C2%A0%EF%BC%8C%E5%85%B6%E4%B8%AD%C2%A0b%E2%88%88%E4%B9%99%C2%A0%E5%92%8C%C2%A0%C4%B7%20N%20%20N%20%EF%BC%88b%20%EF%BC%8CA%20%EF%BC%8Ck%EF%BC%89%C2%A0%E6%98%AFk%E6%9C%80%E8%BF%91%E7%82%B9%C2%A0%20b%20%C2%A0%E5%9C%A8%C2%A0%20%E4%B8%80%E4%B8%AA%7D)
蛮力方法是计算每个训练点和测试点之间的距离。为了简化计算每个训练点之间距离的强力计算,使用四叉树。四叉树在训练点的数量上很好地扩展,但在空间维度上很差。该算法将自动选择是否使用四叉树,但用户可以通过设置参数来强制使用或不使用四叉树来覆盖该决策。
......
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?)</nobr>
# 在管道的引擎盖下看
......
<nobr aria-hidden="true">![](http://latex.codecogs.com/gif.latex?)</nobr>
# 随机异常值选择
......
......@@ -53,7 +53,7 @@ cd flink-*
以下示例说明了具有三个节点(IP地址从_10.0.0.1_ 到_10.0.0.3_以及主机名_master_,_worker1_,_worker2_)的设置,并显示了配置文件的内容(需要在所有计算机上的相同路径上访问) ):
![](https://flink.sojb.cn/page/img/quickstart_cluster.png)
![](img/quickstart_cluster.png)
/ path / to / **flink / conf /
flink-conf.yaml**
......
......@@ -361,7 +361,7 @@ yarn logs -applicationId <application ID>
本节简要介绍Flink和YARN如何交互。
![](https://flink.sojb.cn/fig/FlinkOnYarn.svg)
![](img/FlinkOnYarn.svg)
YARN客户端需要访问Hadoop配置以连接到YARN资源管理器和HDFS。它使用以下策略确定Hadoop配置:
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill-opacity="1" color-rendering="auto" color-interpolation="auto" stroke="black" text-rendering="auto" stroke-linecap="square" width="877" stroke-miterlimit="10" stroke-opacity="1" shape-rendering="auto" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" height="397" font-family="'Dialog'" font-style="normal" stroke-linejoin="miter" font-size="12" stroke-dashoffset="0" image-rendering="auto">
<!--Generated by ySVG 2.5-->
<defs id="genericDefs"/>
<g>
<defs id="defs1">
<linearGradient x1="336.5" gradientUnits="userSpaceOnUse" x2="506.5" y1="386.5" y2="426.5" id="linearGradient1" spreadMethod="reflect">
<stop stop-opacity="1" stop-color="rgb(232,238,247)" offset="0%"/>
<stop stop-opacity="1" stop-color="rgb(183,201,227)" offset="100%"/>
</linearGradient>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath1">
<path d="M0 0 L877 0 L877 397 L0 397 L0 0 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath2">
<path d="M77 45 L954 45 L954 442 L77 442 L77 45 Z"/>
</clipPath>
</defs>
<g fill="white" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="translate(-77,-45)" stroke="white">
<rect x="77" width="877" height="397" y="45" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g fill="rgb(0,153,153)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(0,153,153)">
<rect x="92" y="209" clip-path="url(#clipPath2)" width="119" rx="4" ry="4" height="117" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="107.9238" xml:space="preserve" y="226.1387" clip-path="url(#clipPath2)" stroke="none">"Master" Node</text>
<rect x="92" y="209" clip-path="url(#clipPath2)" fill="none" width="119" rx="4" ry="4" height="117"/>
</g>
<g fill="rgb(0,153,153)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(0,153,153)">
<rect x="369" y="60" clip-path="url(#clipPath2)" width="105" rx="4" ry="4" height="117" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="375.498" xml:space="preserve" y="115.6699" clip-path="url(#clipPath2)" stroke="none">YARN Resource</text>
<text x="395.4492" xml:space="preserve" y="129.6387" clip-path="url(#clipPath2)" stroke="none">Manager</text>
<rect x="369" y="60" clip-path="url(#clipPath2)" fill="none" width="105" rx="4" ry="4" height="117"/>
</g>
<g fill="rgb(0,153,153)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(0,153,153)">
<rect x="369" y="212" clip-path="url(#clipPath2)" width="105" rx="4" ry="4" height="117" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="373.8457" xml:space="preserve" y="229.1387" clip-path="url(#clipPath2)" stroke="none">YARN Container</text>
<rect x="369" y="212" clip-path="url(#clipPath2)" fill="none" width="105" rx="4" ry="4" height="117"/>
</g>
<g fill="rgb(0,153,153)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(0,153,153)">
<rect x="614" y="212" clip-path="url(#clipPath2)" width="105" rx="4" ry="4" height="117" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="618.8457" xml:space="preserve" y="229.1387" clip-path="url(#clipPath2)" stroke="none">YARN Container</text>
<rect x="614" y="212" clip-path="url(#clipPath2)" fill="none" width="105" rx="4" ry="4" height="117"/>
</g>
<g fill="url(#linearGradient1)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="url(#linearGradient1)">
<path d="M336.5 394.5 C341.6 386.5 501.4 386.5 506.5 394.5 L506.5 418.5 C501.4 426.5 341.6 426.5 336.5 418.5 Z" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<path fill="none" d="M336.5 394.5 C341.6 386.5 501.4 386.5 506.5 394.5 L506.5 418.5 C501.4 426.5 341.6 426.5 336.5 418.5 Z" clip-path="url(#clipPath2)"/>
<path fill="none" d="M506.5 394.5 C501.4 402.5 341.6 402.5 336.5 394.5" clip-path="url(#clipPath2)"/>
<text x="405.1084" xml:space="preserve" y="410.6543" font-family="sans-serif" clip-path="url(#clipPath2)" stroke="none">HDFS</text>
</g>
<g fill="rgb(0,153,153)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(0,153,153)">
<rect x="791" y="212" clip-path="url(#clipPath2)" width="105" rx="4" ry="4" height="117" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="795.8457" xml:space="preserve" y="229.1387" clip-path="url(#clipPath2)" stroke="none">YARN Container</text>
<rect x="791" y="212" clip-path="url(#clipPath2)" fill="none" width="105" rx="4" ry="4" height="117"/>
</g>
<g fill="rgb(51,153,102)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(51,153,102)">
<rect x="99" width="105" height="30" y="242.5" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="137.4375" xml:space="preserve" y="254.6699" clip-path="url(#clipPath2)" stroke="none">Flink</text>
<text x="115.7959" xml:space="preserve" y="268.6387" clip-path="url(#clipPath2)" stroke="none">YARN Client</text>
<rect fill="none" x="99" width="105" height="30" y="242.5" clip-path="url(#clipPath2)"/>
</g>
<g fill="rgb(51,153,102)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(51,153,102)">
<rect x="375" width="93" height="30" y="252.5" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="407.4375" xml:space="preserve" y="264.6699" clip-path="url(#clipPath2)" stroke="none">Flink</text>
<text x="385.9512" xml:space="preserve" y="278.6387" clip-path="url(#clipPath2)" stroke="none">JobManager</text>
<rect fill="none" x="375" width="93" height="30" y="252.5" clip-path="url(#clipPath2)"/>
</g>
<g fill="rgb(51,153,102)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(51,153,102)">
<rect x="375" width="93" height="30" y="282.5" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="389.5371" xml:space="preserve" y="294.6699" clip-path="url(#clipPath2)" stroke="none">YARN App.</text>
<text x="401.0098" xml:space="preserve" y="308.6387" clip-path="url(#clipPath2)" stroke="none">Master</text>
<rect fill="none" x="375" width="93" height="30" y="282.5" clip-path="url(#clipPath2)"/>
</g>
<g fill="rgb(51,153,102)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(51,153,102)">
<rect x="620" width="93" height="30" y="255.5" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="652.4375" xml:space="preserve" y="267.6699" clip-path="url(#clipPath2)" stroke="none">Flink</text>
<text x="626.2578" xml:space="preserve" y="281.6387" clip-path="url(#clipPath2)" stroke="none">TaskManager</text>
<rect fill="none" x="620" width="93" height="30" y="255.5" clip-path="url(#clipPath2)"/>
</g>
<g fill="rgb(51,153,102)" text-rendering="geometricPrecision" shape-rendering="geometricPrecision" transform="matrix(1,0,0,1,-77,-45)" stroke="rgb(51,153,102)">
<rect x="797" width="93" height="30" y="255.5" clip-path="url(#clipPath2)" stroke="none"/>
</g>
<g text-rendering="geometricPrecision" stroke-miterlimit="1.45" shape-rendering="geometricPrecision" font-family="sans-serif" transform="matrix(1,0,0,1,-77,-45)" stroke-linecap="butt">
<text x="829.4375" xml:space="preserve" y="267.6699" clip-path="url(#clipPath2)" stroke="none">Flink</text>
<text x="803.2578" xml:space="preserve" y="281.6387" clip-path="url(#clipPath2)" stroke="none">TaskManager</text>
<rect fill="none" x="797" width="93" height="30" y="255.5" clip-path="url(#clipPath2)"/>
<text x="917.1621" xml:space="preserve" y="274.6543" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">...</text>
<path fill="none" d="M210.991 234.6698 L361.997 151.3369" clip-path="url(#clipPath2)"/>
<path d="M369.0012 147.4715 L356.079 148.8919 L361.1215 151.82 L360.9107 157.6472 Z" clip-path="url(#clipPath2)" stroke="none"/>
<text x="157.7557" xml:space="preserve" y="141.7122" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">2. Register resources </text>
<text x="150.4286" xml:space="preserve" y="155.681" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">and request AppMaster </text>
<text x="199.911" xml:space="preserve" y="169.6497" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">container</text>
<path fill="none" d="M421.5 177.0215 L421.5 204.0303" clip-path="url(#clipPath2)"/>
<path d="M421.5 212.0303 L426.5 200.0303 L421.5 203.0303 L416.5 200.0303 Z" clip-path="url(#clipPath2)" stroke="none"/>
<text x="452.5664" xml:space="preserve" y="198.6543" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">3. Allocate AppMaster Container</text>
<path fill="none" d="M473.9872 270.5 L606.0008 270.5" clip-path="url(#clipPath2)"/>
<path d="M614.0008 270.5 L602.0008 265.5 L605.0008 270.5 L602.0008 275.5 Z" clip-path="url(#clipPath2)" stroke="none"/>
<text x="481.2285" xml:space="preserve" y="304.6543" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">4. Allocate Worker</text>
<path fill="none" d="M210.991 298.1268 L380.3388 385.3096" clip-path="url(#clipPath2)"/>
<path d="M387.4516 388.9714 L379.071 379.0333 L379.4497 384.8519 L374.4938 387.9242 Z" clip-path="url(#clipPath2)" stroke="none"/>
<text x="207.4763" xml:space="preserve" y="355.1486" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">1. Store Uberjar</text>
<text x="201.4939" xml:space="preserve" y="369.1174" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">and configuration</text>
<path fill="none" d="M421.5 388.4707 L421.5 336.9957" clip-path="url(#clipPath2)" stroke="gray"/>
<path fill="gray" d="M421.5 328.9957 L416.5 340.9957 L421.5 337.9957 L426.5 340.9957 Z" clip-path="url(#clipPath2)" stroke="none"/>
<path fill="none" d="M453.1718 388.9189 L606.9806 303.5393" clip-path="url(#clipPath2)" stroke="gray"/>
<path fill="gray" d="M613.9752 299.6566 L601.0566 301.109 L606.1063 304.0247 L605.91 309.8523 Z" clip-path="url(#clipPath2)" stroke="none"/>
<path fill="none" d="M719.0037 270.5 L783.0085 270.5" clip-path="url(#clipPath2)"/>
<path d="M791.0085 270.5 L779.0085 265.5 L782.0085 270.5 L779.0085 275.5 Z" clip-path="url(#clipPath2)" stroke="none"/>
<path fill="none" d="M473.6061 389.7075 L783.3726 289.8775" clip-path="url(#clipPath2)" stroke="gray"/>
<path fill="gray" d="M790.987 287.4236 L778.0318 286.3455 L782.4208 290.1843 L781.0992 295.8634 Z" clip-path="url(#clipPath2)" stroke="none"/>
<text x="542.0724" xml:space="preserve" y="392.1359" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">Always Bootstrap containers with</text>
<text x="593.1105" xml:space="preserve" y="406.1046" font-weight="bold" clip-path="url(#clipPath2)" stroke="none">Uberjar and config</text>
</g>
</g>
</svg>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<svg width="1000px" height="350px" viewBox="0 0 1000 350" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
<title>Interval Join (Selected)</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Interval-Join-(Selected)">
<text id="time" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="882" y="262">time</tspan>
</text>
<g id="Group-3" transform="translate(116.000000, 229.000000)" stroke="#979797" stroke-linecap="square">
<path d="M0.5,5.5 L781.5,5.5" id="Line" stroke-width="2"></path>
<path id="Line-decoration-1" d="M781.5,5.5 L770.7,2.5 L770.7,8.5 L781.5,5.5 Z" stroke-width="2"></path>
<path d="M132.5,0.5 L132.5,10.5" id="Line-3"></path>
<path d="M31.5,0.5 L31.5,10.5" id="Line-3-Copy"></path>
<path d="M234.5,0.5 L234.5,10.5" id="Line-3-Copy"></path>
<path d="M334.5,0.5 L334.5,10.5" id="Line-3-Copy"></path>
<path d="M435.5,0.5 L435.5,10.5" id="Line-3-Copy"></path>
<path d="M536.5,0.5 L536.5,10.5" id="Line-3-Copy"></path>
<path d="M638.5,0.5 L638.5,10.5" id="Line-3-Copy"></path>
<path d="M739.5,0.5 L739.5,10.5" id="Line-3-Copy"></path>
</g>
<g id="Group-3-Copy" transform="translate(116.000000, 93.000000)" stroke="#979797" stroke-linecap="square">
<path d="M0.5,5.5 L781.5,5.5" id="Line" stroke-width="2"></path>
<path id="Line-decoration-1" d="M781.5,5.5 L770.7,2.5 L770.7,8.5 L781.5,5.5 Z" stroke-width="2"></path>
<path d="M132.5,0.5 L132.5,10.5" id="Line-3"></path>
<path d="M31.5,0.5 L31.5,10.5" id="Line-3-Copy"></path>
<path d="M234.5,0.5 L234.5,10.5" id="Line-3-Copy"></path>
<path d="M334.5,0.5 L334.5,10.5" id="Line-3-Copy"></path>
<path d="M435.5,0.5 L435.5,10.5" id="Line-3-Copy"></path>
<path d="M536.5,0.5 L536.5,10.5" id="Line-3-Copy"></path>
<path d="M638.5,0.5 L638.5,10.5" id="Line-3-Copy"></path>
<path d="M739.5,0.5 L739.5,10.5" id="Line-3-Copy"></path>
</g>
<g id="StreamRecord-Copy-7" transform="translate(740.000000, 85.000000)">
<circle id="Oval" stroke="#979797" fill="#7ED321" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="6" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">6</tspan>
</text>
</g>
<g id="StreamRecord-Copy-7" transform="translate(842.000000, 86.000000)">
<circle id="Oval" stroke="#979797" fill="#7ED321" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="7" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">7</tspan>
</text>
</g>
<g id="StreamRecord-Copy" transform="translate(435.000000, 222.000000)">
<circle id="Oval" stroke="#979797" fill="#F5A623" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="3" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">3</tspan>
</text>
</g>
<g id="StreamRecord-Copy-2" transform="translate(540.000000, 222.000000)">
<circle id="Oval" stroke="#979797" fill="#F5A623" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="4" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">4</tspan>
</text>
</g>
<g id="StreamRecord-Copy-3" transform="translate(640.000000, 222.000000)">
<circle id="Oval" stroke="#979797" fill="#F5A623" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="5" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">5</tspan>
</text>
</g>
<g id="StreamRecord-Copy-5" transform="translate(842.000000, 222.000000)">
<circle id="Oval" stroke="#979797" fill="#F5A623" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="7" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">7</tspan>
</text>
</g>
<g id="StreamRecord-Copy-6" transform="translate(136.000000, 222.000000)">
<circle id="Oval" stroke="#979797" fill="#F5A623" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="0" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">0</tspan>
</text>
</g>
<text id="0,0-0,1" font-family="AndaleMono, Andale Mono" font-size="20" font-weight="normal" fill="#9B9B9B">
<tspan x="131" y="276">0,0</tspan>
<tspan x="131" y="298">0,1</tspan>
</text>
<text id="2,0-2,1" font-family="AndaleMono, Andale Mono" font-size="20" font-weight="normal" fill="#34323B">
<tspan x="334" y="276">2,0</tspan>
<tspan x="334" y="298">2,1</tspan>
</text>
<text id="3,1" font-family="AndaleMono, Andale Mono" font-size="20" font-weight="normal" fill="#9B9B9B">
<tspan x="429" y="276">3,1</tspan>
</text>
<text id="5,6" font-family="AndaleMono, Andale Mono" font-size="20" font-weight="normal" fill="#9B9B9B">
<tspan x="634" y="276">5,6</tspan>
</text>
<text id="7,6-7,7" font-family="AndaleMono, Andale Mono" font-size="20" font-weight="normal" fill="#9B9B9B">
<tspan x="836" y="276">7,6</tspan>
<tspan x="836" y="298">7,7</tspan>
</text>
<polygon id="Path-3" fill-opacity="0.100000001" fill="#9B9B9B" points="-51 99.8380503 151.566279 235.968947 251.677716 99.8380503"></polygon>
<polygon id="Path-3" fill-opacity="0.100000001" fill="#9B9B9B" points="246 99.8380503 448.566279 235.968947 548.677716 99.8380503"></polygon>
<polygon id="Path-3" fill-opacity="0.100000001" fill="#9B9B9B" points="350 99.8380503 552.566279 235.968947 652.677716 99.8380503"></polygon>
<polygon id="Path-3" fill-opacity="0.100000001" fill="#9B9B9B" points="448 99.8380503 650.566279 235.968947 750.677716 99.8380503"></polygon>
<polygon id="Path-3" fill-opacity="0.100000001" fill="#9B9B9B" points="651 99.8380503 853.566279 235.968947 953.677716 99.8380503"></polygon>
<polygon id="Path-3" fill-opacity="0.5" fill="#F8E71C" points="148.284508 99.8380503 350.850787 235.968947 450.962224 99.8380503"></polygon>
<g id="StreamRecord-Copy-7" transform="translate(235.000000, 85.000000)">
<circle id="Oval" stroke="#979797" fill="#7ED321" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="1" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">1</tspan>
</text>
</g>
<text id="lower-bound" transform="translate(246.800863, 159.474217) rotate(34.000000) translate(-246.800863, -159.474217) " font-family="AndaleMono, Andale Mono" font-size="14" font-weight="normal" fill="#34323B">
<tspan x="200.300863" y="164.474217">lower bound</tspan>
</text>
<text id="upper-bound" transform="translate(398.500000, 156.000000) rotate(-53.000000) translate(-398.500000, -156.000000) " font-family="AndaleMono, Andale Mono" font-size="14" font-weight="normal" fill="#34323B">
<tspan x="352" y="161">upper bound</tspan>
</text>
<g id="StreamRecord" transform="translate(338.000000, 222.000000)">
<circle id="Oval" stroke="#979797" fill="#F5A623" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="2" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">2</tspan>
</text>
</g>
<g id="StreamRecord-Copy-6" transform="translate(135.000000, 86.000000)">
<circle id="Oval" stroke="#979797" fill="#7ED321" cx="12.5" cy="12.5" r="12.5"></circle>
<text id="0" font-family="Roboto-Regular, Roboto" font-size="16" font-weight="normal" fill="#34323B">
<tspan x="8" y="18">0</tspan>
</text>
</g>
</g>
</g>
</svg>
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="974.0144"
height="409.9375"
id="svg2">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(258.42828,-167.38041)"
id="layer1">
<g
transform="translate(-323.70953,144.47416)"
id="g2989">
<path
d="m 66.203993,358.32677 0,73.59333 621.867427,0 0,-73.59333 -621.867427,0 z"
id="path2991"
style="fill:#e4eaf4;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
d="m 66.203993,358.32677 621.867427,0 0,73.59333 -621.867427,0 z"
id="path2993"
style="fill:none;stroke:#898c92;stroke-width:1.87546718px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
x="164.98396"
y="408.29218"
id="text2995"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">Stateful</text>
<text
x="293.41599"
y="408.29218"
id="text2997"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">Stream Processing</text>
<path
d="m 181.69526,246.88651 0,73.59333 506.37616,0 0,-73.59333 -506.37616,0 z"
id="path2999"
style="fill:#f5a030;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
d="m 181.69526,246.88651 506.37616,0 0,73.59333 -506.37616,0 z"
id="path3001"
style="fill:none;stroke:#935f1c;stroke-width:1.87546718px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
x="231.63388"
y="296.79422"
id="text3003"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">DataStream </text>
<text
x="428.33289"
y="296.79422"
id="text3005"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">/ </text>
<text
x="447.83777"
y="296.79422"
id="text3007"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">DataSet</text>
<text
x="582.12122"
y="296.79422"
id="text3009"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">API</text>
<path
d="m 288.93448,135.44624 0,73.4433 399.13694,0 0,-73.4433 -399.13694,0 z"
id="path3011"
style="fill:#be73f1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
d="m 288.93448,135.44624 399.13694,0 0,73.4433 -399.13694,0 z"
id="path3013"
style="fill:none;stroke:#724591;stroke-width:1.87546718px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
x="414.60895"
y="185.29616"
id="text3015"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial"> Table API</text>
<path
d="m 415.0409,23.855943 0,73.593334 273.03052,0 0,-73.593334 -273.03052,0 z"
id="path3017"
style="fill:#e6526e;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
d="m 415.0409,23.855943 273.03052,0 0,73.593334 -273.03052,0 z"
id="path3019"
style="fill:none;stroke:#8a3142;stroke-width:1.87546718px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
x="516.66846"
y="73.79821"
id="text3021"
xml:space="preserve"
style="font-size:34.95870972px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">SQL</text>
<text
x="722.66699"
y="292.85269"
id="text3023"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">Core </text>
<text
x="782.38184"
y="292.85269"
id="text3025"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">APIs</text>
<text
x="722.66699"
y="181.35474"
id="text3027"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">Declarative DSL</text>
<text
x="722.66699"
y="69.856773"
id="text3029"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">High</text>
<text
x="774.27985"
y="69.856773"
id="text3031"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">-</text>
<text
x="782.68195"
y="69.856773"
id="text3033"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">level Language</text>
<text
x="722.66699"
y="389.2005"
id="text3035"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">Low</text>
<text
x="768.72845"
y="389.2005"
id="text3037"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">-</text>
<text
x="777.13055"
y="389.2005"
id="text3039"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">level building block</text>
<text
x="722.66699"
y="419.20798"
id="text3041"
xml:space="preserve"
style="font-size:25.05624199px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Arial">(streams, state, [event] time)</text>
</g>
</g>
</svg>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册