关于java:kafka核心原理的秘密藏在这16张图里

7次阅读

共计 9594 个字符,预计需要花费 24 分钟才能阅读完成。

文章首发公众号:码哥字节(ID:MageByte)

Kafka 是一个优良的分布式消息中间件,许多零碎中都会应用到 Kafka 来做音讯通信。对分布式音讯零碎的理解和应用简直成为一个后盾开发人员必备的技能。明天 码哥字节 就从常见的 Kafka 面试题动手,和大家聊聊 Kafka 的那些事儿。

讲一讲分布式消息中间件

问题

  • 什么是分布式消息中间件?
  • 消息中间件的作用是什么?
  • 消息中间件的应用场景是什么?
  • 消息中间件选型?

分布式音讯是一种通信机制,和 RPC、HTTP、RMI 等不一样,消息中间件采纳分布式两头代理的形式进行通信。如图所示,采纳了消息中间件之后,上游业务零碎发送音讯,先存储在消息中间件,而后由消息中间件将音讯散发到对应的业务模块利用(分布式生产者 – 消费者模式)。这种异步的形式,缩小了服务之间的耦合水平。

定义消息中间件:

  • 利用高效牢靠的消息传递机制进行平台无关的数据交换
  • 基于数据通信,来进行分布式系统的集成
  • 通过提供消息传递和音讯排队模型,能够在分布式环境下扩大过程间的通信

在零碎架构中援用额定的组件,必然进步零碎的架构复杂度和运维的难度,那么 在零碎中应用分布式消息中间件有什么劣势呢?消息中间件在零碎中起的作用又是什么呢?

  • 解耦
  • 冗余(存储)
  • 扩展性
  • 削峰
  • 可恢复性
  • 程序保障
  • 缓冲
  • 异步通信

面试时,面试官常常会关怀面试者对开源组件的选型能力,这既能够考验面试者常识的广度,也能够考验面试者对某类零碎的常识的意识深度,而且也能够看出面试者对系统整体把握和零碎架构设计的能力。开源分布式音讯零碎有很多,不同的音讯零碎的个性也不一样,抉择怎么的音讯零碎,不仅须要对各音讯零碎有肯定的理解,也须要对本身零碎需要有清晰的意识。

上面是常见的几种分布式音讯零碎的比照:

答案关键字

  • 什么是分布式消息中间件?通信,队列,分布式,生产消费者模式。
  • 消息中间件的作用是什么?解耦、峰值解决、异步通信、缓冲。
  • 消息中间件的应用场景是什么?异步通信,音讯存储解决。
  • 消息中间件选型?语言,协定、HA、数据可靠性、性能、事务、生态、繁难、推拉模式。

Kafka 基本概念和架构

问题

  • 简略讲下 Kafka 的架构?
  • Kafka 是推模式还是拉模式,推拉的区别是什么?
  • Kafka 如何播送音讯?
  • Kafka 的音讯是否是有序的?
  • Kafka 是否反对读写拆散?
  • Kafka 如何保证数据高可用?
  • Kafka 中 zookeeper 的作用?
  • 是否反对事务?
  • 分区数是否能够缩小?

Kafka 架构中的个别概念:

  • Producer:生产者,也就是发送音讯的一方。生产者负责创立音讯,而后将其发送到 Kafka。
  • Consumer:消费者,也就是承受音讯的一方。消费者连贯到 Kafka 上并接管音讯,进而进行相应的业务逻辑解决。
  • Consumer Group:一个消费者组能够蕴含一个或多个消费者。应用多分区 + 多消费者形式能够极大进步数据上游的处理速度,同一生产组中的消费者不会反复生产音讯,同样的,不同生产组中的消费者音讯音讯时互不影响。Kafka 就是通过生产组的形式来实现音讯 P2P 模式和播送模式。
  • Broker:服务代理节点。Broker 是 Kafka 的服务节点,即 Kafka 的服务器。
  • Topic:Kafka 中的音讯以 Topic 为单位进行划分,生产者将音讯发送到特定的 Topic,而消费者负责订阅 Topic 的音讯并进行生产。
  • Partition:Topic 是一个逻辑的概念,它能够细分为多个分区,每个分区只属于单个主题。同一个主题下不同分区蕴含的音讯是不同的,分区在存储层面能够看作一个可追加的日志(Log)文件,音讯在被追加到分区日志文件的时候都会调配一个特定的偏移量(offset)。
  • Offset:offset 是音讯在分区中的惟一标识,Kafka 通过它来保障音讯在分区内的程序性,不过 offset 并不逾越分区,也就是说,Kafka 保障的是分区有序性而不是主题有序性。
  • Replication:正本,是 Kafka 保证数据高可用的形式,Kafka 同一 Partition 的数据能够在多 Broker 上存在多个正本,通常只有主正本对外提供读写服务,当主正本所在 broker 解体或产生网络一场,Kafka 会在 Controller 的治理下会从新抉择新的 Leader 正本对外提供读写服务。
  • Record:理论写入 Kafka 中并能够被读取的音讯记录。每个 record 蕴含了 key、value 和 timestamp。

Kafka Topic Partitions Layout

Kafka 将 Topic 进行分区,分区能够并发读写。

Kafka Consumer Offset

zookeeper

  • Broker 注册:Broker 是分布式部署并且之间互相独立,Zookeeper 用来治理注册到集群的所有 Broker 节点。
  • Topic 注册:在 Kafka 中,同一个 Topic 的音讯会被分成多个分区并将其散布在多个 Broker 上,这些分区信息及与 Broker 的对应关系也都是由 Zookeeper 在保护
  • 生产者负载平衡:因为同一个 Topic 音讯会被分区并将其散布在多个 Broker 上,因而,生产者须要将音讯正当地发送到这些分布式的 Broker 上。
  • 消费者负载平衡:与生产者相似,Kafka 中的消费者同样须要进行负载平衡来实现多个消费者正当地从对应的 Broker 服务器上接管音讯,每个消费者分组蕴含若干消费者,每条音讯都只会发送给分组中的一个消费者,不同的消费者分组生产本人特定的 Topic 上面的音讯,互不烦扰。

答案关键字

  • 简略讲下 Kafka 的架构?

    Producer、Consumer、Consumer Group、Topic、Partition

  • Kafka 是推模式还是拉模式,推拉的区别是什么?

    Kafka Producer 向 Broker 发送音讯应用 Push 模式,Consumer 生产采纳的 Pull 模式。拉取模式,让 consumer 本人治理 offset,能够提供读取性能

  • Kafka 如何播送音讯?

    Consumer group

  • Kafka 的音讯是否是有序的?

    Topic 级别无序,Partition 有序

  • Kafka 是否反对读写拆散?

    不反对,只有 Leader 对外提供读写服务

  • Kafka 如何保证数据高可用?

    正本,ack,HW

  • Kafka 中 zookeeper 的作用?

    集群治理,元数据管理

  • 是否反对事务?

    0.11 后反对事务,能够实现”exactly once“

  • 分区数是否能够缩小?

    不能够,会失落数据

Kafka 应用

问题

  • Kafka 有哪些命令行工具?你用过哪些?
  • Kafka Producer 的执行过程?
  • Kafka Producer 有哪些常见配置?
  • 如何让 Kafka 的音讯有序?
  • Producer 如何保证数据发送不失落?
  • 如何晋升 Producer 的性能?
  • 如果同一 group 下 consumer 的数量大于 part 的数量,kafka 如何解决?
  • Kafka Consumer 是否是线程平安的?
  • 讲一下你应用 Kafka Consumer 生产音讯时的线程模型,为何如此设计?
  • Kafka Consumer 的常见配置?
  • Consumer 什么时候会被踢出集群?
  • 当有 Consumer 退出或退出时,Kafka 会作何反馈?
  • 什么是 Rebalance,何时会产生 Rebalance?

命令行工具

Kafka 的命令行工具在 Kafka 包的 /bin 目录下,次要包含服务和集群治理脚本,配置脚本,信息查看脚本,Topic 脚本,客户端脚本等。

  • kafka-configs.sh:配置管理脚本
  • kafka-console-consumer.sh:kafka 消费者控制台
  • kafka-console-producer.sh:kafka 生产者控制台
  • kafka-consumer-groups.sh:kafka 消费者组相干信息
  • kafka-delete-records.sh:删除低水位的日志文件
  • kafka-log-dirs.sh:kafka 消息日志目录信息
  • kafka-mirror-maker.sh:不同数据中心 kafka 集群复制工具
  • kafka-preferred-replica-election.sh:触发 preferred replica 选举
  • kafka-producer-perf-test.sh:kafka 生产者性能测试脚本
  • kafka-reassign-partitions.sh:分区重调配脚本
  • kafka-replica-verification.sh:复制进度验证脚本
  • kafka-server-start.sh:启动 kafka 服务
  • kafka-server-stop.sh:进行 kafka 服务
  • kafka-topics.sh:topic 治理脚本
  • kafka-verifiable-consumer.sh:可测验的 kafka 消费者
  • kafka-verifiable-producer.sh:可测验的 kafka 生产者
  • zookeeper-server-start.sh:启动 zk 服务
  • zookeeper-server-stop.sh:进行 zk 服务
  • zookeeper-shell.sh:zk 客户端

咱们通常能够应用 kafka-console-consumer.shkafka-console-producer.sh脚本来测试 Kafka 生产和生产,kafka-consumer-groups.sh能够查看和治理集群中的 Topic,kafka-topics.sh通常用于查看 Kafka 的生产组状况。

Kafka Producer

Kafka producer 的失常生产逻辑蕴含以下几个步骤:

  1. 配置生产者客户端参数常见生产者实例。
  2. 构建待发送的音讯。
  3. 发送音讯。
  4. 敞开生产者实例。

Producer 发送音讯的过程如下图所示,须要通过 拦截器 序列化器 分区器 ,最终由 累加器 批量发送至 Broker。

Kafka Producer 须要以下必要参数:

  • bootstrap.server:指定 Kafka 的 Broker 的地址
  • key.serializer:key 序列化器
  • value.serializer:value 序列化器

常见参数:

  • batch.num.messages

    默认值:200,每次批量音讯的数量,只对 asyc 起作用。

  • request.required.acks

    默认值:0,0 示意 producer 毋须期待 leader 的确认,1 代表须要 leader 确认写入它的本地 log 并立刻确认,-1 代表所有的备份都实现后确认。只对 async 模式起作用,这个参数的调整是数据不失落和发送效率的 tradeoff,如果对数据失落不敏感而在乎效率的场景能够思考设置为 0,这样能够大大提高 producer 发送数据的效率。

  • request.timeout.ms

    默认值:10000,确认超时工夫。

  • partitioner.class

    默认值:kafka.producer.DefaultPartitioner,必须实现 kafka.producer.Partitioner,依据 Key 提供一个分区策略。_有时候咱们须要雷同类型的音讯必须程序解决,这样咱们就必须自定义调配策略,从而将雷同类型的数据调配到同一个分区中。_

  • producer.type

    默认值:sync,指定音讯发送是同步还是异步。异步 asyc 成批发送用 kafka.producer.AyncProducer,同步 sync 用 kafka.producer.SyncProducer。同步和异步发送也会影响音讯生产的效率。

  • compression.topic

    默认值:none,消息压缩,默认不压缩。其余压缩形式还有,”gzip”、”snappy” 和 ”lz4″。对音讯的压缩能够极大地缩小网络传输量、升高网络 IO,从而进步整体性能。

  • compressed.topics

    默认值:null,在设置了压缩的状况下,能够指定特定的 topic 压缩,未指定则全副压缩。

  • message.send.max.retries

    默认值:3,音讯发送最大尝试次数。

  • retry.backoff.ms

    默认值:300,每次尝试减少的额定的间隔时间。

  • topic.metadata.refresh.interval.ms

    默认值:600000,定期的获取元数据的工夫。当分区失落,leader 不可用时 producer 也会被动获取元数据,如果为 0,则每次发送完音讯就获取元数据,不举荐。如果为负值,则只有在失败的状况下获取元数据。

  • queue.buffering.max.ms

    默认值:5000,在 producer queue 的缓存的数据最大工夫,仅仅 for asyc。

  • queue.buffering.max.message

    默认值:10000,producer 缓存的音讯的最大数量,仅仅 for asyc。

  • queue.enqueue.timeout.ms

    默认值:-1,0 当 queue 满时丢掉,负值是 queue 满时 block, 正值是 queue 满时 block 相应的工夫,仅仅 for asyc。

Kafka Consumer

Kafka 有生产组的概念,每个消费者只能生产所调配到的分区的音讯,每一个分区只能被一个生产组中的一个消费者所生产,所以同一个生产组中消费者的数量如果超过了分区的数量,将会呈现有些消费者调配不到生产的分区。生产组与消费者关系如下图所示:

Kafka Consumer Client 生产音讯通常蕴含以下步骤:

  1. 配置客户端,创立消费者
  2. 订阅主题
  3. 拉去音讯并生产
  4. 提交生产位移
  5. 敞开消费者实例

因为 Kafka 的 Consumer 客户端是线程不平安的,为了保障线程平安,并晋升生产性能,能够在 Consumer 端采纳相似 Reactor 的线程模型来生产数据。

Kafka consumer 参数

  • bootstrap.servers:连贯 broker 地址,host:port 格局。
  • group.id:消费者附属的生产组。
  • key.deserializer:与生产者的 key.serializer 对应,key 的反序列化形式。
  • value.deserializer:与生产者的 value.serializer 对应,value 的反序列化形式。
  • session.timeout.ms:coordinator 检测失败的工夫。默认 10s 该参数是 Consumer Group 被动检测(组内成员 comsummer) 解体的工夫距离,相似于心跳过期工夫。
  • auto.offset.reset:该属性指定了消费者在读取一个没有偏移量后者偏移量有效(消费者长时间生效以后的偏移量曾经过期并且被删除了)的分区的状况下,应该作何解决,默认值是 latest,也就是从最新记录读取数据(消费者启动之后生成的记录),另一个值是 earliest,意思是在偏移量有效的状况下,消费者从起始地位开始读取数据。
  • enable.auto.commit:否主动提交位移,如果为false,则须要在程序中手动提交位移。对于准确到一次的语义,最好手动提交位移
  • fetch.max.bytes:单次拉取数据的最大字节数量
  • max.poll.records:单次 poll 调用返回的最大音讯数,如果解决逻辑很轻量,能够适当进步该值。然而 max.poll.records 条数据须要在在 session.timeout.ms 这个工夫内解决完。默认值为 500
  • request.timeout.ms:一次申请响应的最长等待时间。如果在超时工夫内未失去响应,kafka 要么重发这条音讯,要么超过重试次数的状况下间接置为失败。

Kafka Rebalance

rebalance 实质上是一种协定,规定了一个 consumer group 下的所有 consumer 如何达成统一来调配订阅 topic 的每个分区。比方某个 group 下有 20 个 consumer,它订阅了一个具备 100 个分区的 topic。失常状况下,Kafka 均匀会为每个 consumer 调配 5 个分区。这个调配的过程就叫 rebalance。

什么时候 rebalance?

这也是常常被提及的一个问题。rebalance 的触发条件有三种:

  • 组成员产生变更(新 consumer 退出组、已有 consumer 被动来到组或已有 consumer 解体了——这两者的区别前面谈判到)
  • 订阅主题数产生变更
  • 订阅主题的分区数产生变更

如何进行组内分区调配?

Kafka 默认提供了两种调配策略:Range 和 Round-Robin。当然 Kafka 采纳了可插拔式的调配策略,你能够创立本人的分配器以实现不同的调配策略。

答案关键字

  • Kafka 有哪些命令行工具?你用过哪些?/bin目录,治理 kafka 集群、治理 topic、生产和生产 kafka
  • Kafka Producer 的执行过程?拦截器,序列化器,分区器和累加器
  • Kafka Producer 有哪些常见配置?broker 配置,ack 配置,网络和发送参数,压缩参数,ack 参数
  • 如何让 Kafka 的音讯有序?Kafka 在 Topic 级别自身是无序的,只有 partition 上才有序,所以为了保障解决程序,能够自定义分区器,将需程序解决的数据发送到同一个 partition
  • Producer 如何保证数据发送不失落?ack 机制,重试机制
  • 如何晋升 Producer 的性能?批量,异步,压缩
  • 如果同一 group 下 consumer 的数量大于 part 的数量,kafka 如何解决?多余的 Part 将处于无用状态,不生产数据
  • Kafka Consumer 是否是线程平安的?不平安,单线程生产,多线程解决
  • 讲一下你应用 Kafka Consumer 生产音讯时的线程模型,为何如此设计?拉取和解决拆散
  • Kafka Consumer 的常见配置?broker, 网络和拉取参数,心跳参数
  • Consumer 什么时候会被踢出集群?奔溃,网络异样,解决工夫过长提交位移超时
  • 当有 Consumer 退出或退出时,Kafka 会作何反馈?进行 Rebalance
  • 什么是 Rebalance,何时会产生 Rebalance?topic 变动,consumer 变动

高可用和性能

问题

  • Kafka 如何保障高可用?
  • Kafka 的交付语义?
  • Replic 的作用?
  • 什么事 AR,ISR?
  • Leader 和 Flower 是什么?
  • Kafka 中的 HW、LEO、LSO、LW 等别离代表什么?
  • Kafka 为保障优越的性能做了哪些解决?

分区与正本

在分布式数据系统中,通常应用分区来进步零碎的解决能力,通过副原本保证数据的高可用性。多分区意味着并发解决的能力,这多个正本中,只有一个是 leader,而其余的都是 follower 正本。仅有 leader 正本能够对外提供服务。多个 follower 正本通常寄存在和 leader 正本不同的 broker 中。通过这样的机制实现了高可用,当某台机器挂掉后,其余 follower 正本也能迅速”转正“,开始对外提供服务。

为什么 follower 正本不提供读服务?

这个问题实质上是对性能和一致性的取舍。试想一下,如果 follower 正本也对外提供服务那会怎么样呢?首先,性能是必定会有所晋升的。但同时,会呈现一系列问题。相似数据库事务中的幻读,脏读。比方你当初写入一条数据到 kafka 主题 a,消费者 b 从主题 a 生产数据,却发现生产不到,因为消费者 b 去读取的那个分区正本中,最新消息还没写入。而这个时候,另一个消费者 c 却能够生产到最新那条数据,因为它生产了 leader 正本。Kafka 通过 WH 和 Offset 的治理来决定 Consumer 能够生产哪些数据,曾经以后写入的数据。

只有 Leader 能够对外提供读服务,那如何选举 Leader

kafka 会将与 leader 正本放弃同步的正本放到 ISR 正本汇合中。当然,leader 正本是始终存在于 ISR 正本汇合中的,在某些非凡状况下,ISR 正本中甚至只有 leader 一个正本。当 leader 挂掉时,kakfa 通过 zookeeper 感知到这一状况,在 ISR 正本中选取新的正本成为 leader,对外提供服务。但这样还有一个问题,后面提到过,有可能 ISR 正本汇合中,只有 leader,当 leader 正本挂掉后,ISR 汇合就为空,这时候怎么办呢?这时候如果设置 unclean.leader.election.enable 参数为 true,那么 kafka 会在非同步,也就是不在 ISR 正本汇合中的正本中,选取出正本成为 leader。

正本的存在就会呈现正本同步问题

Kafka 在所有调配的正本 (AR) 中保护一个可用的正本列表 (ISR),Producer 向 Broker 发送音讯时会依据 ack 配置来确定须要期待几个正本曾经同步了音讯才相应胜利,Broker 外部会 ReplicaManager 服务来治理 flower 与 leader 之间的数据同步。

性能优化

  • partition 并发
  • 程序读写磁盘
  • page cache:按页读写
  • 预读:Kafka 会将将要生产的音讯提前读入内存
  • 高性能序列化(二进制)
  • 内存映射
  • 无锁 offset 治理:进步并发能力
  • Java NIO 模型
  • 批量:批量读写
  • 压缩:消息压缩,存储压缩,减小网络和 IO 开销

Partition 并发

一方面,因为不同 Partition 可位于不同机器,因而能够充分利用集群劣势,实现机器间的并行处理。另一方面,因为 Partition 在物理上对应一个文件夹,即便多个 Partition 位于同一个节点,也可通过配置让同一节点上的不同 Partition 置于不同的 disk drive 上,从而实现磁盘间的并行处理,充分发挥多磁盘的劣势。

程序读写

Kafka 每一个 partition 目录下的文件被均匀切割成大小相等(默认一个文件是 500 兆,能够手动去设置)的数据文件,
每一个数据文件都被称为一个段(segment file), 每个 segment 都采纳 append 的形式追加数据。

答案关键字

  • Kafka 如何保障高可用?

    通过副原本保证数据的高可用,producer ack、重试、主动 Leader 选举,Consumer 自均衡

  • Kafka 的交付语义?

    交付语义个别有 at least onceat most onceexactly once。kafka 通过 ack 的配置来实现前两种。

  • Replic 的作用?

    实现数据的高可用

  • 什么是 AR,ISR?

    AR:Assigned Replicas。AR 是主题被创立后,分区创立时被调配的正本汇合,正本个 数由正本因子决定。
    ISR:In-Sync Replicas。Kafka 中特地重要的概念,指代的是 AR 中那些与 Leader 保 持同步的正本汇合。在 AR 中的正本可能不在 ISR 中,但 Leader 正本人造就蕴含在 ISR 中。对于 ISR,还有一个常见的面试题目是如何判断正本是否应该属于 ISR。目前的判断 根据是:Follower 正本的 LEO 落后 Leader LEO 的工夫,是否超过了 Broker 端参数 replica.lag.time.max.ms 值。如果超过了,正本就会被从 ISR 中移除。

  • Leader 和 Flower 是什么?
  • Kafka 中的 HW 代表什么?

    高水位值 (High watermark)。这是管制消费者可读取音讯范畴的重要字段。一 个一般消费者只能“看到”Leader 正本上介于 Log Start Offset 和 HW(不含)之间的 所有音讯。水位以上的音讯是对消费者不可见的。

  • Kafka 为保障优越的性能做了哪些解决?

    partition 并发、程序读写磁盘、page cache 压缩、高性能序列化(二进制)、内存映射 无锁 offset 治理、Java NIO 模型

本文并没有深刻 Kafka 的实现细节和源码剖析,但 Kafka 的确是一个 优良的开源零碎,很多优雅的架构设计和源码设计都值得咱们学习,非常倡议感兴趣的同学更加深刻的去理解一下这个开源零碎,对于本身架构设计能力,编码能力,性能优化都会有很大的帮忙。

举荐浏览

以下几篇文章浏览量与读者反馈都很好,举荐大家浏览:

  • 数据库系统设计概述
  • 不可不知的软件架构模式
  • Tomcat 架构原理解析到架构设计借鉴
  • Tomcat 高并发之道原理拆解与性能调优

正文完
 0