1、ISR:是一个动态与leader保持同步的集群节点集合。
2、OSR:跟leader停滞过多的副本
3.AR:一个分区中所有的集合
1、HW:一个分区中最小的consumer能看到读取的最小的offset。
2、LEO:每个副本的最后一个offset、
kafka只能分区有序,不能全局有序。分区有序是因为每条消息都有一个offsets,每条消息都是直接追加大log文件尾端。
分区器:将一个topic数据分成多个partition数据,方便横向扩展和提高并发读写数据
序列化器:将数据在网络传输的时候序列化为字节流进行传输,保证数据不会丢失
拦截器:主要用于client端的定制化控制逻辑,例如生产者拦截器可以在消息发送前进行拦截某些不符合规则的消息,或者统计或者修改。
拦截器 -》序列化器-》分区器
生产者架构如图,使用了两个线程,分别是主线程和sender线程。
1、producer在主线程产生消息,然后通过拦截器、序列化器、分区器缓存到消息累加器RecordAccumulator,
2、sender线程从RecordAccumulator中获取数据然后发送到kafka中。
正确。一个分区只能被同一个消费者组里的一个consumer消费,如果消费者数大于分区的数,肯定有一个是没办法消费数据。
提交的是offset+1
1、当ack=-1的时候,当follower同步数据后,broker发送ack前故障了,导致没有ack返回producer,producer又会再发一次数据给新选举的leader,造成数据重复
2、手工管理offset的时候,没有提交offset。
1、手动管理offset的时候,先提交offset后消费。提交完offset后,还没消费之前,消费者宕机挂掉,等消费者重启后,读取的offset就是上次提交的offset后了。
2、ack=0时,broker还没写入磁盘就返回ack,当broker故障时,会有漏消费
3、当ack=1,当partition的leader落盘完数据后,follower同步完数据前就返回ack,这时候如果leader挂了,重新选举出的leader系统默认认为其是有了数据,不会重新发送。
4、副本只有1个的适合,一般副本所在的broker宕机,则可能丢失。
5、不清洁选举机制开启的时候,当全部ISR副本broker宕机后,会让OSR副本成为leader,OSR数据是不全的,就算新leader上线,也会被日志截断。
1、先在zookeeper的brokers/topics节点创建一个新的topic节点,例如、brokers/topics/first
2、触发controller的监听程序
3、kafka controller负责topic的创建,更新metadata cache
可以增加
1、通过配置文件启动
2、通过命令增加
/bin/kafka-topics.sh --zookeeper xx --alter --topic xx --partition 4
不可以减少,被删除的分区数难以处理。
有一个内部的_consumer_offsets ,用来保存消费者offset
一个topic有多个分区,一个消费组有多个消费者,所以需要将多分区分配给多个消费者。
kafka都是通过topic来分主题存放数据的,每个topic都有分区,每个分区对应一个文件夹,例如主题topic_name的文件夹有,topic_name-0,topic_name-1,topic_name-3。
每个文件夹内有五个文件:
1、.index 存放消息的物理地址的偏移量
2、.log文件存放消息数据
3、.timeindex映射时间戳和相对offsets的时间戳索引文件
4、.shaphost对幂等型或者事务型producer所生成的快照文件。
5、.leader_epoch_checkpoint 存放每一任leader开始写入消息的offset,会定时更新,
#十六 、如果我指定了一个offset,Kafka Controller怎么查找到对应的消息?
1、先用二分查找法找到对应的index文件,获取对应的物理偏移量offset
2、拿着物理offset去log文件顺序查找对应下消息
3、返回查找的消息。
负责管理集群的上下线,所有的topic副本分配和leader选举工作。
1、partition leader(ISR)
2、kafka controller(先到先得)
是指不能跟leader同步数据的副本,暂时被提出了ISR,需要等数据追上了leader后才能加入ISR。
被踢出ISR的副本,重启后跟leader通信后,需要将之间记录的hw后面的offset删除,然后与leader同步,等同步数据与leader一致后才能回到ISR。
1、分区,能够高并发读取topic数据
2、顺序写磁盘,直接追加文件末端,可以省去大量的磁头寻址时间。
3、index 文件中没有为数据文件中每条message建立索引,而是采取了稀疏存储的方式,每隔一定字节的数据建立一条索引,这也为了避免索引占用过多空间,从而可以将索引文件保留再内存中。
4、零拷贝。通过依赖sendfile()方法实现零拷贝,将数据直接从磁盘文件中复制到网卡设备中,不需要应用程序经手,大大提高了应用程序的性能。
5、批量发送,kafka不是实时对每条消息发送的,而是对消息进行积压,等积压到了一定值才会批量发送。
1、Kafka消费能力不足,可以考虑通过增加topic分区数,同时提高消费组的数量,消费组数量=分区数
2、如果是下游数据处理不及时, 可以提高每次拉取的消息量,使得 拉取数据量/处理时间=数据处理速度 > =生产速度就行
7天
kafka官方自带压测测试脚本(kafka-consumer-perf-test.sh)(kafa-producer-perf-test.sh)
主要是看哪个地方出现了瓶颈(cpu,内存,网络),一般是网络IO瓶颈。
一般将唯一标识保存在外部介质中例如redis,每次消费判断是否被消费过即可。
kafka作用是解耦,如果直接从日志服务器上采集数据,实时离线都需要采集,等于要采集两份。而用了kafka只要采集一份就行,然后用两个不同的consumer group 读取同一个topic就行。
1、分区性:存储不受单一服务器存储空间限制
2、高可用性:副本以及leader的选举
3、消息有序性:一个分区内的数据是有序的
4、负载均衡性:分区内的一条消息,只会被消费组的一个消费者消费,主题topic的消息会均衡的发送给消费组里所有的消费组进行消费。
1、高吞吐、低延迟:kafka每秒可以处理几十万条消息,最低延迟只有几毫秒,每个topic可以分为多个partition。
2、可扩展性:kafka集群支持热扩展
3、持久性、可靠性:消息被持久化存在磁盘中,并且支持数据备份防止数据丢失
4、容错性:允许集群中节点失败(若副本数为n,允许n-1个节点失败)
5、高并发:支持数千个客户端同时读写。
1、日志收集系统,用kafka收集各种服务日志,然后通过kafka以统一接口服务开发给各种consumer,例如hadoop,spark
2、消息系统:解耦生产者和消费组、缓存消息
3、用户活动跟踪:kafka可以被用来记录web用户或者app各种用户的活动例如网页浏览、搜索点击等活动,这些活动信息被各个服务器发送到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析。
4、流式处理:例如spark streaming 或者是flink
对集群好处:实现负载均衡
对消费者好处:高并发读取数据,提高效率。
kafka消息写入的时候是顺序写入,带有偏移量。
consumer读取消息的时候是按偏移量从前往后读取的,所以保证了分区内消息的有序性。但是无法全局有序性
可以
TopicPartition p = new TopicPartition(“test6”, 2);
consumer.assign(Arrays.asList§);//只消费分区号为2的分区
consumer.subscribe(Arrays.asList(“test6”));//消费topic 消费全部分区
consumer.seekToBeginning(Arrays.asList§);//重头开始消费
consumer.seek(p,5);//指定从topic的分区的某个offset开始消费
1、kafka把topic中一个partition文件分成多个小段,容易定期清理以及删除文件,减少磁盘占用。同时避免大文件查找低效率。
2、通过索引文件可以快速定位message和reponse的最大大小
3、通过index元数据全部映射到memory,避免segment file 的IO磁盘瓶颈
4、通过索引文件稀疏存储,大幅降低了index文件占用空间大小。
当log.dir只配置了一个文件路径,就在这个路径下创建
当log.dir配置了多个路径,会选择分区文件夹总数最少的目录,而不是选择磁盘占用量最小的。会一致在这里创建文件直到该路径分区文件夹总数不是最少的位置。
每一个consumer group 会从group内的broker选出一个broker当作coordinator协调者角色,coordinator 会对整个consumer group 的状态进行管理。
当consumer group 发送成员变化或者consumer group订阅的topic数或者topic分区数发送变化时,就会出发rebalance操作,coordinator 就会生成新的分区分配方案。
rebalance本质是一组协议,kafka新版本提供了5个协议处理rebalance。
1、join group :consumer请求加入组
2、leave group : consumer 请求离开组
3、heartbeat :consumer 定期 向coordinator 汇报心跳表示自己还活着。
4、sync group :group leader 把分配方案发送给组内成员.
5、describe group :查看组内所有信息
rebalance流程;
1、consumer group 先确认coordinator 所在的broker位置,所有的成员与coordinator 创建scoket 连接。
2、加入组:group内所有consumer向coordinator发送join group 请求,当收集完全join group 后,coordinator从中选一个consumer 作为group 的leader,把所有的成员信息和订阅topic信息发给leader。(leader是consumer的实例。coordinator是broker的实例)。leader为整个group 的consumer 成员制定分配方案。
3、同步更新分配方案:leader将分配方案封装为syncGROUP请求发送给coordinator(所有成员都会发sync group请求,但是只有leader有分配方案)。coordinator收到所有请求后把每个方案抽取出来然后单独作为sync group 的请求的response返回给各个consumer。
partition数=consumer数 ,一个consumer 一个partition
partition < consumer 数,一个consumer 一个partition, 多的consumer没有partition
partition > consumer 数,某个某些consumer承担多点partition
可以动态感知,但不是马上知道。
通过topic.metadata.refresh.interval.ms参数决定。当用户修改了主题分区数后,在topic.metadata.refresh.interval.ms 时间后可以感知到。设为负值,仅失败感知刷新元数据,0时每条消息都刷元数据,xxms时,xxms后冲刷元数据。
要安装插件
kafkaOffsetMionitor
kafkaManager
kafka Web Console
kafka Eagle
幂等性是用来解决exactly one 的,
在引入幂等性之前,kafka producer第一次将消息(x2,y2)发送给broker,broker将(x2,y2) 追加到了消息流中,但是返回ack给producer的时候因为网络异常失败了,这时候producer会触发重试机制重新发送消息给broker,broker就再次把消息(x2,y2)追加到消息流中,这样消息流就有两条重复消息了。
引入幂等性后,kafka在底层就引入了producerID(PID)和sequenceNumber。
PID:每个producer 初始化就会被分配一个pid,pid对客户端是不可见的
sequenceNumber:对每个pid,producer 发送的数据的每个partition和topic都对应着从0开始递增的sequenceNumber值。
例如发送消息(x2,y2)(pid=100,sequence=1),第一次broker返回ack失败后,producer再次发送该消息(x2,y2)(pid=100,sequence=1),但是因为之前broker缓冲过相同的pid和sequence Number,所以两条信息只会保留一条。
kafka事务前提是要提供唯一的transactionalld,这个设置是要通过客户端参数transactional.id来设置,以及要求producer开启幂等性。
kafka事务作用:1、producer多次发送消息可以封装为一个原子操作,即同时成功或者同时失败。2、将消息生产和消费消息两个操作封装在一个事务中,形成一个原子操作,即生产和消费必须同时成功。
producer定义了五种事务方法在producer,分别是initTransactions和beginTransaction,sendOffsetsToTransaction,commitTransaction,abortTransaction定义在clients.producer.Producer《K,V》中。
kafka事务性一般不使用在consumer,因为跟手动提交offsets结果是一样的。这种场景不是事务引入的目的。
1、是批量,不是真正实时
2、对mqtt协议不支持
3、不支持物联网设备直接接入
4、仅支持分区内有序, 不支持全局有序
5、监控不完善,需要安装插件
6、依赖zookeeper进行元数据管理。
可以用/bin/kafka-topics 增加分区,但是不支持减少分区,因为减少分区的数据不知道如何处理,是删除还是保留,删除的话那没消费的数据就丢失了,保留的话那这些数据放到哪个分区,如何放进去,如果直接追加的话,就破坏了分区有序性,这个逻辑非常复杂。