Kafka学习笔记

一、Kafka介绍

1.概述

Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。主要应用场景是:日志收集系统和消息系统。

2.好处

缓存;解耦合;可恢复性;异步处理;流量削峰。

3.场景介绍

参考各博客的场景

4.名词解释

  • Broker
    Kafka实例的服务器节点。
  • Topic
    用来区分不同类型信息的主题。比如客户端A订阅了主题t1,客户端B订阅了主题t2而没有订阅t1,那么发送到主题t1中的数据将只能被A读到,而不会被B读到。
  • Partition
    每个topic可以有一个或多个partition。分区是在物理层面上的,不同的分区对应着不同的数据文件。Kafka使用分区支持物理上的并发写入和读取,从而大大提高了吞吐量。
  • Replication
    分区的副本,保证分区的高可用性,副本数不能超过节点数。
  • Leader
    一个分区的多个副本的交互角色,生产者和消费者只与leader交互。
  • Follower
    一个分区的多个副本的备份角色,从leader复制数据,保证leader主机故障,数据不丢失。
  • Record
    实际写入Kafka中并可以被读取的消息记录。每个record包含了key、value和timestamp。
  • Producer
    生产者,用来向Kafka中发送数据(record)。
  • Consumer
    消费者,用来读取Kafka中的数据(record)。
  • Consumer Group
    一个消费者组可以包含一个或多个消费者。使用多分区+多消费者方式可以极大提高数据下游的处理速度。

5.数据流(发布-订阅模式)

在这里插入图片描述

  • 图中板块介绍:
    一个zookeeper集群;
    一个kafka集群;
    三个生产者;
    两个消费者组,每个消费者组各有两个消费者成员;
  • Kafka集群介绍:
    三台kafka节点:broker-0,broker-1,broker-2;
  • 三个主题:
    Topic-A,一共两个分区,每个分区三个副本,partition0的leader在broker-0上,partition1的leader在broker-1上;
    Topic-B,一共一个分区三个副本,partition0的leader在broker-2上;
    Topic-C,一个分区两个副本,partition0的leader在broker-0上。

二、基本知识点

1.消息系统

一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的。分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。有两种主要的消息传递模式:点对点传递模式、发布-订阅模式

2.消息传递模式

2.1.点对点传递模式

在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。

2.2.发布-订阅模式

在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中相应的数据,同一条数据可以被多个消费者(必须是不同消费者组)消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。该模式的示例图如下:

在这里插入图片描述
在Kafka中,可以存在多个主题,每一个主题都是互不影响的。每一个主题中又可以分为多个分区。生产者把消息发送到主题中,根据策略具体存放到某个分区中,然后消费者订阅主题根据策略消费某些分区的消息。

三、部分机制策略

下面机制策略根据消费者->kafak服务器->消费者的顺序讲解

1.生产者分区策略

生产者在发消息时,根据一些配置可以指定消息发送到某个特定的服务器节点上
好处:
1、方便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,而一个 topic又可以有多个 Partition 组成;
2、可以提高并发,因为可以以 Partition 为单位读写了。(联想到ConcurrentHashMap在高并发环境下读写效率比HashTable的高效)。
分区原则(DefaultPartitioner.class有说明):

  • 指明 partition 的情况下,直接将指明的值直接作为 partiton 值;
  • 没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值;
  • 既没有 partition 值又没有 key 值的情况下,使用默认的分区分配策略(Sticky Partition:黏性分区器)。

2.生产者ACK确认机制

对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没必要等 ISR 中的 follower 全部接收成功。Kafka 提供了三种可靠性级别对可靠性和延迟的要求进行权衡。

  • 0: producer 不等待 broker 的 ack,这一操作提供了一个最低的延迟, broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据;
  • (默认)1: producer 等待 broker 的 ack, partition 的 leader 落盘成功后返回 ack,如果在 follower同步成功之前 leader 故障,那么将会丢失数据;
  • -1或all: producer 等待 broker 的 ack, partition 的 leader 和 ISR 的follower 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后, broker 发送 ack 之前, leader 发生故障,那么会造成数据重复。

3.服务器ISR(in-sync replica)

情景:leader 收到数据,所有 follower 都开始同步数据,但有一个 follower,因为某种故障,迟迟不能与 leader 进行同步,那 leader 就要一直等下去,直到它完成同步,才能发送 ack。
leader 维护了一个动态的 in-sync replica set (ISR),意为和 leader 保持同步的 follower 集合。如果 follower长时间未向leader同步数据,则该follower将被踢出ISR。Leader 发生故障之后,就会从 ISR 中选举新的 leader。

4.数据一致性问题

在这里插入图片描述
三个标记点:LSO、HW、LEO
LSO:最开始标记点offset;
HW:俗称高水位,特定的消息偏移量,消费者能拉到的消息点;
LEO:消息日志中最后一条的offset。

故障恢复处理

  • follower 故障:follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后, follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower 的 LEO 大于等于该 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。
  • leader 故障:leader 发生故障之后,会从 ISR 中选出一个新的 leader。为保证多个副本之间的数据一致性, 其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。
    这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。

5.文件存储

由于生产者生产的消息会不断追加到 log 文件末尾, 为防止 log 文件过大导致数据定位效率低下, Kafka 采取了分片和索引机制,将每个 partition 分为多个 segment。每个 segment对应三类文件:消息日志文件、索引文件和其他文件
在这里插入图片描述
一个分区下消息分段情况:
在这里插入图片描述
偏移量索引文件:分为两部分,relativeOffset和position。
relativeOffset:消息的相对偏移量,offset – baseOffset,baseOffset为整个segmentLogFile的起始消息的offset。
position:物理地址,也就是日志在分段日志文件中的实际位置。
在这里插入图片描述
时间戳索引文件:也分为两部分,timestamp和relativeOffset。
timestamp:当前日志分段文件中建立索引的消息的时间戳。
在这里插入图片描述

6.消费者分区分配策略(重平衡策略)

一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费。kafka一共提供了四种策略。
Range
范围分配器在每个主题的基础上工作。对于每个主题,按数字顺序排列可用分区,按字典顺序排列消费者。 然后我们将分区数除以消费者总数,以确定分配给每个消费者的分区数。 如果它没有均匀划分,那么前几个消费者将有一个额外的分区。
例:

  • 消费者:C0和C1
  • 主题:t0 、 t1 ,各三个分区,分区为t0p0 、 t0p1 、 t0p2 、 t1p0 、 t1p1 、 t1p2
  • 订阅情况:都订阅了两个主题
    分配后:
    C0: [t0p0, t0p1, t1p0, t1p1]
    C1: [t0p2, t1p2]
    RoundRobinAssignor
    循环分配器布置所有可用分区和所有可用消费者。 然后它继续进行从分区到消费者的循环分配。 如果所有消费者实例的订阅都相同,则分区将均匀分布。当消费者实例之间同的订阅不时,分配过程仍会以循环方式考虑每个消费者实例,但如果实例未订阅该主题,则会跳过该实例。 与订阅相同的情况不同,这会导致分配不平衡。
    例:
  • 消费者:C0 、 C1 、 C2
  • 主题:t0 、 t1 、 t2 ,每个主题分别具有 1、2 和 3 个分区。 因此,分区为t0p0 、 t1p0 、 t1p1 、 t2p0 、 t2p1 、 t2p2
  • 订阅情况:C0订阅了t0 ; C1订阅了t0 、 t1 ; 并且C2订阅了t0 、 t1 、 t2
    分配后:
    C0: [t0p0]
    C1: [t1p0]
    C2: [t1p1, t2p0, t2p1, t2p2]
    C0挂掉,重平衡:
    C1: [t0p0, t1p1]
    C2: [t1p0, t2p0, t2p1, t2p2]
    StickyAssignor(默认)
    粘性分配器有两个目的。 首先,它保证分配尽可能平衡,其次,当发生重新分配时,它尽可能多地保留现有分配。
    例:
  • 消费者:C0 , C1 , C2
  • 主题:t0, t1 , t2 , t3 ,每个主题具有2个分区,分区为t0p0 , t0p1 , t1p0 , t1p1 , t2p0 , t2p1 , t3p0 , t3p1
  • 订阅情况:都订阅了所有四个主题
    分配后:
    C0: [t0p0, t1p1, t3p0]
    C1: [t0p1, t2p0, t3p1]
    C2: [t1p0, t2p1]
    C1挂掉,重平衡:
    C0 [t0p0, t1p1, t3p0, t2p0]
    C2 [t1p0, t2p1, t0p1, t3p1]
    CooperativeStickyAssignor
    因为重平衡过程会触发stop-the-world(STW),此时对应topic的资源都会处于不可用的状态。小规模的集群还好,如果是大规模的集群,比如几百个节点的consumer或kafka connect等,那么重平衡就是一场灾难。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值