Kafka必知必会

什么是Kafka

Kafka是一个分布式流处理平台。一个流平台有这三个关键功能:
1. 发布和订阅记录流,类似一个消息队列或者企业消息系统。
2. 能够以较强的容错性存储流记录。
3. 能够及时处理流记录。

应用场景

Kafka通常用于两类广泛的应用:
1. 构建实时流数据管道,让系统之间或应用之间可靠的获取数据
2. 构建能够改变或响应流数据的实时流应用

实现原理

为了理解Kafka如何实现这些,我们会从下往上研究Kafka的功能。
1. Kafka作为一个集群运行在一个或者多个可跨数据中心的服务器上。
2. Kafka集群以分类的形式存储流记录,称之为主题(topics)。
3. 每一条记录包含键(key),值(value),时间戳(timestamp)。

在Kafka中,客户端和服务器之间通信通过简单,高性能,语言无关的TCP协议实现。该协议自带版本标识,默认向后兼容旧版本协议。官方提供Java的客户端,其他语言由第三方提供。

相关名词

生产者(Producers)

所谓生产者,就是产生消息的服务,它们可以选择发布消息到指定主题。生产者负责选择指定的记录发布到指定主题的指定分区,负载均衡算法有轮询以及根据记录关键字分区。

消费者(Consumers)

所谓的消费者是指,消费kafka消息的服务,通常是各种客户端。

每个消费者使用消费组标识自己(consumer group name)。当消费组里只有一个实例时,当前的消费者消费全部分区的消息。Kafka是通过分区来实现扩展性和容错性。

假设Kafka集群有2个Server(Server1 Server2),4个分区(P0 P1 P2 P3),2个消费组(Consumer Group A Consumer Group B),每个消费组分别有2个和4个消费者(C1 — C6)。见下图:

那么整体消费可能情况如下表:

消费者/分区 Server1(P0) Server1(P3) Server2(P1) Server2(P2)
C1
C2
C3
C4
C5
C6

Kafka实现消费的方式是尽可能的平均分配相关分区,每个分区都只拥有一个消费者。消费者的添加和删除会动态的改变分区的分配,分区会动态分配到其他消费者。

Kafka只保证同一个分区的记录顺序,不同分区的顺序无法保证。通过分区排序和按键(key)分区满足大多数应用的需求。如果需要全局的顺序呢,只能使用一个分区的主题,这个分区只有一个消费者。这意味这同一个分区,如果有2个消费者消费的话,另外一个消费者会”很闲”,也就是无法处理消息。

主题和日志(Topics and Logs)

所谓的主题是,发布记录的类别或者订阅名称。主题一般是多订阅者的,这意味着可以有0个,1个,多个订阅者等订阅写入的数据。

Kafka对每一个主题维护一个分区日志,每个分区都是一个有序的,以不可变的记录,也就是不断追加到结构化的提交日志。分区中每个记录都一个连续的id,称为偏移(offset),唯一标识分区内的记录。这个偏移由消费者控制,所以消费者可以以任何顺序消费消息。

Kafka集群使用可配置的保留时间,来持久化存储全部已发布的消息,无论是否被客户端消费。

分区日志的作用是,可以减少日志的大小,单个服务器可以存储下,更多的作用是方便进行扩展。

分布式(Distribution)

Kafka通过zookeeper实现分区容错性,只需要n/2+1个节点存活,就可以保证较好的容错性。每个分区都在可配置的服务器上进行复制,以便实现容错。

GEO复制(Geo-Replication)

Kafka采用MirrorMaker实现集群的地理复制功能,可以跨数据中心或者多个云。

多租户(Multi-tenancy)

Kafka也支持多租户的配置方案。

保证(Guarantees)

高级别的Kafka提供以下保证:
1. 生产者发送到特定主题分区的消息将按照其发送的顺序追加。也就是说,哪一条记录先发送就具有更低的偏移且在日志中出现得更早。
2. 消费者按照分区日志的顺序查看记录。
3. 对有N个复制者的主题,最多能容忍N-1个服务器挂掉,而不会丢失任何提交到日志的记录。

消息系统(Kafka as a Messaging System)

Kafka作为消息系统的优势:
1. 每个主题可以自动进行扩展,可以有多个订阅者。
2. 比起传统的消息系统,有更好的顺序保证。
3. 通过分区的概念,提供顺序保证和自动负载均衡,提高并发处理的能力。

存储系统(Kafka as a Storage System)

由于kafka较好的存储并且允许客户端控制读取的位置,你可以将其认为是一个高性能,低延迟提交日志存储,用于复制和传播,专用分布式文件系统。

流处理(Kafka for Stream Processing)

Kafka不仅可以读取,写入和存储数据流,还可以实现流的实时处理目的。

为什么Kafka会这么快

大多数人,选择Kafka的特性之一就是极佳的性能,为什么Kafka会这么快?

顺序写入/Sequential IO

Kafka尽量会避免随机磁盘访问,采用了顺序写入的策略。大多数服务器都是采用的SATA硬盘这类机械硬盘,当Kafka收到消息后,会顺序写入到当前的分区文件的末尾,也就是所谓的分区其实就是一个文件。如果所有服务器采用SSD硬盘的话,这个策略的优势提升不大。这个技巧还用在MySQL InnoDB上,运用事务日志把随机IO转成顺序IO。

代价 顺序IO 随机IO
寻道时间 较短(3ms) 较长(15ms)
旋转延迟 较短(2ms) 较大(4ms)
处理资源
IOPS(Input/Output Operations Per Second)
内存映射(Memory Mapped Files)

将操作系统的内存与磁盘上的文件进行映射,也就是虚拟内存页(Page),可以像对硬盘一样读写虚拟内存,通过操作系统的策略稍后定时同步到磁盘上,提升数据写入的效率。

读取数据

采用了零拷贝技术,实现性能极大提升。所谓的零拷贝技术,就是减少了用户空间与内核空间的文件拷贝,避免CPU操作无效的数据存储拷贝,主要还是通过系统mmap实现。

参考链接

  1. Kafka Introduction
  2. KAFKA官方文档
  3. Kafka 官方文档翻译[20171016]
  4. KAFKA官方文档 简介
  5. 20 Best Practices for Working With Apache Kafka at Scale
  6. Apache Kafka Best Practices
  7. Kafka最佳实践 / Kafka Best Practices
  8. Kafka Best Practices
  9. 为什么Kafka这么快
  10. 为什么Kafka这么快
  11. 磁盘I/O那些事
  12. 随机 I/O & 顺序 I/O
  13. Understanding I/O: Random vs Sequential
  14. Kafka消费者:从Kafka中读取数据
  15. Linux下的零拷贝
  16. Here’s what makes Apache Kafka so fast
  17. Why Is Kafka So Fast
打赏作者

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注