Kafka基础系列第2讲:Kafka技术架构剖析

使用过 Kafka 框架的朋友都知道,启动 Kafka 框架只需要两个关联的组件,分别是:Zookeeper 和 Kafka。如果你还没使用过 Kafka 框架,建议先阅读《Kafka 快速入门教程》把玩一下,对 Kafka 有一个感性的认识。

当我们熟悉了 Kafka 的使用之后,我们自然有一些疑惑:Kafka 到底是如何工作的?消息从生产者到 Kafka Server 这中间到底做了什么事情?而 Zookeeper Server 在这过程中有起到什么作用?带着这些疑问,今天我们来深入了解一下 Kafka 的工作机制。

我们先来看一下 Kafka 的架构图:

Kafka 的架构图可以分为四个部分:

  • Producer Cluster:生产者集群。一般由许多个实际的业务项目组成,其不断地往 Kafka 集群中写入数据。
  • Kafka Cluster:Kafka 服务器集群。这里就是 Kafka 作为重要的一部分,这里负责接收生产者写入的数据,并将其持久化到文件里,最终将消息提供给 Consumer Cluster。
  • Zookeeper Cluster:Zookeeper 集群。Zookeeper 负责维护整个 Kafka 集群的 Topic 信息、Kafka Controller 等信息。
  • Consumer Cluster:消费者集群。与 Producer Cluster 一样,其一般是由许多个实际的业务项目组成,不断地从 Kafka Cluster 中读取数据。

根据这个架构图,我们可以将一个消息的流转流程分为下面几个阶段:

  • 服务器启动阶段
  • 生产者发送消息阶段
  • Kafka存储消息阶段
  • 消费者拉取消息阶段

服务器启动阶段

首先,我们会启动 Zookeeper 服务器,作为集群管理服务器。

接着启动 Kafka Server,Kafka Server 会向 Zookeeper 服务器注册信息,接着启动线程池监听客户端的连接请求。(更详细的启动流程可以参考:)

接着启动消费端,连接到 Zookeeper 服务器,从 Zookeeper 服务器获取到对应的 Kafka Server 信息。

生产者发送消息阶段

当需要将消息存入消息队列中时,生产者根据配置的分片算法,选择分到哪一个 partition 中。在发送一条消息时,可以指定这条消息的 key,Producer 根据这个 key 和 Partition 机制来判断应该将这条消息发送到哪个 Parition。

Paritition 机制可以通过指定 Producer 的 paritition.class 这一参数来指定,该 class 必须实现 kafka.producer.Partitioner 接口。如果不实现 Partition 接口,那么会使用默认的分区算法,即根据根据 key 哈希后取余[4]。

随后生产者与该 Partition Leader 建立联系,之后将消息发送至该 partition leader。之后生产者会根据设置的 request.required.acks 参数不同,选择等待或或直接发送下一条消息。

  • request.required.acks = 0 表示 Producer 不等待来自 Leader 的 ACK 确认,直接发送下一条消息。在这种情况下,如果 Leader 分片所在服务器发生宕机,那么这些已经发送的数据会丢失。
  • request.required.acks = 1 表示 Producer 等待来自 Leader 的 ACK 确认,当收到确认后才发送下一条消息。在这种情况下,消息一定会被写入到 Leader 服务器,但并不保证 Follow 节点已经同步完成。所以如果在消息已经被写入 Leader 分片,但是还未同步到 Follower 节点,此时Leader 分片所在服务器宕机了,那么这条消息也就丢失了,无法被消费到。
  • request.required.acks = -1 表示 Producer 等待来自 Leader 和所有 Follower 的 ACK 确认之后,才发送下一条消息。在这种情况下,无论什么情况都不会发生消息的丢失,除非所有 Follower 节点都宕机了。

Kafka存储消息阶段

当 Kafka 接收到消息后,其并不直接将消息写入磁盘,而是先写入内存中。之后根据生产者设置参数的不同,选择是否回复 ack 给生产者。之后有一个线程会定期将内存中的数据刷入磁盘,这里有两个参数控制着这个过程:

# 数据达到多少条就将消息刷到磁盘
#log.flush.interval.messages=10000

# 多久将累积的消息刷到磁盘,任何一个达到指定值就触发写入
#log.flush.interval.ms=1000

如果我们设置 log.flush.interval.messages=1,那么每次来一条消息,就会刷一次磁盘。通过这种方式,就可以达到消息绝对不丢失的目的,这种情况我们称之为同步刷盘。反之,我们称之为异步刷盘。

于此同时,Kafka 服务器也会进行副本的复制,该 Partition 的 Follower 会从 Leader 节点拉取数据进行保存。然后将数据存储到 Partition 的 Follower 节点中。

消费者拉取消息阶段

在消费者启动时,其会连接到 zk 注册节点,之后根据所连接 topic 的 partition 个数和消费者个数,进行 partition 个数。一个 partition 最多只能被一个线程消费,但一个线程可以消费多个 partition。其分配算法如下:

我简单描述下这个算法的内容,假设我们连接的 topic 有 8 个 partition,此时有 3 个消费线程。那么气分配故城大致是这样的:

  • 8/3=2.667,向上取整就是3。
  • 那么给第一个消费者分配p0/p1/p2三个分区。
  • 给第二个消费者分配p3/p4/p5三个分区。
  • 给第三个消费者分配p6/p7两个分区。

接着消费者连接对应的分区,并从该分区服务器拉取数据。这里其实还会涉及到一个叫做「Zero Copy」的知识点,正是因为使用了「Zero Copy」技术才使得 Kafka 的吞吐量如此之高。

总结

从生产者到 Kafka,从 Kafka 到存储以及副本,再从 Kafka 到消费者。了解这整个过程可以让我们更好地理解 Kafka 消息队列。

参考资料

原文地址:https://www.cnblogs.com/chanshuyi/p/kafka_serial_02_kafka_archetecture.html

时间: 2024-10-10 01:38:58

Kafka基础系列第2讲:Kafka技术架构剖析的相关文章

【转】apache kafka监控系列-KafkaOffsetMonitor

apache kafka监控系列-KafkaOffsetMonitor 时间 2014-05-27 18:15:01  CSDN博客 原文  http://blog.csdn.net/lizhitao/article/details/27199863 主题 Apache Kafka apache kafka中国社区QQ群:162272557 概览 最近kafka server消息服务上线了,基于jmx指标参数也写到zabbix中了,但总觉得缺少点什么东西,可视化可操作的界面.zabbix中数据比

apache kafka监控系列-KafkaOffsetMonitor(转)

原文链接:apache kafka监控系列-KafkaOffsetMonitor 概览 最 近kafka server消息服务上线了,基于jmx指标参数也写到zabbix中了,但总觉得缺少点什么东西,可视化可操作的界面.zabbix中数据比较分散,不 能集中看整个集群情况.或者一个cluster中broker列表,自己写web-console比较耗时耗力,用原型工具画了一些管理界面东西,关键自 己也不前端方面技术,这方面比较薄弱.这不开源社区提供了kafka的web管理平台KafkaOffset

Kafka实战系列--Kafka API使用体验

前言: kafka是linkedin开源的消息队列, 淘宝的metaq就是基于kafka而研发. 而消息队列作为一个分布式组件, 在服务解耦/异步化, 扮演非常重要的角色. 本系列主要研究kafka的思想和使用, 本文主要讲解kafka的一些基本概念和api的使用. *) 准备工作1) 配置maven依赖 <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka_2.9.2</

【C++自我精讲】基础系列六 PIMPL模式

0 前言 很实用的一种基础模式. 1 PIMPL解释 PIMPL(Private Implementation 或 Pointer to Implementation)是通过一个私有的成员指针,将指针所指向的类的内部实现数据进行隐藏. 2 PIMPL优点 举例: //x.h class X { public: void Fun(); private: int i; //add int i; }; //c.h #include <x.h> class C { public: void Fun()

apache kafka监控系列-KafkaOffsetMonitor

概览 最近kafka server消息服务上线了,基于jmx指标参数也写到zabbix中了,但总觉得缺少点什么东西,可视化可操作的界面.zabbix中数据比较分散,不能集中看整个集群情况.或者一个cluster中broker列表,自己写web-console比较耗时耗力,用原型工具画了一些管理界面东西,关键自己也不前端方面技术,这方面比较薄弱.这不开源社区提供了kafka的web管理平台KafkaOffsetMonitor.就迅速拿过来运行.大家不要着急,马上娓娓道来. 说明: 这个应用程序来实

【C++自我精讲】基础系列五 隐式转换和显示转换

0 前言 1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换. 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换. 1 隐式转换 定义:隐式转换是系统跟据程序的需要而自动转换的. 1)C++类型(char,int,float,long,double等)的隐式转换: 算术表达式隐式转换顺序为: 1.char - int - long - double 2.float - double //1)算术表达式 int m = 10; double n = m;//n = 10

kafka 基础介绍

kafka 基础 kafka有四个核心API: 应用程序使用 Producer API 发布消息到1个或多个topic(主题). 应用程序使用 Consumer API 来订阅一个或多个topic,并处理产生的消息. 应用程序使用 Streams API 充当一个流处理器,从1个或多个topic消费输入流,并生产一个输出流到1个或多个输出topic,有效地将输入流转换到输出流. Connector API允许构建或运行可重复使用的生产者或消费者,将topic连接到现有的应用程序或数据系统.例如,

1.kafka基础架构

kafka基础架构 什么是kafka? Kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域. 1.什么是消息队列? 2.使用消息队列的好处 1)解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2)可恢复性 系统的一部分组件失效时,不会影响到整个系统.消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理. 3)缓冲 有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度

kafka基础集群部署

kafka集群部署方案 ZooKeeper第一步主机名称到IP地址映射配置ZooKeeper集群中具有两个关键的角色Leader和Follower.集群中所有的结点作为一个整体对分布式应用提供服务集群中每个结点之间都互相连接所以在配置的ZooKeeper集群的时候每一个结点的host到IP地址的映射都要配置上集群中其它结点的映射信息.例如我的ZooKeeper集群中每个结点的配置以zk-01为例/etc/hosts内容如下所示:192.168.0.11   zk-01192.168.0.12