Kafka学习笔记

软件介绍:kafka是领英公司基于Scala语言开发的一款消息中间件,后捐献给Apache基金会

主要概念:

Topic 主题 用于区分不同数据,类似于数据库的表

Producer 生产者、source,负责往kafka写入数据的,比如采集数据的软件flume,canal

Consumer 消费者、sink,负责读取消费kafka数据的,比如spark、flink、kafkastreaming,任何一个消费者必须属于一个消费者组,不允许消费者直接消费数据

Broker kafka集群的节点,kafk的节点都叫做Broker,主节点也叫作Controller

Partitioner         划分分区,不同分区可以在不同节点存储,进行并行消费

Replication 副本,每个分区数据,保存多个副本,每个副本必须保存在不同Broker,总数不超过节点数。多个副本有主从之分,leader副本负责读写,follower节点负责从主节点同步数据。由Kafka主节点Controller负责选择主副本。

Segment 分区中数据的划分,用于加快数据检索的效率,将数据按照规则写入不同文件,以后可以根据规则快速的定位数据所在的文件,读取对应的小的segment文件,不用读取所有数据文件

Offset 分区中每条数据的唯一标识,从小到大,是消费者按照offset读取数据,kafka保证消费数据不重复不遗漏的关键,offset是分区级别的概念,每个分区各自管理一套offset,从0开始

ConsumerGroup 消费者组,每个消费者必须属于一个组,以组为单位消费数据,组内多个消费者可并行消费数据,但是单个消费者不能同时消费多个分区数据,只能串行消费它负责的分区。

功能:分布式实时的消息队列

定义:分布式的基于订阅发布模式的高性能高可靠消息队列

高效率读写         kafka数据直接写入pagecache内存(内存使用达到阈值或者达到一定时间比如30s)再写入磁盘,顺序写磁盘,读也是先读pagecache内存,如果pagecache有,则通过零拷贝机制读取,如果pagecache没有,则读取segment index文件使用索引读取

高并发        对数据分区,多个消费者对多个分区消费时,可以进行并行消费

内存数据安全保证          副本机制       分区保存多份,存储在不同节点上

大数据量存储       Kafka写入数据写入的不是普通的内存,是操作系统级别的内存,不会随着kafka的服务关闭或重启而关闭。生产数据发送到主副本分区后,从副本节点会向主副本分区进行同步数据,内存数据占用pageCache(操作系统级别内存)达到10%或者数据写入超过30s ,通过顺序写入机制写入磁盘进行持久化。

高可用:公平架构,zookeeper负责辅助选举和存储Kafka的元数据

集群模式(Kafka只有集群模式)

架构:Kafka集群采用公平架构,每一个节点都有称为主节点的机会,发生故障时会进行故障转移

单点故障:Kafka主节点Controller

数据存储:Kafka管理的分布式磁盘

高可用(HA):Kafka基于Zookeeper实现,日志保存在Zookeeper(新版可以kafka自己实现)

集群启动时:所有节点会尝试在Zookeeper 某个固定目录下注册一个临时节点,注册成功的成为主节点,其他节点会成为从节点,从节点会给该临时节点注册监听。

当主节点挂掉:收到监听的从节点,会尝试去Zookeeper注册该节点,注册成功的成为主节点,其它的成为从节点。从节点给该临时节点注册监听。这时即使主节点重启,也只能成为从节点。

生产数据安全(生产的一次性语义)

丢失问题:

Ack三种级别处理方式

0 :发送不等待ack,直接发送下一条,性能最好,但是数据丢失风险大,一般不用(异步,效率最高,但是数据不能保证不丢失)

1:发送等待写入分区的leader副本后即返回ack,如果leader故障,数据有一定丢失风险,取0和all的折中

all:发送等待写入所有副本都成功再返回ack,无丢失风险,但是性能最差

重复问题:

Ack校验机制,生产者生产数据后,进行Ack校验,如果生产者收到Kafka返回的Ack则继续发送下一条,如果超时没有收到,则进行默认三次的重试。如果数据发送成功,但是返回的Ack丢失,会再次重试发送数据,可能会造成重复。

解决:

幂等性机制:生产者对每条数据进行编号,kafka收到数据后将其和上一条收到的数据的进行比对,如果sequenceID和上一次的sequenceID+1不相等,则直接返回生产者一条ack信息。幂等性机制可以保证数据在生产过程中不重复。(幂等性,类似于mysql的replace into 插入更新命令 ,多次插入和一次插入数据结果不会变化,noSQL数据库都实现了幂等性写入)

消费数据安全(消费的一次性语义)

Kafka通过严格按照offset来消费保证数据的顺序性(分区内)和不重复不遗漏(理论上)

segment:分区数据的更细的划分,按照offset,每写入1G产生一个新的segment,segment包含两种文件,一个是.log文件,是存储的消息数据,另一种是.index文件,存储消息的索引。

消费:

第一次消费:默认是从最新数据开始消费,也可以设置为从最早位置开始消费

后续的消费:从上次最后消费的offset+1的位置开始消费

原则:消费者必须以消费者组的形式进行消费,如果一个组的有多个消费者,则多个消费者消费的数据合起来为完整数据。多个分区多个消费者的情况下,需要遵循消费分配策略来分配。

offset机制

问题:消费者offset为了效率是保存在内存的,如果消费者故障,则offset会丢失,重启之后不知道该从哪里开始消费

kafka将offset保存在__consumer_offset这个Topic中,如果消费者重启,可以从kafka读取上次的offset。offset由消费者进行提交,提交有三种方式,也可以保存在外部存储系统比如Redis或者MySQL等

offset提交kafka方式

1.定时提交(不建议)

设置一个时间间隔,每隔这个时间间隔就提交一次,比如每秒提交一次

缺点:跟消费数据没有直接关联,可能未提交但已消费,也可能已提交但是未消费,消费宕机后,数据可能会重复和遗漏。

2.手动提交(Topic)

每消费处理一个Topic消息,就手动提交一次

优点:比定时提交稍优

缺点:不同分区的消息被不同消费者消费,消费者宕机后,也可能会重复和遗漏

3.手动提交(Partition)(常用)

每消费处理一个Partition消息,就手动提交一次

优点:数据不会遗漏,但有可能重复

4.手动提交(message)

每消费一个消息,手动提交一次

优点,数据不会遗漏,但有极低几率遗漏,性能最差。

生产分区策略:

kafka生产数据有四种分区原则

1.先判断是否有指定分区,如果指定了分区,则放入指定分区

2.如果没有指定分区,再判断是否指定了自定义分区器,如果指定了自定义分区器,则按照自定义分区器分区

3.如果没有指定分区器,在再判断是否指定了Key,如果指定了Key,则按照key的mur值取分区数的余数获取分区编号,放入对应分区

4.如果也没有指定key,则按照默认的粘性分区规则,如果内存中有partition,则继续放入该partition,如果没有,则随机一个分区。

消费分配策略:

一、范围分配策略  RangeAssignor(默认)

按照范围尽量均分,如果不能均分,优先分配编号较小的消费者

优点:如果topic少,分配会比较均衡

缺点:如果topic多,且分区不能均分,会产生负载不均衡问题

问题:数据分配

二、轮询分配策略  RoundRobinAssignor(kafka2.x之前的版本推荐使用)

将各分区进行编号,一个一个分配给消费者

优点:如果有多个消费者,消费的Topic都是一样的,实现将所有分区轮询分配给所有消费者

缺点:遇到消费者订阅topic不一致的,容易产生负载不均衡,如果一个消费者故障,将会重写进行分配。

三、粘性分配策略 StickRobinAssignor(kafka2.x之后推荐使用)

底层采用算法,尽量平均分配消息,求取最优解,执行过程如果某个消费者发送故障,可以直接将其任务平均分配给剩下的消费者,不去改变正在消费的分配。尽量避免进行网络传输

优点:尽量保证所有分配均衡,尽量保证每个消费者如果出现故障,剩余消费者依旧保留自己原来消费的分区

缺点:kafka2.x版本才有

Offset索引设计

offset索引表采用了稀疏索引,采用消息条数偏移量作为key,消息物理存储位置作为value,记录log文件中消息的位置。当消费一个offset时,根据offset,与segment文件名进行比较,segment文件名以当前segment最小的offset偏移量命名。从最后一个segment往前比较,如果比其小,则继续比较上一个,一旦找到比其大的,则根据(查找的offset-segment文件的offset+1)对该文件的index进行检索,采用二分法查找最近偏下的那条数据,再去原表的直接找对应物理地址的数据即可。采用稀疏索引是为了减小索引文件大小,采用从0开始的数据作为key而不选择偏移量存储直接寻址也是为了减少索引文件大小。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦㐅触及轮回

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值