一、概述
(一)、kafka的定义
1、定义
1)kafka传统的定义:kafka是一个分布式的基于发布/订阅模式的消息队列,主要用于大数据实时处理领域
2)kafka最新的定义:kafka是一个开源的分布式事件流平台(event stream platform),主要用高性能数据管道,流分析,数据集成和关键任务等领域
2、消息队列
目前市面上大部分公司采用的消息队列主要有kafka,activeMQ,rabbitMQ,rocketMQ等。kafka作为消息队列,主要应用于大数据场景下,而在Javaee开发中更多采用的是activeMQ,rabbitMQ,rockectMQ等。
3、消息队列的应用场景
传统的消息队列的主要应用场景包括:缓冲/削峰,解耦和异步通信
缓冲/削峰:在实际的应用系统中,如果数据生产端(比如其前端)的数据产生的速率与数据处理端(服务端)的数据处理速率相当或小于时,整合系统运行就不会有很大的压力。但是当系统上了个秒杀活动或者双11活动到来,前端用户猛增,数据率随之也会增加数倍,甚至是数十倍。但是服务端需要对数据进行处理,持久化等操作,处理速率必然跟不上数据产生的速度,久而久之系统就会产生数据积压,最终就有可能导致系统的崩溃。在数据生产端和处理端之间使用消息队列就可以解决这种问题。此时,消息队列就发挥了不同系统之间数据的缓冲和削峰的作用。数据生产端将数据发送到消息队列,然后随即返回响应,这个过程相对来说是非常快的。数据处理端则根据自己的处理速度从消息队列中拉取数据。示意图如下:
编辑 切换为居中
不使用消息队列的情况
编辑 切换为居中
使用消息队列的情况
解耦:允许独立的拓展和修改两边的处理过程,但两边需要确保使用相同的接口约束。
编辑 切换为居中
异步通信:将处理的用户数据写入到消息队列中,并立即返回处理结果,队列中数据由另一个线程拉取出来做响应的处理。下面是用户注册,并把注册成功的消息发送到用户手机上的同步处理和异步处理的流程。想学习交流HashMap,nginx、dubbo、Spring MVC,分布式、高性能高可用、MySQL,redis、jvm、多线程、netty、kafka、的加尉(同英):1253431195 扩列获取资料学习,无工作经验不要加哦!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-40gK75Wj-1646732688895)(https://upload-images.jianshu.io/upload_images/27509882-f4335982b273464d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
编辑 切换为居中
(二)、kafka基础架构
1、消息队列的两种模式
1)点对点模式
- 消费者主动拉取数据,数据消费完后就会在队列中删除
2)发布/订阅模式
-
可以有有多个主题(topic)
-
消费者拉取数据消费完后,不删除数据
-
每个消费者相互独立,都可以消费到数据
2、基础架构
编辑 切换为居中
1)producer:消息生产者,就是向broker发送消息的客户端
2)consumer:消息消费者,就是从broker拉取数据的客户端
3)consumer group:消费者组,由多个消费者consumer组成。消费者组内每个消费者负责消费不同的分区,一个分区只能由同一个消费者组内的一个消费者消费;消费者组之间相互独立,互不影响。所有的消费者都属于某个消费者组,即消费者组是一个逻辑上的订阅者。想学习交流HashMap,nginx、dubbo、Spring MVC,分布式、高性能高可用、MySQL,redis、jvm、多线程、netty、kafka、的加尉(同英):1253431195 扩列获取资料学习,无工作经验不要加哦!
4)broker:一台服务器就是一个broker,一个集群由多个broker组成,一个broker可以有多个topic。
5)topic:可以理解为一个队列,所有的生产者和消费者都是面向topic的。
6)partition:分区,kafka中的topic为了提高拓展性和实现高可用而将它分布到不同的broker中,一个topic可以分为多个partition,每个partition都是有序的,即消息发送到队列的顺序跟消费时拉取到的顺序是一致的。
7)replication:副本。一个topic对应的分区partition可以有多个副本,多个副本中只有一个为leader,其余的为follower。为了保证数据的高可用性,leader和follower会尽量均匀的分布在各个broker中,避免了leader所在的服务器宕机而导致topic不可用的问题。
8)leader:多个副本的主副本,生产者发送的数据和消费者消费的数据都是通过leader进行处理的。
9)follower:多个副本中除了leader副本,其余的均为follower副本,也即从副本。从副本不会和生产者和消费者提供服务,而是实时同步主副本的数据。当主副本宕机后,通过一定算法选举出新的从副本成为主副本,继续为生产者和消费者提供服务。
(三)、kafka常用命令行操作
1、主题相关
编辑 切换为居中
2、生产者相关
编辑 切换为居中
3、消费者相关
编辑 切换为居中
二、生产者
(一)、重要参数列表
编辑 切换为居中
(二)、发送流程以及发送API
1、发送流程
编辑 切换为居中
(三)、分区
1、分区的好处
-
便于合理使用存储资源。每一个partition存储在不同的broker上面,可以把海量的数据切割成更小数据存储在不同的broker上。合理是分配分区的任务,可以实现负载均衡效果,避免单机数据量太大而导致的压力。
-
提高并行度。生产者可以以分区为单位发送数据;消费者可以以分区为单位消费数据。
编辑 切换为居中
2、分区策略
1)、默认分区策略:DefaultPartitioner
-
若生产者发送数据时指明partition,那么就会将该数据发送指定的分区,比如partition=0,则数据发送到第零个分区上
-
若没有指明partition,但是有key的情况下,用key的hashcode值与该topic对应的partition的数量进行取余得到partition,然后将数据发送到该分区上。比如:key的hashcode值为5,topic对应的分区数为3,那么 5 % 3 = 2,所以该数据应该发送到第二个分区。
-
既没有指定partition和key,kafka采用粘性分区器,会随机选择一个分区,然后尽可能使用该分区,指导该分区batch-size满了或已完成,然后再随机寻找另一个分区(与当前的分区不一样)。比如:这次随机到分区0,等当前批次满了或者linger.ms时间已到,kafka再随机一个分区,如果仍然随机到分区0则继续随机。
2)自定义分区器
在实际的企业应用中,可能会有不用的场景,默认的分区器无法满足需求,那么就需要自定也分区器来满足需求,比如某个分区的服务器性能比较好,另一个是比较久的服务器,性能相对差一点,那么就需要通过自定义分区器让更多的数据向性能更好的分区倾斜。
自定义分区器的实现:第一,定义类实现 Partitioner 接口。第二,重写partition()方法。第三,在生产者配置中指定自定义的分区器。
(四)、提高生产者的吞吐量
要想更好的提高生产者的吞吐量,则必须先了解生产者发送数据的流程,具体流程可以看靠(一)的介绍。以下是提高生产者的吞吐量的建议。
-
修改batch.size的大小。batch.size默认大小为16k,提高批次大小可以一定程度提高吞吐量。这就好比用小卡车拉货物和用大卡车拉货物,小卡车单位时间内不能一次拉完货物,那么来回就需要消耗额外时间,而大卡车一次性把货物拉走,那么就节省了来回的时间。
-
修改linger.ms的时间,默认为0,即直接发送数据,一般设置为5-100ms,通过设置延迟时间一次性可以发送更多的数据。
-
修改compression.type的数据压缩类型,默认snappy。根据不同的业务场景选择不同的数据压缩方法,提高数据压缩率。kafka提供的压缩类型有:gzip,snappy,lz4,zstd。
-
修改RecordAccumulator缓冲区的大小。默认32m,增加缓冲区大小可以那么每个batch.size的值就更大,每次发送的数据更多。
(五)、数据可靠性
数据的可靠性是指producer发送数据到kafka收到应答后,该数据都能成功落盘,那么这次发送是可靠的。但是,为了适应不用的应用场景以及实现高可用,kafka会将数据备份到不同的副本当中,在数据同步的过程中如果出现的故障,那么就有可能出现数据丢失,重复情况。想要弄清楚kafka数据可靠性,就必须先要了解kafka中ACK的应答原理。
1、ACK应答原理
ACK应答是指在leader分区接收到生产者的数据后,何时对生产者做出应答的策略。ACK可选的值有0,1,-1三个,可以在生产者的配置项 acks 中设置,ACK设置不同,对生产者做出应答的时机也不同。
ACK=0:可靠性级别最低。leader收到生产者数据后不需要等数据落盘,立即对生产者做出应答。生产者收到应答后认为leader已成功接收数据,因此不需要再发当前数据了。但是,如果leader在将内存中的数据落盘时突然出现故障,那么这条数据因为没有保存到磁盘中而导致数据的丢失。
ACK=1:可靠性级别较高。leader收到生产者的数据并将数据落盘后,对生产者做出应答。生产者收到应答后继续发送其他数据。如果leader做出应答并且follower未同步到该数据时,leader出现故障。kafka会重新在follower中选出新的leader,而新的leader心有同步到数据,生产者也不会再发该数据,因此导致该数据的丢失。
ACK=-1(all):可靠性级别最高,kafka的acks默认值。leader收到数据并落盘,并且确认所有follower收到数据后再给生产者应答。此时,所有分区副本都有该数据了,即使任意分区出现故障数据仍然是完整的。
(六)、数据去重
1、数据重复原因
在使用kafka时为了保证数据的高可靠性,我们一般都会将应答级别设置为-1(all),即leader的ISR列表的follower均收到数据后再应答。非常不幸的是,leader在收到所有的follower的确认后发生故障,所有的分区均已保存到磁盘中,但是生产者没有收到应答,认为leader没有收到生产者发送请求,于是尝试重新发送请求。由于leader发生故障,kafka重新选举leader,生产者将数据再一次发送到新的leader上,所以造成的数据重复。想学习交流HashMap,nginx、dubbo、Spring MVC,分布式、高性能高可用、MySQL,redis、jvm、多线程、netty、kafka、的加尉(同英):1253431195 扩列获取资料学习,无工作经验不要加哦!
编辑 切换为居中