kafka集群controller的选举机制:
kafka从broker中选出一个controller,所有的broker会尝试在zookeeper中创建临时节点/controller,谁先创建成功,谁就是leader
如果controller挂掉(网络出现问题),临时节点就会消失,其他的broker就会通过watch机制监听到controller下线的通知
然后就会按照之前的谁先创建/controller临时节点谁就是leader的原则,进行重新选择controller,只有在ISR中保持心跳同步的副本才有资格参与竞选,leader选举,类似蛇形走位,默认让ISR中的第一个副本成为leader
ISR机制:
能够和leader保持同步的follower+leader本身组成的集合
broker成为controller后会有以下职责:
1、监听broker变化
2、监听topic变化
3、监听partition变化
4、获取和管理broker、topic、partition的信息
5、管理partition的主从信息
leader负责对分区的读写,follower负责同步leader分区数据
kafka零拷贝:
应用程序可以直接把磁盘中的数据从内核中直接传输给socket,减少了拷贝次数
并不是完全没有个数据赋值,只是相对于用户空间来说,不在需要进行数据拷贝了
kafkacaiyongsendfile()方式
在程序中实现零拷贝的方式:
1、在linux中,零拷贝技术依赖底层sendfile()方法实现
2、在java中,引用方法实现
3、mmap文件映射机制
可以省区用户空间的拷贝次数(2次),从而提升i/o性能
1、概念:
kafka是一个用scala语言编写的,分布式、支持分区(partition)、多副本(replica),基于zookeeper协调分布式消息系统,它最大的特性就是可以实时处理大量数据以满足各种需求场景,比如基于hadoop的批处理系统、Spark流式处理引擎、web/nginx的日志
2、kafka特性:
高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
可扩展性:kafka集群支持热扩展
持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
高并发:支持数千个客户端同时读写
3、kafka场景应用:
消息系统:解耦和生产者和消费者、缓存消息等
用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,
然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘
流式处理:比如spark streaming和storm
4、kafka一些重要设计思想:
4.1、consumergroup:
各个consumer组成一个组,每个消息只能被组内的一个consumer消费,如果一个消息可以被多个consumer消费的话,那么这些consumer必须在不用的组里
4.2、消息状态
在kafka中,消息的状态被保存在consumer中,通过offset值指定下一个被消费的消息位置
4.3、消息持久化
kafka将消息持久化道本地文件系统中,并保持极高的效率
4.4、消息有效期
kafka会长久保留其中的消息,以便consumer可以多次消费,其中的细节可以配置
4.5、批量发送
kafka支持以消息集合为单位进行批量发送,以提高push效率
4.6、push-and-pull
kafka中的producer和consumer采用push-and-pull模式
生产者只管向broker push消息
消费者只管从broker pull消息
2者对消息的生产和消费是异步的
4.7、kafka集群中broker之间的关系
集群中的broker地位是一样的,我们可以随意的增加和删除任何一个broker节点
4.8、负载均衡方面
kafka提供了一个metadata api来管理broker之间的负载(8.x以后是内置zookeeper,7.x之前是要单独部署zookeeper)
4.9、同步异步
producer采用异步push方式,极大提高了kafka系统的吞吐量(可以通过控制参数采用同步还是异步)
4.10、分区机制partition
kafka的broker端支持消息分区,producer可以决定把消息分到哪个区,在一个分区中消息的顺序就是producer发送消息的顺序
4.11、离线数据装载
kafka由于对可拓展的数据持计划的支持,它非常适合向hadoop或数据仓库进行数据装载
4.12、插件支持
有不少插件拓展了kafka功能,用来配合hadoop、flume、storm相关的插件
5、消息队列通信模式
5.1、点对点
点对点模式通常是基于拉取或者轮询的消息传送模型
模型特点:消息发送到队列,被一个且一个消费者进行消费(offset值),生产者将消息放入队列后,有消费者主动拉取消息进行消费(消费后数据从队列删除)
优点:消费者拉取消息的频率可以由自己控制
队列模型:
生产者产消息 ➡️ 消息队列 ➡️ 消费者主动拉取数据(pull)
消息队列中是否有消息需要消费,在消费者端无法感知,需要消费者端额外的线程去监控
5.2、发布订阅模式
发布订阅模式是一个基于主动发送的消息传送模型,该模型可以有多种不同的订阅者
模型特点:消息发送到队列后,可以被订阅过该消息的多个消费者进行消费(offset值)
缺点:消费者的机器性能不一样,所以处理消息的能力也不一样,更改producer配置文件可设置数据发送速度(kafka缓存数据批量发送)
消息是消费者被动接收的,所以无需感知消息队列中是否有待消费的消息
队列模型:
生产者产消息 ➡️ 消息队列(push) ➡️ 多个订阅的消费者
6、kafka的架构原理
基础架构和名称解释
架构:
producer ➡️➡️➡️ kafka cluster(broker0(topci A、topic B)、broker1、broker2) ➡️➡️➡️ consumer
⬇️⬇️⬇️⬇️⬇️
zookeeper
名词解释:
producer:生产者
broker:kafka的实例,对应服务器
topic:消息的主题,数据就存放在topic中
partition:topic的分区,分区的作用就是负载,提供kafka的吞吐量
replication:每一个分区都有多个副本,副本的作用就是备胎,当leader出现故障时会有备胎(follower)成为leader,默认最大副本数10个,副本数不能大于broker数量
message:消息主体
consumer:消费者
consumer group:将多个消费组组成一个消费者组,
在kafka中同一个分区中的数据只能被消费者组中的一个消费者消费,
同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!
zookeeper:kafka集群依赖zookeeper来保存集群的元数据,来保证系统的可用性
工作流程分析:
1、写入数据时,先从集群获取分区的leader,在发送数据
2、leader将消息写入本地(producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘)
3、follower从leader处拉取(pull)消息,写入本地后向leader发送ack
分区的主要目的:
1、方便扩展
因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松应对日益增长的数据量
2、提高兵法
以partition为读写单位,多个消费者可以同时消费数据,提高消息的处理效率
kafka怎么知道该将数据写入到哪个partition?
1、写入时指定partition
2、没有指定partition,但是设置了数据的key,则会更具key的hash值出一个partition
3、partition,key都没有设置,则会轮询选出一个partiton
kafka如何保持数据写入不会丢失?
ack应答机制
producer向队列写入数据时,可以设置参数来确认kafka接收到数据
0代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功,安全性最低,效率最高
1代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader成功
all代表producer往集群发送数据需要所有follower都完成从leade同步,才会发送下一条,安全性最高,效率最低
如果往不存的topic写数据,kafka会自动创建topic,分区和副本默认是1
保持数据:
kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高)
partition结构:
一个topic下可以有一个或多个partition,partition在磁盘上的表现形式就是一个一个的文件夹
每个partition下面有多个segment文件,每组segment文件包含.index文件、.log文件、.timeindex文件三个文件
log文件是实际存储message的地方,index和timeindex文件为索引文件用于检索信息
查找数据:
1、先找到offset为368801message所在的segment文件
2、打开segment中的.index文件,查看文件起始偏移量,在查找咱们要的数据
利用segment+有序offset+稀疏索引+二分查找+顺序查找等多种手段来高效的查找数据
message结构:
消息主体主要包含offset、消息大小、消息体等等
offset是一个占8byte的有序id号,通过id号可以确认消息在partition中的位置
消息大小占4byte,用于描述消息的大小
消息体存放的是实际的消息数据(被压缩过)
存储策略:
无论消息是否被消费,kafka都会保存所有消息,那么对旧的消息有什么删除策略?
1、基于时间,默认是7天(168小时)
2、基于大小(单位字节)
需要注意的是删除过期文件并不会提高kafka性能
消费数据:
消息存储在log文件后,消费者可以进行消费了
kafka采用发布订阅模式,消费者驻地哦那个的去kafka集群拉取消息(找leader去拉)
在实际应用场景中,建议吧consumer的数量设置成与partition数量一致