Kafka为什么拥有高性能?

架构层面

1.利用Partition实现并行处理

       Kafka中的每个Topic都包含一个或多个Partition,且它们位于不同节点。同时,Partition在物理上对应一个本地文件夹,每个Partition包含一个或多个Segment,其中包含一个数据文件与一个索引文件。Partition像一个数组,可以通过索引(offset)去访问其数据。
       Kafka不仅可以实现机器间的并行处理,因为其Partition物理上对应一个文件夹,可以通过配置让同一节点的不同Partition置于不同的disk drive上,从而实现磁盘间的并行处理。具体方法:将不同磁盘mount到不同目录,在server.properties中,将log.dirs设置为多目录(逗号分隔),Kafka会自动将所有Partition均匀分配到不同disk上。
       一个Partition只能被一个Consumer消费,如果Consumer的个数多于Partition的个数,会有部分Consumer无法消费该Topic的数据,所以,Partition的个数决定了最大并行度
       如果用Spark消费Kafka数据,如果Topic的Partition数为N,则有效的Spark最大并行度也为N,即使Spark的Executor数为N+M,最多也只有N个Executor可以同时处理该Topic数据。

2.ISR实现CAP中可用性与数据一致性的动态平衡

       Kafka的数据复制方案接近于Master-Slave,不同的是,Kafka既不是完全的同步复制,也不是完全的一步复制,而是基于ISR的动态复制方案。
       ISR,In-Sync Replica,每个Partition的Leader都会维护这样一个列表,其中包含了所有与之同步的Replica。每次写入数据时,只有ISR中的所有Replica都复制完,Leader才会将这条数据置为Commit,它才能被Consumer消费。
       与同步复制不同的是,这个ISR是由Leader动态维护的,如果Follower不能紧跟上Leader,它将被Leader从ISR中移除,待它重新“跟上”Leader后,会被Leader再次加入ISR中。每次改变ISR后,Leader会将最新ISR持久化到Zookeeper中。
       那么如何判断Follower是否“跟上”Leader?

  • 如果Follower在replica.lag.time.max.ms时间内未向Leader发送Fetch请求(数据复制请求),则Leader将其从ISR中移除。

为什么要使用ISR方案?

  • Leader可移除不能及时与之同步的Follower,所以与同步复制相比可以避免最慢的Follower拖慢整体速度,提高系统可用性。
  • 从Consumer角度来看,ISR中所有Replica都始终处于同步状态,从而与异步复制相比提高了数据一致性。

ISR相关配置

  • Broker的min.insync.replicas参数制定了Broker所要求的ISR最小长度,默认值为1.极限情况下ISR可以只包含Leader,但此时如果Leader宕机,则该Partition不可用,可用性不可保证。
  • 只有被ISR中所有Replica同步的消息才被commit,但是Producer在写数据时,Leader不需要ISR中所有Replica同步该数据才确认收到数据。Producer可以通过acks参数指定最少需要多少个Replica确认收到该消息才视为该消息发送成功。acks默认值为1,即Leader收到该消息后立即告诉Producer收到该消息,此时如果在ISR中的消息复制完该消息前Leader宕机,那该条消息会丢失。推荐做法是:将acks设置为all或-1,此时只有ISR中的所有Replica都收到该数据(也及消息被commit),Leader才会告诉Producer该消息发送成功,这样保证了不会有未知的数据丢失。

实现层面

1.高效实用磁盘

顺序写磁盘

       将写磁盘的过程变为顺序写,可极大提高对磁盘的利用率。Consumer通过offset顺序消费这些数据,且不删除已经消费的数据,从而避免随机写磁盘的过程。
       Kafka删除旧数据的方式是删除整个Segment对应的log文件和整个index文件,而不是删除部分内容。如下代码所示:

 

image.png

充分利用Page Cache

Page Cache的优点:

  • I/O Scheduler会将连续的小块写组装成大块的物理写从而提高性能。
  • I/O Scheduler会尝试将一些写操作重新按顺序排好,从而减少磁头移动时间。
  • 充分利用所有空闲内存(非JVM内存)。
  • 读操作可以直接在Page Cache内进行。如果消费和生产速度相当,甚至不需要通过物理磁盘交换数据。
  • 如果进程重启,JVM内的Cache会失效,但Page Cache仍然可用

零拷贝

       Kafka中存在大量网络数据持久化到磁盘(Producer到Broker)和磁盘文件通过网络发送(Broker到Consumer)的过程,这个过程中,传统模式下要进行数据的四次拷贝,但是Kafka通过零拷贝技术将其减为了一次,大大增加了效率,原理可以在另一篇文章(https://www.jianshu.com/p/835ec2d4c170)中获得。

3.减少网络开销

批处理

       批处理减少了网络传输的overhead,又提高了写磁盘的效率。
       Kafka的API做中,从send接口来看,一次只能发送一个ProducerRecord,但是send方法并不是立即将消息发送出去,而是通过batch.size和linger.ms控制实际发送频率,从而实现批量发送。

数据压缩降低网络负载

高效的序列化方式

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

41摄氏度男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值