Hadoop核心源码剖析系列(六): Kafka的架构、原理、特点介绍

作者 | 吴邪   大数据4年从业经验,目前就职于广州一家互联网公司,负责大数据基础平台自研、离线计算&实时计算研究

编辑 | auroral-L

‍Kafka作为时下火热的分布式消息中间件,应用于实际生产中的很多场景,包括实时计算场景、离线处理场景等等,作为一名与大数据有密切关系的IT从业者,在今天的市场环境中,一般你去其他公司面试,面试官几乎都会提出与kafka相关的各种问题让你解答,kafka可谓是大数据开发人员必备的技术栈。那么kafka究竟是什么呢?是用来干嘛的?以及为什么能成为主流的消息中间件呢?读者肯定关心这一系列问题,带着问题读文章会更加有目的性,通过这篇文章会得到你想知道的答案。‍

 

Apache Kafka简介

Kakfa最初由Linkedin公司开发,使用 Scala 编写,拥有高吞吐、可持久化、可水平扩展的基于发布/订阅模式的分布式消息队列,支持分区策略、多副本策略,基于zookeeper协调的分布式消息系统,主要应用于大数据的实时或离线数据处理、日志收集以及实时指标监控等领域。

 

kafka的出现

Kafka一开始出现的目的是为了用作 LinkedIn 公司业务的活动流(Activity Stream)和运营数据处理管道(Pipeline)。活动流数据是所有的网站对用户的使用情况做分析的时候要用到的,基于活动数据的最常规指标包括页面的访问量(PV)、被查看内容方面的信息以及搜索内容等。这种数据通常的处理方式是先把各种活动以日志的形式写入某种文件,然后周期性的对这些文件进行统计分析。运营数据指的是服务器的性能数据(CPU、IO 使用率、请求时间、服务日志等),Kafka作为一个消息中间件,类似消息管道,可以解决数据骤增和短时间持久化数据。目前,越来越多的开源分布式处理系统支持与Kafka集成,例如:Apache Storm、Spark、Flink。也有越来越多的公司在Kafka的基础上建立了近实时的信息处理平台。

 

kafka常用术语

消息:message,消息是kafka的基本数据单元,代表着一条一条的数据,为了提高网络和存储的利用率,生产者会批量发送消息到Kafka,并在发送之前对消息进行压缩。

主题:topic,主题是kafka对消息的分类,是一个逻辑概念,可以看作消息集合,用于接收不同业务的消息。

 

 

分区:partition,类似数据库的分区表,通常topic下会多个分区,每个分区内的数据是有序的,同一个topic的多个分区kafka不保证消息的顺序性,一个分区在逻辑上对应一个Log,对应磁盘上的一个文件夹。

偏移量:offset,偏移量是表示消息在分区中的位置,kafka存储的文件是按照offset.log的格式来命名的,便于快速查找。

 

副本:replicas,副本是针对分区而言的,kafka对消息做了冗余备份,目的就是为了容灾,每个分区可以指定多个副本来冗余数据,分为leader partition和follower partition,只有leader partition对外提供服务,follower partition单纯是从leader partition同步数据,因此会存在多份相同的数据。

 

生产者:producer,生产者是kafka集群的上游,顾名思义就是往kafka输入数据的客户端。

消费者:comsumer,消费者是kafka集群的下游,与生产者相辅相成,kafka类似一个仓库,生产者负责生产消息往仓库放,自然得有消费者从仓库里拿消息,不然仓库容易爆满。

消费者组:Comsumer Group,简称CG,这个比较容易理解,就是将多个消费者捆绑起来,组团消费消息,一个Consumer只能属于一个Consumer Group,Kafka还通过Consumer Group实现了消费者的水平扩展和故障转移。

 

节点:broker,一个broker就是一个kafka server实例,多个broker组成kafka集群,主要用于接收生产者发送过来的消息,写入磁盘,同时可以接收消费者和其他broker的请求。

重新负载均衡:rebalance,当消费者组的消费者实例出现变化时,例如新增消费者或者减少消费者,都会触发kafka的Rebalance机制,这个过程比较耗性能,要尽量避免这个过程被触发。

 

Kafka架构

我们把架构分主从架构和对等架构,主从架构就是分为管理节点和工作节点,职责不同,如HDFS 、spark、flink;对等架构则不区分节点属性,所有的实例职责都是一样的,kafka的架构有点类似于对等架构,但又不完全是。Kafka的设计理念之一就是同时提供离线处理和实时处理。

图1:kafka集群架构

如上图所示,一个Kafka集群中通常有多个producer,多个broker节点,多个consumer,以及一个zookeeper集群组成。Kafka通过Zookeeper管理集群配置,作为协调节点选举leader,以及在consumer group发生变化时进行rebalance。上游的producer使用push模式将消息发布到broker,下游的consumer使用pull模式负责从broker订阅并消费消息。需要注意的是,kakfa 旧版本的kafka的消费者偏移量是由zookeeper集群来维护的,新版本的kafka自身支持了元数据管理机制,自己维护消息的偏移量,减少对外部的依赖同时提高读写性能。

 

Kafka工作原理

从图1可以知道,kafka的工作流程主要是处理生产者推送的消息请求以及处理消费者拉取消息的请求。

  1. 首先,生产者在往kafka集群写入消息之前会通过集群获取到leader partition的位置。

  2. 知道leader partition的位置之后就开始将消息以批次的方式加入队列并写入到leader partition。

  3. leader partition接收到数据之后,会先将数据持久化到磁盘文件。

  4. 完成数据持久化之后,此时follower partition会主动从leader partition同步数据。

  5. 同步完成之后,向leader partition发送ack信号,表明已经完成数据同步。

  6. leader partition收到所有副本完成同步的ack信号之后,就通知producer该请求包含的数据已经写入成功,可以接着写了。

 

Kafka ACK消息确认机制有三个值,分别为1,0和-1,默认是1,对应不同的状态:

  1. ack=1,意味着producer要等待leader成功收到数据并得到确认,才发送下一条message,安全性较高但是性能相对较低。

  2. ack=0,意思就是说,我只管发送消息,不用你给我回复,成就成,不成我也不管,这种策略的性能是最高的,但是容易丢失数据。

  3. ack=-1,这种情况下,生产者只有收到所有副本写入成功的通知后,才会认为消息写入成功,安全性最高,但是性能是三者里面最差的。

 

每个分区都相当于一个队列,每条消息会根据不同的分区策略持续有序地追加到分区中,保证每个分区里面的消息是有序的,每个消息都有自己的偏移量。消息写成log文件之后,消费者就可以进行消费了。与生产消息相同的是,消费者在拉取消息的时候也是找leader去拉取。通常多个消费者会组成一个消费者组,每个消费者组都有唯一的group id!同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会出现组内多个消费者消费同一分区的数据,如下图所示。

 

kafka分区和副本机制

kafka分区机制是实现kafka高吞吐量的重要手段,实现流量分发和负载均衡,试想一下,如果所有的消息都往同一个数据写,对于服务器来说会造成极高的负载,特别是出现热点数据的时候容易崩溃,对于多个生产者和多个消费者来说,只有一个分区可以用于生产和消费,这显然是非常受限的。

kafka提供了三种分区策略:

  1. 轮询策略:Round-robin,轮询策略是Kafka默认的分区策略,根据主题分区数量从头到尾进行轮询,目的就是为了将消息均匀地分布在分区中,保证消息最大限度地被平均分配到所有分区上。

  2. 随机策略:Range Strategy,所谓随机就是我们随意地将消息放置到任意一个分区上,随机分发,这样有可能会造成消息分发不均匀,相比之下,轮询策略显得更加合理,旧版本默认是用随机策略,新版本默认用的是轮询策略。

  3. 按key分发策略:顾名思义就是根据消息的key指定分区写入,这种方式主观性比较强,相对比较灵活。

除此之外,kafka支持自定义分区器,实现更多复杂的逻辑处理消息。

 

kafka副本机制是为了提供数据冗余、数据备份的安全策略,等同于备份,实际上,基本所有的分布式消息队列都会存在副本机制,不光是消息队列,HDFS也是如此。

前面在kafka常用术语中说到,Kafka 是有主题概念的,主题下划分成若干个分区,副本是分区的逻辑概念,分区可以指定多个副本。本质上副本就是一个只能不断追加的日志文件,在实际的生产中,为了保障数据安全,通常会配置多个副本,根据算法分散在不同的broker上,一份数据(leader和副本)不会同时出现在一台服务器上,这样当服务器出现故障时,能够最大程度保证数据不丢失,如下图。

其中leader partition和 follower partition的工作原理如下,正常情况下,只有leader partition对外提供服务,follower partition负责从leader partition拉取数据,当leader发送故障时,follower拥有被选举为新leader的权利。

 

Kafka的优势

号称大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开Kafka,这款专为大数据而生的消息中间件,以其百万级TPS的吞吐量而名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。

  • 支持数据离线和实时处理

  • 能保证消息的可靠性传递

  • 支持消息的持久化存储,并通过多副本分布式的存储方案来保证消息的容错

  • 高吞吐率,每秒处理百万级的消息量

  • 高并发,支持数千个客户端同时读写

  • 支持在线水平扩展

kafka为什么能实现读写都这么快呢?离不开kafka顺序读写机制和零拷贝数据传输,减少了寻址的时间消耗,降低了读写延迟,同时有利于快到定位消息偏移量,零拷贝机制可以提高数据传输的效率,减少IO资源的占用。

 

常用MQ组件比较

常见的主流分布式消息队列有Kafka、RabbitMQ、RocketMQ和ActiveMQ,这几者都是分布式消息中间件,各自有不同的功能特性和优势,企业可以根据不同场景的要求选择最合适的组件。

特性

ActiveMQ

RabbitMQ

RocketMQ

kafka

开发语言

java

erlang

java

scala

单机吞吐量

万级

万级

10万级

10万级

时效性

ms级

us级

ms级

ms级以内

可用性

高(主从架构)

高(主从架构)

非常高(分布式架构)

非常高(分布式架构)

功能特性

成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好

基于erlang开发,所以并发能力很强,性能极其好,延时很低;管理界面较丰富

MQ功能比较完备,扩展性佳

只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。

根据社区热度的数据可以看到,Kafka是最受欢迎的。

 

从搜索的热度上体现出Kafka受到用户的持续关注,相反,ActiveMQ和RabbitMQ显得不愠不火,说明更多的用户比较认可Kafka这个开源的分布式消息中间件。

在技术选型中有一个原则,没有最好,只有最合适。

温馨提示:对kafka感兴趣的小伙伴可以关注后续的Kafka源码分析系列,尽在公众号:数据与智能

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据与智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值