Kafka

官方文档:https://kafka.apache.org/documentation/#introduction

kafka底层是啥 kafka底层协议_kafka

一、什么是Kafka

Kafka是一种基于发布/订阅模式分布式消息队列。它是用scala语言实现的,通信基于TCP,服务模式是基于Client/Server

【发布订阅】

  • 支持一对多,即一个消息可同时被多个消费者消费
  • 延申:一对一的模式指一个消息仅能被一个消费者消费

【分布式】

  • kafka以集群的方式存在

【消息队列】

  • 相当于生产者和消费者之间的消息中转站。

二、为什么要使用Kafka

1、存在什么实际问题

【实际问题1】
当生产者生产的速度和消费者消费的速度不一致时(通常是指生产速度大于消费速度的情况),具有木桶效应,谁处理的最慢,整体服务的性能就是最慢的那个速度。尤其是数据量特别大的时候,性能退化明显。

【实际问题2】
不同时间段,消息的生产速度是不一样的,时而多时而少。消费者提供的服务量是稳定不变的,当一下子涌来巨大的处理请求时,容易将服务打崩(类似redis的雪崩、击穿等场景)。

就解决方法

  • 加服务(成本高,并且请求少的时候就会造成资源浪费)
  • 申请云服务,随实际需求变化服务器数量(好像是一种不错的方式,但本文不讲)
  • 加缓存(存消息的缓存一般是内存,当服务崩溃了,由于内存具有易失性,消息会丢失,且内存量也有限)
  • 加消息队列(好像是个不错的主意,消息队列可以实现‘缓冲带’,类似于加缓存,并且它可以实现云服务伸缩提供服务)

2、Kafka有什么特点

在IT领域,没有什么问题是加一层无法解决的。消息队列是一种中间件,相当于在生产者和消费者之间加了一层来解决上述问题。

【消息队列通用的特点】

解耦生产者和消费者,让其彼此不可知。

  • 各司其职,解耦彼此业务逻辑
  • 生产者只专心生产消息,至于谁来消费与我无关;
  • 消费者也只专心消费消息,谁生产的跟我也无关。
  • 实现异步
  • 速度不一致没关系,生产者生产完消息就可以接着向后提供服务,不必等到消费者消费完毕。
  • 服务不必同时开着
  • 可以削峰,灵活
  • 依据消息数量提供消费能力,或者实现限流

【Kafka特点】

  • 有容错的保证机制
  • 收到消息的确认机制
  • 消息丢失的重传机制
  • 副本保存机制
  • 磁盘存储机制(分段存储、索引+数据分离存储)
  • 支持一对多的消费模式
  • 消费拉去模式,而非推送模式
  • 消息消费完可以不马上删除,可以存储一段时间

应用场景

  1. 消息队列
  2. web网站的活动跟踪
  3. 数据统计
  4. 日志搜集、监控
  5. 流处理

三、Kafka的架构和相关的运行机制

1、架构图

  • producer:生产者,消息的产生来源
  • consumer:消费者,消息的去向
  • consumer group:消费者组,包含一组提供相同服务的消费者
  • M:消息,一个消息只能被同一个消费者组里的一个消费者消费,但是可以被不同消费者组消费
  • broker:一个kafka服务器
  • topic:主题,逻辑概念,存储相同类型的消息
  • partition:分区,物理概念,同topic的消息可以放在不同分区上,消息排序以分区为单位从头开始排
  • leader:消息生产和消费的源分区
  • follower:leader的一份拷贝

kafka底层是啥 kafka底层协议_数据_02

2、运行机制

1)kafka使用磁盘存储,为什么它的性能依然很高

一提到磁盘存储,大家的第一直觉就是很慢,实则不然。磁盘读写速度实际取决于它的读写方式,顺序地线性读写可达600MB/s,随机读写速度仅有100KB/s。磁盘读写速度慢的罪魁祸首在于找数据读写的起始位置的部分(移动指针,找盘面,找磁道很费时),之后进行磁盘读写操作是很快的。

OS中磁盘操作有预读和后置写的新特性。它会在磁盘上预留出一块连续的磁盘缓冲区,每当要从内存写入磁盘或从磁盘写数据到内存时,都必须经过次缓冲区。然后,再通过二次flush到内存或磁盘。这样可以充分“提高”磁盘读写效率。

2)为什么要进行主题分区,消息具体写入哪个分区的原则又是什么

当同一个消息的生产者很多时,都需要写入同一个主题的消息队列,这样就存在临界资源争抢的问题。分区可以提高并发率,实现并行的消息写入。另外,支持分区便于扩展。

消息写入分区的原则:

  • 写入消息时,同时告知具体需要传入的分区号
  • 写入消息时,通过key,计算出其哈希码,通过哈希码与分区数求余确定写入的分区号
  • 写入分区时,即不知道key也不知道分区号,则采用轮询的方式round-robin算法实现
3)如何保证每个消息可靠地被存放到kafka中,以及如何确保故障时的数据恢复

副本保存机制+ack机制

【故障时数据恢复】

  • 为了避免在broker出现服务崩溃的时候数据丢失(kafka文档介绍中的log不是指日志,而是指数据data的意思),kafka默认开启副本保存机制,可以通过手动设置副本因子来修改副本数。
    副本因子n = 1个leader +(n-1)个follower
    leader中的数据和follower中的数据保持完全一致,但是不可避免地,在某一时刻,follower中的数据略少于leader,即缺少leader队尾的些许数据,因为数据同步有一定的时延。

【可靠传输】

  • 当生产者每发送一个消息给leader,当leader将所有follower中都同步了消息,生产者就会收到一个ack信息。为保证效率,当然不是一个消息对应一个ack,而是follower同通过拉取的方式批量获取。
  • 如果follower由于挂掉一直没有响应,生产者亦不会一直等待下去。这依赖于leader维护的同步副本集,当副本超过replica.lag.time.max.ms的设置时间,默认follower坏掉了,会将follower踢出同步副本集,并返回ack信息给生产者