前言
kafka的核心设计实现就是分区,所谓成也分区,败也是分区。因为分区巧妙设计,让kafka有强大性能。但是分区使用不当,也会让kafka的性能得不到充分发挥
kafka是怎么投递消息?
kafka直接由producer投递给分区。
topic 和partition 和broker之间的关系
Topic 是一个逻辑概念,Partition 是最小的存储单元,掌握着一个 Topic 的部分数据。
每个 Partition 都是一个单独的 log 文件,每条记录都以追加的形式写入。
同一个topic的下的partition是分布在不同的broker的上。
这样做的好处。
1.支持机器水平拓展能力,消息处理能力瓶颈本质就是io瓶颈。因为消息的的写入和消费都是基于partition,分布在不同broker就可以横行拓展io的能力,从而拓展了并行处理消息能力。
2.支持更大消息读取能力,即支持更多的consumer连接不同broker同时并行处理消息
3.支持更大写入能力,即支持更多生产者,本质也是加了多台机器意味可以同时写多个partition,同时写入更大的消息量。
kafka的hw,lw,leo,lso代表什么
hw:高水位,它标识一个特殊的偏移量(offset),消费者只能拉去到这个offset之前消息(对消费者可见消息)。随着日志写入不断递增。
lw:低水位,标示所有副本中集合最小LSO(log start offset)日志起始偏移量。
日志清理和消息删除都会影响该偏移量。
leo(log end offset):日志分区中最后一条消息offset+1,待写入消息的分配的offset。
lso:(log start offset),日志起始偏移量
消费者能消费的消息=【lw,hw】
kafka的ar,isr和osr代表什么。
这三个都是代表不同副本集合,关系如下
AR=ISR+OSR
AR:所有副本集合
ISR:正常同步leader副本所有副本集合,当leader副本挂掉,会根据选举算法从ISR集合中重新选择一个,随着时间的变化这个集合数量也会变化,这个副本集合是动态的
OSR:非正常同步副本集合,所以ISR成员可以变为OSR成员,OSR的成员也可以变成ISR的成员。
判断条件由两个:
(1)根据从和主同步超时时间判断,单位毫米。 如1000ms
(2)根据消息同步条数差值判断,单位条数。 如1000条
kafka消费组消费消息
1.kafka消费消费组消费消息之后,需要主动向broker提交消费消息的offset,更新消息offset,避免消费组宕机重启之后重复消费消息。
kafka消息高可用(多副本)也是基于partition
1.因为partition是kafka设计的物理结构,所以副本最小单位也是基于partition。要做到高可用,partition的所有副本存在不同的broker之上。
2.kafka写消息都是写在leader副本上,再由leader副本同步到其他副本上面,而且读也是在leader上面读,其他副本仅仅备灾作用。
3.同步消息机制ASK=1,kafka写到leader副本之后,由leader副本确认(isr集合)副本都写入消息之后(仅仅收到写入的请求,并未刷盘,影响性能太大,折中处理);
kafka之零拷贝
除了消息顺序追加,页缓存等技术,kafka使用零拷(zero-copy)技术进一步提升性能。所谓零拷贝是指将数据从磁盘文件当中直接复制到网卡当中,不需要经过用户程序经手,减少了应用程序和内核之间的文件复制(白白来回绕了一圈(2次),啥都没干)。
从而从4次复制直接降级为2次复制,性能得到一倍提升。
jave的具体实现就是FileChanal.transferTo()方法底层调用了senfile()实现的。
零拷贝技术在网络编程之中经常看到,如大名顶顶的netty也用到零拷贝技术,这边就不展开讲了。
参考
https://blog.youkuaiyun.com/easylife206/article/details/121600918(分区写入特性)