实用工具之Kafka

image-20210621145318002

Kafka基础

简介

Kafka是什么?

  • Apache Kafka是一个分布式流平台
  • Kafka作为一个集群运行在一个或多个服务器上,这些服务器可以跨越多个数据中心
  • Kafka集群将记录流存储在称为主题Topic的类别中
  • 每个记录由一个键key、一个值value和一个时间戳timestamp组成

流平台的关键特性

  • 发布和订阅记录流,类似于消息队列或企业消息传递系统
  • 以容错的持久方式存储记录流
  • 处理记录流(当它们发生时)

Kafka的应用领域

  • 构建实时流数据管道,在系统或应用程序之间可靠地获取数据
  • 构建转换或响应数据流的实时流应用程序

Kafka的四个核心API

Kafka-APIs

  • Producer API:允许应用程序将记录流发布到一个或多个Kafka主题Topic
  • Consumer API:允许应用程序订阅一个或多个主题Topic,并处理产生给它们的记录流。
  • Streams API:允许应用程序充当流处理器,使用一个或多个主题Topic的输入流,并生成一个或多个输出主题Topic的输出流,从而有效地将输入流转换为输出流
  • Connector API:允许构建和运行将Kafka主题Topic连接到现有应用程序或数据库的可重用生产者或消费者。例如,到关系数据库的连接器可能捕获对表的每个更改。

通信协议

  • 在Kafka中,客户端和服务器之间的通信是通过一个简单的、高性能的、语言无关的TCP协议来完成的。此协议经过版本控制,并保持与旧版本的向后兼容性

核心概念

主题[Topics]

  • 主题是被发布记录所属类别或订阅源的名词
  • 一个主题可以有零个,一个或多个消费者来订阅写入该主题的数据

日志[Logs]

  • 对于每个主题,Kafka集群维护一个类似下图的分区日志

log_anatomy

  • 每个分区都是有序的,不可变的记录序列,这些记录连续地附加到结构化的提交日志中
  • 每个分区中的记录都分配有一个称为偏移的顺序ID号,该ID唯一地标识分区中的每个记录
  • Kafka集群使用可配置的保留期限持久保留所有已发布记录(无论是否已使用它们),超过保留期限后,记录将被丢弃以释放空间
  • Kafka的性能在数据大小方面是稳定的,所以长时间存储数据不是问题

  • 如下图,偏移量由使用者控制:通常,使用者在读取记录时会线性地推进其偏移量,但是实际上,由于位置是由使用者控制的,因此它可以按喜欢的任何顺序使用记录。 例如,使用者可以重置到较旧的偏移量以重新处理过去的数据,或者跳到最近的记录并从“现在”开始使用。

log_consumer

  • 这些特性的组合意味着Kafka消费者非常便宜,他们可以来去自如,对集群或其他消费者没有太大影响。例如,您可以使用命令行工具“跟踪”任何主题的内容,而不需要更改任何现有使用者所使用的内容
  • 日志中的分区有多种用途。 首先,它们允许日志扩展到超出单个服务器所能容纳的大小。 每个单独的分区都必须适合托管它的服务器,但是一个主题可能有很多分区,因此它可以处理任意数量的数据。 其次,它们充当并行性的单元

分布[Distribution]

  • 日志的分区分布在Kafka群集中的服务器上,每个服务器处理数据并要求共享分区。
  • 每个分区都在可配置数量的服务器之间复制,以实现容错功能
  • 每个分区有一个充当“领导者”的服务器和零个或多个充当“追随者”的服务器
  • 领导者处理该分区的所有读写请求,而追随者则被动复制领导者
  • 如果领导者失败,则追随者之一将自动成为新领导者
  • 每个服务器既充当某些分区的领导者,又充当其他分区的追随者,这样集群中的负载得到了很好的平衡

异地备份[Geo-Replication]

  • Kafka MirrorMaker为集群提供异地备份支持
  • 使用MirrorMaker,消息可以跨多个数据中心或云区域进行备份
  • 您可以在主动/被动方案中使用它进行备份和恢复,或在主动/主动方案中将数据放置在离您的用户更近的位置,或支持本地数据需求

生产者[Producers]

  • 生产者将数据发布到他们选择的主题
  • 生产者负责选择将哪个记录分配给主题中的哪个分区
  • 这可以以循环的方式来完成,只是为了平衡负载,也可以根据某种语义划分函数来完成(比如基于记录中的某个键)

消费者[Consumers]

  • 消费者使用消费者组名称标记自己,并且发布到主题的每条记录都会传递到每个订阅消费者组中的一个消费者实例
  • 消费者实例可以在单独的进程中或在单独的机器上
  • 如果所有消费者实例具有相同的消费者组,那么记录将有效地在消费者实例上进行负载平衡
  • 如果所有消费者实例都有不同的消费者组,那么每个记录将被广播到所有消费者进程

举例如下图:

log_consumer

  • 一个包含四个分区(P0-P3)和两个消费者组的两台服务器【Kafka集群】
  • 消费者组A有两个消费者实例(C1、C2),而组B有四个(C3-C6)
  • Kafka中实现消费的方法是在消费者实例的日志中划分分区,这样每个实例在任何时候都是分区“公平共享”的唯一消费者
  • 这个保持组成员身份的过程是由Kafka协议动态处理的
  • 如果新的实例加入组,它们将从组的其他成员那里接管一些分区
  • 如果一个实例死亡,它的分区将分配给其余的实例
  • 如图中:消费者组A中C1负责P0\P3,C2负责P1\P2;消费者组B中每个实例负责一个分区
  • Kafka只提供分区内记录的总顺序,而不提供主题中不同分区之间的总顺序
  • 对大多数应用程序来说,按分区排序和按键分区数据的能力已经足够
  • 但是,如果需要记录的总顺序,则可以使用只有一个分区的主题来实现
  • 尽管这意味着每个使用者组只有一个使用者进程(一个使用者实例?)

多租户[Multi-tenancy]

  • 可以将Kafka部署为多租户解决方案
  • 通过配置哪些主题可以生成或使用数据,可以启用多租户
  • 还有对限额的操作支持
  • 管理员可以对请求定义和强制配额,以控制客户端使用的代理资源
  • 有关更多信息,请参阅安全文档

保证性[Guarantees]

在较高级别上,Kafka提供以下保证:

  • 生产者发送到特定主题分区的消息将按照发送的顺序追加
    1. 也就是说,如果记录M1是由与记录M2相同的生产者发送的,并且M1是先发送的,那么M1的偏移量将比M2低,并出现在日志的前面
  • 消费者实例按【记录在日志中存储的顺序】查看记录
  • 对于具有复制因子N的主题,我们将容忍至多N-1个服务器故障,而不会丢失提交到日志的任何记录

Kafka进阶

Kafka作为消息传递系统[Kafka as a Messaging System]

传统的企业消息传递系统

传统的消息传递系统拥有两个模块:

队列-queuing

  • 在队列中,消费者池可以从服务器读取数据,而每条记录都将被发送到其中的一位消费者
  • 队列的优点是它允许在多个消费者实例上划分数据处理
  • 不幸的是,队列不是多用户的:一旦一个进程读取了数据,其他用户就读取不了了
  • 传统队列在服务器上按顺序保留记录,如果多个使用者从队列中消费,则服务器按存储记录的顺序分发记录
  • 然而,尽管服务器按顺序分发记录,但这些记录是异步传递给消费者的,因此它们可能在不同的消费者上不按顺序到达
  • 这实际上意味着记录的顺序在并行使用时丢失
  • 消息传递系统通常通过“独占消费者”的概念来解决这个问题,该概念只允许一个进程从队列中消费,但这当然意味着处理中不存在并行性

发布-订阅-publish-subscribe

  • 在发布-订阅中,记录被广播给所有消费者
  • 发布-订阅允许将数据广播到多个进程,但是由于每个消息都传递到每个订阅者,因此无法扩展处理

Kafka

  • Kafka中的消费者组概念概括了队列&发布-订阅
  • 与队列一样,消费者组允许将处理划分到一组进程(消费者组的成员)上
  • 与发布-订阅一样,Kafka允许向多个消费者组广播消息
  • Kafka也比传统的消息传递系统有更强的订购保证
  • 通过对主题内分区的并行性的概念,Kafka能够在用户进程池上提供排序保证负载平衡
  • 这是通过将主题中的分区分配给消费者组中的消费者实例来实现的,这样每个分区正好由组中的一个消费者使用
  • 通过这样做,我们可以确保消费者是该分区的唯一读取者,并按顺序使用数据
  • 由于有许多分区,这仍然可以在许多消费者实例上平衡负载
  • 但是请注意,在一个消费者组中不能有比分区更多的消费者实例

Kafka操作

基本操作

主题列表

bin/kafka-topics.sh --list --zookeeper localhost:2181

消费topic

bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic topic-name 
--from-beginning

查看topic分区和副本情况

bin/kafka-topics.sh --describe --zookeeper 127.0.0.1:2181  --topic test0

查看topic消费到的offset

bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 127.0.0.1:9092 --topic test0 --time -1

查看topic各个分区的消息的信息

bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --group testgroup --topic test0 --zookeeper 127.0.0.1:2181
  • 运行结果:

    | GROUP | TOPIC | PID | OFFSET | LOGSIZE | LAG |
    | ———— | ————- | —————— | ———————— | ———- | —————— |
    | 消费者组 | topic名字 | partition id | 当前已消费的条数 | 总条数 | 未消费的条数 |
    | | | | | | |

参考书籍

疑难解答


文章作者: Myhaa
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Myhaa !
评论
  目录