分布式消息队列Kafka

分布式消息队列Kafka

消息队列是位于生产者和消费者之间的中间件,解除了生产者和消费者的直接依赖关系,使得软件架构更容易扩展和伸缩。能够缓冲生产者产生的数据,防止消费者无法及时处理生产者产生的数据。
kafka架构由Producer、Broker和Consumer三类组件构成,其中Producer将数据写入Broker、Consumer则从Broker上读取数据进行处理,而Broker构成了连接Producer和Consumer的缓冲区。Kafka Broker中的消息被划分成若干个topic,同属一个topic的所有数据按照某种策略被分成多个partition,以实现负载分摊和数据并行处理。

分布式Kafka集群部署参考CentOS7下安装Kafka集群

一、Kafka设计动机

业务简单,只需要一条数据流水线即可,即从前端机器上收集日志,直接导入后端的存储系统中进行分析。当业务规模发展到一定程度后,业务逻辑会变得复杂起来,数据量也会越来越多,此时可能需要增加多条数据线,每条数据线将收集到的数据导入不同的存储和分析系统中。此时若仍采用之前的数据收集模式,将收集到的数据直接写入后端,则会产生以下几个潜在的问题:

  • 数据生产者和消费者耦合度过高。
  • 生产者和消费者间数据处理速率不对等。如果生产者产生数据速度过快,可能会导致消费者压力过大,设置崩溃。
  • 大量并发的网络连接对后端消费者不够友好。大量生产者直接与消费者通信,对消费者造成过大的网络并发压力,会成为系统扩展过程中潜在的性能瓶颈。另外大量并发生产者同时写入后端存储,可能产生大量小文件,对Hadoop等分布式文件系统造成过大存储压力(HDFS不适合存储大量小文件)。

Kafka重要地位:

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

Kafka特点:

  • 高性能:更高的性能和吞吐率。
  • 良好的扩展性:分布式设计架构。
  • 数据持久性:数据消息会持久化到磁盘上,并通过多副本策略避免数据丢失。

二、Kafka设计架构

Kafka是一个分布式消息队列,将数据分区保存,并将每个分区保存成多份以提高数据可靠性。

1.Kafka基本架构

Kafka架构由Producer、Broker和Consumer三类组件构成。Producer将数据写入Broker,Consumer则从Broker上读取数据进行处理。Broker和Consumer通过ZooKeeper做协调和服务发现。
多个Broker构成一个可靠的分布式消息存储系统,避免数据丢失。Broker中的消息被划分成若干个topic,同属一个topic的所有数据按照某种策略被分成多个partition,以实现负载分摊和数据并行处理。

分布式消息队列Kafka_第1张图片
Kafka采用了push-pull架构,即Producer将数据直接"push"给Broker,而Consumer从Broker端“pull”数据,这种优势主要体现在以下两点:

  • Consumer可根据自己的实际负载和需求获取数据,避免采用"push"方式给Consumer带来较大压力。
  • Consumer自己维护已读取消息的offset而不是由Broker端维护,大大缓解了Broker的压力,使得它更加轻量级。

2.Kafka各组件详解

1)Kafka Producer
Kafka Producer是由用户使用Kafka提供的SDK开发的,Producer将数据转化成"消息",并通过网络发送给Broker。
在Kafka中,每条数据被称为消息,每条消息表示为一个三元组:
每个元素表示的含义如下:

  • topic:表示该条消息所属的topic。topic是划分消息的逻辑概念,一个topic可以分布到多个不同的broker上。
  • key:表示该条消息的主键。Kafka会根据主键将同一个topic下的消息划分成不同的分区(partition),默认是基于哈希取模的算法。
  • message:表示该条消息的值。
    Kafka Producer发送消息时,不需要指定所有Broker的地址,只需给定一个或几个初始化Broker地址即可(一般给定多于一个以达到容错的目的),Producer可通过指定的Broker获取其他所有Broker的位置信息,并自动实现负载均衡。

2)Kafka Broker
Broker一般有多个,组成一个分布式高容错的集群。Broker的主要职责是接受Producer和Consumer的请求,并把消息持久化到本地磁盘。
Broker以topic为单位将消息分成不同的分区(partition),每个分区可以有多个副本,通过数据冗余的方式实现容错。当partition存在多个副本时,其中有一个是leader,对外提供读写请求,其他均是follow,不对外提供读写服务,只是同步leader中的数据,并在leader出现问题时,通过选举算法将其中的某一个提升为leader。
Kafka Broker能够保证同一topic下同一partition内部的消息是有序的,但无法保证partition之间的消息全局有序。
Kafka Broker以追加的方式将消息写道磁盘文件中,且每个分区中的消息被赋予了唯一整数标识,称为"offset"(偏移量)。
Consumer读取数据时告诉Broker请求消息的起始offset值,Broker将之后的消息流式发送过去。
Broker中保存的数据是有有效期的,比如7天,一旦超过了有效期,对应的数据将被移除以释放磁盘空间。

3)Kafka Consumer
Kafka Consumer主动从Kafka Broker拉取消息进行处理。每个Kafka Consumer自己维护最后一个已读取消息的offset,并在下次请求从这个offset开始的消息,这种基于pull的机制大大降低了Broker的压力,使得Kafka Broker的吞吐率很高。
Kafka允许多个Consumer构成一个Consumer Group,共同读取同一个topic中的数据,提高数据读取效率。Kafka可自动为同一Group中的Consumer分摊负载,实现消息的并发读取,并在某个Consumer发生故障时,自动将它处理的partition转移给同Group中其他Consumer处理。
分布式消息队列Kafka_第2张图片

  1. Zookeeper
    Broker和Consumer直接依赖于Zookeeper才能正常工作:
  • Broker与Zookeeper:所有Broker会向ZooKeeper注册,将自己的位置、健康状态、维护的topic、partition等信息写入Zookeeper,以便于其他Consum可以发现和获取这些数据,当一个Consumer宕掉后,其他Consumer会通过Zookeeper发现这一故障,并自动分摊该Consumer的负载,进而触发相应的容错机制。
  • Consumer与Zookeeper:Consumer Group通过ZooKeeper保证内部各个Consumer的负载均衡,并在某个Consumer或Broker出现故障时,重新分摊负载。Consumer会将最近所获取消息的offset写入ZooKeeper,以便出现故障重启后,能够接着故障前的断点继续读取数据。

3.Kafka关键技术点

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

  • 0:无需对消息进行确认,当Producer向Broker发送消息后马上返回,无需等待对方写成功。这种方式性能最高,但不能保证消息被成功接收并写入磁盘。
  • 1:当Producer向Broker发送消息后,需等到leader partition写成功后才会返回但对应的follow partition不一定写成功。这种方式在性能和可靠性之间进行了折中,能够在比较高的情况下,保证数据至少成功写入一个节点。
  • -1:当Producer向Broker发送消息后,需等到所有Partition均写成功后才会返回。容错性高,写性能要低。

2)数据多副本
Kafka Broker允许为每个topic中的数据存放多个副本。Kafka采用了强一致的数据赋值策略,消息首先被写入leader partition,之后由leader partition负责将收到的消息同步给其他副本。Leader Partition负责对外的读写服务,follow partition仅负责同步数据,并在leader partition出现故障时,通过选举的方式竞选成为leader。
Kafka Broker负载均衡实际上是对leader partition的负载均衡,即保证leader partition在各个Broker上数目尽可能相近。
分布式消息队列Kafka_第3张图片
3) 高效的持久化机制
Kafka Broker直接将消息持久化到磁盘上而不是内存中,这要求必须采用高效的数据写入和存储方式。当将数据写入磁盘时,采用顺序写速度要远远高于随机写,经测试同样环境下,顺序写速度为600MB/s,而随机写仅达到100KB/s,两者相差6000倍。基于此,Kafka Broker将收到的数据顺序写入磁盘,并结合基于offset的数据组织方式,能达到很高效的读速度和写速度。

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

  • 批处理:Kafka Broker将多条消息组装在一起,一并发送给Consumer,Kafka对数据格式进行了统一设计,保证数据存储和发送时采用统一的数据格式,避免数据格式转换带来的开销。
  • zero-copy技术:通常情况下一条存储在磁盘上的数据从读取到发送出去需要经过四次拷贝两次系统调用,四次数据拷贝依次为:内核态read buffer,用户态应用程序buffer,内核态socket buffer,网卡NIC buffer,通过zero-copy技术优化后数据只需经过三次拷贝即可发送出去:内核态read buffer,内核态socket buffer,网卡NIC buffer,且无需使用任何系统调用,大大提高数据发送效率。

5)可控的消息传递语义
消息传递语义分为三种:
1)at most once:发送者将消息发送给消费者后,立刻返回,不会关心消费者是否成功收到消息。这种情况下,消息可能被消费者成功接收。
2)at least once:发送者将消息发送给消费者后,需等待确认,如果未收到确认消息,则会重复发消息。这种语义能保证消费者收到消息,但可能会收到多次。
3)exactly once:消费者会且只会处理一次同一条消息。通常由两种常用的技术手段

  • 两段锁协议:分布式中常用的一致性协议。
  • 在支持幂等操作(多次处理一条消息跟只处理一次是等效的)的前提下,使用at least once语义。

你可能感兴趣的:(大数据平台搭建)