Flink-Kafka-Connector Flink結合Kafka實戰

王知無發表於2019-03-03

簡介

Flink-kafka-connector用來做什麼?

Kafka中的partition機制和Flink的並行度機制結合,實現資料恢復 Kafka可以作為Flink的source和sink 任務失敗,通過設定kafka的offset來恢復應用

kafka簡單介紹

關於kafka,我們會有專題文章介紹,這裡簡單介紹幾個必須知道的概念。

1.生產者(Producer) 顧名思義,生產者就是生產訊息的元件,它的主要工作就是源源不斷地生產出訊息,然後傳送給訊息佇列。生產者可以向訊息佇列傳送各種型別的訊息,如狹義的字串訊息,也可以傳送二進位制訊息。生產者是訊息佇列的資料來源,只有通過生產者持續不斷地向訊息佇列傳送訊息,訊息佇列才能不斷處理訊息。 2.消費者(Consumer) 所謂消費者,指的是不斷消費(獲取)訊息的元件,它獲取訊息的來源就是訊息佇列(即Kafka本身)。換句話說,生產者不斷向訊息佇列傳送訊息,而消費者則不斷從訊息佇列中獲取訊息。 3.主題(Topic) 主題是Kafka中一個極為重要的概念。首先,主題是一個邏輯上的概念,它用於從邏輯上來歸類與儲存訊息本身。多個生產者可以向一個Topic傳送訊息,同時也可以有多個消費者消費一個Topic中的訊息。Topic還有分割槽和副本的概念。Topic與訊息這兩個概念之間密切相關,Kafka中的每一條訊息都歸屬於某一個Topic,而一個Topic下面可以有任意數量的訊息。

kafka簡單操作

啟動zk:nohup bin/zookeeper-server-start.sh config/zookeeper.properties &

啟動server: nohup bin/kafka-server-start.sh config/server.properties &

建立一個topic:bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

檢視topic:bin/kafka-topics.sh --list --zookeeper localhost:2181

傳送資料:bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

啟動一個消費者:bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning

刪除topic: bin/kafka-topics.sh --delete --zookeeper localhost:2181 --topic topn

Flink消費Kafka注意事項

  • setStartFromGroupOffsets()【預設消費策略】

    預設讀取上次儲存的offset資訊 如果是應用第一次啟動,讀取不到上次的offset資訊,則會根據這個引數auto.offset.reset的值來進行消費資料

  • setStartFromEarliest() 從最早的資料開始進行消費,忽略儲存的offset資訊

  • setStartFromLatest() 從最新的資料進行消費,忽略儲存的offset資訊

  • setStartFromSpecificOffsets(Map<KafkaTopicPartition, Long>) 從指定位置進行消費

  • 當checkpoint機制開啟的時候,KafkaConsumer會定期把kafka的offset資訊還有其他operator的狀態資訊一塊儲存起來。當job失敗重啟的時候,Flink會從最近一次的checkpoint中進行恢復資料,重新消費kafka中的資料。

  • 為了能夠使用支援容錯的kafka Consumer,需要開啟checkpoint env.enableCheckpointing(5000); // 每5s checkpoint一次

搭建Kafka單機環境

我本地安裝了一個kafka_2.11-2.1.0版本的kafka

Flink-Kafka-Connector Flink結合Kafka實戰

啟動Zookeeper和kafka server:

啟動zk:nohup bin/zookeeper-server-start.sh config/zookeeper.properties  &

啟動server: nohup bin/kafka-server-start.sh config/server.properties &
複製程式碼

建立一個topic:

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
複製程式碼

Flink-Kafka-Connector Flink結合Kafka實戰

實戰案例

所有程式碼,我放在了我的公眾號,回覆Flink可以下載

  • 海量【java和大資料的面試題+視訊資料】整理在公眾號,關注後可以下載~
  • 更多大資料技術歡迎和作者一起探討~

Flink-Kafka-Connector Flink結合Kafka實戰

Kafka作為Flink Sink

首先pom依賴:

<dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka_2.11</artifactId>
            <version>1.7.0</version>
        </dependency>
複製程式碼

向kafka寫入資料:

public class KafkaProducer {


    public static void main(String[] args) throws Exception{

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStreamSource<String> text = env.addSource(new MyNoParalleSource()).setParallelism(1);

        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "localhost:9092");
        //new FlinkKafkaProducer("topn",new KeyedSerializationSchemaWrapper(new SimpleStringSchema()),properties,FlinkKafkaProducer.Semantic.EXACTLY_ONCE);
	    FlinkKafkaProducer<String> producer = new FlinkKafkaProducer("test",new SimpleStringSchema(),properties);
/*
        //event-timestamp事件的發生時間
        producer.setWriteTimestampToKafka(true);
*/
        text.addSink(producer);
        env.execute();
    }
}//
複製程式碼

大家這裡特別注意,我們實現了一個並行度為1的MyNoParalleSource來生產資料,程式碼如下:

//使用並行度為1的source
public class MyNoParalleSource implements SourceFunction<String> {//1

    //private long count = 1L;
    private boolean isRunning = true;
    
    /**
     * 主要的方法
     * 啟動一個source
     * 大部分情況下,都需要在這個run方法中實現一個迴圈,這樣就可以迴圈產生資料了
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void run(SourceContext<String> ctx) throws Exception {
        while(isRunning){
            //圖書的排行榜
            List<String> books = new ArrayList<>();
            books.add("Pyhton從入門到放棄");//10
            books.add("Java從入門到放棄");//8
            books.add("Php從入門到放棄");//5
            books.add("C++從入門到放棄");//3
            books.add("Scala從入門到放棄");//0-4
            int i = new Random().nextInt(5);
            ctx.collect(books.get(i));

            //每2秒產生一條資料
            Thread.sleep(2000);
        }
    }
    //取消一個cancel的時候會呼叫的方法
    @Override
    public void cancel() {
        isRunning = false;
    }
}

複製程式碼

程式碼實現了一個傳送器,來傳送書名<Pyhton從入門到放棄><Java從入門到放棄>等...

然後右鍵執行我們的程式,控制檯輸出如下:

Flink-Kafka-Connector Flink結合Kafka實戰

開始源源不斷的生產資料了。

然後我們用命令去檢視一下 kafka test這個topic:

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
複製程式碼

輸出如下:

Flink-Kafka-Connector Flink結合Kafka實戰

Kafka作為Flink Source

直接上程式碼:

public class KafkaConsumer {

    public static void main(String[] args) throws Exception{

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "localhost:9092");

        FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("test", new SimpleStringSchema(), properties);
        //從最早開始消費
        consumer.setStartFromEarliest();
        DataStream<String> stream = env
                .addSource(consumer);
        stream.print();
        //stream.map();
        env.execute();

    }
}//
複製程式碼

控制檯輸出如下:

Flink-Kafka-Connector Flink結合Kafka實戰
將我們之前發往kafka的訊息全部列印出來了。

相關文章