Kafka笔记

参考资料:

简介

Kafka是一种 高吞吐量分布式 发布-订阅 消息系统,具有高性能、持久化、多副本备份、横向扩展能力。生产者往队列里写消息,消费者从队列里取消息进行业务逻辑处理。一般在架构设计中起到解耦、削峰、异步处理的作用。Kafka适合离线和在线消息消费。 Kafka消息保留在磁盘上,并在群集内复制以防止数据丢失。 Kafka构建在ZooKeeper同步服务之上。它与Apache Storm和Spark非常好地集成,用于实时流式数据分析。

kafka和JMS(Java Message Service)实现(activeMQ)不同的是:即使消息被消费,消息仍然不会被立即删除.日志文件将会根据broker中的配置要求,保留一定的时间之后删除;比如log文件保留2天,那么两天后,文件会被清除,无论其中的消息是否被消费.kafka通过这种简单的手段,来释放磁盘空间,以及减少消息消费之后对文件内容改动的磁盘IO开支.

Zookeeper在kafka的作用

Zookeeper是一种在分布式系统中被广泛用来作为分布式状态管理、分布式协调管理、分布式配置管理、和分布式锁服务的集群。kafka增加和减少服务器都会在Zookeeper节点上触发相应的事件,kafka系统会捕获这些事件,进行新一轮的负载均衡,客户端也会捕获这些事件来进行新一轮的处理。

Zookeeper是Kafka代理和消费者之间的协调接口。 Kafka服务器通过Zookeeper集群共享信息。 Kafka在Zookeeper中存储基本元数据,例如关于主题,代理,消费者偏移(队列读取器)等的信息。

由于所有关键信息存储在Zookeeper中,并且它通常在其整体上复制此数据,因此Kafka代理/ Zookeeper的故障不会影响Kafka集群的状态。 一旦Zookeeper重新启动,Kafka将恢复状态。 这为Kafka带来了零停机时间。 Kafka代理之间的领导者选举也通过使用Zookeeper在领导者失败的情况下完成。

ZooKeeper用于管理和协调Kafka代理。 ZooKeeper服务主要用于通知生产者和消费者Kafka系统中存在任何新代理或Kafka系统中代理失败。 根据Zookeeper接收到关于代理的存在或失败的通知,然后产品和消费者采取决定并开始与某些其他代理协调他们的任务。

Kafka的特性

  • 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作。
  • 可扩展性:kafka集群支持热扩展,无需停机
  • 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失。通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。
  • 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
  • 高并发:支持数千个客户端同时读写
  • 轻量级,支持实时数据处理和离线数据处理两种方式

Kafka的使用场景

  • 日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。
  • 消息系统:解耦和生产者和消费者、缓存消息等。
  • 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
  • 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
  • 流式处理:流行的框架(如Storm和Spark Streaming)从主题中读取数据,对其进行处理,并将处理后的数据写入新主题,供用户和应用程序使用。 Kafka的强耐久性在流处理的上下文中也非常有用。
  • 事件源

核心概念

Kafka架构

Kafka架构是一种生产者生产消息、kafka集群、消费者获取消息的架构,如下图:

Kafka的集群图。

Cluster Architecture

工作图

  1. Kafka Cluster(Kafka集群)

    Kafka有多个代理服务器broker被称为Kafka集群。可以扩展Kafka集群,无需停机。 这些集群用于管理消息数据的持久性和复制。

  2. Topic

    kafka集群中的消息,是通过Topic(主题)来进行组织的,如下图:

    一个主题类似新闻中的体育、娱乐、教育等分类概念,在实际工程中通常一个业务一个主题。

    Topic分配partition和partition replica的算法:

    1. 将Broker(size=n)和待分配的Partition排序。
    2. 将第i个Partition分配到第(i%n)个Broker上。
    3. 将第i个Partition的第j个Replica分配到第((i + j) % n)个Broker上
  3. 分区(Partition)

    一个Topic中的消息数据按照多个分区组织,分区是kafka消息队列组织的最小单位,一个分区可以看作是一个FIFO( First Input First Output的缩写,先入先出队列)的队列。每个分区消息具有称为 offset 的唯一序列标识。

    kafka分区是提高kafka性能的关键所在,当你发现你的集群性能不高时,常用手段就是增加Topic的分区,分区里面的消息是按照从新到老的顺序进行组织,消费者从队列头订阅消息,生产者从队列尾添加消息。

    partition物理上由多个segment组成,每个Segment存着message信息。

  4. Broker(代理/经纪人)

    Kafka集群通常由多个代理组成以保持负载平衡。 Kafka代理是无状态的,所以他们使用ZooKeeper来维护它们的集群状态。 一个Kafka代理实例可以每秒处理数十万次读取和写入,每个Broker可以处理TB的消息,而没有性能影响。 Kafka经纪人领导选举可以由ZooKeeper完成。

    代理是负责维护发布数据的简单系统。 每个代理中的每个主题可以具有零个或多个分区。 假设,如果在一个主题和N个代理中有N个分区,每个代理将有一个分区。

    假设在一个主题中有N个分区并且多于N个代理(n + m),则第一个N代理将具有一个分区,并且下一个M代理将不具有用于该特定主题的任何分区。

    假设在一个主题中有N个分区并且小于N个代理(n-m),每个代理将在它们之间具有一个或多个分区共享。 由于代理之间的负载分布不相等,不推荐使用此方案。

  5. Leader(领导者)

    Leader 是负责给定分区的所有读取和写入的节点。每个分区都有一个服务器充当Leader。

    kafka会为partition选出一个leader,之后所有该partition的请求,实际操作的都是leader,然后再同步到其他的follower。当一个broker歇菜后,所有leader在该broker上的partition都会重新选举,选出一个leader。

  6. Follower(追随者)

    跟随领导者指令的节点被称为Follower。 如果领导失败,一个追随者将自动成为新的领导者。 跟随者作为正常消费者,拉取消息并更新其自己的数据存储。

  7. Producers(生产者)

    生产者是发送给broker一个或多个Kafka主题的消息的发布者。 每当生产者将消息发布给代理时,代理只需将消息附加到最后一个段文件。 实际上,该消息将被附加到分区。 生产者还可以向他们选择的分区发送消息。当新代理启动时,所有生产者搜索它并自动向该新代理发送消息。 Kafka生产者不等待来自代理的确认,并且发送消息的速度与代理可以处理的一样快。

  8. Consumers(消费者)

    Consumers从代理broker处读取数据。消费者订阅一个或多个主题,并通过从代理中提取数据来使用已发布的消息。

    每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

    一个partition,只能被消费组里的一个消费者消费,但是可以同时被多个消费组消费。

    因为Kafka代理是无状态的,这意味着消费者必须通过使用分区偏移来维护已经消耗了多少消息。 如果消费者确认特定的消息偏移,则意味着消费者已经消费了所有先前的消息。 消费者向代理发出异步拉取请求,以具有准备好消耗的字节缓冲区。 消费者可以简单地通过提供偏移值来快退或跳到分区中的任何点。 消费者偏移值由ZooKeeper通知。

  9. 备份(Replication)

    为了保证分布式可靠性,kafka0.8开始对每个分区的数据进行备份(不同的Broker上),防止其中一个Broker宕机造成分区上的数据不可用。副本从不读取或写入数据。 它们用于防止数据丢失。

    kafka0.7是一个很大的改变:1、增加了备份2、增加了控制借点概念,增加了集群领导者选举 。

Kafka的工作流程

工作图

  • Kafka只是分为一个或多个分区的主题的集合。
  • Kafka分区是消息的线性有序序列,其中每个消息由它们的索引(称为偏移)来标识。
  • Kafka集群中的所有数据都是不相连的分区联合。
  • 传入消息写在分区的末尾,消息由消费者顺序读取。
  • 通过将消息复制到不同的代理提供持久性。

Kafka以快速,可靠,持久,容错和零停机的方式提供基于pub-sub和队列的消息系统。 在这两种情况下,生产者只需将消息发送到主题,消费者可以根据自己的需要选择任何一种类型的消息传递系统。

如果所有的consumer都具有相同的group,这种情况和queue模式很像,消息将会在consumers之间负载均衡.

如果所有的consumer都具有不同的group,那这就是"发布-订阅",消息将会广播给所有的消费者.

发布-订阅消息的工作流程

以下是Pub-Sub消息的逐步工作流程

  • 生产者定期向主题发送消息。

  • Kafka代理存储为该特定主题配置的分区中的所有消息。 它确保消息在分区之间平等共享。 如果生产者发送两个消息并且有两个分区,Kafka将在第一分区中存储一个消息,在第二分区中存储第二消息。

  • 消费者订阅特定主题。

  • 一旦消费者订阅主题,Kafka将向消费者提供主题的当前偏移,并且还将偏移保存在Zookeeper系综中。

  • 消费者将定期请求Kafka(如100 Ms)新消息。

  • 一旦Kafka收到来自生产者的消息,它将这些消息转发给消费者。

  • 消费者将收到消息并进行处理。

  • 一旦消息被处理,消费者将向Kafka代理发送确认。

  • 一旦Kafka收到确认,它将偏移更改为新值,并在Zookeeper中更新它。 由于偏移在Zookeeper中维护,消费者可以正确地读取下一封邮件,即使在服务器暴力期间。

  • 以上流程将重复,直到消费者停止请求。

  • 消费者可以随时回退/跳到所需的主题偏移量,并阅读所有后续消息。

队列消息/用户组的工作流

在队列消息传递系统而不是单个消费者中,具有相同
组ID 的一组消费者将订阅主题。 简单来说,订阅具有相同
Group ID 的主题的消费者被认为是单个组,并且消息在它们之间共享。 让我们检查这个系统的实际工作流程。

  • 生产者以固定间隔向某个主题发送消息。

  • Kafka存储在为该特定主题配置的分区中的所有消息,类似于前面的方案。

  • 单个消费者订阅特定主题,假设
    Topic-01
    Group ID
    Group-1

  • Kafka以与发布 - 订阅消息相同的方式与消费者交互,直到新消费者以相同的
    组ID 订阅相同主题
    Topic-01 1 。

  • 一旦新消费者到达,Kafka将其操作切换到共享模式,并在两个消费者之间共享数据。 此共享将继续,直到用户数达到为该特定主题配置的分区数。

  • 一旦消费者的数量超过分区的数量,新消费者将不会接收任何进一步的消息,直到现有消费者取消订阅任何一个消费者。 出现这种情况是因为Kafka中的每个消费者将被分配至少一个分区,并且一旦所有分区被分配给现有消费者,新消费者将必须等待。

  • 此功能也称为使用者组。 同样,Kafka将以非常简单和高效的方式提供两个系统中最好的。

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐