关于kafka:精心整理面试必问的-kafka-知识点

34次阅读

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

Kafka 概述

定义

Kakfa 是一个分布式的基于公布 / 订阅模式的音讯队列(message queue),次要利用于大数据的实时处理畛域。

音讯队列

传统音讯队列与旧式音讯队列模式

下面是传统的音讯队列,比方一个用户要注册信息,当用户信息写入数据库后,前面还有一些其余流程,比方发送短信,则须要等这些流程解决实现后,再返回给用户。而旧式队列,比方一个用户注册信息,数据间接丢进数据库,就间接返回给用户胜利。

应用音讯队列的益处
  • 解耦
  • 可恢复性
  • 缓冲
  • 灵活性与峰值解决能力
  • 异步通信
音讯队列的模式
  • 点对点模式

音讯生产者发送音讯到音讯队列中,而后音讯消费者从队列中取出并且生产音讯,音讯被生产后,队列中不在存储。所以音讯消费者不可能生产到曾经被生产的音讯;队列反对存在多个消费者,然而对于一个音讯而言,只会 有一个消费者能够生产;如果想发给多个消费者,则须要屡次发送该条音讯。

  • 公布 / 订阅模式(一对多,消费者生产数据之后不会革除音讯)

音讯生产者将音讯公布到 topic 中,同时有多个音讯消费者(订阅)生产该音讯。和点对点的形式不同,公布到 topic 的音讯会被所有的订阅者生产;然而数据保留是期限的,默认是 7 天,因为它不是存储系统。Kafka 就是这种模式的。有两种形式,一种是是消费者去被动去生产(拉取)音讯,而不是生产者推送音讯给消费者;另外一种就是生产者被动推送音讯给消费者,相似公众号。

Kafka 基础架构

Kafka 的基础架构次要有 broker、生产者、消费者组形成,以后还包含 ZooKeeper。

生产者负责发送音讯,broker 负责缓冲音讯,broker 中能够创立 topic,每个 topic 又有 partition 和 replication 的概念。

消费者组负责解决音讯,同一个消费者组的中消费者不能生产同一个 partition 中的数据。消费者组次要是进步生产能力,比方之前是一个消费者生产 100 条数据,当初是 2 个消费者生产 100 条数据,能够进步生产能力。所以消费者组的消费者的个数要小于 partition 的个数,不然就会有消费者没有 partition 能够生产,造成资源的节约。

留神:不同消费者组的消费者是能够生产雷同的 partition 数据。

Kakfa 如果要组件集群,则只须要注册到一个 ZooKeeper 中就能够了,ZooKeeper 中还保留音讯生产的进度或者说偏移量或者生产地位。

  • 0.9 之前的版本偏移量存储在 ZooKeeper;
  • 0.9 之后的版本偏移量存储在 Kafka 中。Kafka 定义了一个零碎 topic,专用用来存储偏移量的数据。

为什么要改?

次要是思考到频繁更改偏移量,对 ZooKeeper 的压力较大,而且 Kafka 自身本人的解决也较简单。

装置 Kafka

1)Kafka 的装置只须要解压安装包就能够实现装置。

tar -zxvf kafka_2.11-2.1.1.tgz -C /usr/local/

2) 查看配置文件。

[root@es1 config]# pwd
/usr/local/kafka/config
[root@es1 config]# ll
total 84
-rw-r--r--. 1 root root  906 Feb  8  2019 connect-console-sink.properties
-rw-r--r--. 1 root root  909 Feb  8  2019 connect-console-source.properties
-rw-r--r--. 1 root root 5321 Feb  8  2019 connect-distributed.properties
-rw-r--r--. 1 root root  883 Feb  8  2019 connect-file-sink.properties
-rw-r--r--. 1 root root  881 Feb  8  2019 connect-file-source.properties
-rw-r--r--. 1 root root 1111 Feb  8  2019 connect-log4j.properties
-rw-r--r--. 1 root root 2262 Feb  8  2019 connect-standalone.properties
-rw-r--r--. 1 root root 1221 Feb  8  2019 consumer.properties
-rw-r--r--. 1 root root 4727 Feb  8  2019 log4j.properties
-rw-r--r--. 1 root root 1925 Feb  8  2019 producer.properties
-rw-r--r--. 1 root root 6865 Jan 16 22:00 server-1.properties
-rw-r--r--. 1 root root 6865 Jan 16 22:00 server-2.properties
-rw-r--r--. 1 root root 6873 Jan 16 03:57 server.properties
-rw-r--r--. 1 root root 1032 Feb  8  2019 tools-log4j.properties
-rw-r--r--. 1 root root 1169 Feb  8  2019 trogdor.conf
-rw-r--r--. 1 root root 1023 Feb  8  2019 zookeeper.properties

3) 批改配置文件 server.properties。

设置 broker.id 这个是 Kafka 集群辨别每个节点的惟一标志符。

4) 设置 Kafka 的数据存储门路。

留神:这个目录下不能有其余非 Kafka 目录,不然会导致 Kafka 集群无奈启动。

5) 设置是否能够删除 topic,默认 Kafka 的 topic 是不容许删除的。

6)Kafka 的数据保留的工夫,默认是 7 天。

7)Log 文件最大的大小,如果 log 文件超过 1 G 会创立一个新的文件。

8)Kafka 连贯的 ZooKeeper 的地址和连贯 Kafka 的超时工夫。

9) 默认的 partition 的个数。

启动 Kafka

  • 启动形式一

Kafka 只能单节点启动,所以每个 Kakfa 节点都须要手动启动,上面的形式阻塞的形式启动。

  • 启动形式二,守护的形式启动,举荐应用。

Kafka 操作

1) 查看以后 Kafka 集群已有的 topic。

留神:这里连贯的 ZooKeeper,而不是连贯的 Kafka。

2) 创立 topic,指定分片和正本个数。

阐明:replication-factor 正本数,replication-factor 分区数,topic 主题名。

如果以后 Kafka 集群只有 3 个 broker 节点,则 replication-factor 最大就是 3 了,上面的例子创立正本为 4,则会报错。

3) 删除 topic。

4)查看 topic 信息。

1.7 启动生产者生产音讯,Kafka 自带一个生产者和消费者的客户端

  • 启动一个生产者,留神此时连的 9092 端口,连贯的 Kafka 集群。

  • 启动一个消费者,留神此时连贯的还是 9092 端口,在 0.9 版本之前连贯的还是 2181 端口。

这里咱们启动 2 个消费者来测试一下。

阐明:如果不指定的消费者组的配置文件的话,默认每个消费者都属于不同的消费者组。

  • 发送音讯,能够看到每个消费者都能收到音讯。

  • Kakfa 中的理论数据。

Kafka 架构深刻

Kafka 不能保障音讯的全局有序,只能保障音讯在 partition 内有序,因为消费者生产音讯是在不同的 partition 中随机的。

Kafka 的工作流程

Kafka 中的音讯是以 topic 进行分类的,生产者生成音讯、消费者生产音讯都面向 topic。

Topic 是一个逻辑上的概念,而 partition 是物理上的概念。每个 partition 又有正本的概念。每个 partition 对应于一个 log 文件,该 log 文件中存储的就是生产者生成的数据,生产者生成的数据会一直的追加到该 log 的文件末端,且每条数据都有本人的 offset,消费者都会实时记录本人生产到了那个 offset,以便出错的时候从上次的地位持续生产,这个 offset 就保留在 index 文件中。Kafka 的 offset 是分区内有序的,然而在不同分区中是无程序的,Kafka 不保证数据的全局有序。

Kafka 原理

因为生产者生产的音讯会一直追加到 log 文件的开端,为避免 log 文件过大导致数据定位效率低下,Kafka 采纳分片和索引的机制,将每个 partition 分为多个 segment,每个 segment 对应 2 个文件 — index 文件和 log 文件,这 2 个文件位于一个雷同的文件夹下,文件夹的命名规定为:topic 名称 + 分区序号。

Index 和 log 的文件的文件名是以后这个索引是最小的数据的 offset。Kafka 如何疾速的生产数据呢?

Index 文件中存储的数据的索引信息,第一列是 offset,第二列这这个数据所对应的 log 文件中的偏移量,就像咱们去读文件,应用 seek() 设置以后鼠标的地位一样,能够更快的找到数据。

如果要去生产 offset 为 3 的数据,首先通过二分法找到数据在哪个 index 文件中,而后在通过 index 中 offset 找到数据在 log 文件中的 offset;这样就能够疾速的定位到数据,并生产。

所以,Kakfa 尽管把数据存储在磁盘中,然而他的读取速度还是十分快的。

Kafka 生产者和消费者

Kafka 生产者

Kafka 的 partition 分区的作用

Kafka 分区的起因次要就是提供并发进步性能,因为读写是 partition 为单位读写的;那生产者发送音讯是发送到哪个 partition 中呢?

  • 在客户端中指定 partition;
  • 轮询(举荐)音讯 1 去 p1,音讯 2 去 p2,音讯 3 去 p3,音讯 4 去 p1,音讯 5 去 p2,音讯 6 去 p3……

Kafka 如何保证数据可靠性呢?通过 ack 来保障

为保障生产者发送的数据,能牢靠的发送到指定的 topic,topic 的每个 partition 收到生产者发送的数据后,都须要向生产者发送 ack(确认收到),如果生产者收到 ack,就会进行下一轮的发送,否则从新发送数据。

那么 Kafka 什么时候向生产者发送 ack?

确保 follower 和 leader 同步实现,leader 在发送 ack 给生产者,这样能力确保 leader 挂掉之后,能在 follower 中选举出新的 leader 后,数据不会失落。

那多少个 follower 同步实现后发送 ack?
  • 计划 1:半数曾经实现同步,就发送 ack;
  • 计划 2:全副实现同步,才发送 ack(Kafka 采纳这种形式)

采纳第二种计划后,构想以下场景:leader 收到数据,所有的 follower 都开始同步数据,然而有一个 follower 因为某种故障,始终无奈实现同步,那 leader 就要始终等下,直到他同步实现,能力发送 ack。这样就十分影响效率,这个问题怎么解决?

Leader 保护了一个动静的 ISR 列表(同步正本的作用),只须要这个列表的中的 follower 和 leader 同步;当 ISR 中的 follower 实现数据的同步之后,leader 就会给生产者发送 ack,如果 follower 长时间未向 leader 同步数据,则该 follower 将被剔除 ISR,这个工夫阈值也是自定义的;同样 leader 故障后,就会从 ISR 中选举新的 leader。

怎么抉择 ISR 的节点呢?

首先通信的工夫要快,要和 leader 要能够很快的实现通信,这个工夫默认是 10s

而后就看 leader 数据差距,音讯条数默认是 10000 条(前面版本被移除)

为什么移除:因为 Kafka 发送音讯是批量发送的,所以会一瞬间 leader 承受实现,然而 follower 还没有拉取,所以会频繁踢出和退出 ISR,这个数据会保留到 ZooKeeper 和内存中,所以会频繁更新 ZooKeeper 和内存。

然而对于某些不太重要的数据,对数据的可靠性要求不是很高,可能容忍数据的大量失落,所以没必要等 ISR 中的 follower 全副承受胜利。所以 Kafka 为用户提供了三种可靠性级别,用户能够依据可靠性和提早进行衡量,这个设置在 kafka 的生成中设置:ack 参数设置。

  • acks 为 0

生产者不等 ack,只管往 topic 丢数据就能够了,这个丢数据的概率十分高。

  • ack 为 1

leader 落盘后就会返回 ack,会有数据失落的景象,如果 leader 在同步实现后呈现故障,则会呈现数据失落。

  • ack 为 -1(all)

leader 和 follower(ISR)落盘才会返回 ack,会有数据反复景象,如果在 leader 曾经写实现,且 follower 同步实现,然而在返回 ack 的呈现故障,则会呈现数据反复景象;极限状况下,这个也会有数据失落的状况,比方 follower 和 leader 通信都很慢,所以 ISR 中只有一个 leader 节点,这个时候,leader 实现落盘,就会返回 ack,如果此时 leader 故障后,就会导致失落数据。

Kafka 如何保障生产数据的一致性?通过 HW 来保障

LEO:指每个 follower 的最大的 offset;

HW(高水位):指消费者能见到的最大的 offset,LSR 队列中最小的 LEO,也就是说消费者只能看到 1~6 的数据,前面的数据看不到,也生产不了。

防止 leader 挂掉后,比方以后消费者生产 8 这条数据后,leader 挂了,此时比方 f2 成为 leader,f2 基本就没有 9 这条数据,那么消费者就会报错,所以设计了 HW 这个参数,只裸露起码的数据给消费者,防止下面的问题。

HW 保证数据存储的一致性
  • follower 故障

follower 产生故障后会被长期提出 LSR,待该 follower 复原后,follower 会读取本地的磁盘记录的上次的 HW,并将该 log 文件高于 HW 的局部截取掉,从 HW 开始向 leader 进行同步,等该 follower 的 LEO 大于等于该 partition 的 hw,即 follower 追上 leader 后,就能够重新加入 LSR。

  • leader 故障

leader 产生故障后,会从 ISR 中选出一个新的 leader,之后,为了保障多个正本之间的数据一致性,其余的 follower 会先将各自的 log 文件高于 hw 的局部截掉(新 leader 本人不会截掉),而后从新的 leader 同步数据。

留神:这个是为了保障多个正本间的数据存储的一致性,并不能保证数据不失落或者不反复。

精准一次(幂等性),保证数据不反复

ack 设置为 -1,则能够保证数据不失落,然而会呈现数据反复(at least once)

ack 设置为 0,则能够保证数据不反复,然而不能保证数据不失落(at most once)

然而如果鱼和熊掌兼得,该怎么办?这个时候就就引入了 Exact once(精准一次)。

在 0.11 版本后,引入幂等性解决 Kakfa 集群外部的数据反复,在 0.11 版本之前,在消费者处本人做解决。如果启用了幂等性,则 ack 默认就是 -1,Kafka 就会为每个生产者调配一个 pid,并未每条音讯调配 seqnumber,如果 pid、partition、seqnumber 三者一样,则 Kafka 认为是反复数据,就不会落盘保留;然而如果生产者挂掉后,也会呈现有数据反复的景象;所以幂等性解决在单次会话的单个分区的数据反复,然而在分区间或者跨会话的是数据反复的是无奈解决的。

Kafka 消费者

生产形式

音讯队列有两种生产音讯的形式,push(微信公众号)、pull(kafka)。push 模式很难适应生产速率不同的消费者,因为生产发送速率是由 broker 决定的,他的指标是尽可能以最快的的速度传递音讯,然而这样很容易造成消费者来不及解决音讯,典型的体现就是拒绝服务以及网络拥塞。而 pull 的形式能够消费者的生产能力以适当的速率生产音讯。

pull 模式的不足之处是如果 Kafka 没有数据,消费者可能会陷入死循环,始终返回空数据,针对这一点,Kafka 消费者在生产数据时候回传递一个 timeout 参数,如果过后没有数据可供生产,消费者会期待一段时间在返回。

分区调配策略

一个消费者组有多个消费者,一个 topic 有多个 partition。所以必然会波及到 partition 的调配问题,即确定哪个 partition 由哪个消费者来生产。Kafka 提供两种形式,一种是轮询(RountRobin)对于 topic 组失效,一种是(Range)对于单个 topic 失效

轮询:前置条件是须要一个消费者里的消费者订阅的是雷同的 topic。不然就会呈现问题;非默认的的形式。

同一个消费者组里的消费者不能同时生产同一个分区,比方三个消费者生产一个 topic 的 9 个分区。

如果一个消费者组里有 2 个消费者,这个消费者组里同时生产 2 个 topic,每个 topic 又有三个 partition。首先会把 2 个 topic 当做一个主题,而后依据 topic 和 partition 做 hash,而后在依照 hash 排序。而后轮询调配给一个消费者组中的 2 个消费者。

如果是上面这样的形式订阅的呢?

比方有 3 个 topic,每个 topic 有 3 个 partition,一个消费者组中有 2 个消费者。消费者 1 订阅 topic1 和 topic2,消费者 2 订阅 topic2 和 topic3。那么这样的场景,应用轮训的形式订阅 topic 就会有问题。

如果是上面这种形式订阅呢?

比方有 2 个 topic,每个 topic 有 3 个 partition,一个消费者组 有 2 个消费者,消费者 1 订阅 topic1,消费者 2 订阅 topic2,这样应用轮训的形式订阅 topic 也会有问题。

所以咱们始终强调,应用轮训的形式订阅 topic 的前提是一个消费者组中的所有消费者订阅的主题是一样的;所以轮询的形式不是 Kafka 默认的形式;Range 是依照单个 topic 来划分的,默认的调配形式。

Range 的问题会呈现消费者数据不平衡的问题。比方上面的例子,一个消费者组订阅了 2 个 topic,就会呈现消费者 1 生产 4 个 partition,而另外一个消费者只生产 2 个 partition。

分区策略什么时候会触发呢?当消费者组里的消费者个数变动的时候,会触发分区策略调整,比方消费者里减少消费者,或者缩小消费者。

保护 offset

因为消费者在生产过程中可能会呈现断电宕机等故障,消费者复原后,须要从故障前的地位持续生产,所以消费者须要施行记录本人生产哪个 offset,以便故障复原后持续生产。

Offset 保留的地位有 2 个,一个 ZooKeeper,一个是 Kafka。首先看下 offset 保留到 ZooKeeper,由消费者组、topic、partition 三个元素确定惟一的 offset。

所以消费者组中的某个消费者挂掉之后,或者的消费者还是能够拿到这个 offset。

Controller 这个节点和 ZooKeeper 通信,同步数据,这个节点就是谁先起来,谁就先注册 controller,谁就是 controller。其余节点和 controller 信息放弃同步。

消费者组的案例

批改消费者组 id

启动一个消费者发送 3 条数据。

指定消费者组启动消费者,启动三个消费者,能够看到每个消费者生产了一条数据。

在演示下不同组能够生产同一个 topic 的,咱们看到 2 个消费者的消费者都生产到同一条数据。再次启动一个消费者,这个消费者属于另外一个消费者组。

Kafka 的高效读写机制

分布式部署

多节点并行操作。

程序写磁盘

Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程中始终追加到文件开端,为程序写,官网有数据表明。同样的磁盘,程序写能到 600M/S,而随机写只有 100K/S。这与磁盘的机械构造无关,程序写之所以快,是因为其省去了大量磁头寻址的工夫。

零复制技术

失常状况下,先把数据读到内核空间,在从内核空间把数据读到用户空间,而后在调操作系统的 IO 接口写到内核空间,最终在写到硬盘中。

Kafka 是这样做的,间接在内核空间流转 IO 流,所以 Kafka 的性能十分高。

ZooKeeper 在 Kafka 中的作用

Kafka 集群中有一个 broker 会被选举为 controller,负责管理集群 broker 的高低线,所有的 topic 的分区正本调配和 leader 选举等工作。

作者:bainianminguo
原文:https://www.cnblogs.com/baini…

正文完
 0