1、kafka定义
kafka是一个开源的分布式事件流平台
2.为什要使用kafka?
1.缓冲和削峰:上游数据时有突发流量,下游可能虹不住,或者下游没有足够多的机器来保证冗
余,kafka在中间可以起到一个缓冲的作用,把消息暂存在kafka中,下游服务就可以按照自己
的节奏进行慢慢处理。
2.解耦和扩展性:项目开始的时候,并不能确定具体需求。消息队列可以作为一个接口层,解耦重
要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能力。
3.冗余:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅toic的服务消费到,供
多个毫无关联的业务使用。
4.健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常
进行。
5.异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用
户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的
时候再去处理它们。
3、消息队列的两种模式
3.1)点对点模式
*消费者主动拉取数据,收到消息后清除消息
3.1)发布/订阅模式
*可以有多个topic主题
*消费者消费数据之后,不删除数据
*每个消费者相互独立,都可以消费到数据
4.kafka角色定义
- producer:消息生产者,就是向kafka broker发消息的客户端
- Consumer:消息消费者,向kafka broker取消息的客户端。
- Consumer group:消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个消费组内消费者消费;消费者组之间互不影响。
- Broker:一台kafka服务器就是一个broker。一个集群由多个broker组成,一个broker可以容纳多个topic。
- topic:可以理解为一个队列,生产者和消费者面向的都是一个topic。
- partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition就是一个有序的队列。
- replica:副本。一个topic的每个分区都有若干个副本,一个leader和若干个follower。
- leader:每个分区有多个副本的“领导”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
- follower:每个分区多个多个副本的“跟从者”,实时从leader中同步数据,保持和leader数据的同步,leader发送故障时,某个follow会成为新的leader。
5、kafka发送原理
发送原理:在消息发送过程中,涉及到了两个线程——main线程和sender线程在main线程中创建了一个双端队列RecordAccumulator。main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka Broker。
3.1.2 生产者重要参数列表
描述 | |
bootstrap.servers | 生产者连接集群所需的broker地址清单。例如hadoop102:9092,hadoop103:9092,hadoop104:9092,可以设置1个或者多个,中间用逗号隔开。注意这里并非需要所有的broker地址,因为生产者从给定的broker里查找到其他broker信息。 |
key.serializer和value.serializer | 指定发送消息的key和value的序列化类型。一定要写全类名。 |
buffer.memory | RecordAccumulator缓冲区总大小,默认32m。 |
batch.size | 缓冲区一批数据最大值,默认16k。适当增加该值,可以提高吞吐量,但是如果该值设置太大,会导致数据传输延迟增加。 |
linger.ms | 如果数据迟迟未达到batch.size,sender等待linger.time之后就会发送数据。单位ms,默认值是0ms,表示没有延迟。生产环境建议该值大小为5-100ms之间。 |
0:生产者发送过来的数据,不需要等数据落盘应答。 1:生产者发送过来的数据,Leader收到数据后应答。 -1(all):生产者发送过来的数据,Leader+和isr队列里面的所有节点收齐数据后应答。默认值是-1,-1和all是等价的。 | |
max.in.flight.requests.per.connection | 允许最多没有返回ack的次数,默认为5,开启幂等性要保证该值是 1-5的数字。 |
当消息发送出现错误的时候,系统会重发消息。retries表示重试次数。默认是int最大值,2147483647。 如果设置了重试,还想保证消息的有序性,需要设置 MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION=1否则在重试此失败消息的时候,其他的消息可能发送成功了。 | |
retry.backoff.ms | 两次重试之间的时间间隔,默认是100ms。 |
是否开启幂等性,默认true,开启幂等性。 | |
compression.type | 生产者发送的所有数据的压缩方式。默认是none,也就是不压缩。 支持压缩类型:none、gzip、snappy、lz4和zstd。 |
6.生产者分区
kafka分区的好处:
1.便于合理使用存储资源,每个partition在一个broker上储存,可以吧海量的数据按照分区切割成一块一块数据存储在多台broker上,合理控制分区,可以实现负载均衡的效果
2.提高并行度,生产者可以以分区为单位发送数据,消费者可以以分区为单位进行消费数据。
6.生产经验——数据去重
数据传递语意:
至少一次=ACK级别设置为-1+分区副本数大于等于2+ISR里应答的最小副本数量大于等于2
最多一次=ACK级别设置为0
总结:
至少一次可以保证数据不丢失,但是不能保证数据不重复,
最多一次可以保证数据不重复,但是不能保证数据不丢失。
精确一次:对于一些非常重要的信息,要求数据既不能重复也不能丢失,kafka在0.11版本后,引入了一项重大特性:幂等性和事务。
7.幂等性原理
幂等性就是指producer不论向broker发送多少次重复数据,Broker端都只会持久化一条数据,保证了不重复。
精确一次=幂等性+至少一次(Ack= -1 +分区副本数>=2+ISR最小副本数量>=2).
重复数据的判断标准:具有<PID,partition seqNumber>相同主键的消息提交时,broker只会持久化一条,其中PID是kafka每次启动都会分配一个新的:partition表示分区号;sequence Number是单调自增的
所以幂等性只能保证的是在单分区单会话内不重复
如何使用幂等性
开启参数enable.idempotence 默认为true,false关闭。
8 Kafka 副本
副本基本信息
(1)Kafka副本作用:提高数据可靠性。
(2)Kafka默认副本1个,生产环境一般配置为2个,保证数据可靠性;太多副本会增加磁盘存储空间,增加网络上数据传输,降低效率。
(3)Kafka中副本分为:Leader和Follower。Kafka生产者只会把数据发往Leader,然后Follower找Leader进行同步数据。
(4)Kafka分区中的所有副本统称为AR(Assigned Repllicas)。
AR = ISR + OSR
ISR,表示和Leader保持同步的Follower集合。如果Follower长时间未向Leader发送通信请求或同步数据,则该Follower将被踢出ISR。该时间阈值由replica.lag.time.max.ms参数设定,默认30s。Leader发生故障之后,就会从ISR中选举新的Leader。
OSR,表示Follower与Leader副本同步时,延迟过多的副本。
9.文件存储机制
topic数据的存贮机制
每个partition对应一个log文件,该log文件中存储的就是producer生产的数据,producer生产的数据会被不断的追加到该log文件末端,为了防止log文件过大导致数据定位效率低下,kafka采用了分片和索引机制,每个partition分为多个多个segment,每个segment包括(index文件(偏移量索引文件),log文件(日志文件),timeindex时间戳索引文件)
10、高效读写数据
1)Kafka本身是分布式集群,可以采用分区技术,并行度高
2)读数据采用稀疏索引,可以快速定位要消费的数据
3)顺序写磁盘
Kafka的producer生产数据,要写入到log文件中,写的过程是一直追加到文件末端,为顺序写。官网有数据表明,同样的磁盘,顺序写能到600M/s,而随机写只有100K/s。这与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。
4)页缓存 + 零拷贝技术
11、kafka消费者
kafka消费方式
pull模式:consumer采用从broker中主动拉取数据。
pull模式不足之处就是:如果kafka中没有数据,消费者可能会陷入循环中,一直返回空数据。
Consumer Group(CG):消费者组,由多个consumer组成。形成一个消费者组的条件,是所有消费者的groupid相同。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费。消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
1、coordinator:辅助实现消费者组的初始化和分区的分配。
coordinator-节点选择=groupid的hashcode值%50(_consumer_.offsets的分区数量)
例如:groupid的nashcode值=1,1%50=1,那么consumer_.offsets主题的1号分区,在哪个broker_上,就选择这个节点的coordinator
作为这个消费者组的老大。消费者组下的所有的消费者提交offset的时候就往这个分区去提交offset。