关于后端:程序员必须了解的消息队列之王Kafka

33次阅读

共计 6216 个字符,预计需要花费 16 分钟才能阅读完成。

1. Kafka 概述

1.1 定义

Kafka 是由 Apache 软件基金会开发的一个开源流解决平台。

Kafka 是一个 分布式 的基于 公布 / 订阅模式的音讯队列(Message Queue),次要利用于大数据实时处理畛域。

1.2 音讯队列

1.2.1 传统音讯队列的利用场景

1.2.2 为什么须要音讯队列

  1. 解耦:容许你独立的扩大或批改两边的处理过程,只有确保它们恪守同样的接口束缚。
  2. 冗余:音讯队列把数据进行长久化直到它们曾经被齐全解决,通过这一形式躲避了数据失落危险。许多音讯队列所采纳的 ” 插入 - 获取 - 删除 ” 范式中,在把一个音讯从队列中删除之前,须要你的解决零碎明确的指出该音讯曾经被处理完毕,从而确保你的数据被平安的保留直到你应用结束。
  3. 扩展性:因为音讯队列解耦了你的处理过程,所以增大音讯入队和解决的频率是很容易的,只有另外减少处理过程即可。
  4. 灵活性 & 峰值解决能力:在访问量剧增的状况下,利用依然须要持续发挥作用,然而这样的突发流量并不常见。如果为以能解决这类峰值拜访为规范来投入资源随时待命无疑是微小的节约。应用音讯队列可能使要害组件顶住突发的拜访压力,而不会因为突发的超负荷的申请而齐全解体。
  5. 可恢复性:零碎的一部分组件生效时,不会影响到整个零碎。音讯队列升高了过程间的耦合度,所以即便一个解决音讯的过程挂掉,退出队列中的音讯依然能够在零碎复原后被解决。
  6. 程序保障:在大多应用场景下,数据处理的程序都很重要。大部分音讯队列原本就是排序的,并且能保证数据会依照特定的程序来解决。(Kafka 保障一个 Partition 内的音讯的有序性)
  7. 缓冲:有助于管制和优化数据流通过零碎的速度,解决生产音讯和生产音讯的处理速度不统一的状况。
  8. 异步通信:很多时候,用户不想也不须要立刻解决音讯。音讯队列提供了异步解决机制,容许用户把一个音讯放入队列,但并不立刻解决它。想向队列中放入多少音讯就放多少,而后在须要的时候再去解决它们。

1.2.3 音讯队列的两种模式

  • 点对点模式(一对一,消费者被动拉取数据,收到后音讯革除)

    音讯生产者生产音讯发送到 Queue 中,而后消费者从 Queue 中取出并且生产音讯。音讯被生产当前,queue 中不再有存储,所以音讯消费者不可能生产到曾经被生产的音讯。Queue 反对存在多个消费者,然而对一个音讯而言,只会有一个消费者能够生产。

  • 公布 / 订阅模式(一对多,数据生产后,推送给所有订阅者)

    音讯生产者(公布)将音讯公布到 topic 中,同时有多个音讯消费者(订阅)生产该音讯。和点对点形式不同,公布到 topic 的音讯会被所有订阅者生产。

1.3 Kafka 根底架构图

  • Producer:音讯生产者,就是向 kafka broker 发消息的客户端;
  • Consumer:音讯消费者,向 kafka broker 取音讯的客户端;
  • Consumer Group(CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责生产不同分区的数据,一个分区只能由一个组内消费者生产;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
  • Broker:一台 kafka 服务器就是一个 broker(尽管多个 Broker 过程可能运行在同一台机器上,但更常见的做法是将不同的 Broker 扩散运行在不同的机器上)。一个集群由多个 broker 组成。一个 broker 能够包容多个 topic;
  • Topic:能够了解为一个队列,Kafka 的音讯通过 Topics(主题) 进行分类,生产者和消费者面向的都是一个 topic;
  • Partition:为了实现扩展性,一个十分大的 topic 能够散布到多个 broker(即服务器)上,一个 topic 能够分为多个 partition,每个 partition 是一个有序的队列;partition 中的每条音讯都会被调配一个有序的 id(offset)。kafka 只保障按一个 partition 中的程序将音讯发给 consumer,不保障一个 topic 的整体(多个 partition 间)的程序;
  • Replica:正本,为保障集群中的某个节点产生故障时,该节点上的 partition 数据不失落,且 kafka 依然可能持续工作,kafka 提供了正本机制,一个 topic 的每个分区都有若干个正本,一个 leader 和若干个 follower;
  • leader:每个分区多个正本的“主”,生产者发送数据的对象,以及消费者生产数据的对象都是 leader
  • follower:每个分区多个正本中的“从”,实时从 leader 中同步数据,放弃和 leader 数据的同步。leader 产生故障时,某个 follower 会成为新的 follower;
  • offset:kafka 的存储文件都是依照 offset.kafka 来命名,用 offset 做名字的益处是不便查找。例如你想找位于 2049 的地位,只有找到 2048.kafka 的文件即可。当然 the first offset 就是 00000000000.kafka。

2. Hello Kafka

2.1 动起手来

Quickstart

中文版入门指南

2.2 基本概念(官网介绍翻译)

Kafka 是一个分布式的流解决平台。是反对分区的(partition)、多正本的(replica),基于 ZooKeeper 协调的分布式音讯零碎,它的最大的个性就是能够实时的解决大量数据以满足各种需要场景:比方基于 hadoop 的批处理零碎、低提早的实时零碎、storm/Spark 流式解决引擎,web/nginx 日志、拜访日志,音讯服务等等

有三个要害能力

  • 它能够让你公布和订阅记录流。在这方面,它相似于一个音讯队列或企业音讯零碎
  • 它能够让你长久化收到的记录流,从而具备容错能力
  • 它能够让你解决收到的记录流

利用于两大类利用

  • 构建实时的流数据管道,牢靠地获取零碎和应用程序之间的数据。
  • 构建实时流的应用程序,对数据流进行转换或反馈。

想要理解 Kafka 如何具备这些能力,首先,明确几个概念:

  • Kafka 作为一个集群运行在一个或多个服务器上
  • Kafka 集群存储的音讯是以主题(topics)为类别记录的
  • 每个音讯记录蕴含一个键,一个值和工夫戳

Kafka 有五个外围 API:

  • Producer API 容许应用程序公布记录流至一个或多个 Kafka 的话题(Topics)
  • Consumer API 容许应用程序订阅一个或多个主题,并解决这些主题接管到的记录流
  • Streams API 容许应用程序充当流处理器(stream processor),从一个或多个主题获取输出流,并生产一个输入流至一个或多个的主题,可能无效地变换输出流为输入流
  • Connector API 容许构建和运行可重用的生产者或消费者,可能把 Kafka 主题连贯到现有的应用程序或数据系统。例如,一个连贯到关系数据库的连接器 (connector) 可能会获取每个表的变动
  • Admin API 容许治理和查看主题、brokes 和其余 Kafka 对象。(这个是新版本才有的)

Kafka 的客户端和服务器之间的通信是靠一个简略的,高性能的,与语言无关的 TCP 协定实现的。这个协定有不同的版本,并放弃向后兼容旧版本。Kafka 不光提供了一个 Java 客户端,还有许多语言版本的客户端。

主题和日志

主题是同一类别的音讯记录(record)的汇合。Kafka 的主题反对多用户订阅,也就是说,一个主题能够有零个,一个或多个消费者订阅写入的数据。对于每个主题,Kafka 集群都会保护一个分区日志,如下所示:

每个分区是一个有序的,不可变的音讯序列,新的音讯一直追加到 partition 的开端。在每个 partition 中,每条音讯都会被调配一个程序的惟一标识,这个标识被称为 offset,即偏移量。kafka 不能保障全局有序,只能保障分区内有序

Kafka 集群保留所有公布的记录,不论这个记录有没有被生产过,Kafka 提供可配置的保留策略去删除旧数据(还有一种策略依据分区大小删除数据)。例如,如果将保留策略设置为两天,在数据公布后两天,它可用于生产,之后它将被抛弃以腾出空间。Kafka 的性能跟存储的数据量的大小无关(会长久化到硬盘),所以将数据存储很长一段时间是没有问题的。

事实上,在单个消费者层面上,每个消费者保留的惟一的元数据就是它所生产的数据日志文件的偏移量。偏移量是由消费者来管制的,通常状况下,消费者会在读取记录时线性的进步其偏移量。不过因为偏移量是由消费者管制,所以消费者能够将偏移量设置到任何地位,比方设置到以前的地位对数据进行反复生产,或者设置到最新地位来跳过一些数据。

分布式

日志的分区会跨服务器的散布在 Kafka 集群中,每个服务器会共享分区进行数据申请的解决。每个分区能够配置肯定数量的正本分区提供容错能力

每个分区都有一个服务器充当“leader”和零个或多个服务器充当“followers”。leader 解决所有的读取和写入分区的申请,而 followers 被动的从领导者拷贝数据。如果 leader 失败了,followers 之一将主动成为新的领导者。每个服务器可能充当一些分区的 leader 和其余分区的 follower,所以 Kafka 集群内的负载会比拟平衡。

生产者

生产者公布数据到他们所抉择的主题。生产者负责抉择把记录调配到主题中的哪个分区。这能够应用轮询算法 (round-robin) 进行简略地均衡负载,也能够依据一些更简单的语义分区算法(比方基于记录一些键值)来实现。

消费者

消费者以消费群(consumer group)的名称来标识本人,每个公布到主题的音讯都会发送给订阅了这个主题的消费群外面的一个消费者的一个实例。消费者的实例能够在独自的过程或独自的机器上。

如果所有的消费者实例都属于雷同的消费群,那么记录将无效地被平衡到每个消费者实例。

如果所有的消费者实例有不同的消费群,那么每个音讯将被播送到所有的消费者过程。

这是 kafka 用来实现一个 topic 音讯的播送(发给所有的 consumer)和单播(发给任意一个 consumer)的伎俩。一个 topic 能够有多个 CG。topic 的音讯会复制(不是真的复制,是概念上的)到所有的 CG,但每个 partion 只会把音讯发给该 CG 中的一 个 consumer。如果须要实现播送,只有每个 consumer 有一个独立的 CG 就能够了。要实现单播只有所有的 consumer 在同一个 CG。用 CG 还能够将 consumer 进行自在的分组而不须要屡次发送音讯到不同的 topic;

举个栗子:

如上图所示,一个两个节点的 Kafka 集群上领有一个四个 partition(P0-P3)的 topic。有两个消费者组都在生产这个 topic 中的数据,消费者组 A 有两个消费者实例,消费者组 B 有四个消费者实例。

从图中咱们能够看到,在同一个消费者组中,每个消费者实例能够生产多个分区,然而每个分区最多只能被消费者组中的一个实例生产。也就是说,如果有一个 4 个分区的主题,那么消费者组中最多只能有 4 个消费者实例去生产,多进去的都不会被调配到分区。其实这也很好了解,如果容许两个消费者实例同时生产同一个分区,那么就无奈记录这个分区被这个消费者组生产的 offset 了。如果在消费者组中动静的上线或下线消费者,那么 Kafka 集群会主动调整分区与消费者实例间的对应关系。

Kafka 消费群的实现形式是通过宰割日志的分区,分给每个 Consumer 实例,使每个实例在任何工夫点的都能够“偏心分享”独占的分区。维持消费群中的成员关系的这个过程是通过 Kafka 动静协定解决。如果新的实例退出该组,他将接管该组的其余成员的一些分区;如果一个实例死亡,其分区将被调配到残余的实例。

Kafka 只保障一个分区内的音讯有序,不能保障一个主题的不同分区之间的音讯有序。分区的音讯有序与依附主键进行数据分区的能力相结合足以满足大多数利用的要求。然而,如果你想要保障所有的音讯都相对有序能够只为一个主题调配一个分区,尽管这将意味着每个消费群同时只能有一个生产过程在生产。

保障

Kafka 提供了以下一些高级别的保障:

  • 由生产者发送到一个特定的主题分区的音讯将被以他们被发送的程序来追加。也就是说,如果一个音讯 M1 和音讯 M2 都来自同一个生产者,M1 先发,那么 M1 将有一个低于 M2 的偏移,会更早在日志中呈现。
  • 消费者看到的记录排序就是记录被存储在日志中的程序。
  • 对于正本因子 N 的主题,咱们将接受最多 N-1 次服务器故障切换而不会损失任何的曾经保留的记录。

2.3 Kafka 的应用场景

音讯

Kafka 被当作传统消息中间件的替代品。消息中间件的应用起因有多种(从数据生产者解耦解决,缓存未解决的音讯等)。与大多数音讯零碎相比,Kafka 具备更好的吞吐量,内置的分区,多正本和容错性能,这使其成为大规模音讯解决应用程序的良好解决方案。

网站行为跟踪

Kafka 的初衷就是可能将用户行为跟踪管道重构为一组实时公布 - 订阅数据源。这意味着网站流动(页面浏览量,搜寻或其余用户行为)将被公布到核心主题,这些核心主题是每个用户行为类型对应一个主题的。这些数据源可被订阅者获取并用于一系列的场景,包含实时处理,实时监控和加载到 Hadoop 或离线数据仓库零碎中进行离线解决和报告。用户行为跟踪通常会产生微小的数据量,因为用户每个页面的浏览都会生成许多行为流动音讯。

测量

Kafka 通常用于监测数据的解决。这波及从分布式应用程序汇集统计数据,生产出集中的运行数据源 feeds(以便订阅)。

日志聚合

许多人用 Kafka 作为日志聚合解决方案的替代品。日志聚合通常从服务器收集物理日志文件,并将它们集中搁置(可能是文件服务器或 HDFS),以便后续解决。kafka 形象出文件的细节,并将日志或事件数据作为音讯流清晰地形象进去。这为低时延的解决提供反对,而且更容易反对多个数据源和分布式的数据生产。相比集中式的日志解决零碎(如 Scribe 或 Flume),Kafka 性能同样杰出,而且因为正本备份提供了更强的可靠性保障和更低的端到端提早。

流解决

Kafka 的流数据管道在解决数据的时候蕴含多个阶段,其中原始输出数据从 Kafka 主题被生产而后汇总,加工,或转化成新主题用于进一步的生产或后续解决。例如,用于举荐新闻文章的数据流解决管道可能从 RSS 源抓取文章内容,并将其公布到“文章”主题; 进一步的解决可能是标准化或删除反复数据,而后公布解决过的文章内容到一个新的主题,最初的解决阶段可能会尝试举荐这个内容给用户。这种解决管道依据各个主题创立实时数据流图。从版本 0.10.0.0 开始,Apache Kafka 退出了轻量级的但功能强大的流解决库 Kafka Streams,Kafka Streams 反对如上所述的数据处理。除了 Kafka Streams,能够抉择的开源流解决工具包含 Apache Storm and Apache Samza

事件源

事件源是一种利用程序设计格调,是依照工夫程序记录的状态变动的序列。Kafka 的十分弱小的存储日志数据的能力使它成为构建这种应用程序的极好的后端抉择。

提交日志

Kafka 能够为分布式系统提供一种内部提交日志 (commit-log) 服务。日志有助于节点之间复制数据,并作为一种数据从新同步机制用来复原故障节点的数据。Kafka 的 log compaction 性能有助于反对这种用法。Kafka 在这种用法中相似于 Apache BookKeeper 我的项目。

本文由 mdnice 多平台公布

正文完
 0