Kafka初試
昨天在測試環境搭建了一套zookeeper+kafka(各一臺)的機器,開始進行kafka的實踐之旅。昨天下班前一直都出現無法傳送無法接收的問題,今天終於搞定了。
zookeeper的安裝
直接從官網下載bin包後,解壓即可
tar -zxvf zookeeper-3.4.9.tar.gz
需要修改的配置有:
- 把conf目錄下的zoo_sample.cfg改名為zoo.cfg(並修改dataDir)
- 修改bin目錄下的zkEnv.sh指令碼中的ZOO_LOG_DIR和ZOO_LOG4J_PROP
啟動zookeeper
bin/zkServer.sh start
Kafka的安裝
由於只使用了一個broker,所以直接解壓包
tar -zxvf kafka_2.11-0.10.2.0.tgz
需要修改的配置為config/server.properties檔案,主要修改的有log.dirs和listeners。
listeners=PLAINTEXT://localhost:9092
這裡有個坑,server.properties中一定要配置host.name或者listeners,不然會出現無法收發訊息的現象
然後啟動即可
bin/kafka-server-start.sh config/server.properties &
客戶端
安裝完以後需要寫生產者的消費者了,直接用最簡單的方法來寫。
Producer
package producer;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
public class Producer {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Properties props = new Properties();
props.put("bootstrap.servers","122.20.109.68:9092");
props.put("acks","1");
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");
//生產者的建立
KafkaProducer producer = new KafkaProducer<>(props);
for (int i=0;i<100;i++) {
System.out.println("seding message "+i);
ProducerRecord record = new ProducerRecord("testTopic",String.valueOf(i),"this is message"+i);
producer.send(record, new Callback() {
public void onCompletion (RecordMetadata metadata, Exception e) {
if (null != e) {
e.printStackTrace();
} else {
System.out.println(metadata.offset());
}
}
});
}
Thread.sleep(100000);
producer.close();
}
}
這裡有個坑,如果我直接用producer.send(ProducerRecord)方法,發完100條以後producer.close(),會導致Kafka無法收到訊息,懷疑是非同步傳送導致的,需要真的傳送到Kafka以後才能停止Producer,所以我在後面sleep了一下,加上以後就可以正常傳送了。
使用callback是非同步傳送,此外還能使用同步傳送,直接在send方法後加上一個get方法就會直接阻塞直到broker返回訊息已收到。
producer.send(record).get();
Producer的properties有幾個常用配置:
- bootstrap.servers:Kafka叢集連線串,可以由多個host:port組成
- acks:broker訊息確認的模式,有三種:
0:不進行訊息接收確認,即Client端傳送完成後不會等待Broker的確認
1:由Leader確認,Leader接收到訊息後會立即返回確認資訊
all:叢集完整確認,Leader會等待所有in-sync的follower節點都確認收到訊息後,再返回確認資訊
我們可以根據訊息的重要程度,設定不同的確認模式。預設為1 - retries:傳送失敗時Producer端的重試次數,預設為0
- batch.size:當同時有大量訊息要向同一個分割槽傳送時,Producer端會將訊息打包後進行批量傳送。如果設定為0,則每條訊息都DuLi傳送。預設為16384位元組
- linger.ms:傳送訊息前等待的毫秒數,與batch.size配合使用。在訊息負載不高的情況下,配置linger.ms能夠讓Producer在傳送訊息前等待一定時間,以積累更多的訊息打包傳送,達到節省網路資源的目的。預設為0
- key.serializer/value.serializer:訊息key/value的序列器Class,根據key和value的型別決定
- buffer.memory:訊息緩衝池大小。尚未被髮送的訊息會儲存在Producer的記憶體中,如果訊息產生的速度大於訊息傳送的速度,那麼緩衝池滿後傳送訊息的請求會被阻塞。預設33554432位元組(32MB)
Consumer
package consumer;
import java.util.Arrays;
import java.util.Properties;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
public class Consumer {
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers","122.20.109.68:9092");
props.put("group.id","test");
props.put("enable.auto.commit","true");
props.put("auto.commit.interval.ms","1000");
props.put("session.timeout.ms","30000");
props.put("key.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("testTopic"));
while(true) {
ConsumerRecords records = consumer.poll(1000);
for (ConsumerRecord record: records) {
System.out.println("offset "+record.offset()+" Message: "+record.value());
}
}
}
}
Consumer的Properties的常用配置有:
- bootstrap.servers/key.deserializer/value.deserializer:和Producer端的含義一樣,不再贅述
- fetch.min.bytes:每次最小拉取的訊息大小(byte)。Consumer會等待訊息積累到一定尺寸後進行批量拉取。預設為1,代表有一條就拉一條
- max.partition.fetch.bytes:每次從單個分割槽中拉取的訊息最大尺寸(byte),預設為1M
- group.id:Consumer的group id,同一個group下的多個Consumer不會拉取到重複的訊息,不同group下的Consumer則會保證拉取到每一條訊息。注意,同一個group下的consumer數量不能超過分割槽數。
- enable.auto.commit:是否自動提交已拉取訊息的offset。提交offset即視為該訊息已經成功被消費,該組下的Consumer無法再拉取到該訊息(除非手動修改offset)。預設為true
- auto.commit.interval.ms:自動提交offset的間隔毫秒數,預設5000。
相關文章
- Kafka 初識Kafka
- 初談KafkaKafka
- 《Kafka筆記》1、Kafka初識Kafka筆記
- 筆記:初識Kafka筆記Kafka
- kafka初認識(一)Kafka
- kafka初裝學習Kafka
- 初識kafka叢集Kafka
- Kafka從入門到放棄(一) —— 初識KafkaKafka
- Kafka效能測試Kafka
- 初試
- 安裝測試kafkaKafka
- Kafka效能測試分析Kafka
- Kafka效能測試方法Kafka
- github 初試Github
- 初試 GithubGithub
- Kafka 入門(四)-- Python Kafka Client 效能測試KafkaPythonclient
- Python測試Kafka叢集(kafka-python)PythonKafka
- Kafka效能測試例項Kafka
- 騰訊前端初試前端
- 初試PythonPython
- python初試Python
- Rust: tokio初試Rust
- Vue + GraphQL初試Vue
- 初嘗試swiftSwift
- sqlite 小刀 初試SQLite
- Confluent之Kafka Connector初體驗Kafka
- Accessability 專案初試
- python初試七Python
- python初試二Python
- python初試三Python
- python初試四Python
- python初試五Python
- python初試六Python
- kafka 測試遇到掉資料的問題 nmred/kafka-PHPKafkaPHP
- Python測試Kafka叢集(pykafka)PythonKafka
- 2020年焊工(初級)考試試題及焊工(初級)考試軟體
- PHP 初級 試崗要求PHP
- 初試MongoDB資料庫MongoDB資料庫