赞
踩
发现问题的小伙伴可以随时评论或私信我进行修改,愿意扩大题库的小伙伴也可以随时私信我嗷。愿大家都能找到期望的工作。
相同:都是一端生产数据,一端消费数据
不同:生产者-消费者,同一类别下,消费者拿到的都是一样的数据;发布-订阅,订阅者只拿自己感兴趣的数据。
(1)增加数据可靠性和持久性:采用了分布式复制机制,将消息副本分布到不同的Broker节点上,并确保故障发生时的数据可恢复性。
(2)高吞吐量和低延迟:处理大量的消息并能够提供毫秒级的延迟,适用于实时数据流处理和高负载场景。
(3)分布式流处理:Kafka不仅仅是一个消息队列,还是一个流处理平台。它支持对数据流进行实时处理、转换和聚合,可以构建复杂的流处理应用程序。
(4)水平扩展和负载均衡:通过增加Broker节点来处理更多的消息和请求。
(5)数据持久化和回溯能力:将消息持久化存储在磁盘上,保证数据的可靠性和持久性。
高性能:单一的Kafka代理可以处理成千上万的客户端,每秒处理数兆字节的读写操作,Kafka性能远超过传统的消息队列
可扩展性:提供透明扩展,增加新的服务器进集群
容错性:每个分区有多个副本保障数据安全性
持久性:提供数据的磁盘存储
Kafka是一种分布式流处理平台,可以处理大规模动作流数据,主要应用于大数据实时处理,具有高吞吐量、低延迟和持久化的特点。
主要作用有:
(1)消息传递系统;因为它具有高吞吐量和低延迟的特点,能够在分布式系统中可靠地传输大量数据消息。
(2)流处理平台:Kafka支持实时数据流处理,在数据流中进行转换、聚合和分析,并将结果输出到其他系统中。
(3) 存储系统;Kafka可持久化存储,可以将数据持久保存在磁盘上,以便进行后续的处理和分析。
基于以上作用,可以应用于日志的收集聚合、实时检测分析系统、消息队列、事件驱动架构等场景。
Producer:生产者,就是向kafka broker发消息的客户端。
Consumer:消费者,向kafka broker取消息的客户端。
Consumer Group:消费者组,由1个或n个consumer组成,消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。
Broker:一台kafka服务器就是一个broker。
Topic:消费主题,可以理解为一个队列,生产者和消费者面向的都是一个topic。
Partition:为了实现扩展性,一个topic可以分为多个partition,分布到多个broker(即服务器)上。
Replication:为了实现Partition的可靠性,一个Partition会保留多个Replication,分为一个leader和若干个follower;其中leader是Producer发送数据的对象,以及Consumer消费数据的对象。
Zookeeper:用于leader选举和follower信息同步、Broker的管理、Topic维护、生产者负载均衡、消费者负载均衡,在0.9版本之前还存储Customer的消费的offset。
Kafka由生产者、Broker集群和消费者组成。
其中消息以Topic分类,每个Topic可以看做是一个队列,为提高其扩展性、安全性以及并发能力,每个Topic由多个Partition组成。
每个Partition有多个副本,分为leader和follower,leader负责读写,follower与leader数据保持同步,以做容错作用。同时为了防止文件过大,partition分为了多个segment,每个segment由一个.index文件和.log文件组成,存储在同一个文件夹:topic名字-分区号。
消费者则是以组为单位消费数据,消费者组内的消费者消费不同的Partition,每个Partition只能组内一个消费者消费,消费者组之间互不影响,消费者会记录每一次消费的offset。
同时还有zookeeper提供broker管理,topic管理,leader选举等服务。
(1)吞吐量高,单机TPS约在百万条/秒
(2)时效性高,毫秒级
(3)可用性高,每个数据有多个副本
(4)消费者采用pull方式,通过控制能保证所有消息精准一次消费
(5)在日志领域比较成熟
(1)队列越多,load时间越长,发送消息响应时间变长。
(2)使用轮询方式时,实时性取决于轮询间隔时间。
(3)相对较大的存储需求:支持持久性,并且为了保证高可靠性,数据有多个副本,因此需要较大的存储容量。
(4)不适用小规模数据:kafka结构较为复杂,对于小规模应用而言,显得复杂笨重。
(5)数据顺序保证局限性:保证了同一分区内消息的顺序性,但对于跨分区的消息顺序性无法保证。
单播:一条消息只能被同一个消费者组中的一个消费者消费
多播:一条消息能被多个消费者组中的消费者共同消费
LEO (Log End Offset):LEO 是指当前分区中日志的最高偏移量。
HW (High Watermark):HW 是指消费者组能够读取的最大偏移量。
每个副本(leader/follow)都会有自己的LEO,表示当前自身数据的最大偏移量,HW则表示目前该分区对消费者组可见的最大偏移量,取的是所有副本的最小LEO(木桶原理),除了保存自身LEO外,还保存了其他follower的LEO,一般称为副本LEO。
概念 | 作用 | 每个角色更新时机 | |
LEO | 副本写入下一条消息的位移值 | leader | 接受到生产者消息落盘后 |
follower | 从leader拉取消息落盘后 | ||
远程副本(leader存储) | follower从leader拉取消息时,会告诉leader拉取起始位置,即为该值 | ||
HW |
| leader | 自身更新LEO后 |
更新完远程副本的LEO后 | |||
follower | 自身LEO更新完后,取min(LEO,HW) |
每个副本都有一个HW和一个LEO,LEO是每个副本末端偏移量,HW则是表示该Partition对外服务的最大位移量(木桶原理,木桶装多少水取决于最短的木板有多长)。
Kafka中leader的选举由controller管理。旧的leader挂掉后,被Zookeeper监听到,注销掉相应节点,通知controller开始选举新的leader。首先确定挂掉的leader的ISR队列中有哪些follower,这些follower抢占式在Zookeeper创建节点,谁先创建谁作为新的leader,所有follower删除HW以上的消息,重新向新的leader同步数据。
ISR(InSyncRepli):内部副本同步队列;
OSR(OutSyncRepli):外部副本同步队列;
AR(AllRepli):所有副本;AR = ISR + OSR;
任意一个超过延迟时间或延迟条数阈值的follower都会被剔除出ISR, 存入OSR列表,新加入的follower也会先存放在OSR中。
为避免因某个副本的follower故障不能同步数据而造成leader一直等待,leader维护了一个列表,为保持同leader同步的follower集合,该集合中副本和leader相差数据不超过一个阈值(可设置),超出一定时间数据未达到该阈值,则follower会被踢出ISR。ISR主要在leader出现故障后作为选举新leader的备用池。
三种:
0 - 生产者向leader发送数据后即视为leader已经成功接收数据登上,有数据丢失风险
1 - leader接收数据写入后,向生产者发送确认信息。如果leader返回ack后还未向follower同步消息而挂掉,会造成数据丢失情况。
-1/all - leader收到数据后,向所有follower发送数据,等所有follower数据罗盘后再向生产者回复确认信息。如果follower同步完消息还未向生产者发送确认信息时leader挂掉,则可能数据重复。
生产者:Kafka存在幂等性机制,Produce初始化时会有一个PID,向同一个partition发送数据时会带有一个sequence number,borker端会对<PID,partition, seq>缓存起来,produce多次发送时,broker会保证只消费一条数据。但只能保证在同一会话中有效。
消费者:将消费过程和提交offset过程做原子绑定,保存到支持事务的自定义介质中(比如MySQL)。
生产者:ack设为-1/all
消费者:设置消费者手动提交offset
同上个问题合并就保证了exactly-one语义
(1)RoundRobin(轮询)
kafka默认策略,对所有分区和所有消费者循环分配,分区更均衡。
(2)Range(平均)
以Topic为单位,以数据顺序排列可用分区,以字典顺序排列消费者,将topic分区数除以消费者总数,以确定分配给每个消费者的分区数;如果没有平均分配,那么前几个消费者将拥有一个额外的分区。
(3)Sticky(粘性分配,0.11后出现)
当触发重新分配时(消费者组中消费者数量发生变化),尽可能保留现有分配,将已经终止的消费者所分配的分区移动到另一个消费者,避免全部分区重新平衡,节省开销(不知道这个的小伙伴可以找下相关例子,这里座作为面试回答,不做详细讲解)。
(1)一个消费者组有n个消费者
(2)一个消费者组内,一个分区只能由一个消费者消费
(3)一个消费者组,所有消费者组合起来消费一个Topic下所有分区
(4)一个消费者组内,一个消费者可消费多个分区
(5)分区通过分配算法分配给一个组内的消费者,消费者消费时会有一个offset来保存自己的消费位置
0.9版本之前zookeeper管理,0.9之后由kafka在broker中名为__consumer_offsets的topic中
offset+1
消费者消费后没有提交offset(程序崩溃/强行kill/消费耗时/自动提交偏移情况下unsubscrible)。
消费者没有处理完消息就提交offset(自动提交偏移 未处理情况下程序异常结束)。
创建:在zk上/brokers/topics/下创建一个新的topic节点,然后触发Controller的监听程序,kafkabroker会监听节点变化创建topic,kafka Controller 负责topic的创建工作,并更新metadata cache
删除:调用脚本删除topic会在zk上将topic设置待删除标志,kafka后台有定时的线程会扫描所有需要删除的topic进行删除,也可以设置一个配置server.properties的delete.topic.enable=true直接删除
只能增加,不能减少。
kafka的offset不是为单个消费者存的,是为消费者组存的
groupid-topic-partition -> offset
可以给offset提交设置失败后重复提交,如果依旧提交失败,就要进行人工干预了
先看current-offset,再看auto.offset.reset
current-offset表示消费者消费了数据之后提交的offset;
auto.offset.reset表示消费者在初始化或偏移发生故障时的起始位置。
current-offset | auto.offset.reset | 开始位置 |
unknown | earliest | 从该分区当前最开始的offset消息开始消费 |
latest | 只消费当前消费者启动完成后生产者新生产的数据 | |
none | 启动消费者时,该消费者所消费的主题的分区没有被消费过,就会抛异常 | |
known | earliest/latest/none | 不考虑auto.offset.reset配置,直接从current-offset一直消费到log-end-offset。也就是不会更新offset。 |
性能:为了实现水平扩展和提供高吞吐量的消息处理能力
灵活:不同的组合方式,可以实现不同的效果,比如每个消费者组只有一个消费者,同时消费一个主题,可以实现订阅-广播模式
容灾:如果只有一个消费者,出现问题就是灾难性的;消费者组的话,组内消费者出现问题,它的消费任务,可以被分配到其他消费者。
(1)创建ProducerRecord(以下记为PR)对象,包含Topic和要发送的内容,还可以指定key或分区。
(2)调用拦截器来对消息进行相应的定制化操作。
(3)发送PR时,生产者先把key-value序列化成字节数组,这样才能在网络上传输。
(4)数据被传给分区器,如果有key,则按照hash返回分区,如果没有key,则按照某种策略(默认轮询)。
(5)选好分区后,信息被添加到一个记录的批次里(Segment),这个批次里的所有消息都会被发送的相同的主题分区上,Broker 会为消息生成一个 Offsets(在 Partition 内唯一标识消息的数字),Producer 可以通过检查 Offsets 来确认消息是否已被正确写入 Kafka Topic。
(6)如果发送消息的过程中出现错误或异常,Producer 可以选择重试、忽略或处理失败。
优点:灵活控制消费速率;批量拉取提高效率。
缺点:需要消费者不断进行主动拉取,会增加网络负担;消费者长时间不拉取或拉取速度过慢情况下,可能导致信息阻塞。
(1)消息中间件
副本机制。
(2)ISR
只有与leader数据相差在阈值以内的副本才有可能被选为leader。
(1)主线程
负责初始化和设置 Producer 的配置,创建 KafkaProducer 实例,并处理用户发送的消息等。主线程还负责管理其他后台线程。
(2)IO线程
负责与 Kafka Broker 进行网络通信,将消息发送到指定的主题分区。
(3)超时检测线程
通过参数设置。
(1)KafkaUtils
适用于数据的吞吐量要求不是很高,且不需要精确控制分区读取和处理。
(2)Direct
允许直接从 Kafka 分区读取数据,并将其作为 RDD 在 Spark Streaming 中进行处理;适用于高吞吐量,低延迟的场景,可以实现精准分区读取和负载均衡
(3)Receiver
通过在 Spark Streaming Application 中创建 Kafka Receiver 来读取 Kafka 数据,并将其作为 DStream 在 Spark Streaming 中处理;适用于低吞吐量且对数据处理的可靠性要求较高的场景,通过数据复制和容错机制来保证数据处理的可靠性。
(4)结合 Spark Structured Streaming 和 Kafka
Spark 2.0 及以上版本引入了 Structured Streaming,可以直接集成 Kafka,并使用高级的结构化 API 处理流数据;适用于需要更复杂的流数据处理逻辑和数据转换的场景。
依次顺序:拦截器、序列化器、分区器
拦截器:用来在消息发送前做一些准备工作,如过滤,修改,定制化。
序列化器:将key和value序列化成字节数组,以便进行网络传输。
分区器:如果制定了partition字段,就不需要分区器作用;默认调用两个方法,partition(~)方法,参数分别表示主题、键、序列化后的键、值、序列化后的值以及集群的元数据信息,返回值为分区号;close()方法,关闭分区器并回收一些资源。
角色 | 说明 | 选举过程 |
controller | 在 ZooKeeper 的帮助下管理和协调整个 Kafka 集群,集群中的每个 broker 都可以成为 controller,但是在 Kafka 集群启动后,只有一个 broker 会成为 Controller。 | 第一个启动的broker通过在ZooKeeper里创建一个临时节点 /controller 让自己成为controller,其他broker创建时发现已经存在节点,则注册一个zookeeper的watch对象,如果/controller发生变化,其他broker则收到通知 |
leader | 副本的leader选举 | unclean.leader.election.enable参数为false时,在ISR中选择一个作为新的leader,一般leader有一个首选副本 ISR为空时,允许从OSR中选择副本作为leader |
消费者组leader | 群组协调器是一个能够从消费者群组中收到所有消费者发送心跳消息的 broker | 第一个加入消费组的消费者即为消费组的leader |
Produce的生产主要是一个producer线程和sender线程,通过BatchQueue来获取数据,过程是异步的,因此称为蓄水池。
如果指定了partition key,然后根据其hash分区,如果没有指定key,则采用轮询方法,除此之外还可以自定义分区规则。
可以。
过程:
(1)topic 此时正在生产或消费的话,则这些生产和消费程序需要停止;(避免topic的offset信息一直在broker更新。调用kafka delete命令则无法删除该topic)
(2)设置 auto.create.topics.enable = false;(该值为true时,produce或者fetch不存在的topic会自动创建这个topic。)
(3)server.properties 设置 delete.topic.enable=true;(如果没有设置,则调用kafka 的delete命令无法真正将topic删除,而是显示(marked for deletion))
(4)调用命令删除topic:
./bin/kafka-topics --delete --zookeeper 【zookeeper server:port】 --topic 【topic name】
(5)删除kafka存储目录(server.properties文件log.dirs配置,默认为"/data/kafka-logs")相关topic的数据目录。
(6)如果还未删除干净
在zk节点登录zk shell,找到topic所在目录rmr /brokers/topics/【topic name】
(7) 完成后使用命令./bin/kafka-topics.sh --list --zookeeper 【zookeeper server:port】查看
如果还可以看到,重启kafka和zk即可
工具:
(1)JMX实现
可通过JConsole、VisualVM 等查看Broker、Topic、Partition、Consumer Group 等的各项指标。
(2)Kafka 自带的监控工具
(3)日志文件的监控
监控方向:
消费者:存活告警,消费滞后告警
生产者:存活告警,生产者消费上游数据能力告警
broker:存活告警,流量告警,isr列表,topic异常告警,control变换告警
定长的Header:校验码,消息属性,时间戳等
变长的Body:数据
方法:根据已保存时间;根据log设置的max size。
过程:定期检查每个log段的最大时间戳/文件大小;达到阈值的添加删除标记;整个log消费完后,在后台进程执行真正的删除操作。
在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从而实现的是一种主写主读的生产消费模型。不采用读写分离是因为两点原因:
(1)数据一致性问题
数据从主节点转到从节点必然会有一个延时的时间窗口,这个时间 窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A 数据的值都为 X, 之后将主节点中 A 的值修改为 Y,那么在这个变更通知到从节点之前,应用读取从节点中的 A 数据的值并不为最新的 Y,由此便产生了数据不一致的问题。
(2)延时问题
类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程需要经 历网络→主节点内存→网络→从节点内存这几个阶段,整个过程会耗费一定的时间。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历网络→主节点内存→主节点磁盘→网络→从节 点内存→从节点磁盘这几个阶段。对延时敏感的应用而言,主写从读的功能并不太适用。
(1)顺序写
(2)PageCache缓存
(3)批量以流的形式传输消息,速度可达网络上限
(4)Pull 拉模式 使用拉模式进行消息的获取消费,与消费端处理能力相符。
(5)零拷贝技术
零拷贝技术扩展:
平时应用程序读取磁盘数据时,服务器先切换为内核态读取文件,再切为用户态将文件复制到用户缓存,写入Socket时,要再切到内核态发往网卡。
零拷贝技术在磁盘数据被读到内核区缓存中时,操作系统将这块缓存直接共享给应用程序(少一次复制),用户程序调用write,直接把数据拷贝到Socket
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。