Kafka簡單示例以及常用命令

Dictator丶發表於2018-12-07

kafka producer 示例

public void sendMsg() throws IOException {
    Properties props = new Properties();
    props.put("bootstrap.servers", "ip:9092");
    props.put("acks", "all");
    props.put("retries", 0);
    props.put("batch.size", 16384);
    props.put("linger.ms", 1);
    props.put("buffer.memory", 33554432);
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

    Producer<String, String> producer = new KafkaProducer<String, String>(props);
    /*for (int i = 0; i < 100; i++) {
        producer.send(new ProducerRecord<String, String>("test", Integer.toString(i), Integer.toString(i)));
    }*/
    JSONObject jsonObject = new JSONObject();
    jsonObject = getJsonData();
    producer.send(new ProducerRecord<String, String>("test", jsonObject.toJSONString()));

    List<PartitionInfo> partitions = new ArrayList<PartitionInfo>() ;
    partitions = producer.partitionsFor("test");
    for(PartitionInfo p:partitions)
    {
        System.out.println(p);
    }
    producer.close();
}

public JSONObject getJsonData() throws IOException {
    File file=new File("C:\\Users\\user\\Desktop\\Json檔案.json");
    // apache的commons的FileUtils類就是這樣一個工具類,使用它能大大的簡化我們對檔案的操作。
    String content= FileUtils.readFileToString(file,"UTF-8");
    JSONObject jsonObject = JSONObject.parseObject(content);
    System.out.println(jsonObject);
    return jsonObject;
}
複製程式碼

注:

  1. 官方API

  2. 引數:

    • acks: 生產者認為一個請求完成,所需要kafka叢集主服務的應答次數。這個配置控制已傳送訊息的永續性。下面是這個配置可能的值。acks=0:如果設定為0,生產者不會等待kafka的響應。訊息會被立刻加到傳送緩衝通道中,並且認為已經傳送成功。這種情況下,不能保證kafka接收到了這條訊息,retries配置不會生效,每條訊息的偏移量都是1;acks=1:這個配置意味著kafka會把這條訊息寫到本地日誌檔案中,但是不會等待叢集中其他機器的成功響應。這種情況下,在寫入日誌成功後,叢集主機器掛掉,同時從機器還沒來得及寫的話,訊息就會丟失掉。acks=all:這個配置意味著leader會等待所有的follower同步完成。這個確保訊息不會丟失,除非kafka叢集中所有機器掛掉。這是最強的可用性保證。
    • retries: 設定大於0的值將使客戶端重新傳送任何資料,一旦這些資料傳送失敗。注意,這些重試與客戶端接收到傳送錯誤時的重試沒有什麼不同。允許重試將潛在的改變資料的順序,如果這兩個訊息記錄都是傳送到同一個partition,則第一個訊息失敗第二個傳送成功,則第二條訊息會比第一條訊息出現要早。
    • batch.size: producer將試圖批處理訊息記錄,以減少請求次數。這將改善client與server之間的效能。這項配置控制預設的批量處理訊息位元組數。不會試圖處理大於這個位元組數的訊息位元組數。傳送到brokers的請求將包含多個批量處理,其中會包含對每個partition的一個請求。較小的批量處理數值比較少用,並且可能降低吞吐量(0則會僅用批量處理)。較大的批量處理數值將會浪費更多記憶體空間,這樣就需要分配特定批量處理數值的記憶體大小。預設值:16384
    • linger.ms: producer組將會彙總任何在請求與傳送之間到達的訊息記錄一個單獨批量的請求。通常來說,這隻有在記錄產生速度大於傳送速度的時候才能發生。然而,在某些條件下,客戶端將希望降低請求的數量,甚至降低到中等負載一下。這項設定將通過增加小的延遲來完成–即,不是立即傳送一條記錄,producer將會等待給定的延遲時間以允許其他訊息記錄傳送,這些訊息記錄可以批量處理。這可以認為是TCP種Nagle的演算法類似。這項設定設定了批量處理的更高的延遲邊界:一旦我們獲得某個partition的batch.size,他將會立即傳送而不顧這項設定,然而如果我們獲得訊息位元組數比這項設定要小的多,我們需要“linger”特定的時間以獲取更多的訊息。 這個設定預設為0,即沒有延遲。設定linger.ms=5,例如,將會減少請求數目,但是同時會增加5ms的延遲。預設值: 0
    • buffer.memory: producer可以用來快取資料的記憶體大小。如果資料產生速度大於向broker傳送的速度,producer會阻塞或者丟擲異常,以“block.on.buffer.full”來表明。這項設定將和producer能夠使用的總記憶體相關,但並不是一個硬性的限制,因為不是producer使用的所有記憶體都是用於快取。一些額外的記憶體會用於壓縮(如果引入壓縮機制),同樣還有一些用於維護請求。預設值:33554432
  3. Apache Commons IO

kafka consumer 示例

 public void getMsg() {
    Properties props = new Properties();
    props.put("bootstrap.servers", "ip:9092");
    props.put("group.id", "test_B");
    props.put("enable.auto.commit: ", "true");
    props.put("auto.commit.interval.ms", "1000");
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
    consumer.subscribe(Arrays.asList("test"));
    String result = null;
    while (true) {
        ConsumerRecords<String, String> records = consumer.poll(100);
        for (ConsumerRecord<String, String> record : records) {
          System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
        }
    }
}
複製程式碼

注:

  1. 官方API

  2. 引數:

    • group.id:標識此消費者所屬的消費者群組的唯一字串。如果消費者通過使用subscribe(topic)基於kafka的偏移量管理策略來使用組管理功能,則此屬性是必需的。 自己定義
    • enable.auto.commit: Consumer 在commit offset時有兩種模式:自動提交,手動提交。自動提交:是Kafka Consumer會在後臺週期性的去commit。預設值是true。

consumer 沒有消費訊息

解決步驟:

  1. 判斷是否能連線到kafka。 通過topic列表命令(在下面)在命令列檢視是否producer新建topic成功。

  2. 若 topic 新建成功,通過命令列,執行消費者命令,檢視是否能接受到訊息。注意先啟動客戶端的消費者,再傳送訊息。 (只有第一次需要,因為在此之前,還沒有註冊到消費列表中,之前在topic裡的訊息就不會被剛啟動的消費者消費到。)

  3. 若第二步在consumer命令下能接收到訊息,檢視 server.properties, 找到

     #listeners=PLAINTEXT://:9092
    複製程式碼

    取消註釋,修改為 機器的ip + 9092

     listeners=PLAINTEXT://ip:9092
    複製程式碼

kafka 命令

  1. 啟動,在kafka的bin目錄下

     ./kafka-server-start.sh -daemon ../config/server.properties
    複製程式碼

    輸入 jps, 檢視是否啟動成功。

  2. 檢視topic列表:

     bin/kafka-topics.sh --zookeeper localhost:2181 --list
    複製程式碼
  3. 新建topic

     ./bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test_kafka
    複製程式碼
  4. 檢視某一topic的詳細資訊

     bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic test
    複製程式碼
  5. 刪除topic

     bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test
    複製程式碼
  6. 啟動producer

     bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
    複製程式碼
  7. 啟動consumer

     bin/kafka-console-consumer.sh --bootstrap-server ip:9092 --topic test --from-beginning
     叢集就寫多個ip+埠,用逗號分開。
     ip1:9092,ip2:9092,ip3:9092 
    複製程式碼
  8. 檢視offset

     bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper :2181,ip2:2181,ip3:2181 --group test_A --topic test
    複製程式碼
  9. 設定offset

     bin/kafka-consumer-groups.sh --bootstrap-server ip1:9092,ip2:9092,ip3:9092 --group test_A --topic test --execute --reset-offsets --to-offset 0
    複製程式碼

參考:

  1. kafka producer 配置
  2. kafka consumer 配置
  3. Kafka消費組(consumer group) (寫的很好)
  4. kafka java客戶端消費不到訊息,但也不報錯
  5. kafka生產者與消費者相關命令列
  6. 使用FileUtils簡化你的檔案操作

相關文章