この記事は一連の「FlinkのDataSource Trilogy」の2番目です。前の記事「One of Flink's DataSource Trilogy:Direct API」では、StreamExecutionEnvironmentのAPIを学習してDataSourceを作成しました。今日練習したいのは、Flinkの組み込みコネクタですつまり、次の図の赤いボックスの位置です。これらのコネクタは、StreamExecutionEnvironmentのaddSourceメソッドを介して使用できます。
今日の実際の戦闘では、操作するデータソースとしてKafkaを選択し、最初に文字列メッセージを受信して処理してから、JSONメッセージを受信して、JSONを逆にします。 Beanインスタンスに。
FlinkのDataSource三部作の記事へのリンク
- 「FlinkのDataSource Trilogy:Direct APIの1つ」
- 「FlinkのDataSource Trilogyパート2:組み込みコネクター」
- 「FlinkのDataSource Trilogyパート3:カスタマイズ」
ソースコードのダウンロード
コードを記述したくない場合は、シリーズ全体のソースコードをGitHubからダウンロードできます。アドレスとリンク情報は、次の表(https://github.com/zq2599/blog_demos)に表示されています。
名前 | リンク | 備考 |
---|---|---|
プロジェクトホームページ | https://github.com/zq2599/blog_demos | GitHub上のプロジェクトのホームページ |
gitリポジトリアドレス(https) | https://github.com/zq2599/blog_demos.git | プロジェクトのソースコード、httpsプロトコルの倉庫アドレス |
gitリポジトリアドレス(ssh) | [email protected]:zq2599 / blog_demos.git | プロジェクトのソースコード、sshプロトコルの倉庫アドレス |
このgitプロジェクトには複数のフォルダがあります。この章のアプリケーションは、以下の赤いボックスに示すように、flinkdatasourcedemoフォルダの下にあります。
環境とバージョン
この実際の戦闘の環境とバージョンは次のとおりです。
- JDK:1.8.0_211
- 強い:1.9.2
- メイベン:3.6.0
- オペレーティングシステム:macOS Catalina 10.15.3(MacBook Pro 13-inch、2018)
- IDEA:2018.3.5(Ultimate Edition)
- カフカ:2.4.0
- 飼育係:3.5.5
実際の戦闘を続行する前に、上記のコンテンツが準備できていることを確認してください。
FlinkはKafkaバージョンと一致します
- Flinkの公式担当者は、Kafkaのバージョンの一致について詳細に説明しています。アドレスは次のとおりです。https://ci.apache.org/projects/flink/flink-docs-stable/dev/connectors/kafka.html
- Flink 1.7から発売され、Kafka 1.0.0以降で使用できる、公式に言及されたユニバーサルKafkaコネクタに焦点を当てています。
- 下の図の赤いボックスは私のプロジェクトが依存するライブラリで、青いボックスはKafkaを接続するために使用されるクラスです。読者はKafkaのバージョンに応じて適切なライブラリとクラスを表から見つけることができます。
実際の文字列メッセージ処理
- kafkaにtest001という名前のトピックを作成します。次のコマンドを参照してください:
./kafka-topics.sh \
--create \
--zookeeper 192.168.50.43:2181 \
--replication-factor 1 \
--partitions 2 \
--topic test001
- 前の章で作成したflinkdatasourcedemoプロジェクトを引き続き使用し、pom.xmlファイルを開いて、次の依存関係を追加します。
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_2.11</artifactId>
<version>1.10.0</version>
</dependency>
- ブローカーに接続し、受信した文字列メッセージに対してWordCount操作を実行するために使用されるクラスKafka240String.javaを追加しました。
package com.bolingcavalry.connector;
import com.bolingcavalry.Splitter;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import java.util.Properties;
import static com.sun.tools.doclint.Entity.para;
public class Kafka240String {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//设置并行度
env.setParallelism(2);
Properties properties = new Properties();
//broker地址
properties.setProperty("bootstrap.servers", "192.168.50.43:9092");
//zookeeper地址
properties.setProperty("zookeeper.connect", "192.168.50.43:2181");
//消费者的groupId
properties.setProperty("group.id", "flink-connector");
//实例化Consumer类
FlinkKafkaConsumer<String> flinkKafkaConsumer = new FlinkKafkaConsumer<>(
"test001",
new SimpleStringSchema(),
properties
);
//指定从最新位置开始消费,相当于放弃历史消息
flinkKafkaConsumer.setStartFromLatest();
//通过addSource方法得到DataSource
DataStream<String> dataStream = env.addSource(flinkKafkaConsumer);
//从kafka取得字符串消息后,分割成单词,统计数量,窗口是5秒
dataStream
.flatMap(new Splitter())
.keyBy(0)
.timeWindow(Time.seconds(5))
.sum(1)
.print();
env.execute("Connector DataSource demo : kafka");
}
}
- kafkaのトピックが作成されていることを確認し、Kafka240を実行します。メッセージを消費し、単語をカウントする機能は正常です。
- カフカ文字列メッセージを受信する実際の戦闘は完了しました。次に、JSON形式のメッセージを試してください。
実際の戦闘JSONメッセージ処理
- 次に受け入れられるJSON形式のメッセージをBeanインスタンスに逆シリアル化でき、JSONライブラリーが使用されます。
- pom.xmlにgson依存関係を追加します。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
- Student.javaクラスを追加します。これは通常のBeanであり、idとnameの2つのフィールドのみです。
package com.bolingcavalry;
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- DeserializationSchemaインターフェースの実装であるStudentSchema.javaクラスを追加します。これは、JSONをStudentインスタンスに逆シリアル化するときに使用されます。
ackage com.bolingcavalry.connector;
import com.bolingcavalry.Student;
import com.google.gson.Gson;
import org.apache.flink.api.common.serialization.DeserializationSchema;
import org.apache.flink.api.common.serialization.SerializationSchema;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import java.io.IOException;
public class StudentSchema implements DeserializationSchema<Student>, SerializationSchema<Student> {
private static final Gson gson = new Gson();
/**
* 反序列化,将byte数组转成Student实例
* @param bytes
* @return
* @throws IOException
*/
@Override
public Student deserialize(byte[] bytes) throws IOException {
return gson.fromJson(new String(bytes), Student.class);
}
@Override
public boolean isEndOfStream(Student student) {
return false;
}
/**
* 序列化,将Student实例转成byte数组
* @param student
* @return
*/
@Override
public byte[] serialize(Student student) {
return new byte[0];
}
@Override
public TypeInformation<Student> getProducedType() {
return TypeInformation.of(Student.class);
}
}
- 新しいクラスKafka240Bean.javaが追加されました。これは、ブローカーの接続、受信したJSONメッセージのStudentインスタンスへの変換、および各名前の出現回数のカウントに使用されます。ウィンドウはまだ5秒です:
package com.bolingcavalry.connector;
import com.bolingcavalry.Splitter;
import com.bolingcavalry.Student;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import java.util.Properties;
public class Kafka240Bean {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//设置并行度
env.setParallelism(2);
Properties properties = new Properties();
//broker地址
properties.setProperty("bootstrap.servers", "192.168.50.43:9092");
//zookeeper地址
properties.setProperty("zookeeper.connect", "192.168.50.43:2181");
//消费者的groupId
properties.setProperty("group.id", "flink-connector");
//实例化Consumer类
FlinkKafkaConsumer<Student> flinkKafkaConsumer = new FlinkKafkaConsumer<>(
"test001",
new StudentSchema(),
properties
);
//指定从最新位置开始消费,相当于放弃历史消息
flinkKafkaConsumer.setStartFromLatest();
//通过addSource方法得到DataSource
DataStream<Student> dataStream = env.addSource(flinkKafkaConsumer);
//从kafka取得的JSON被反序列化成Student实例,统计每个name的数量,窗口是5秒
dataStream.map(new MapFunction<Student, Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> map(Student student) throws Exception {
return new Tuple2<>(student.getName(), 1);
}
})
.keyBy(0)
.timeWindow(Time.seconds(5))
.sum(1)
.print();
env.execute("Connector DataSource demo : kafka bean");
}
}
- テスト中に、JSON形式の文字列をkafkaに送信する必要があります。flinkは各名前の数をカウントします
。この時点で、組み込みコネクタの実際の戦いは完了しています。次の章では、DataSourceをカスタマイズするために一緒に作業します;