kafka 基础入门

kafka是什么

Kafka (Apache kafka is a distributed streaming platform) ,官方定义是一个分布式流式计算平台。在我开发的项目中,是把kafka当作一种高吞吐量、基于发布/订阅的 分布式消息队列 ,暂未接触到流式计算功能。
kafka最初由 LinkedIn 公司开发,使用 Scala 语言编写,目前是 Apache 的开源项目。

kafka与redis的区别

举个简单的例子:
老板有个好消息要告诉大家,有两个办法:
1.老板到员工座位上挨个儿告诉每个人。什么?张三去上厕所了?那张三就只能错过好消息了!
2.老板把消息写到黑板报上,谁想知道就自己来看。什么?张三请假了?没关系,我一周之后才擦掉,总会看见的!什么张三请假两周?那就算了,我反正只保留一周,不然其他好消息没地方写了。
redis用第一种办法,kafka用第二种办法,这就是区别

kafka基础

kafka系统

基本概念

通过上图,我们会发现kafka系统中有以下几个概念:

  1. broker: Kafka 服务器,负责消息存储和转发的中介;kafka作为集群运行在一个或者多个服务器上;
  2. topic: 消息类别,Kafka 按照 topic 来分类消息;存储的消息是k-v键值对,k是offset偏移量,v就是消息的内容;
  3. partition: topic 的分区,一个 topic 可以包含多个 partition,topic 消息保存在各个partition 上;topic是逻辑上的概念,patition是物理概念。
  4. offset: 消息在日志中的位置,即消息在 partition 上的偏移量,也是代表该消息的唯一序号;
  5. Producer: 消息生产者;产生消息,并将消息送给broker。
  6. Consumer: 消息消费者;从broker中拿消息;
  7. Consumer Group: 消费者分组,每个 Consumer 必须属于一个 group;
  8. Zookeeper: 保存着集群 broker、topic、partition 等 meta 数据;另外,还负责 broker 故障发现,partition leader 选举,负载均衡等功能;

核心api

  1. 应用程序使用 Producer API 发布消息到1个或多个topic(主题)中。
  2. 应用程序使用 Consumer API 来订阅一个或多个topic,并处理产生的消息。
  3. 应用程序使用 Streams API 充当一个流处理器,从1个或多个topic消费输入流,并生产一个输出流到1个或多个输出topic,有效地将输入流转换到输出流。
  4. Connector API 可构建或运行可重用的生产者或消费者,将topic连接到现有的应用程序或数据系统。例如,连接到关系数据库的连接器可以捕获表的每个变更。

kafka数据存储设计

Kafka的数据存储使用了分区(Partition)的设计模型,将主题(Topic)消息打散到多个分区,并分布保存在不同的Kafka Broker节点上;以此实现了消息处理的高吞吐量。其生产者和消费者都可以多线程地并行操作,而每个线程处理的是一个分区的数据。
Kafka中的消息是以主题(Topic)为基本单位进行组织的,各个主题之间相互独立。topic只是一个逻辑上的抽象概念,实际数据文件的存储中,在物理上是以一个或多个分区(Partition)构成,每个分区对应本地磁盘上的一个文件夹,每个文件夹内包含了日志索引文件(“.index”和“.timeindex”)和日志数据文件(“.log”)两部分。分区数量可以在创建主题时指定,也可以在创建Topic后进行修改。(ps:Topic的Partition数量只能增加而不能减少)。

消息数据(offset, MessageSize, data)

每条 Message 包含以下三个属性: offset, MessageSize, data;kafka存储的消息是k-v键值对,其中k是offset偏移量,v就是消息的内容data;offset唯一确定了 partition 中的一条 Message; MessageSize 表示消息内容 data 的大小。

数据文件分段(顺序读写、分段命令、二分查找)

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

数据文件索引(分段索引、 稀疏存储)

Kafka 为每个分段后的数据文件建立了索引文件 (“.index”和“.timeindex”,分别表示偏移量索引文件和消息时间戳索引文件),文件名与数据文件的名字是一样的,扩展名不一样。 index 文件中并没有为数据文件中的每条 Message 建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。
数据文件

kafka生产者

数据生产流程

kafka 生产数据

  • kafka生产者将消息封装成 ProducerRecord ,向 kafka集群发送消息;
  • 消息首先经过序列化器进行序列化;以便在网络中传输;
  • 序列化之后,经过分区器决定消息分发到哪个 partition;如果已指定分区,则不需要分区器;
  • 开始往kafka集群指定的partition 发送消息;
  • 消息写入成功,kafka集群会回应 生产者一个 RecordMetaData 的消息;如果失败会根据配置的允许失败次数进行重试;超过重试次数,则消息写入失败并反馈给生产者。

负载均衡策略

由于消息 topic 由多个 partition 组成, 且 partition 分布在不同 broker 上;因此,为了有效利用 broker 集群的性能,提高消息的吞吐量, 生产者需要通过一定的策略使消息平均发送到多个 partition 上,以实现负载均衡。
Kafka 默认的分区器是 Kafka 提供的 DefaultPartitioner。它的分区策略是根据 Key 值进行分区分配的:

  • 如果 key 不为 null:对 Key 值进行 Hash 计算,从所有分区中根据 Key 的 Hash 值计算出一个分区号;拥有相同 Key 值的消息被写入同一个分区;
  • 如果 key 为 null:消息将以轮询的方式,在所有可用分区中分别写入消息。

如果不想使用 Kafka 默认的分区器,用户可以实现 Partitioner 接口,自行实现分区方法。

批量发送

生产者发送多个消息到同一个分区的时候,为了减少网络带来的系能开销,kafka会对消息进行批量发送。批量发送是提高消息吞吐量重要的方式, Producer 端可以在内存中合并多条消息后, 以一次请求的方式发送批量的消息给 broker,从而大大减少 broker 存储消息的 IO 操作次数。但也一定程度上影响了消息的实时性,相当于以时延代价,换取更好的吞吐量。
生产者配置中有以下几个批量发送的属性:

名称 类型 默认值 重要性 描述
batch.size int 16384 medium 控制默认的批量处理消息字节数。 不会试图处理大于这个字节数的消息字节数。
linger.ms long 0 medium 设定了批量处理的更高的延迟边界
max.request.size int 1028576 medium 请求的最大字节数(默认是1M)

当batch.size与linger.ms这两个参数同时设置的时候,只要两个条件中满足一个就会发送。比如说batch.size设置16kb,linger.ms设置50ms,那么当消息积压达到16kb就会发送,如果没有到达16kb,那么在第一个消息到来之后的50ms之后消息将会发送。

数据压缩

在对大数据处理上,瓶颈往往体现在网络上而不是 CPU(压缩和解压会耗掉部分 CPU 资源)。压缩的好处就是减少传输的数据量,减轻对网络传输的压力;
Kafka(本文是以0.8.2.x的版本做基准的)本身可以支持几种类型的压缩,比如gzip和snappy,更高的版本还支持lz4。默认是none,即不采用任何压缩。开启压缩的方式是在客户端调用的时候设置producer的参数。与压缩有关的参数有:

名称 默认值 使用 描述
compression.type none new producer configs(kafka-client) 用于压缩数据的压缩类型。默认是无压缩。正确的选项值是none、gzip、snappy。(压缩的速度上snappy<gzip。)
compression.codec none kafka-scala-client 此项参数可以设置压缩数据的codec,可选codec为:“none”, “gzip”, “snappy”
compressed.topics none kafka-scala-client 此项参数可以设置某些特定的topics是否进行压缩。如果压缩codec是NoCompressCodec之外的codec,则对指定的topics数据应用这些codec。如果压缩topics列表是空,则将特定的压缩codec应用于所有topics。如果压缩的codec是NoCompressionCodec,压缩对所有topics军不可用。
posted @ 2021-03-12 15:10  super_龙  阅读(147)  评论(0编辑  收藏  举报