becketqin commented on a change in pull request #12492:
URL: https://github.com/apache/flink/pull/12492#discussion_r437184266



##########
File path: docs/dev/stream/sources.md
##########
@@ -0,0 +1,168 @@
+---
+title: "Data Sources"
+nav-title: "Data Sources"
+nav-parent_id: streaming
+nav-pos: 10
+---
+<!--
+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.
+-->
+
+
+* This will be replaced by the TOC
+{:toc}
+
+<div class="alert alert-warning">
+  <p><strong>Note:</strong> This describes the new Data Source API, introduced 
in Flink 1.11 as part of <a 
href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-27%3A+Refactor+Source+Interface";>FLIP-27</a>.
+  This new API is currently in <strong>BETA</strong> status.</p>
+  <p>Most of the existing source connectors are not yet (as of Flink 1.11) 
implemented using this new API,
+  but using the previous API, based on <a 
href="https://github.com/apache/flink/blob/master/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/functions/source/SourceFunction.java";>SourceFunction</a>.</p>
+</div>
+
+
+This page describes Flink's Data Source API and the concepts and architecture 
behind it.
+**Read this, if you are interested in how data sources in Flink work, or if 
you want to implement a new Data Source.**
+
+If you are looking for pre-defined source connectors, please check the 
[Connector Docs]({{ site.baseurl }}/dev/connectors/).
+
+
+## Data Source Concepts
+
+**Core Components**
+
+A Data Source has three core components: *Splits*, the *SplitEnumerator*, and 
the *SourceReader*.
+
+  - A **Split** is a portion of data consumed by the source, like a file or a 
log partition. Splits are granularity by which the source distributes the work 
and parallelizes the data reading.
+
+  - The **SourceReader** requests *Splits* and processes them, for example by 
reading the file or log partition represented by the *Split*. The 
*SourceReader* run in parallel on the Task Managers in the `SourceOperators` 
and produces the parallel stream of events/records.
+
+  - The **SplitEnumerator** generates the *Splits* and assignes them to the 
*SourceReaders*. It runs as a single instance on the Job Manager and is 
responsible for maintaining the backlog of pending *Splits* and assigning them 
to the readers in a balanced manner.
+  
+The [Source]() class is API entry point that ties the above three components 
together.
+
+<div style="text-align: center">
+  <img width="70%" src="{{ site.baseurl }}/fig/source_components.svg" 
alt="Illustration of SplitEnumerator and SourceReader interacting." />
+</div>
+
+
+**Unified Across Streaming and Batch**
+
+The Data Source API supports both unbounded streaming sources and bounded 
batch sources, in a unified way.
+
+The difference between both cases is minimal: In the bounded/batch case, the 
enumerator generates a fix set of splits, and each split is necessarily finite. 
In the unbounded streaming case, one of the two is not true (splits are not 
finite, or the enumerator keep generating new splits).
+
+#### Examples
+
+Here are some simplified conceptual examples to illustrate how the data source 
components interact, in streaming and batch cases.
+
+*Note that this does not the accurately describe how the Kafka and File source 
implementations work; parts are simplified, for illustrative purposes.*
+
+**Bounded File Source**
+
+The source has the URI/Path of a directory to read, and a *Format* that 
defines how to parse the files.
+
+  - A *Split* is a file, or a region of a file (if the data format supports 
splitting the file).
+  - The *SplitEnumerator* lists all files under the given directory path. It 
assigns Splits to the next reader that requests a Split. Once all Splits are 
assigned, it responds to requests with *NoMoreSplits*.
+  - The *SourceReader* requests a Split and reads the assigned Split (file or 
file region) and parses it using the given Format. If it does not get another 
Split, but a *NoMoreSplits* message, it finishes.
+
+**Unbounded Streaming File Source**
+
+This source works the same way as described above, except that the 
*SplitEnumerator* never responds with *NoMoreSplits* and periodically lists the 
contents under the given URI/Path to check for new files. Once it finds new 
files, it generates new Splits for them and can assign them to the available 
SourceReaders.
+
+**Unbounded Streaming Kafka Source**
+
+The source has a Kafka Topic (or list of Topics or Topic regex) and a 
*Deserializer* to parse the records.
+
+  - A *Split* is a Kafka Topic Partition.
+  - The *SplitEnumerator* connects to the brokers to list all topic partitions 
involved in the subscribed topics. The enumerator can optionally repeat this 
operation to discover newly added topics/partitions.
+  - The *SourceReader* reads the assigned Splits (Topic Partitions) using the 
KafkaConsumer and deserializes the records using the provided Deserializer. The 
splits (Topic Partitions) do not have an end, so the reader never reaches the 
end of the data.
+
+**Bounded Kafka Source**
+
+Same as above, except that each Split (Topic Partition) has a defined end 
offset. Once the *SourceReader* reaches the end offset for a Split, it finishes 
that Split. Once all assigned Splits are finished, the SourceReader finishes.
+
+----
+----
+
+## The Data Source API
+
+Source, SourceEnumerator, SourceReader.
+
+env.continuousSource(...).
+
+----
+----
+
+## The Split Reader API
+
+
+core SourceReader API is asynchronous and rather low level, leavers users to 
handle splits manually.
+in practice, many sources have perform blocking poll() and I/O operations, 
needing separate threads.
+Split Reader is base implementation for that.
+
+----
+----
+
+## Event Time and Watermarks
+
+*Event Time* assignment and *Watermark Generation* happen as part of the data 
sources. The event streams leaving the Source Readers have event timestamps and 
(during streaming execution) contain watermarks. See [Timely Stream 
Processing]({{ site.baseurl }}/concepts/timely-stream-processing.html) for an 
introduction to Event Time and Watermarks.
+
+<span class="label label-danger">Important</span> Applications based on the 
legacy 
[SourceFunction](https://github.com/apache/flink/blob/master/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/functions/source/SourceFunction.java)
 typically generate timestamps and watermarks in a separate later step via 
`stream.assignTimestampsAndWatermarks(WatermarkStrategy)`. This function should 
not be used with the new sources, because timestamps will be already assigned, 
and it will override the previous split-aware watermarks.
+
+#### API
+
+The `WatermarkStrategy` is passed to the Source during creation in the 
DataStream API and creates both the 
[TimestampAssigner](https://github.com/apache/flink/blob/master/flink-core/src/main/java/org/apache/flink/api/common/eventtime/TimestampAssigner.java)
 and 
[WatermarkGenerator](https://github.com/apache/flink/blob/master/flink-core/src/main/java/org/apache/flink/api/common/eventtime/WatermarkGenerator.java).
+
+{% highlight java %}
+environment.continuousSource(
+    Source<OUT, ?, ?> source,
+    WatermarkStrategy<OUT> timestampsAndWatermarks,
+    String sourceName)
+{% endhighlight %}
+
+The `TimestampAssigner` and `WatermarkGenerator` run transparently as part of 
the `ReaderOutput`(or `SourceOutput`) so source implementors do not have to 
implement and timestamp extraction and watermark generation code.
+
+#### Event Timestamps
+
+Event timestamps are assigned in two steps:
+
+  1. The SourceReader may attach the *source record timestamp* to the event, 
by calling `SourceOutput.collect(event, timestamp)`.
+     This is relevant only for data sources that are record-based and have 
timestamps, such as Kafka, Kinesis, Pulsar, or Pravega.
+     Sources that are not based on records with timestamps (like files) do not 
have a *source record timestamp*.
+     This step is part of the source connector implementation and not 
parameterized by the application that uses the source.
+
+  2. The `TimestampAssigner`, which is configured by the application, assigns 
the final timestamp.
+     The `TimestampAssigner` sees the original *source record timestamp* and 
the event. The assigner can use the *source record timestamp* or access a field 
of the event obtain the final event timestamp.
+  
+This two-step approach allows users to reference both timestamps from the 
source systems and timestamps in the event's data as the event timestamp.
+
+*Note:* When using a data source without *source record timestamps* (like 
files) and but selecting the *source record timestamp* as the final event 
timestamp, events will get a default timestamp equal to `LONG_MIN` 
*(=-9,223,372,036,854,775,808)*.

Review comment:
       "and but" -> and?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to