前言
说这几个概念之前呢?先说几个问题
1.kakfa是什么?
Kafka 是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用与大数据"实时"处理领域
2.kafka有什么作用
Kafka 本质上是一个 MQ(Message Queue),使用消息队列的好处?(此处是面试题)
- 解耦:允许我们独立的扩展或修改队列两边的处理过程。
- 可恢复性:即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
- 缓冲:有助于解决生产消息和消费消息的处理速度不一致的情况。
- 灵活性&峰值处理能力:不会因为突发的超负荷的请求而完全崩溃,消息队列能够使关键组件顶住突发的访问压力(削峰)。
- 异步通信:消息队列允许用户把消息放入队列但不立即处理它。
1. producer - 生产者
顾名思义,生产者,生产消息的那个家伙。
在准确点形容就是:向 Kafka Broker 发消息的客户端。
既然发送消息了,那么消息就有可能存在丢失,比如消息发送失败了。
那怎么预防这类事情发生呢?
Kafka 在生产者上有一个可选的参数 ack,该参数指定了必须要有多少个分区副本收到消息,生产者才会认为消息写入成功:
acks=0 :消息发送出去就认为已经成功了,不会等待任何来自服务器的响应
acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应
acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应
2. broker - 消息服务器
【这里只是举了一个消费者采用啦的模式,当然还有推的模式】
从这张图来理解broker的定位会更好记一点,可以理解为,生产者把消息给broker,consumer从broker拉取消息进行消费(数据处理)
来看下百科的解释
它的主要作用是在ZooKeeper 的帮助下管理和协调整个Kafka 集群。 集群中任意一台Broker 都能充当控制器的角色,但是在运行过程中,只能有一个Broker 成为控制器,来执行管理和协调的职责。
这么说来,broker就不是一台机器了,而是一个集群(类似于redis集群,同样有leader的选举和存活检测,不过这个就由zookeeper来帮助了,毕竟人家才是背后的大哥)
(记住这个图有点问题,后面会改正,看下面这句话就知道图不是很形象了)
那么实际的关系是:
一台 Kafka 机器就是一个 Broker。一个集群由多个 Broker 组成。一个 Broker 可以容纳多个 Topic。
这样看起来的话,当producer将消息投递到broker的时候,会存在一个很严重的问题,就是消息丢失。
既然存在那么如何解决呢?
2.1 消息在broker丢失了怎么办
脑补中。。
Broker丢失消息是由于Kafka本身的原因造成的,kafka为了得到更高的性能和吞吐量,将数据异步批量的存储在磁盘中。消息的刷盘过程,为了提高性能,减少刷盘次数,kafka采用了批量刷盘的做法。即,按照一定的消息量,和时间间隔进行刷盘。这种机制也是由于linux操作系统决定的。将数据存储到linux操作系统种,会先存储到页缓存(Page cache)中,按照时间或者其他条件进行刷盘(从page cache到file),或者通过fsync命令强制刷盘。数据在page cache中时,如果系统挂掉,数据会丢失。
刷盘触发条件有三:
主动调用sync或fsync函数
可用内存低于阀值
dirty data时间达到阀值。dirty是pagecache的一个标识位,当有数据写入到pageCache时,pagecache被标注为dirty,数据刷盘以后,dirty标志清除。
Broker配置刷盘机制,是通过调用fsync函数接管了刷盘动作。从单个Broker来看,pageCache的数据会丢失。
也就是说,理论上,要完全让kafka保证单个broker不丢失消息是做不到的,只能通过调整刷盘机制的参数缓解该情况。比如,减少刷盘间隔,减少刷盘数据量大小。时间越短,性能越差,可靠性越好(尽可能可靠)。这是一个选择题。
为了解决该问题,kafka通过producer和broker协同处理单个broker丢失参数的情况。一旦producer发现broker消息丢失,即可自动进行retry。除非retry次数超过阀值(可配置),消息才会丢失。此时需要生产者客户端手动处理该情况。那么producer是如何检测到数据丢失的呢?是通过ack机制,类似于http的三次握手的方式。
3. topic - 消息主题
topic是消息的逻辑分类,可以看做是一个消息类别的名称,同类消息发送到同一个Topic下面。
举个荔枝,订单消息,商品的信息,2个类型,他们的消息内容,消息格式可能会存在差异性,并且都有各自的生产者和消费者。
如果按照一个消息类型建立kafka系统,那么得搭建多少个系统能满足一个庞大的业务系统呢?
所以就有了Topic这个东西-逻辑分类,假如一个消息类型放到一个Topic中就合理了。
所以在生产消息时,就需要指定Topic了。这么想来是不是就合理了呢。
好了,到了总结时间了
1.消息生产时需要指定生产到哪个topic
2.每个topic就是一类消息
3.消费时需要指定消费那个topic数据
既然每个topic消息是一种类型,那么相信你面试过程中听过一个非常经典的面试题:kakfa如何保证顺序消费呢?
没错,单一partition内的消息天然有序的
假如有人问怎么保证有序,这下知道怎么回了吧,那么如何保证不同topic之间的顺序呢,这个得从自己的业务出发,植入相应的数据消费序号,或者消费者拿到数据后再放到自己的mq中消费了。
好了,结合上述,画出图吧
image.png
4.patition - 主题内分区
4.1定义
partition是个什么东西呢?
既然有topic了,分类都有了,还缺什么吗?
topic是逻辑的概念,partition是物理的概念。 啥是物理概念,就是物理上进行分离,分布在不同的实体机器上。
引用知乎上一个非常合适的荔枝来说明就在合适不过了
Kafka的设计也是源自生活,好比是为公路运输,不同的起始点和目的地需要修不同高速公路(主题topic)。高速公路上可以提供多条车道(分区partition),流量大的公路多修几条车道保证畅通,流量小的公路少修几条车道避免浪费。收费站好比消费者,车多的时候多开几个一起收费避免堵在路上,车少的时候开几个让汽车并道就好了。
说直白点呢,不同的公路就是topic, 公路上存在多条车道,每条车道就是分区partition
4.2 作用
如果没有分区,一个topic对应的消息集在分布式集群服务组中,就会分布不均匀,即可能导致某台服务器A记录当前topic的消息集很多,若此topic的消息压力很大的情况下,服务器A就可能导致压力很大,吞吐也容易导致瓶颈。
所以很明显partition的作用就来了:通过多分区实现负载均衡的效果,提高kafka访问吞吐率。
Topic 是一个逻辑概念,Partition 是最小的存储单元,掌握着一个 Topic 的部分数据。每个 Partition 都是一个单独的 log 文件;
借用下知乎图
image.png
那么patition和topic的关系就是
4.3 如何写入partition?
消息以追加的方式写入分区,然后以先入先出的顺序读取。Kafka 通过分区来实现数据的冗余和伸缩性,分区可以分布在不同的服务器上,这意味着一个 Topic 可以横跨多个服务器,以提供比单个服务器更强大的性能。
具体的方式有3种:
- 采用轮训的方式写入到每个partition中(默认采用的方式)
- producer指定写入到哪个partition中
- 自定义写入
producer指定写入到哪个partition中或者自定义写入有一个最好的利用点,就是不至于热点数据全部到一个partition中,导致数据严重倾斜。
5. groups - 消费组
消费者组内每个消费者负责消费不同分区的数据,提高消费能力。一个分区只能由组内一个消费者消费,消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
那么消费组和消费者的关系就是这样子了
image.png
6.概念说完了,那么如何消费数据呢?
6.1 pull(拉)模式
由消费者,主动从 broker 中读取数据
pull 模式可以根据 consumer 的消费能力以适当的速率消费消息。
优点:主动权在消费者手里,想什么时候要就要,类似于现在bsp+缓存池 数据进专工的模型
缺点:如果 kafka 没有数据,消费者可能会陷入循环中
针对这一点,Kafka 的消费者在消费数据时会传入一个时长参数 timeout,如果当前没有数据可供消费,consumer 会等待一段时间之后再返回,这段时长即为 timeout
6.2 push (推)模式
消息有broker来决定,决定发送的效率。
它的目标是尽可能以最快速度传递消息,但是这样很容易造成 consumer 来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。
类似于目前bsp多数的干预模式,不管下游要不要,盲推,但是不同于kfk推模式的在于,bsp架构是有自我熔断与限流的,一方面也是防止了那种大批量数据推入下游,导致阻塞的情况
6.3 offset
由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢复后继续消费。
group + topic + partition(GTP) 才能确定一个 offset!
7.整体框架图
- producer:消息生产者
- consumer:消息消费者
- Topic:消息主题
- partition:主题内分区
- Brokers:消息服务器
- Groups:消费者组
网友评论