​前言​

好了,开始进入正题。今天给大家带来的的是关于我们的老朋友​​Kafka​​的来世今生。

随着对实时性的要求越来越高,那么在庞大的数据的传输过程中怎么能保证数据的快速传递呢,由此,消息队列产生了。

“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。

消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。Kafka是一个分布式消息队列对我们来说掌握它是必不可少的。

本文对 ​​Kafka​​​ 的基本组件的实现细节及其基本应用进行了详细介绍,同时,也熬了几天夜画了图解,希望能让大家对 Kafka 核心知识的有了更深刻的理解,最后也总结了 ​​Kafka​​ 在实际业务中的应用。跟着小羽一起再来熟悉一下这些属于Kafka的小秘密吧:


​Kafka 概念​

Kafka 是一种高吞吐量、分布式、基于发布/订阅的​消息系统​,最初由 LinkedIn 公司开发,使用Scala 语言编写,目前是 Apache 的开源项目。

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_kafka

​Kafka 主要组件​

  • broker​:Kafka 服务器,负责消息​存储​和​

  • topic​:消息类别,Kafka 按照 topic 来​分类消息

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_消息队列_02​​

  • partition​:topic 的​分区​,一个 topic 可以包含多个 partition,topic 消息保存在各个 partition 上

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_kafka_03

  • offset​:消息在日志中的位置,可以理解是消息在 partition 上的​偏移量​,也是代表该消息的唯一序号

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_消息队列_04

  • Producer​:消息生产者

  • Consumer​:消息消费者

  • Consumer Group​:消费者​分组​,每个 Consumer 必须属于一个 group

  • Zookeeper​​:保存着集群 broker、topic、partition 等 ​​meta​​ 数据;另外,还负责 broker 故障发现,partition leader 选举,负载均衡等功能

​Kafka 优点​

  • 解耦​:消息系统在处理过程中间插入了一个隐含的、基于数据的​接口层​,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的​接口约束​。

  • 冗余​:消息队列把数据进行持久化直到它们已经被​完全处理​,通过这一方式规避了数据丢失风险。许多消息队列所采用的"​插入-获取-删除​"范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。

  • 扩展性​:因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外​增加处理过程​即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。

  • 灵活性 & 峰值处理能力​:使用消息队列能够使关键组件​顶住突发的访问压力​,而不会因为突发的超负荷的请求而完全崩溃。

  • 可恢复性​:消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在​系统恢复后被处理​。

  • 顺序保证​:大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。Kafka保证一个Partition内的​消息的有序性​。

  • 缓冲​:消息队列通过一个​缓冲层​来帮助任务最高效率的执行。写入队列的处理会尽可能的快速。该缓冲有助于控制和优化数据流经过系统的速度。

  • 异步通信​:消息队列提供了​异步处理机制​,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

​Kafka 应用场景​

  • 活动追踪​:跟踪网站⽤用户与前端应⽤用程序发⽣生的交互,如:​网站PV/UV分析

  • 传递消息​:系统间异步的信息交互,如:​营销活动​(注册后发送券码福利利)

  • 日志收集​:收集系统及应⽤用程序的度量量指标及⽇日志,如:​应用监控和告警

  • 提交日志​:将数据库的更更新发布到kafka上,如:​交易统计

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_消息队列_05​​

​Kafka 数据存储设计​

​partition 的数据文件​

partition 中的每条 Message 包含三个属性:​​offset​​​,​​MessageSize​​​,​​data​​,其中 offset 表 示 Message 在这个 partition 中的​偏移量​,offset 不是该 Message 在 partition 数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了 partition 中的一条 Message,可以认为 offset 是 partition 中 Message 的 ​id​;MessageSize 表示消息内容 data 的​大小​;data 为 Message 的​具体内容​。

​数据文件分段 segment​

partition 物理上由多个 segment 文件组成,每个 segment 大小相等,​顺序读写​。每个 segment数据文件以该段中最小的 offset 命名,文件扩展名为.log。这样在查找指定 offset 的 Message 的时候,用​二分查找​就可以定位到该 Message 在哪个 segment 数据文件中。

​数据文件索引​

Kafka 为每个分段后的数据文件建立了​索引​文件,文件名与数据文件的名字是一样的,只是文件扩展名为.index。index 文件中并没有为数据文件中的每条 Message 建立索引,而是采用了​稀疏存储​的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_消息队列_06

​Zookeeper 在 kafka 的作用​

无论是 kafka 集群,还是 producer 和 consumer 都依赖于 zookeeper 来保证系统可用性集群保存一些​​meta​​信息。

Kafka 使用 zookeeper 作为其分布式协调框架,很好的将消息生产、消息存储、消息消费的过程​结合​在一起。

同时借助 zookeeper,kafka 能够生产者、消费者和 broker 在内的所以组件在无状态的情况下,建立起生产者和消费者的​订阅关系​,并实现生产者与消费者的负载均衡。

​生产者设计​

​负载均衡​

由于消息 topic 由多个 partition 组成,且 partition 会​均衡分布​到不同 broker 上,因此,为了有效利用 broker 集群的性能,提高消息的吞吐量,producer 可以通过​随机​或者 ​hash​ 等方式,将消息平均发送到多个 partition 上,以实现负载均衡。

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_数据_07

​批量发送​

是提高消息吞吐量重要的方式,Producer 端可以在内存中合并多条消息后,以一次请求的方式发送了批量的消息给 broker,从而大大减少 broker 存储消息的 IO 操作次数。但也一定程度上影响了消息的实时性,相当于以时延代价,换取更好的​吞吐量​。

​压缩​

Kafka支持以集合(batch)为单位发送消息,在此基础上,Kafka还支持对消息集合进行压缩,Producer 端可以通过 ​​GZIP​​​ 或 ​​Snappy​​ 格式对消息集合进行压缩。Producer 端进行压缩之后,在Consumer 端需进行解压。压缩的好处就是减少传输的数据量,减轻对网络传输的压力,在对大数据处理上,瓶颈往往体现在网络上而不是 CPU(压缩和解压会耗掉部分 CPU 资源)。

那么如何区分消息是压缩的还是未压缩的呢,Kafka在消息头部添加了一个​描述压缩属性字节​,这个字节的后两位表示消息的压缩采用的编码,如果后两位为0,则表示消息未被压缩。

​消费者设计​

​Consumer Group​

同一 Consumer Group 中的多个 Consumer 实例,不同时消费同一个 partition,等效于​队列模式​​。partition 内消息是有序的,Consumer 通过 ​​pull​​​ 方式消费消息。Kafka 不删除已消费的消息对于 partition,顺序读写磁盘数据,以时间复杂度 ​​O(1)​​方式提供​消息持久化能力​。

图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_消息队列_08

​实践应用​

​Kafka 作为消息系统​

kafka 通过在主题中具有并行性概念 - ​分区​ - ,Kafka能够在消费者流程池中提供订购保证和负载平衡。这是通过将主题中的分区分配给使用者组中的使用者来实现的,以便每个分区仅由该组中的一个使用者使用。通过这样做,我们确保使用者是该分区的​唯一读者​并按顺序使用数据。由于有许多分区,这仍然可以平衡许多消费者实例的负载。但请注意,消费者组中的​消费者实例不能超过分区​。

​Kafka 作为存储系统​

Kafka是一个非常好的存储系统。写入Kafka的数据将写入磁盘并进行复制以实现容错。Kafka允许生产者​等待确认​,以便在完全复制之前写入不被认为是完整的,并且即使写入的服务器失败也保证写入仍然存在。

磁盘结构Kafka很好地使用了规模 - 无论服务器上有50 KB还是50 TB的持久数据,Kafka都会执行相同的操作。

由于认真对待存储并允许客户端控制其读取位置,您可以将Kafka视为一种专用于高性能,低延迟提交日志存储,复制和传播的专用​分布式文件系统​。

​Kafka 用于流处理​

对于复杂的换,Kafka提供了完全集成的​​Streams API​​。这允许构建执行非平凡处理的应用程序,这些应用程序可以计算流的​聚合​或将流​连接​在一起。

此工具有助于解决此类应用程序面临的难题:处理无序数据,在代码更改时重新处理输入,执行有状态计算等。

流API构建在Kafka提供的核心原理上:它使用生产者和消费者API进行输入,使用Kafka进行8​有状态存储​,并在流处理器实例之间使用相同的组机制来实现​容错​*。

​关于我​

更多精彩敬请关注公众号


图文详解:Kafka到底有哪些秘密让我对它情有独钟呢?_数据_09

Java极客思维

微信扫一扫,关注公众号