カスタム データ ソースの読み取り (ソース オペレーター)
DataStream は Flink プログラムであり、実際には DataStream のさまざまな変換です。具体的には、コードは基本的に次の部分で構成されています。
- 実行環境を取得する
- データ ソースの読み取り (ソース)
- データベース変換操作の定義 (変換)
- 計算結果の出力先を定義(Sink)
- プログラム実行のトリガー (Execute)
実行環境
実行環境を作成する
Flink プログラムを書く最初のステップは、実行環境を作成することです。取得したい実行環境は、すべての Flink プログラムの基礎となる StreamExecutionEnvironment クラスのオブジェクトです。コードで実行環境を作成する方法は、このクラスの静的メソッドを呼び出すことです. 具体的な方法は 3 つあります:
1. getExecutionEnvironment (スマート)
getExecutionEnvironment メソッドを直接呼び出すことです。現在実行中のコンテキストに従って、正しい結果を直接取得します。つまり、このメソッドは、現在の実行モードに従って、返す実行環境の種類を決定します。
val env = StreamExecutionEnvironment.getExecutionEnvironment
この「スマートな」方法は、追加の判断を行う必要がなく、使用するのが簡単で効率的であり、実行環境を作成するために最も一般的に使用される方法です。
2. createLocalEnvironment (ローカル)
このメソッドは、ローカル実行環境を返します。呼び出し時にパラメータを渡して、デフォルトの並列度を指定できます。パラメータを渡さない場合、デフォルトの並列度はローカル CPU コアの数になります。
val localEnvironment = StreamExecutionEnvironment.createLocalEnvironment()
3.、createRemoteEnvironment (リモート)
このメソッドは、クラスター実行環境を返します。呼び出し時にジョブマネージャーのホスト名とポート番号を指定し、クラスターで実行するJarパッケージを指定する必要があります。
val remoteEnv = StreamExecutionEnvironment
.createRemoteEnvironment(
"host", // JobManager 主机名
1234, // JobManager 进程端口号
"path/to/jarFile.jar" // 提交给 JobManager 的 JAR 包
)
実行モード
以前のバージョンの Flink では、バッチ処理の実行環境はストリーム処理の実行環境に似ており、クラス ExecutionEnvironment の静的メソッドを呼び出してそのオブジェクトを返します。
// 批处理环境
val batchEnv = ExecutionEnvironment.getExecutionEnvironment
// 流处理环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
- ストリーミング実行モード (STREAMING) これは、DataStream API の最も古典的なモードであり、通常、継続的なリアルタイム処理を必要とする無制限のデータ ストリームに使用されます。デフォルトでは、プログラムは STREAMING 実行モードを使用します。
- バッチ実行モード (BATCH) はバッチ処理の実行モード専用です. このモードでは, Flink は MapReduce フレームワークと同様にジョブを処理します. 継続的に計算されない境界のあるデータの場合、このモードを使用して処理する方が便利です。
- 自動モード (AUTOMATIC) このモードでは、入力データ ソースがバインドされているかどうかに応じて、プログラムが自動的に実行モードを選択します。Flink プログラムはデフォルトで STREAMING モードになっているため、ここでは BATCH モードの設定に焦点を当てます。
BATCH (バッチ処理) モードを構成するには、主に 2 つの方法があります。
1.コマンド ラインから構成する
ジョブを送信するときに、execution.runtime-mode パラメーターを追加し、値を BATCH として指定します。
bin/flink run -Dexecution.runtime-mode=BATCH ...
2. コードで構成する (非推奨)
コードでは、実行環境に基づいて setRuntimeMode メソッドを直接呼び出し、BATCH モードで渡します。
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setRuntimeMode(RuntimeExecutionMode.BATCH)
プログラムの実行をトリガーする
プログラムの実行をトリガーするには、実行環境の execute() メソッドを明示的に呼び出す必要があります。execute() メソッドは、ジョブが完了するのを待ってから、実行結果 (JobExecutionResult) を返します。
env.execute()
ソース演算子 (ソース)
Flink はさまざまなソースからデータを取得し、変換処理のために DataStream を構築できます。一般に、データの入力元をデータソース、データを読み込むオペレーターをソースオペレーター(Source)と呼びます。したがって、Source はハンドラー全体への入力です。
The general way to add Source in Flink code is to call the addSource() method of the execution environment. メソッドはオブジェクト パラメータを渡し、SourceFunction インターフェイスを実装する必要があり、DataStream を返します。
//通过调用 addSource()方法可以获取 DataStream 对象
val stream = env.addSource(...)
バインドされたデータ ストリームの読み取り
ケースの要件:
理解を深めるために、まず実用的なアプリケーション シナリオを作成しましょう。たとえば、Web サイトのアクセス操作は 3 つ (ユーザー名、ユーザーがアクセスした URL、ユーザーがアクセスした URL のタイムスタンプ) に抽象化できるため、ここではクラス Event を作成して、ユーザーの行動を 1 つにまとめることができます。そのオブジェクトの。イベントには次のフィールドが含まれます
サンプル クラスを定義する
case class Event(user: String, url: String, timestamp: Long)
1.要素からデータを読み取る
//从元素中读取数据
val stream: DataStream[Int] = env.fromElements(1, 2, 3, 4, 5, 6) //指定元素数据
//创建当前样例类Event的对象
val value1: DataStream[Event] = env.fromElements(
Event("张三", "01", 1000L),
Event("李四", "04", 2000L),
Event("王五", "01", 6000L),
Event("赵六", "03", 1000L)
)
2. コレクションからデータを読み取る
//从集合中读取数据
//定义一个集合
val e = List(
Event("张三", "01", 1000L),
Event("李四", "04", 2000L),
Event("王五", "01", 6000L),
Event("赵六", "03", 1000L)
)
val value2: DataStream[Event] = env.fromCollection(e)
3. ファイルからデータを読み取る
実際の実用的なアプリケーションでは、当然、データがコードに直接書き込まれることはありません。通常、ストレージ メディアからデータを取得します。一般的な方法は、ログ ファイルを読み取ることです。これは、バッチで読み取る最も一般的な方法でもあります。
val value3: DataStream[String] = env.readTextFile("datas\\wc.txt")
無制限のデータを読み取る
1. ソケットからデータを読み取る
コレクションであろうとファイルであろうと、実際に読み取るのは境界のあるデータです。ストリーム処理シナリオでは、多くの場合、データは無制限です。簡単な例は、前に使用したソケット テキスト ストリームを読み取ることです。スループットが小さく、安定性が低いため、この方法は一般的にテストに使用されます。
val stream = env.socketTextStream("localhost", 7777)
2. Kafka からデータを読み取る
Flink は公式に接続ツール flink-connector-kafka を提供しています。これは、Kafka データを読み取るために使用される SourceFunction であるコンシューマー FlinkKafkaConsumer を実装するのに直接役立ちます。
コネクタの依存関係を追加する
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
env.addSource() を呼び出し、FlinkKafkaConsumer のオブジェクト インスタンスを渡します。
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
//设置全局并行度
env.setParallelism(1)
//使用Properties对象保存kafa连接的相关配置
val properties: Properties = new Properties()
properties.setProperty("bootstrap.servers","master:9000")
properties.setProperty("group.id","consumer-group")
val stream: DataStream[String] = env.addSource( new FlinkKafkaConsumer[String]("clicks", new SimpleStringSchema(),properties))
stream.print()
env.execute()
}
カスタム データ ソースの読み取り (ソース オペレーター)
次に、カスタム データ ソースを作成し、SourceFunction インターフェイスを実装します。主に、run() と cancel() の 2 つの主要なメソッドを書き直します。
- run() メソッド: ランタイム コンテキスト オブジェクト (SourceContext) を使用してデータを下流に送信します。
- cancel() メソッド: 識別ビット制御を介してループを終了し、データ ソースを中断する効果を実現します。
カスタム読み取りデータ ソース クラスを作成する
class f4 extends SourceFunction[ Event ]{ //实现SourceFunction接口 泛型为之前定义好的样例类Event
//标志位
var running = true
//重写抽象方法
override def run(sourceContext: SourceFunction.SourceContext[Event]): Unit = {
//随机数生成器
val random = new Random ()
//定义数据随机选择的范围
val user = Array ("张三", "李四", "王五")
val url = Array ("02", "01", "03", "04")
//用标志位作为循环判断条件,不停的发出数据
while (running) {
val event = Event (user (random.nextInt (user.length) ), url (random.nextInt (url.length) ), Calendar.getInstance.getTimeInMillis)
//调用ctx的方法向下游发送数据
sourceContext.collect (event)
//每隔1秒发送一条数据
Thread.sleep (1000)
}
}
override def cancel(): Unit = running = false
}
テストクラスの実行
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
//全局并行度设置为1
env.setParallelism(1)
//读取自定义的数据源
val ste: DataStream[Event] = env.addSource(new f4)
//输出
ste.print()
//执行
env.execute()
}
実行効果: 1 秒ごとに 1 行のデータを自動的に出力する