深入浅出Kafka(3):我的生命是如何运转的?

点击上方“Python与算法社区”,选择“星标”公众号

第一时间速享原创干货

系列第三篇,总第290篇原创


1

Kafka作为一个消息系统,为什么会如此受欢迎?消息系统在不同系统传输数据中扮演着非常重要的角色。让我们看看没有消息系统的数据管道会怎样?


以Hadoop为例,Kafka起始于数据存储与处理的Hadoop开源框架。如果没有数据,Hadoop就变的一点用没有,所以首先应该是将数据迁移到Hadoop。


640?wx_fmt=png


数据可能来源于不同的独立系统,这些系统都需要与Hadoop交互,相互交互。


这就会变的非常复杂,不同系统之间可能存在许多通信通道,不同通道之间需要自定义协议与通信方法,因此迁移数据就成了开发团队的焦点,所有精力都被集中到数据传输而不是业务实现


640?wx_fmt=png


在看这张图片,如果使用Kafka作为消息传输的缓冲区,所有应用程序之间的依赖都被解耦合了,只需要发送数据到Kafka,然后从Kafka取消息。应用程序只需要针对Kafka的消息传输接口,开发出一套消息生产或者消费接口即可。


640?wx_fmt=png


2

什么是Kafka?


Kafka是一个基于发布订阅模式实现的快速、高可扩展、高可备份的分布式消息系统。


Kafka的分布式设计有以下几个优点:

(1)Kafka允许有大量的永久或者临时消费者消费消息。

(2)对于节点障碍,Kafka支持自动恢复。


这些优点使得kafka活跃在大规模数据系统之间。


3

Kafka术语


Kafka理论主要涉及以下概念:topics、producers、consumers、brokers、partitions


Kafka消息是以topic来归类集中到一起,不同topic的消息将不会被归类到一起。如果你想要发送一条消息,首先你要指定相应的topic,将消息缓存到指定的topic里。


消费者想要从Kafka拉取消息,也要指定相应的topic,获取哪个topic里的消息。Kafka作为一个分布式消息系统,是以集群的方式运行,每个节点都被称作broker


4

Kafka topic


Topic对消息的管理分类是以partitions来实现的,partition是分区的意思,producers产生的消息都会被存储到partition中,一个topic可以有一个或者多个partition


每个消息在partition中都会分配一个offset标识,标识这个消息在这个partition中的位置。因此一个消息可以通过(topic、partition、offset)这个元组来确定。


消息进入到partition中是有顺序的且不可变,但是可以通过offset来实现任意需求的消费消息。不一定非要从消息队列的尾部消息,也不一定是头部,有了offset你可以从任意位置,任意的方向,甚至是随机的消费消息。


640?wx_fmt=png


5

Kafka Log

分区(partition)读写消息实际上也是一种逻辑上的实现,消息真正的读写是在Kafka Log文件系统中实现的。


如果你在主机上启动Kafka在topic为test的情况下创建两个分区,你可以进入到具体目录里面看到,有test0、与test1两个文件夹(假设没有指定副本个数),进入到test0里面,会有index与log两个文件,log文件就负责物理意义上的存储消息。


所以为什么Kakfa读写速度如此之快,其中一个原因就是按照顺序将消息存储到文件系统当中。下图是数据源往Log文件中写数据, 其他两个消费者在自定义offset的情况下消息消费数据。


640?wx_fmt=png


也是因为如此,Kafka的消息不会因为被消费了而消失,其他的消费者在指定offset的情况下也能够消费到已经被其他消费者消费过的消息。


Kakfa可以自定义配置有效消息时间周期,也就是说会按期清理过期的消息。


如果有效消息周期设置为1天,消费者不能够在一天内消费完,那么消息将会丢失,如果在消费过程中节点挂掉,恢复后又会重新消费。从Kafka的角度来看,它没有对消费者从主题中消费的消息保持任何状态。


6

Partitions and Brokers


每个broker是一个运行的kafka实例,每个broker下可以有多个partition,一个topic可以由多个broker来维护,因此可以得知就概念的范围来说:topic>broker>partition


Kakfa为了保障数据的安全性,也有副本机制。创建topic时候一般会指定分区个数与副本个数,如下图,假设启动3个broker指定3个分区分别是partition0、partition1、partition2,和2个副本。


Kafka中每个partition都会有一个leader负责读写数据,另外两个作为副本,只备份leader中的数据。这里leader负责了两个功能,一是负责响应producer与consumer,也就是读写消息。另外负责把新的消息协调更新到副本。


640?wx_fmt=png


假设客户端往partition0中写消息,如下图,leader响应后,将消息存储到broker1的partition0中,然后再往broker2、broker3中的partiton0中备份消息。


640?wx_fmt=png


7

消费者与消费者组


Kafka是以组来归类消费者,因为Kafka是基于发布订阅模式设计的,如果生产一条消息,那么所有订阅相应topic的consumer都会收到这条消息,如果想要所有consumer只能其中一个来消费,那么就把它们都设置为同一组,这样consumer就会排队消费message,如果想要所有的consumer都收到消息(比如说新闻消息)那么把所有的consumer都设置为不同的组即可。


Kafka为什么会有较高的吞吐量呢?假设把consumers归为一组,那么consumer只会从topic下的其中一个partition去拉取消息,其他partition不管,这样就保证了在多个consumers条件下每条消息只会被消费一次。


这样就会存在这样一种现象,如果consumers的数量大于partitions,则有部分consumer将会处于闲置状态,如果小于的话,则部分partition不会被消费,这将由kafka的负载均衡机制来解决,避免partition之间messages数量差异过大。


如果consumers等于patitions的数量,那么每个partition都会分配一个consumer并行消息,这样就造成了Kafka有较高的吞吐量。笔者之前也设计过相关的程序,采取的是消息队列的方式,多个consumers从一个队列中拉取messages,这个弊端就是在一定情境下,无论我启动多少个consumers,只有固定数量的consumer在工作,而其他的处于闲置状态。


这张图来自kafka官方文档,图中有两个server,分别是server1、server2。有两个消费者组,groupA与groupB。图中,C1与C2向Server1拉取messages,C2向Server2拉取。GroupB中,每个consumer都分配了一个partition。


640?wx_fmt=png


8

Kafka写操作


Kafka写操作主要由leader完成,leader要将消息写入到partition中,并且还要写到其他replica(副本)中。


640?wx_fmt=png


一共有三种形式来完成Kafka写操作

  1. producer 产生一条消息,发送给leader,leader写入到partition中,然后询问replica你们是否alive?如果得到ack则写到replica中,replica在返回一个ack告诉leader写完了,然后leader再把ack返回给producer,告诉它我完成了写操作。


  2. leader直接将message写到partition中,得到replica的alive响应后,直接将message写到replica的partition中不等待replica的写完ack直接响应producer告诉它我完成了写操作


  3. producer直接将message扔给leader,不等待任何响应就继续下一条message生产。


如果某个replica发生故障呢?


Partition之间都有一个心跳机制,leader通过心跳获取follower的状态,如果一段时间内没有得到follower的响应,则认为死亡就不会把消息备份到这个replica中。


如果leader发生故障,则在其他replica中继续选举一个leader。有趣的是kafka的选举机制依赖于zookeeper,通过zookeeper的序列节点来完成,每启动一个partition, 就会在zookeeper中注册一个序列节点(如果忘记序列节点特性的话,可以去看看上一节中zookeeper的介绍)。哪个节点的编号最小,则为leader。如果leader故障,选次之作为leader。


9

Kafka的理论就介绍到这,如还有没覆盖到的欢迎提出一起学习,笔者作为Kafka小白总结本篇文章主要参考https://sookocheff.com/post/kafka/kafka-in-a-nutshell/。


下篇文章将会介绍如何搭建分布式Kafka集群,以及Kafka Stream介绍。




推荐阅读

Kafka入门教程(2): 我是 Zookeeper

Kafka入门教程(1)



点个在看smiley_66.png

支持原创!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值