Kafka学习笔记

Sunday, April 24, 2022

1. 概述

这篇文章是学习 Kafka 时的一些笔记,对于一些重要的特性或者概念进行了简要的记录,后续会针对这些特性和概念进行详细的阐述说明,文章内容来自书籍《Kafka 入门与实践》以及网络上的一些文章。

Kafka 是一个高吞吐量、开源的、轻量级的、可分区的、具有复制备份的分布式发布订阅消息系统,当前,它的定位为一个分布式流式处理平台,作为针对流式处理平台,它具有三个特性:

  1. 能够允许发布和订阅流数据
  2. 存储数据时提供相应的容错机制
  3. 当流数据到达时能够及时处理

1.1 基本结构

Kafka 基本结构中包含 生产者(Producer) 和 消费者(Consumer) 两个部分,简单的结构图如下,其中消费者是采取 拉取(Pull) 的方式从 Kafka 集群获取消息。

image-20220409003947256

1.2 基本概念

  1. 主题(Topic)

​ Kafka 将一组消息抽象归纳为一个主题(Topic),即主题是一类消息的集合,生产者将消息发送到特定主题,消费者订阅主题或者主题的某些分区来拉取消息进行消费。

  1. 消息(Message)

​ 消息是 Kafka 通信的基本单位,由一个固定长度的消息头和一个可变长度的消息体构成。

  1. 分区(Partition)

    • 每个分区在物理上对应为一个文件夹,命名规则为主题名称后接 - 连接符,之后再接分区编号,编号从0开始,最大值为分区总数减1。每个主题对应的分区数可以在配置文件中指定,也可以在创建主题时指定,也可以在创建后进行修改。

    • 理论上来说,分区数越多吞吐量越高,因为每个分区只能被同一个组的一个消费者订阅,但这个也要根据实际的业务场景来定,同时,分区也是 Kafka 保证消息顺序消费以及负载均衡的基础。

    • 每个主题会被划分为一个或多个分区,Kafka 只能保证一个分区内消息的有序性,不能保证跨分区消息的有序性,每条消息都被追加到指定的分区,由于是顺序写磁盘,因此效率非常高,这也是高吞吐量的一个保证。

    • 与传统消息系统不同的是,Kafka 不会立即删除已被消费的消息,由于磁盘的限制,消息也不会一直存储,Kafka 提供了两种删除老数据的策略,一是基于消息存储的时间长度,二是基于分区的大小,这两种策略都可以通过配置文件进行配置。

    如下所示,我的 Kafka 集群有3个Broker,创建了一个主题为"study",指定有3个分区,3个副本,分区的文件夹命名如下:

    I have no name!@kafka2:/bitnami/kafka/data$ pwd
    /bitnami/kafka/data
    I have no name!@kafka2:/bitnami/kafka/data$ ls -l | grep study
    drwxr-xr-x 7 1001 root  224 Apr  8 17:14 study-0
    drwxr-xr-x 7 1001 root  224 Apr  8 17:14 study-1
    drwxr-xr-x 7 1001 root  224 Apr  8 17:14 study-2
    
  2. 副本(Replica)

    每一个分区都有一个或多个副本,分区的副本分布在集群的不同代理商以提高可用性,从存储角度上分析,分区的每个副本在逻辑上抽象为一个日志对象,即分区的副本与日志对象是一一对应的。

  3. Leader副本和Follower副本

    由于副本的存在,Kafka 需要确保副本之间数据的一致性,Kafka 会选择该分区的一个副本作为 Leader 副本,其它副本为 Follow 副本,只有 Leader 副本才处理客户端的读写请求,Follow 副本从 Leader 副本同步数据。

    如果没有 Leader 副本,所有的副本都要处理客户端的请求,并且要与其它的副本同步数据,这样就会有 n*n 个通路来同步数据,并且,数据的一致性和时序性无法得到保证,因此 Kafka 引入了 Leader 副本的概念,Leader 副本负责客户端请求以及与其它的 n-1 个副本之间同步数据,使得系统简单而高效。

    副本之间的角色不是固定的,一旦 Leader 副本失效,Kafka 内部就会进行选举,选出新的 Leader 副本。

  4. 偏移量(Offset)

    发布到分区的消息都会被直接追加到 .log 文件尾部,而每条消息再日志文件中的位置都会对应一个按序递增的偏移量,它不代表消息在磁盘上的物理位置。

    消费者可以通过控制偏移量来进行消费,在旧版本中,Kafka 将消费的偏移量保存在 ZooKeeper 中,新版本已经存在了 Kafka 的一个主题(__consumer_offsets-xx)当中,消费者也可以在外部保存自己的消费偏移量。

  5. 日志段(LogSegment)

    日志段是 Kafka 日志对象分片的最小单位,一个日志对象可以分为多个日志段,与日志对象一样,日志段也是一个逻辑概念,一个日志段对应一个具体的日志文件和两个索引文件,分别如下:

    • 数据文件:xxxxx.log
    • 消息偏移量索引文件:xxxxx.index
    • 消息时间戳索引文件:xxxxx.timeindex
    I have no name!@kafka2:/bitnami/kafka/data/study-0$ pwd
    /bitnami/kafka/data/study-0
    I have no name!@kafka2:/bitnami/kafka/data/study-0$ ls -l
    total 4
    -rw-r--r-- 1 1001 root 10485760 Apr  8 17:14 00000000000000000000.index
    -rw-r--r-- 1 1001 root        0 Apr  8 17:14 00000000000000000000.log
    -rw-r--r-- 1 1001 root 10485756 Apr  8 17:14 00000000000000000000.timeindex
    -rw-r--r-- 1 1001 root        0 Apr  8 17:14 leader-epoch-checkpoint
    -rw-r--r-- 1 1001 root       43 Apr  8 17:14 partition.metadata
    
  6. 代理(Broker)

    Kafka 集群包含一个或多个 Kafka 实例,其中每一个实例我们称之为代理(Broker),实际部署中,Kafka 集群可能包含一台或多台服务器,其中一台服务器上有可能部署一个或多个Broker,每一个代理都有自己的唯一标识id,该id为非负整数,该值会存在于配置文件 server.properties 中,如下:

    I have no name!@kafka2:/opt/bitnami/kafka/config$ pwd
    /opt/bitnami/kafka/config
    I have no name!@kafka2:/opt/bitnami/kafka/config$ cat server.properties | grep broker.id
    broker.id=2
    
  7. 生产者(Producer)

    生产者负责将消息发送给代理,也就是向 Kafka 发送消息的客户端。

  8. 消费组(Consumer Group)和消费者(Consumer)

    在 Kafka 中,每一个消费者都属于一个特定的消费组,每个消费组都有一个唯一的id,即 group.id,同样,每一个消费者也有自己的一个唯一id,即 client.id。

    同一个主题的一条消息只能被同一个消费组下的某一个消费者消费,但不通消费组的消费者可同时消费该消息。

    消费组是 Kafka 用来实现对一个主题进行广播和单播的手段,实现广播只需指定各消费者均属于不同的消费组,单播则只需让各消费者属于同一个消费组。

  9. ISR

    ISR 的全称是 In-sync Replica,即保存同步的副本列表,该列表由 Kafka 保存在 ZooKeeper 中,里面保存的是与 Leader 副本保持消息同步的所有副本对应的代理节点id,如果一个 Follower 副本宕机或者落后太多,则该副本将从 ISR 列表中移除。

  10. ZooKeeper

​ Kafka 利用 ZooKeeper 保存响应的元数据信息,比如代理节点信息(Broker)、集群信息、旧版消费者及其消费偏移量信息、主题信息、分区状态信息、分区副本分配方案信息、动态配置信息等。

​ Kafka 在启动或运行过程中会在 ZooKeeper 上创建相应节点来保存元数据信息,并且通过监听机制在这些节点注册相应监听器来监听元数据的变化,从而由 ZooKeeper 负责管理维护 Kafka 集群,同时通过 ZooKeeper 可以很方便对 Kafka 集群进行水平扩展或数据迁移。

​ 需要注意的是,新版本的 Kafka 可以不依赖 ZooKeeper 运行,它将这些元数据信息维护在了自己的一个主题当中,从而摆脱了对 ZooKeeper 的依赖。

结合以上基本概念,Kafka 的基本结构图如下:

image-20220409111354498

1.3 特性

  1. 消息持久化

    消息系统数据持久化一般采用为每个消费队列提供一个B树或其它通用的随机访问数据结构来维护消息的元数据,时间复杂度低,并且支持事务性和非事务性消息的传递,但是有个缺点,不适合磁盘操作,而 Kafka 是高度依赖文件系统来存储和缓存消息的,因为基于内存的话特别消耗内存,并且无法存储海量(TB)级数据以及无法将数据进行持久化,另外,针对磁盘的线性写和随机写速度差别很大,因此,Kafka 选择了将数据简单追加的方式存储到磁盘上,这样,既能持久化海量数据,也能保证速度。

    正式因为持久化,Kafka 不用在消息被消费后就删掉消息,在重启后已存储的消息可继续恢复使用,同时能够狠友好的支持在线或离线处理以及与其它存储及流处理框架的集成。

  2. 高吞吐量

    高吞吐量是 Kafka 设计的一个重要指标,当前 Kafka 支持每秒数百万级别的消息,这得益于以下几个技术:

    • Kafka 数据才用了线性读写磁盘
    • 数据写入与数据同步才用零拷贝(zero-copy)技术,完全在内核操作,避免了内核缓冲区与用户缓冲区之间的数据拷贝,操作效率极高
    • Kafka 支持数据压缩及批量发送
    • Kafka 为每个主题划分了多个分区
  3. 扩展性

    Kafka 依赖 ZooKeeper 对集群进行协调管理,这样可以更加容易的进行水平扩展,生产者、消费者和代理都为分布式,可配置多个,同时,机器扩展时无需将整个集群停机,集群可以自动感知进行负载均衡和数据复制。

  4. 多客户端支持

    Kafka 提供了多种开发语言的接入,同时支持多种连接器(Connector)的接入,也提供了 Connector API 供开发者调用,当前,Kafka 与很多主流的大数据框架进行了很好的集成,如 Flume、Hadoop、Hbase、Hlive、Spark、Storm 等。

  5. Kafka Streams

    Kafka 在 0.10 之后的版本加入了 Kafka Steams,这是一个 Java 语言实现的用于流处理的 jar 文件。

  6. 安全机制

    当前 Kafka 支持以下集中安全措施:

    • 通过 SSL 和 SASL(Kerberos),SASL/PLAIN 验证机制支持生产者、消费者与代理(Broker)连接时的身份认证
    • 支持代理(Broker)与 ZooKeeper 连接身份验证
    • 通信时数据加密
    • 客户端读写权限认证
    • 支持与外部其它认证授权服务的集成
  7. 数据备份

    Kafka 可以为每个主题指定副本数,对数据进行持久化备份,一定程度上可以防止数据丢失,提高可用性。

  8. 轻量级

    Kafka 的轻量级表现在两个方面:

    • 代理(Broker)是无状态的,即代理不记录消息是否被消费,消费偏移量交由消费者自己或组协调器来维护
    • 集群本身几乎不需要生产者和消费者的状态信息
    • 生产者和消费者的客户端实现也非常的轻量级
  9. 消息压缩

    Kafka 支持 Gzip、Snappy、LZ4 这3中压缩方式,通常把多条消息放在一起组成 MessageSet,然后再把 MessageSet 放到一条消息里面去,从而提高压缩比率进而提高吞吐量。

1.4 应用场景

  1. 消息系统

    Kafka 作为一个优秀的消息系统,具有高吞吐量、内置分区、备份冗余分布式等特点,为大规模消息处理提供了一个很好的解决方案。

  2. 应用监控

    利用 Kafka 采集应用程序和服务器健康相关的指标,如 CPU 占用率、IO、内存、连接数、TPS、QPS 等,然后将指标信息进行处理,从而构建一个具有监控仪表盘、曲线图等可视化监控系统,典型的应用为 Kafka + ELK + Grafana 构建应用监控系统。

  3. 网站用户行为跟踪

    通过将用户操作轨迹、内容等信息发送到 Kafka,再结合 Hadoop 或 Spark 等进行数据分析处理,生成相应的统计报告,为推荐系统提供数据源,进而为用户提供个性化推荐。

  4. 流处理

    将已收集的流数据提供给其它流式计算框架进行处理,用 Kafka 收集流数据是一个不错的选择,而且当前 Kafka 提供了 Kafka Steams 支持对流数据的处理。

  5. 持久性日志

​ Kafka 可以为外部系统提供一种持久性日志的分布式系统,日志可以在多个节点进行备份,Kafka 为故障节点数据恢复提供了一种重新同步的机制。同时,Kafka 很方便与 HDFS 和 Flume 进行整合,这样就方便将 Kafka 采集的数据持久化到其它外部系统,典型的应用为 Kafka + ELK。

MQ Kafka MQ

Go信号监听canal学习及k8s集群部署