Flinkをエンドツーエンドでコンピューティングするビッグデータストリームの完全なケース

第1章;序章

前回の記事では、Flink関連環境の準備を紹介し、簡単なFlink開発環境の確立を完了しました。この記事では、Flinkコンピューティングをカバーする完全なエンドツーエンドのケースを紹介します:client => Web API service = > Kafka => Flink => MySQL。今回も例としてFlinkTable API / SQL取り上げ、docker-composeにデプロイします。(コードの重要な部分のみが記事に記載されています。完全なコードについては、作成者がアップロードしたフォローアップgithubを参照してください)。

 

第2章docker-compose

2.1docker-compose.ymlファイルを追加します

version: '2'
services:
  jobmanager:
    image: zihaodeng/flink:1.11.1
    volumes:
      - D:/21docker/flinkDeploy:/opt/flinkDeploy
    hostname: "jobmanager"
    expose:
      - "6123"
    ports:
      - "4000:4000"
    command: jobmanager
    environment:
      - JOB_MANAGER_RPC_ADDRESS=jobmanager
  taskmanager:
    image: zihaodeng/flink:1.11.1
    volumes:
      - D:/21docker/flinkDeploy:/opt/flinkDeploy
    expose:
      - "6121"
      - "6122"
    depends_on:
      - jobmanager
    command: taskmanager
    links:
      - jobmanager:jobmanager
    environment:
      - JOB_MANAGER_RPC_ADDRESS=jobmanager
  zookeeper:
    container_name: zookeeper
    image: zookeeper:3.6.1
    ports:
      - "2181:2181"
  kafka:
    container_name: kafka
    image: wurstmeister/kafka:2.12-2.5.0
    volumes:
      - D:/21docker/var/run/docker.sock:/var/run/docker.sock
    ports:
      - "9092:9092"
    depends_on:
      - zookeeper
    environment:
      #KAFKA_ADVERTISED_HOST_NAME: kafka
      HOSTNAME_COMMAND: "route -n | awk '/UG[ \t]/{print $$2}'"
      KAFKA_CREATE_TOPICS: "order-log:1:1"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      #KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://127.0.0.1:9092
      #KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
  mysql:
    image: mysql:5.7
    container_name: mysql
    volumes:
      - D:/21docker/mysql/data/db:/var/lib/mysql/
      - D:/21docker/mysql/mysql-3346.sock:/var/run/mysql.sock
      - D:/21docker/mysql/data/conf:/etc/mysql/conf.d
    ports:
      - 3306:3306
    command:
      --default-authentication-plugin=mysql_native_password
      --lower_case_table_names=1
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      TZ: Asia/Shanghai

2.2docker-作成開始

$ docker-compose up -d

動作確認

このセクションでは、docker-composeの準備ができており、後で作業環境を開始すると非常に便利です。次に、対応するプログラムの準備を開始します。

 

第3章WebApiプロジェクトの作成

3.1 WebApi(Restful API)インターフェイスプロジェクトを作成する

springbootを使用してAPIプロジェクトをすばやく構築します。ここでの作成者はRestfulApiインターフェイス形式を使用しています。コードの一部は次のとおりです(完全なコードについては、作成者のgithubを参照してください)。

クライアントが呼び出すための投稿インターフェイスを作成します

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private Sender sender;

    @PostMapping
    public String insertOrder(@RequestBody Order order) {
        sender.producerKafka(order);
        return "{\"code\":0,\"message\":\"insert success\"}";
    }
}

Senderクラスを作成し、Kafkaにデータを送信します 

public class Sender {
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    private static Random rand = new Random();

    public void producerKafka(Order order){
        order.setPayTime(String.valueOf(new Timestamp(System.currentTimeMillis()+ rand.nextInt(100))));//EventTime
        kafkaTemplate.send("order-log", JSON.toJSONString(order));
    }
}

 

第4章Flinkジョブの作成

ここでは、Flink Table API / SQLを使用してタンブルウィンドウ計算を実装しています。Kafkaで読み取られたデータは、ウィンドウ計算によって要約され、MySQLに書き込まれます。

public class Kafka2MysqlByEnd2End {
    public static void main(String[] args) throws Exception {
        // Kafka source
        String sourceSQL="CREATE TABLE order_source (\n" +
                "   payTime VARCHAR,\n" +
                "   rt as TO_TIMESTAMP(payTime),\n" +
                "   orderId BIGINT,\n" +
                "   goodsId INT,\n" +
                "   userId INT,\n" +
                "   amount DECIMAL(23,10),\n" +
                "   address VARCHAR,\n" +
                "   WATERMARK FOR rt as rt - INTERVAL '2' SECOND\n" +
                " ) WITH (\n" +
                "   'connector' = 'kafka-0.11',\n" +
                "   'topic'='order-log',\n" +
                "   'properties.bootstrap.servers'='kafka:9092',\n" +
                "   'format' = 'json',\n" +
                "   'scan.startup.mode' = 'latest-offset'\n" +
                ")";

        //Mysql sink
        String sinkSQL="CREATE TABLE order_sink (\n" +
                "   goodsId BIGINT,\n" +
                "   goodsName VARCHAR,\n" +
                "   amount DECIMAL(23,10),\n" +
                "   rowtime TIMESTAMP(3),\n" +
                "   PRIMARY KEY (goodsId) NOT ENFORCED\n" +
                " ) WITH (\n" +
                "   'connector' = 'jdbc',\n" +
                "   'url' = 'jdbc:mysql://mysql:3306/flinkdb?characterEncoding=utf-8&useSSL=false',\n" +
                "   'table-name' = 'good_sale',\n" +
                "   'username' = 'root',\n" +
                "   'password' = '123456',\n" +
                "   'sink.buffer-flush.max-rows' = '1',\n" +
                "   'sink.buffer-flush.interval' = '1s'\n" +
                ")";

        // 创建执行环境
        EnvironmentSettings settings = EnvironmentSettings
                .newInstance()
                .useBlinkPlanner()
                .inStreamingMode()
                .build();
        //TableEnvironment tEnv = TableEnvironment.create(settings);
        StreamExecutionEnvironment sEnv = StreamExecutionEnvironment.getExecutionEnvironment();

        //sEnv.setRestartStrategy(RestartStrategies.fixedDelayRestart(3, Time.of(1, TimeUnit.SECONDS)));
        //sEnv.enableCheckpointing(1000);
        //sEnv.setStateBackend(new FsStateBackend("file:///tmp/chkdir",false));

        StreamTableEnvironment tEnv= StreamTableEnvironment.create(sEnv,settings);

        Configuration configuration = tEnv.getConfig().getConfiguration();
        //设置并行度为1
        configuration.set(CoreOptions.DEFAULT_PARALLELISM, 1);

        //注册souuce
        tEnv.executeSql(sourceSQL);
        //注册sink
        tEnv.executeSql(sinkSQL);

        //UDF 在作业中定义UDF
        tEnv.createFunction("exchangeGoods", ExchangeGoodsName.class);

        String strSQL=" SELECT " +
                "   goodsId," +
                "   exchangeGoods(goodsId) as goodsName, " +
                "   sum(amount) as amount, " +
                "   tumble_start(rt, interval '5' seconds) as rowtime " +
                " FROM order_source " +
                " GROUP BY tumble(rt, interval '5' seconds),goodsId";

        //查询数据 插入数据
        tEnv.sqlQuery(strSQL).executeInsert("order_sink");

        //执行作业
        tEnv.execute("统计各商品营业额");
    }
}

 

第5章MySQLデータベーステーブルの作成

5.1ライブラリを構築する

mysql> create database flinkdb;

5.2テーブルを作成する

mysql> create table good_sale(goodsId bigint primary key, goodsName varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci, amount decimal(23,10), rowtime timestamp);

注:プライマリキーは、flinkジョブddlで定義されたプライマリキーと同じです。プライマリキーはflink ddlで定義され、コネクタはアップサートモードです(Flinkは、プライマリキーに従って新しい行を挿入するか、既存の行を更新するかを決定して、同一性を確保します)。定義は追加モードです(挿入モードを挿入します。主キーが競合すると、挿入は失敗します)。

この時点で、環境とコードが準備され、検証の実行が開始されます。

 

第6章ジョブの実行

6.1ローカルデバッグ検証

6.1.1クラスターを開始します

第2章の方法を使用して、準備したクラスター環境を開始します。

$ docker-compose up -d

 

6.1.2ジョブを開始する

ローカルIDEAWebApiプロジェクトFlinkジョブプロジェクトを開始します。

6.1.3リクエストを開始する

ここでは、httpツールを使用して、クライアントをシミュレートして要求を開始し、json形式でデータを送信します。

6.1.4flinkジョブの実行ステータスを表示する

IDEAコンソールでログを直接表示する

6.1.5結果の表示

MySQLで結果を表示する

 

このステップでは、ローカルIDEによってデバッグされたジョブがソースからデータを正常にプルし、flinkによる計算後、データがMySQLに書き込まれていることがわかります。次に、実行するクラスターへのジョブの送信を完了します。

6.2クラスター動作の検証

6.2.1パッケージング

WebAPIプロジェクトjarパッケージのパッケージ化

lotemall-webapi(作成者のWebApiプロジェクト)ディレクトリに移動して、パッケージ化コマンドを実行します

mvn clean package -DskipTests

Dockerfileを準備し、jarパッケージと同じディレクトリに配置します。次のコマンドを実行してイメージを作成します。

$ docker build -t lotemall-webapi .

Flinkジョブjarパッケージをパッケージ化します

flink-kafka2mysql(作成者のFlinkジョブプロジェクト)ディレクトリに移動して、パッケージ化コマンドを実行します

使用するためにコンテナに送信するため、ソースおよびシンク接続の構成IPを元のlocalhostからコンテナ名に変更する必要があることに注意してください

mvn clean package -DskipTests

パッケージ化されたjarパッケージをdockerのマウントディレクトリに配置します

6.2.2クラスターを開始します

第2章の方法を使用して、準備したクラスター環境を開始します。 

$ docker-compose up -d

6.2.3WebAPIプロジェクトを開始します

dockerrunコマンドを実行してWebAPIプロジェクトを開始します

$ docker run --link kafka:kafka --net flink-online_default -e TZ=Asia/Shanghai -d -p 8090:8080 lotemall-webapi

6.2.4Flinkジョブの実行

flink jobmanagerコンテナに入り、ジョブを実行します

$ docker exec -it flink-online_jobmanager_1 /bin/bash
$ bin/flink run -c sql.Kafka2MysqlByEnd2End /opt/flinkDeploy/flink-kafka2mysql-0.0.1.jar -d

または、Webインターフェイスを介してジョブjarパッケージを送信します

ジョブが送信されたら、Flink Webインターフェイスを確認してください。送信したジョブが、実行を開始したことがわかります。

6.2.5リクエストを開始する

また、httpツールを使用してクライアントをシミュレートし、要求を開始してjson形式でデータを送信します。

6.2.6Flinkジョブの実行ステータスを表示する

実行するクラスターに送信すると、FlinkWebインターフェイスでジョブの実行ステータスを直接表示できます。

 生成されたウォーターマークを表示する

6.2.7結果の表示 

MySQLで結果を表示する

最初の行のgoodsNameが「cake」であるレコードは、このクラスターでのFlink計算の結果です。 

 

要約すると、この記事では、docker-composeを使用したクラスターの便利な展開を紹介し、完全なFlinkストリームコンピューティングのケースを完了します。

おすすめ

転載: blog.csdn.net/dzh284616172/article/details/109251225
おすすめ