• Kafka Kafka 生产者


    一、生产者 如何将消息发送到 kafka集群?

    将下图纵向分为4列:

    1.1 生产者的主线程

    Producer对象:生成一个该对象,然后调用send方法

    拦截器:不是必须的,可选

    序列化器:kafka自己的更轻便,大部分都是数据,保证安全校验的只是小部分;而Java数据只占一小部分,大部分都是安全校验。因此在大数据的情况下,不能用Java自带的序列化功能。

    分区器:这里的分区器,只是分recordAccumulator的区域,分到哪个DQueue

    1.2 RecordAccumulator

    该部分都在内存中,默认大小是32M

    该部分有两个参数要注意 batch.size 和 linger.ms,具体含义见图。

    这部分还有个内存池:

    在生产者发送数据时,会从内存池拿内存用来储存数据;

    待kafka集群成功接收到数据后,数据从DQueue删除释放内存,再归还给内存池

    1.3 生产者的sender线程

    sender线程会主动拉取数据。拉取数据的条件是batch.size 或 linger.ms,任何一个符合要求了就能拉取。

    sender能容忍某个broker不返回应答的个数,是5。如果发了5个数据,都没有答复,那就不会再给该broker发送。

    如果成功收到应答acks,就会清理掉DQueue里的数据;

    如果发送不成功,会重试。该值默认设置的是Integer.MAX_VALUE

    1.4 kafka集群

    返回的应答种类,见图。

    二、生产者 异步发送api

    本节关注的是这一块:

    1.1->1.2这一步是异步的。1.1只管给1.2塞消息,不必管1.2-》1.3-》1.4是否完成。

    2.1 普通异步发送

    2.2 带回调的异步发送

    三、生产者 同步发送api

    加一个get()就变成同步方法了....

    四、生产者 分区

    本节关注的是这一块:

    4.1 生产者分区的好处

    4.2 生产者默认分区策略

    如果指定了分区,就用指定分区

    如果未指定分区,但指定了key,那么就用 hashcode(key) % 分区数

    如果未指定分区,也未指定key,那么会选择sticky partition 粘性分区策略 -- 会随机选择一个分区,并尽可能一直使用该分区,待该分区的batch己满或者已完成,Kafka再随机选择一个分区进行使用(和上一次的分区不同)。例如:第一次随机选择0号分区, 等0号分区当前批次满了(默认16k) 或者linger.ms设置的时间到,Kafka再随机- -个分区进行使用(如果还是0会继续随机)。

    4.3 自定义生产者分区策略

    新建一个类,实现Partitioner接口

    在主函数关联自定义的分区器:

    五、生产者 - 提高吞吐量

    由于默认linger.ms是0ms,即代表没有任何延迟,那么batch.size哪怕设置为16k也是无效的。接收到一个消息就会立马发送出去 1.2-》1.3-》1.4。但是这样子吞吐量也会下降。。。适当延长linger.ms为5-100ms,可以增加吞吐量

    compression.type 参数的作用就是压缩数据,那么16k的空间就能存更多东西,自然吞吐量就大了

    RecordAccumulator(也就是1.2部分),增大默认内存容量

     

    六、生产者 - 数据可靠性

    本小节说的是这一模块:

    6.1 可靠性总结

    6.2 ack=-1详细图解

    下图中“hello”灰色,代表已落盘。已落盘才会发送确认应答。

    6.3 参数配置

    七、生产者 - 数据去重

    7.1 数据传递语义

     

     

    7.2 幂等性

    7.3 事务

    代码示例:

    保证事务ID全局唯一

    事务api

    八、生产者 - 数据乱序

    本节讨论的是这一块的问题:

    为了保证单分区的有序 (1.x版本之后):

    • 如果不开启幂等性,那么max.in.flight.requests.per.connection =1, 意味着一个request发送出去,确认后才能发送第二个
    • 如果开启了幂等性,那么max.in.flight.requests.per.connection = 1~5, 意味着生产者的缓存队列(DQueue)可以在不收到确认的情况下,连续向broker发送5个request,且这5个request能在broker里保证有序:
      • request 1 & 2 正常接收并落盘;
      • request3出现问题会申请重发;
      • request 4 & 5也按时到达...但通过幂等性的SeqNumber单调递增的原则,发现应该落盘的是 3。所以 4 & 5暂时还在内存中,不落盘。等待 3 的重发
      • 等request 3到达,服务端重检查其SeqNumber,会优先落盘3. 其次才是4 & 5落盘

    参考文献

    【尚硅谷】2022版Kafka3.x教程(从入门到调优,深入全面): https://www.bilibili.com/video/BV1vr4y1677k?p=22&spm_id_from=pageDriver 

  • 相关阅读:
    12.16省选模拟t2 消防
    12.17省选模拟t3 围豆豆
    12.17省选模拟t1 生日礼物
    CF1322D Reality Show
    winform拖动无边框窗体
    关于ToolTip控件在XP系统中问题
    JDK源代码里面的一个for循环
    IIS5.1 无法运行asp.net网站但可访问静态页的解决方案
    winform窗体去掉标题头部的两种方式
    C# 语法之泛型
  • 原文地址:https://www.cnblogs.com/frankcui/p/16065365.html
Copyright © 2020-2023  润新知