Kafka 生產者和消費者學習筆記

最近搭建 kafka 集羣環境以便於收集應用程序日誌並進行個性化的處理,因此學習了 kafka 生產者和消費者 python 程序的實現。這篇文章當是 kafka 的學習筆記。

一、搭建 kafka 集羣

爲方便測試,我們在 MacOS 單機上搭建具有三個 kafka 節點的集羣。如果在生產上部署 kafka ,請在不同的物理機上部署 kafka 集羣。

1. 下載 kafka 鏡像

我們使用 wurstmeister/kafka 鏡像來部署 kafka,由於 kafka 依賴於 zookeeper ,因此,我們需要下載 zookeeper 和 kafka 兩個鏡像。

docker pull wurstmeister/kafka
docker pull wurstmeister/zookeeper

2. 編寫 docker-compopse.yml

我們搭建的 kafka 集羣包括一個 zooker 節點和三個 kakfa 節點。

使用 ifconfig 命令獲取本機的 ip 爲 192.168.0.104,完整的 docker-compose.yml 文件如下。有關 docker-compose 的使用,可以參考 《Docker Compose 入門教程》

version: '3'
services:
  zookeeper:
    image: docker.io/wurstmeister/zookeeper
    container_name: zookeeper
    restart: always
    ports:
      - "2181:2181"

  kafka1:
    image: docker.io/wurstmeister/kafka
    container_name: kafka1
    restart: always
    ports:
      - "9095:9092"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 0
      KAFKA_ZOOKEEPER_CONNECT: 192.168.0.104:2181
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.0.104:9095

  kafka2:
    image: docker.io/wurstmeister/kafka
    container_name: kafka2
    restart: always
    ports:
      - "9096:9093"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: 192.168.0.104:2181
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.0.104:9096

  kafka3:
    image: docker.io/wurstmeister/kafka
    container_name: kafka3
    restart: always
    ports:
      - "9097:9094"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: 192.168.0.104:2181
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9094
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.0.104:9097

使用 docker-compose up -d 運行相關的容器,完成 kafka 集羣的搭建。

二、Kafka 生產者

我們使用 kafka-python 包來編寫 kafka 生產者。使用以下命令下載 kafka-python 包:

pip install kafka-python

Kafka 生產者的源代碼如下:

from kafka import KafkaProducer

producer = KafkaProducer(bootstrap_servers=["192.168.0.104:9095", '192.168.0.104:9096', '192.168.0.104:9097']) 

for _ in range(10):
    producer.send('topic_test', b'hello kafka')
producer.flush()

先創建一個 KafkaProducer 對象 producerKafkaProducer 指定了 kafka 集羣各個節點的地址。然後通過 KafkaProducer 對象向 topic topic_test 發送消息。

三、Kafka 消費者

爲接收生產者的消息,我們定義消費者 KafkaConsumer 對象 consumer。定義 KafkaConsumer 對象時,指定 topic 爲 topic_test,這樣當運行上面的生產者程序時,可以正常接收到消息。

from kafka import KafkaConsumer

consumer = KafkaConsumer('topic_test', group_id="my_group", bootstrap_servers=["192.168.0.104:9095", '192.168.0.104:9096', '192.168.0.104:9097'])

for msg in consumer:
    print(msg.value)

先運行消費者程序,再運行生產者程序,可以看到消費者程序輸出:

b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’

多個消費者

如果需要啓動多個消費者來消費生產者發送的消息,並實現負載均衡,可以爲 topic 設置多個 partition。爲方便起見,我們設置 topic 的 partition 數量與消費者數量均爲 2。

進入其中一個 kafka 容器:

docker exec -it kafka1 /bin/bash

在容器內,查看topic_test 的 partition 數量:

cd /opt/kafka
bin/kafka-topics.sh --describe --zookeeper 192.168.0.104:2181 --topic topic_test

可以看到 topic_test 的 partition 數量爲 1。修改 topic_test partition 數量爲 2:

bin/kafka-topics.sh --zookeeper 192.168.0.104:2181 --alter --topic topic_test --partitions 2

啓動兩個消費者程序,然後啓動一個生產者程序,可以看到,其中一個消費者輸出:

b’hello kafka’
b’hello kafka’
b’hello kafka’

另一個消費者輸出:

b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’
b’hello kafka’

生產者發送的消息被兩個消費者進行了消費,不同的消費者接收到的消息數量不一致,這是由於使用了默認的負載均衡策略所致。多次運行生產者程序,可以看到消費者接收到的總的消息數量基本上一致。

參考資料

  1. http://kafka.apache.org/
  2. http://wurstmeister.github.io/kafka-docker/
  3. https://www.cnblogs.com/answerThe/p/11267129.html
  4. https://www.jianshu.com/p/fe73765ef74d
  5. https://pypi.org/project/kafka-python/
  6. https://www.cnblogs.com/small-office/p/9399907.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章