【ELFK】之消息队列kafka

目录

一、Kafka简介

1、为什么需要消息队列(MQ)

2、消息队列的好处

3、Kafka的特性

4、Kafka作为存储系统

二、Kafka消费模式

1、一对一 (点对点消息传递模式)

2、一对多 (发布订阅消息传递模式)

三、Kafka的基础架构

1、Kafka架构

2、工作流程

3、分区的原因

4、分区目的

四、Kafka原则


一、Kafka简介

Kafka是一种消息队列,主要用来处理大量数据状态下的消息队列,一般用来做日志的处理。既然是消息队列,那么Kafka也就拥有消息队列的相应的特性了。
可以在系统中起到“削峰填谷”的作用,也可以用于异构、分布式系统中海量数据的异步化处理。

1、为什么需要消息队列(MQ)

主要原因是由于在高并发环境下,同步请求来不及处理,请求往往会发生阻塞。比如大量的请求并发访问数据库,导致行锁表锁,最后请求线程会堆积过多,从而触发 too many connection 错误,引发雪崩效应。
我们使用消息队列,通过异步处理请求,从而缓解系统的压力。消息队列常应用于异步处理,流量削峰,应用解耦,消息通讯等场景。

当前比较常见的 MQ 中间件有 ActiveMQ、RabbitMQ、RocketMQ、Kafka 等。

2、消息队列的好处

解耦合
耦合的状态表示当你实现某个功能的时候,是直接接入当前接口,而利用消息队列,可以将相应的消息发送到消息队列,这样的话,如果接口出了问题,将不会影响到当前的功能。

异步处理
异步处理替代了之前的同步处理,异步处理不需要让流程走完就返回结果,可以将消息发送到消息队列中,然后返回结果,剩下让其他业务处理接口从消息队列中拉取消费处理即可。

流量削峰
高流量的时候,使用消息队列作为中间件可以将流量的高峰保存在消息队列中,从而防止了系统的高请求,减轻服务器的请求处理压力。

3、Kafka的特性

高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
可扩展性:kafka集群支持热扩展
持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
高并发:支持数千个客户端同时读写

4、Kafka作为存储系统

任何允许发布与消费它们分离的消息的消息队列实际上充当了正在进行的消息的存储系统。
Kafka的不同之处在于它是一个非常好的存储系统。
写入Kafka的数据将写入磁盘并进行复制以实现容错。Kafka允许生产者等待确认,以便在完全复制之前写入不被认为是完整的,并且即使写入的服务器失败也保证写入仍然存在。
磁盘结构Kafka很好地使用了规模 - 无论服务器上有50 KB还是50 TB的持久数据,Kafka都会执行相同的操作。

二、Kafka消费模式

Kafka的消费模式主要有两种:

① 一种是一对一的消费,也即点对点的通信,即一个发送一个接收。

② 第二种为一对多的消费,即一个消息发送到消息队列,消费者根据消息队列的订阅拉取消息消费。

1、一对一 (点对点消息传递模式)

【ELFK】之消息队列kafka_第1张图片

消息生产者发布消息到Queue队列中,通知消费者从队列中拉取消息进行消费。消息被消费之后则删除,Queue支持多个消费者,但对于一条消息而言,只有一个消费者可以消费,即一条消息只能被一个消费者消费。

2、一对多 (发布订阅消息传递模式)

【ELFK】之消息队列kafka_第2张图片

这种模式也称为发布/订阅模式,即利用Topic存储消息,消息生产者将消息发布到Topic中,同时有多个消费者订阅此topic,消费者可以从中消费消息,注意发布到Topic中的消息会被多个消费者消费,消费者消费数据之后,数据不会被清除,Kafka会默认保留一段时间,然后再删除。

三、Kafka的基础架构

Kafka像其他Mq一样,也有自己的基础架构,主要存在生产者Producer、Kafka集群Broker、消费者Consumer、注册消息Zookeeper

1、Kafka架构

【ELFK】之消息队列kafka_第3张图片

Producer:Producer即生产者,消息的产生者,是消息的入口。
Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号.
Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。
Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹!
Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。
Message:每一条发送的消息主体。
Consumer:消费者,即消息的消费方,是消息的出口。
Consumer Group:我们可以将多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!
Zookeeper:kafka集群依赖zookeeper来保存集群的的元信息,来保证系统的可用性。

#offset和zookeeper理解

由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置继续消费,所以consumer需要时实记录自己消费到了哪个offset,以便恢复后继续消费。

kafka 在0.9 版本之前,consumer默认将offset保存在zookeeper中。
从0.9版本后,consumer默认将offset保存在kafka一个内置的topic中,该topic为_consumer_offset.

也就是说,zookeeper的作用就是,生产者输出数据到kafka集群,就必须要找到kafka集群的节点在哪里,这些都是通过zookeeper去寻找的,消费者消费到哪一条数据,也需要zookeeper的支持,从zookeeper获得offset,offset记录上一次消费的数据消费到哪里,这样就可以接着下一跳数据进行消费。

Leader:每个分区多个副本的主角色,生产者发送数据的对象,以及消费者消费数据的对象都是Leader。
Follower:每个分区多个副本的从角色,实时的从Leader中同步数据,保持和Leader数据的同步,Leader发生故障的时候,某个Follower会成为新的Leader。

上述一个Topic会产生多个分区Partition,分区中分为Leader和Follower,消息一般发送到Leader,Follower通过数据的同步与Leader保持同步,消费的话也是在Leader中发生消费,如果多个消费者,则分别消费Leader和各个Follower中的消息,当Leader发生故障的时候,某个Follower会成为主节点,此时会对齐消息的偏移量。

2、工作流程

producer就是生产者,是数据的入口。Producer在写入数据的时候永远的找leader,不会直接将数据写入follower

【ELFK】之消息队列kafka_第4张图片

先从集群获取分区的leader
① Producter将消息发送给leader
② Leader将消息写入本地文件
③ Followers从leader同步消息
④ Follower将消息写入本地后向leader发送ACK确认消息
⑤ Leader收到所有副本的ACK后,向producter发送ACK
注:消息写入leader后,follower是主动的去leader进行同步的

3、分区的原因

① 便在集群中扩展,每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了;

② 可以提高并发,因为可以以Partition为单位读写了。

4、分区目的

producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的。

【ELFK】之消息队列kafka_第5张图片

数据会写入到不同的分区,分区的目的是

  1. 方便扩展:因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松的应对日益增长的数据量。
  2. 提高并发:以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率。

四、Kafka原则

类似于负载均衡,当我们向某个服务器发送请求的时候,服务端可能会对请求做一个负载,将流量分发到不同的服务器,那在kafka中,如果某个topic有多个partition,producer又怎么知道该将数据发往哪个partition呢?kafka中有几个原则:

① partition在写入的时候可以指定需要写入的partition,如果有指定,则写入对应的partition。
② 如果没有指定partition,但是设置了数据的key,则会根据key的值hash出一个partition。
③ 如果既没指定partition,又没有设置key,则会轮询选出一个partition。
 

保证消息不丢失是一个消息队列中间件的基本保证,那producer在向kafka写入消息的时候,怎么保证消息不丢失呢?其实上面的写入流程图中有描述出来,那就是通过ACK应答机制!在生产者向队列写入数据的时候可以设置参数来确定是否确认kafka接收到数据,这个参数可设置的值为0、1、all。

① 0代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效率最高。
② 1代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。
③ all代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有的副本都完成备份。安全性最高,但是效率最低。
 

你可能感兴趣的:(kafka,java,大数据)