Kafka 是分布式发布-订阅消息系统。它最初由 LinkedIn 公司开发,之后成为 Apache 项目的一部分。Kafka 是一个分布式的,可划分的,冗余备份的持久性的日志服务。它主要用于处理活跃的流式数据。
在大数据系统中,常常会碰到一个问题,整个大数据是由各个子系统组成,数据需要在各个子系统中高性能,低延迟的不停流转。传统的企业消息系统并不是非常适合大规模的数据处理。为了已在同时搞定在线应用(消息)和离线应用(数据文件,日志)Kafka 就出现了。Kafka 可以起到两个作用:
Kafka 主要特点:
Kayka 的架构:
Kayka 的整体架构非常简单,是显式分布式架构,producer、broker(kafka)和 consumer 都可以有多个。Producer,consumer 实现 Kafka 注册的接口,数据从 producer 发送到 broker,broker 承担一个中间缓存和分发的作用。broker 分发注册到系统中的 consumer。broker 的作用类似于缓存,即活跃的数据和离线处理系统之间的缓存。客户端和服务器端的通信,是基于简单,高性能,且与编程语言无关的 TCP 协议。几个基本概念:
消息发送的流程:
Kayka 的设计:
1、吞吐量
高吞吐是 kafka 需要实现的核心目标之一,为此 kafka 做了以下一些设计:
负载均衡
拉取系统
由于 kafka broker 会持久化数据,broker 没有内存压力,因此,consumer 非常适合采取 pull 的方式消费数据,具有以下几点好处:
可扩展性
当需要增加 broker 结点时,新增的 broker 会向 zookeeper 注册,而 producer 及 consumer 会根据注册在 zookeeper 上的 watcher 感知这些变化,并及时作出调整。
Kayka 的应用场景:
1. 消息队列
比起大多数的消息系统来说,Kafka 有更好的吞吐量,内置的分区,冗余及容错性,这让 Kafka 成为了一个很好的大规模消息处理应用的解决方案。消息系统一般吞吐量相对较低,但是需要更小的端到端延时,并尝尝依赖于 Kafka 提供的强大的持久性保障。在这个领域,Kafka 足以媲美传统消息系统,如 ActiveMR 或 RabbitMQ。
2. 行为跟踪
Kafka 的另一个应用场景是跟踪用户浏览页面、搜索及其他行为,以发布-订阅的模式实时记录到对应的 topic 里。那么这些结果被订阅者拿到后,就可以做进一步的实时处理,或实时监控,或放到 hadoop/离线cangku.html" target="_blank">数据仓库里处理。
3. 元信息监控
作为操作记录的监控模块来使用,即汇集记录一些操作信息,可以理解为运维性质的数据监控吧。
4. 日志收集
日志收集方面,其实开源产品有很多,包括 Scribe、Apache Flume。很多人使用 Kafka 代替日志聚合(log aggregation)。日志聚合一般来说是从服务器上收集日志文件,然后放到一个集中的位置(文件服务器或 HDFS)进行处理。然而 Kafka 忽略掉文件的细节,将其更清晰地抽象成一个个日志或事件的消息流。这就让 Kafka 处理过程延迟更低,更容易支持多数据源和分布式数据处理。比起以日志为中心的系统比如 Scribe 或者 Flume 来说,Kafka 提供同样高效的性能和因为复制导致的更高的耐用性保证,以及更低的端到端延迟。
5. 流处理
这个场景可能比较多,也很好理解。保存收集流数据,以提供之后对接的 Storm 或其他流式计算框架进行处理。很多用户会将那些从原始 topic 来的数据进行阶段性处理,汇总,扩充或者以其他的方式转换到新的 topic 下再继续后面的处理。例如一个文章推荐的处理流程,可能是先从 RSS 数据源中抓取文章的内容,然后将其丢入一个叫做“文章”的 topic 中;后续操作可能是需要对这个内容进行清理,比如回复正常数据或者删除重复数据,最后再将内容匹配的结果返还给用户。这就在一个独立的 topic 之外,产生了一系列的实时数据处理的流程。Strom 和 Samza 是非常著名的实现这种类型数据转换的框架。
6. 事件源
事件源是一种应用程序设计的方式,该方式的状态转移被记录为按时间顺序排序的记录序列。Kafka 可以存储大量的日志数据,这使得它成为一个对这种方式的应用来说绝佳的后台。比如动态汇总(News feed)。
7. 持久性日志(commit log)
Kafka 可以为一种外部的持久性日志的分布式系统提供服务。这种日志可以在节点间备份数据,并为故障节点数据回复提供一种重新同步的机制。Kafka 中日志压缩功能为这种用法提供了条件。在这种用法中,Kafka 类似于 Apache BookKeeper 项目。
Kayka 的设计要点:
1、直接使用 linux 文件系统的 cache,来高效缓存数据。
2、采用 linux Zero-Copy 提高发送性能。传统的数据发送需要发送 4 次上下文切换,采用 sendfile 系统调用之后,数据直接在内核态交换,系统上下文切换减少为 2 次。根据测试结果,可以提高 60% 的数据发送性能。Zero-Copy 详细的技术细节可以参考:https://www.ibm.com/developerworks/linux/library/j-zerocopy/
3、数据在磁盘上存取代价为O(1)。kafka 以 topic 来进行消息管理,每个 topic 包含多个 part(ition),每个 part 对应一个逻辑 log,有多个 segment 组成。每个 segment 中存储多条消息(见下图),消息 id 由其逻辑位置决定,即从消息 id 可直接定位到消息的存储位置,避免 id 到位置的额外映射。每个 part 在内存中对应一个 index,记录每个 segment 中的第一条消息偏移。发布者发到某个 topic 的消息会被均匀的分布到多个 part 上(随机或根据用户指定的回调函数进行分布),broker 收到发布消息往对应 part 的最后一个 segment 上添加该消息,当某个 segment 上的消息条数达到配置值或消息发布时间超过阈值时,segment 上的消息会被 flush 到磁盘,只有 flush 到磁盘上的消息订阅者才能订阅到,segment 达到一定的大小后将不会再往该 segment 写数据,broker 会创建新的 segment。
4、显式分布式,即所有的 producer、broker 和 consumer 都会有多个,均为分布式的。Producer 和 broker 之间没有负载均衡机制。broker 和 consumer 之间利用 zookeeper 进行负载均衡。所有 broker 和 consumer 都会在 zookeeper 中进行注册,且 zookeeper 会保存他们的一些元数据信息。如果某个 broker 和 consumer 发生了变化,所有其他的 broker 和 consumer 都会得到通知。
参考资料: