【中间件】大数据之分布式消息队列Kafka

目录

Kafka设计动机

Kafka特点

Kafka设计架构

基本架构

Kafka各组件详解

Kafka关键技术点

典型应用场景


      在大数据数据收集环节,需要构建数据流水线,其中一种方式可以通过消息队列实现。在实际应用中,不同服务器产生的日志,比如指标监控数据,用户搜索日志,用户点击日志等,需要同时传送到多个系统中以便进行相应的逻辑处理和挖掘。

      消息队列位于生产者和消费者之间的“中间件”,解除了生产者和消费者的直接依赖关系,使得软件架构更容易扩展伸缩;能够缓冲生产者产生的数据,防止消费者无法及时处理生产者产生的数据。


Kafka设计动机

数据流水演化
数据流水演化

随着业务复杂度和产生数据量不断增加,逐渐演化成上图数据收集模式,并将收集到数据直接写入后端,则会产生以下几个潜在问题:

  • 数据生产者和消费者耦合度过高
  • 生产者和消费者间数据处理速率不对等
  • 大量并发的网络连接对后端消费者不够友好

为了解决以上问题,引入“中间件”,从这个角度理解Kafka 如下图所示(Kafka在数据流中扮演的角色):

  • 消息中间件:避免生产者和消费者直接相互产生的彼此高度依赖,使得两者中任何一个由变化,都不会影响另一方。
  • 消息队列:缓存生产者产生的数据,使得消费者可以重复消费历史数据;平滑生产者产生数据速度和消费处理数据速度的不对等
  • 发布订阅系统:消费者订阅某类主题的数据,当生产者产生对应主题的数据后,所有订阅者会快速获取到数据。随时增加新的消费者而无需进行任何系统层面的修改。
  • 消息总线:所有收集到的数据会流经 Kafka,之后由Kafka分流后,进入各个消费者系统。
Kafka在数据流中扮演的角色

Kafka特点

Kafka是在大数据背景下产生,能应对海量数据的处理系统。具有以下特点:

  • 高性能:相比RabbitMQ等消息队列,Kafka 具有更高的性能和吞吐率
  • 良好扩展性:采用分布式设计架构,数据经分片后写入多个节点,既可以突破单节点数据存储和处理的瓶颈,也可以实现容错等功能。
  • 数据持久化:数据消息均会持久化到磁盘上,并通过多副本策略避免数据丢失,采用顺序写,顺序读,和批量写等机制,提升磁盘操作的效率。

Kafka设计架构

1. 基本架构

Kafka 架构由 ProducerBrokerConsumer 三类组件构成。

  • Producer 将数据写入Broker,Consumer 从 Broker上读取数据进行处理,Broker构成了连接 Producer 和 Consumer 的“缓冲区”。
  • Broker 和 Cunsumer 通过 Zookeeper 做协调和服务发现。
  • 多个 Broker 构成一个可靠的分布式消息存储系统,避免数据丢失。
  • Broker 中的消息被划分成若干个 topic ,同属于一个 topic 的所有数据按照某种策略被分成多个 partition 以实现负载分摊数据并行处理
  • 采用 push-pull,即 Producer 将数据直接 “push” 给 Broker, 而 Consumer 从Broker “pull”数据,这种架构优势带来以下两点:
    1. Consumer 可以根据自己的实际负载和需求获取数据(自己主动去拉取消息进行消费)
    2. Consumer 自己维护已读取消息的 offset 而不是由Broker 端维护,大大缓解 Broker压力,使得它更加轻量级。 

Kafka 基本架构

2. Kafka各组件详解

1.producer

由用户使用 Kafka 提供的 SDK 开发的,Producer 将数据转化成 “消息”,并通过网络发送Broker。每条消息表示为一个三元组<topic, key, message>

  • topic:表示该条消息所属的 topic,划分消息逻辑概念。一个 topic 可以分布到多个不同的 Broker 上。
  • key:表示该消息的主键。根据主键将同一个 topic 下消息划分成不同的分区 ( partition ),默认基于哈希取模算法,用户可以自行设置分区算法。如下图演示 Producer 写消息的过程,假设 topic A 共分为 4 个 partition (创建 topic 时静态制定)。
  • message:消息值,其类型为字节数组,可以是普通字符串,JSON对象,或者 JSON, Acro,Thrift或Protobuf等序列化框架序列化后的对象。
Kafka Producer 写消息过程

2. Broker

主要职责是接受 ProducerConsumer 的请求,并把消息持久化到本地磁盘Broker一般有多个,组成一个分布式高容错的集群

Kafka Broker 集群
  • Broker 以 topic 为单位将消息分成不同的分区 (partition),每个分区可以有多个副本,通过数据冗余的方式实现容错。当 partition 存在多个副本时,其中一个是 leader,对外提供读写请求,其余均是 follower,仅仅同步 leader 中的数据,并在 leader 出现问题时,通过选举算法将其中的某一个提升为 leader
  • Broker 能够保证同一个 topic 在同一个 partition 内部的消息是有序的,但无法保证 partition 之间的消息全局有序。在实际应用中,合理利用分区内部有序这一特征即可完成时序相关的需求。
  • Broker 中保存数据是有有效期,一旦超过了有效期,对应的数据被移除释放磁盘空间。在有效期期内,消息可以重复读取而不受限制。
  • Broker 以追加的方式将消息写到磁盘文件中,且每个分区中消息被赋予了唯一整数标识,称之为 “offset” (偏移量)。
  • Broker 仅提供基于 offset 的读取方式 ,不会维护各个 Consumer 当前已消费的 offset 值,而是由 Consumer 各自维护当前读取的进度。Consumer 读取数据时告诉 Broker 请求消息的起始 offset 值,Broker将之后的消息流式发送过去。如下图所示:
Kafka Broker 数据分区

3.Consumer

  • 主动从 Broker 拉取(pull)消息进行处理,这个机制大大降低了 Broker 的压力,使得 Broker 吞吐率很高
  • 每个Consumer 自己维护最后一个已读取消息的 offset,并在下次请求从这个 offset 开始的消息。
  • 多个Consumer 构成一个Consumer Group,共同读取同一个 topic 中的数据,提高数据读取效率。Kafka 可自动为同一个Group 中的 Consumer 分摊负载,从而实现消息的并发读取,在某个Consumer发生故障时,自动将它处理的 partition 转移给同 Group 中的 Consumer 处理。
Kafka Consumer Group 原理

4.Zookeeper

在 Kafka 集群中,Zookeeper 担任分布式服务协调作用,Broker 和 Consumer 直接依赖于 Zookeeper 才能工作

  • Broker 与 Zookeeper:所有 Broker 会向 Zookeeper 注册,将自己的位置,健康状况,维护的 topic,partition等信息写入 Zookeeper ,以便其他 Consumer 可以发现和获取这些数据。
  • Consumer 与 Zookeeper:Consumer Group 通过Zookeeper 保证内部各个 Consumer 的负载均衡,在某个 Consumer 或 Broker 出现故障时,重新分摊负载。Consumer (仅限于 height-level API,如果是 low-level API,用户需要自己保存和恢复offset)会将最近获取消息的 offset 写入 Zookeeper,以便出现故障重启后,能够接着故障前的断点继续读取数据。

3. Kafka关键技术点

1. 可控的可靠性级别

Producer 通过两种方式向 Broker 发送数据:同步异步。异步方式通过批处理的方式,可大大提高数据写入效率。这两种方式均支持通过控制消息应答方式,在写性能与可靠性之间做一个较好的权衡。目前支持三种消息应答方式,通过request.required.ack 控制:

  • 0:无需对消息进行确认,性能最高,但不能确保消息被成功接收并写入磁盘。
  • 1:需要等到 leader partition 写成功后才会返回,但对应的 follower partition 不一定写成功。在性能与可靠性之间进行折中。
  • -1:需要等到所有 partition 均写成功后才会返回。性能较低,但可靠性最高

2. 数据多副本

Broker 允许为每个 topic 中的数据存放多个副本,以达到容错的目的。Kafka 采用强一致的数据复制策略。

Kafka Broker 多副本放置

3. 高效的持久化机制

直接将消息持久化到磁盘而不是内存中,这要求必须采用高效的数据写入和存储方式。Kafka Broker 将收到的数据顺序写入磁盘,并结合基于 offset 的数据组织方式,能达到高效的读速度和写速度。


4. 数据传输优化:批处理与zero-copy技术

为了优化 BrokerConsumer 之间的网络数据传输效率,Kafka引入了大量优化技术,典型的两个代表:

  • 批处理:发送是将多条消息进行组装,同时对数据格式统一设计,避免数据格式转换带来开销。
  • zero-copy技术:一般情况下,一条存储在磁盘的数据从读取到发送出去需要经过四次拷贝(内核状态 read buffer  > 用户态应用程序 buffer  > 内核态 socket buffer  > 网卡NIC buffer)和两次系统调用。经过zero-copy技术优化后,数据只需三次拷贝(少了 用户态应用程序 buffer),且无需使用任何系统调用,大大提高数据发送效率。如下图所示:
application-copy 与 zero-copy 对比

5. 可控的消息传递语义

根据接受者受到重复消息的次数,将消息传递语义分为三种:

  • at most once:不需要等待确认,消息可能被消费者成功接收,也可能丢失
  • at least once:需要等待确认,如未收到确认则会重发;保障消费者收到消息,但可能会收到多次。
  • exactly once:消费者会且只会处理一次同一条消息。

实现第三种语义,常用技术手段有:

  • 两段锁协议:分布式中常用的一致性协议。
  • 在支持幂等操作下,使用 at least once 语义。Producer 与 Broker,  Broker 与 Consumer 之间,均存在消息传递语义问题。

典型应用场景

1. 消息队列

与 RabbitMQ 和 ZeroMQ 等开源消息队列相比,Kafka 具有高吞吐率,自动分区,多副本以及良好容错性等特点,使得它非常适合大数据应用场景。


2. 流式计算框架的数据源

在流式计算框架,为了保证数据不丢失,具备“at least once”数据发送语意,通常在数据源中使用具有高性能的消息队列。


3. 分布式日志收集系统中Source或Sink

可与日志收集组件 Flume 或 Logstash 组合使用,担任 Source 或 Sink 的角色。


4. Lambda Architecture 中的 Source

同时为批处理和流式处理两条流水线提供数据源

 

注:内容主要整理自书本《大数据技术体系详解 原理、架构与实践》 董西成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值