一、生产者producer 1.ack模式kafka是一个以日志形式存储消息的消息中间件,以高吞吐而闻名。
1.1 ack = 0前提:kafka的服务器broker是个集群
1.2 ack = 1生产者只管投递,并不关注kafka服务器broker是否接收到消息。
缺点:可能会出现消息丢失。
1.3 ack = -1生产者投递消息后,broker副本的leader接收到消息,在本地持久化后,就返回生产者消息发送成功;然后开启线程向其它follower同步这条消息。
缺点:leader在ack后,还未来得及将消息同步给follower就宕机了,kafka集群新的leader并没这条消息,原leader启动后,由于高水位线机制(下文会讲到),也不会有这条消息,该消息丢失。
解决方法:建立一张本地消息表,生产者发送消息前,将消息先写入本地。
2.批量发送生产者投递消息后,broker副本的leader接收消息后,将消息同步给整个副本集群后,在返回给生产者。
缺点:耗时久;leader将数据都同步给副本集群后,在ack过程中宕机;生产者会以为出现错误而重试,导致新leader上重复接收了这条消息。
3.消息压缩kafka发送消息不会一条一条发送,而是有一个缓冲区,当缓冲区满了,生产者会批量将这些消息发送到broker,减少IO通讯次数。也会通过定时任务定时发送缓冲区的消息。
4.零拷贝(linux的api)发送消息时会将消息进行压缩(去掉注释,空格等信息),降低带宽。
二、消息服务器 1. broker采用dma拷贝代替cpu拷贝,降低cpu压力。
同时使用mmap内存映射,使用户空间和内核空间进行内存共享,减少用户态和内核态的切换次数。
使用sendfile将mmap中的数据直接发送到网卡传输。
整个过程cpu切换两次,cpu拷贝0次。
2.topickafka的物理服务器,用于保存和转发消息。
3.partition逻辑概念,消息的一种类型,或者说消息的一种属性。
topic的物理存储概念,也是topic在broker中的具体存放空间。
以segment格式存放(类似于ConcurrentHashMap7的原理,分摊治理),当单个segment文件的大小超过500M(默认配置)时,会自动生成下一个Segment,文件以上一个segment的最大offset命名,长度20位,不足补零。
4.zookeepersegment中由.index和.log组成。.index为offset的稀疏索引,key为offset,value为地址指针;.log为实际存放消息的文件,key为地址指针,value为消息体。
5.controllerkafka的注册中心,存储broker、topic、partition、group等信息。
6.副本管理副本选举以及topic分配等 *** 作,通过分布式锁的方式创建。(多个broker去zk上创建相同的临时节点,谁创建成功谁就是controller,其余broker订阅该节点,当controller宕机后,zk会自动删除,发送事件通知这些broker重新竞争)。
集群模式下,为了高可用,数据会在多个broker上存在多份,也就是副本。controller会通过broker与zk的链接而保存一个副本的集合,即ISR。
副本leader就是ISR的第一个节点,当leader宕机后,zk与其断开链接,controller将其从ISR头部剔除,新的leader就是ISR的新头部,原leader恢复后,与ZK保持通讯,controller将其重新加入ISR,放入集合末尾。
三、消费者consumer 1.consumer每个副本都有两个参数:LEO和HW。LEO表示当前副本中存放的最大的offset值,HW则表示消费者可以看到的最大offset值(即所有副本交集中最大的offset),当副本数据同步时,follower副本会舍弃高于HW的offset的消息,重新去leader同步消息,所以可能会 出现消息丢失。
2.group消费者节点,订阅partition,根据offset从partition上取数据,当消费成功后,会commit offset至partition,partition通过定时任务删除这些已消费的数据。
3.消费记录消费组,将消费者分类,同一个消费组中的消费者消费同一个partition的相同消息,commit offset时会有问题。
topic的日志文件中会消费者在分区中的消费记录,默认分成50个文件,来通过key(key=group-id.topic.partition)取模的方式,找到文件查询消费记录,进而消费下一个offset。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)