Kafka-生产者(Producer)

作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

图片

我们上一章介绍了中间件:Zookeeper,本章将介绍另外一个中间件:Kafka。目前这2个中间件都是基于JAVA语言的。

我们上前面介绍了Topic的基本概念和涉及到Topic核心的分区和副本概念,但是我们还得往里面写入数据才行,然后数据写进入以后我们还得把里面的数据读出来,我们今天首先介绍的负责向Kafka写入消息角色:生产者(Producer)。

生产者(Producer)

将数据(消息)发布到 Kafka 的 Topic 中的Leader分区里面。生产者可以发送带有或不带有键的消息,并且可以选择这些消息应该被发送到哪个分区。下面是几个关于消息的核心特性。

消息路由

    • 轮询(Round Robin):当消息没有指定 key 时,生产者会采用轮询的方式均匀地将消息分布到所有的分区上。

    • 哈希(Key-based):如果消息包含了一个 key,那么生产者会根据这个 key 的哈希值选择一个分区。默认情况下,Kafka 使用 murmur2 算法计算哈希值,然后对分区总数取模以确定具体的分区。

    • 自定义分区策略:实现 Partitioner 接口自定义逻辑。

    生产者首先需要连接到 Kafka 集群中的一个或多个 Broker,并获取关于目标 Topic 的元数据信息,包括该 Topic 所有分区及其对应的Leader Broker。根据上述的路由策略,生产者会选择合适的目标分区,并直接与该分区所在的 Leader Broker 建立连接,将消息发送出去。也就是链接Broker和发送的Topic所在Broker并没有直接关系。

    可靠性保证

    • acks=0:生产者不会等待任何来自服务器的确认。这意味着如果发送过程中发生错误(例如网络故障),则消息可能会丢失。

    • acks=1:生产者会等待 Leader 副本确认收到消息后才认为发送成功。

      这种模式下,只要 leader 副本写入成功,即使后续副本同步失败也不会影响消息的确认状态,但是存在 leader 宕机且未完成副本同步的风险,可能导致数据丢失

    • acks=all:生产者会等待 ISR 中的所有副本都确认收到了消息后才认为发送成功。提供了最高的可靠性保障,但同时也可能增加消息发送的延迟。

    重试机制

    生产者可以通过配置 retries 参数启用自动重试机制。当遇到临时性的发送失败(如网络抖动)时,生产者可以尝试重新发送消息。结合 retry.backoff.ms 参数,可以设置每次重试前的等待时间,避免过于频繁地重试造成更大的压力。

    高性能优化

      • 批处理(Batching):生产者将多条消息合并为一批发送,减少网络开销(通过 linger.ms 和 batch.size 控制)。

      • 压缩(Compression):支持 gzipsnappylz4 等压缩算法减少网络传输量。这里需要注意,生产者和消费者必须同时支持相同的算法,并不需要服务端支持。gzip 压缩率高,但 CPU 开销大,可能增加生产者和消费者的延迟。lz4/snappy 压缩速度快,适合高吞吐低延迟场景。

      发送消息

      #或者可以多次发送不同或者相同的内容 
      echo "hello world" | ./bin/kafka-console-producer.sh \
        --topic my-topic \
        --bootstrap-server 192.168.31.143:9092

      图片

      也可以进入交互模式再输入内容。

      # 启动控制台生产者(带 Key 支持)
      ./bin/kafka-console-producer.sh \
        --topic my-topic \
        --bootstrap-server 192.168.31.143:9092 \
        --property "parse.key=true" \
        --property "key.separator=:"
      # 进入交互模式后,输入以下消息(按回车发送):
      > user1:Hello Kafka
      > order123:{"id": 123, "status": "created"}
      > sensor01:25.5

      下面是使用程序代码发送。

      #python3代码 需要下安装 kafka模块 
      #pip3 install kafka  -i https://mirrors.aliyun.com/pypi/simple/
      import time
      import json
      from datetime import datetime
      from kafka import KafkaProducer
      from kafka.errors import KafkaError
      
      # 配置 Kafka 生产者
      producer = KafkaProducer(
          bootstrap_servers=['192.168.31.143:9092','192.168.31.144:9092','192.168.31.145:9092'],  # Kafka 服务器地址
          value_serializer=lambda v: json.dumps(v).encode('utf-8')  # 将消息序列化为 JSON
      )
      
      topic = 'my-topic1'  # 目标 Topic
      
      try:
          count = 0
          while True:
              # 生成消息内容(示例:包含时间戳和计数)
              message = {
                  "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                  "count": count,
                  "data": f"Message-{count}"
              }
      
              # 发送消息(异步)
              future = producer.send(topic, value=message)
      
              # 可选:等待消息发送完成(同步确认)
              # record_metadata = future.get(timeout=10)
              # print(f"发送成功 → 分区: {record_metadata.partition}, 偏移量: {record_metadata.offset}")
      
              print(f"已发送: {message}")
              count += 1
              time.sleep(1)  # 每秒发送一次
      
      except KafkaError as e:
          print(f"Kafka 错误: {e}")
      except KeyboardInterrupt:
          print("用户终止程序")
      finally:
          producer.close()  # 关闭生产者

      ​​​​​​​

      如果系统不存在这个Topic,它将自动创建,默认只有1个分区和1个副本,这2个参数我们前面也讲过。​​​​​​​

      #副本数量,默认是1,参数默认不存在,如果要修改配置需要手工添加 
      default.replication.factor  
      
      #分区数量,默认是1,参数默认存在
      num.partitions 
      
      #如果生产者向不存在的Topic发送消息,
      #默认是true,就是允许创建Topic
      #参数默认不存在
      auto.create.topics.enable 

      通过下面的命令可以查看到各个分区里面有多少数据。​​​​​​​

      #查看topic的消息数量,一般不会用,这里为了方便统计才使用 
      ./bin/kafka-run-class.sh \
      kafka.tools.GetOffsetShell \
      --broker-list 192.168.31.143:9092 
      --topic my-topic123 \
      --time -1
      [root@localhost kafka_2.13-2.8.2]# ./bin/kafka-run-class.sh kafka.tools.GetOffsetShell   --broker-list 192.168.31.143:9092   --topic my-topic123   --time -1
      OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, then you should configure the number of parallel GC threads appropriately using -XX:ParallelGCThreads=N
      my-topic123:0:0
      my-topic123:1:0
      my-topic123:2:0

      ​​​​​​​

      运维小路

      一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!

      关注微信公众号《运维小路》获取更多内容。

      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值