关于java:详解Kafka背后优秀的架构设计图文版

48次阅读

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

本文章转自:乐字节

文章次要解说:Kafka 架构设计

获取更多 Java 相干常识能够关注公众号《乐字节》发送:999

前言

应大部分的小伙伴的要求,在 Yarn 之前先来一个 kafka 的小插曲,轻松愉快。

一、Kafka 根底

音讯零碎的作用

应该大部份小伙伴都分明,用机油装箱举个例子

所以音讯零碎就是如上图咱们所说的仓库,能在两头过程作为缓存,并且实现解耦合的作用。

引入一个场景,咱们晓得中国移动,中国联通,中国电信的日志解决,是交给外包去做大数据分析的,假如当初它们的日志都交给了你做的零碎去做用户画像剖析。

依照刚刚后面提到的音讯零碎的作用,咱们晓得了音讯零碎其实就是一个模仿缓存,且仅仅是起到了缓存的作用而并不是真正的缓存,数据依然是存储在磁盘下面而不是内存。

1.Topic 主题

kafka 学习了数据库外面的设计,在外面设计了 topic(主题),这个货色相似于关系型数据库的表

此时我须要获取中国移动的数据,那就间接监听 TopicA 即可

2.Partition 分区

kafka 还有一个概念叫 Partition(分区),分区具体在服务器下面体现起初就是一个目录,一个主题上面有多个分区,这些分区会存储到不同的服务器下面,或者说,其实就是在不同的主机上建了不同的目录。这些分区次要的信息就存在了.log 文件外面。跟数据库外面的分区差不多,是为了进步性能。

至于为什么进步了性能,很简略,多个分区多个线程,多个线程并行处理必定会比单线程好得多

Topic 和 partition 像是 HBASE 里的 table 和 region 的概念,table 只是一个逻辑上的概念,真正存储数据的是 region,这些 region 会分布式地存储在各个服务器下面,对应于 kafka,也是一样,Topic 也是逻辑概念,而 partition 就是分布式存储单元。这个设计是保障了海量数据处理的根底。咱们能够比照一下,如果 HDFS 没有 block 的设计,一个 100T 的文件也只能独自放在一个服务器下面,那就间接占满整个服务器了,引入 block 后,大文件能够扩散存储在不同的服务器上。

留神:1. 分区会有单点故障问题,所以咱们会为每个分区设置正本数

2. 分区的编号是从 0 开始的

3.Producer – 生产者

往音讯零碎外面发送数据的就是生产者

4.Consumer – 消费者

从 kafka 里读取数据的就是消费者

5.Message – 音讯

kafka 外面的咱们解决的数据叫做音讯

二、kafka 的集群架构

创立一个 TopicA 的主题,3 个分区别离存储在不同的服务器,也就是 broker 上面。Topic 是一个逻辑上的概念,并不能间接在图中把 Topic 的相干单元画出

须要留神:kafka 在 0.8 版本以前是没有正本机制的,所以在面对服务器宕机的突发状况时会失落数据,所以尽量避免应用这个版本之前的 kafka

Replica – 正本

kafka 中的 partition 为了保障数据安全,所以每个 partition 能够设置多个正本。

此时咱们对分区 0,1,2 别离设置 3 个正本(其实设置两个正本是比拟适合的)

而且其实每个正本都是有角色之分的,它们会选取一个正本作为 leader,而其余的作为 follower,咱们的生产者在发送数据的时候,是间接发送到 leader partition 外面,而后 follower partition 会去 leader 那里自行同步数据,消费者生产数据的时候,也是从 leader 那去生产数据的。

Consumer Group – 消费者组

咱们在生产数据时会在代码外面指定一个 group.id, 这个 id 代表的是生产组的名字,而且这个 group.id 就算不设置,零碎也会默认设置

咱们所熟知的一些音讯零碎一般来说会这样设计,就是只有有一个消费者去生产了音讯零碎外面的数据,那么其余所有的消费者都不能再去生产这个数据。可是 kafka 并不是这样, 比方当初 consumerA 去生产了一个 topicA 外面的数据。

再让 consumerB 也去生产 TopicA 的数据,它是生产不到了,然而咱们在 consumerC 中从新指定一个另外的 group.id,consumerC 是能够生产到 topicA 的数据的。而 consumerD 也是生产不到的,所以在 kafka 中,不同组可有惟一的一个消费者去生产同一主题的数据。

所以消费者组就是让多个消费者并行生产信息而存在的,而且它们不会生产到同一个音讯,如下,consumerA,B,C 是不会相互烦扰的

如图,因为后面提到过了消费者会间接和 leader 建立联系,所以它们别离生产了三个 leader,所以一个分区不会让消费者组外面的多个消费者去生产,然而在消费者不饱和的状况下,一个消费者是能够去生产多个分区的数据的。

Controller

熟知一个法则:在大数据分布式文件系统外面,95% 的都是主从式的架构,个别是对等式的架构,比方 ElasticSearch。

kafka 也是主从式的架构,主节点就叫 controller,其余的为从节点,controller 是须要和 zookeeper 进行配合治理整个 kafka 集群。

kafka 和 zookeeper 如何配合工作

kafka 重大依赖于 zookeeper 集群(所以之前的 zookeeper 文章还是有点用的)。所有的 broker 在启动的时候都会往 zookeeper 进行注册,目标就是选举出一个 controller,这个选举过程非常简单粗犷,就是一个谁先谁当的过程,不波及什么算法问题。

那成为 controller 之后要做啥呢,它会监听 zookeeper 外面的多个目录,例如有一个目录 /brokers/,其余从节点往这个目录上 注册(就是往这个目录上创立属于本人的子目录而已)本人,这时命名规定个别是它们的 id 编号,比方 /brokers/0,1,2

注册时各个节点必定会裸露本人的主机名,端口号等等的信息,此时 controller 就要去读取注册上来的从节点的数据(通过监听机制),生成集群的元数据信息,之后把这些信息都分发给其余的服务器,让其余服务器能感知到集群中其它成员的存在。

此时模仿一个场景,咱们创立一个主题(其实就是在 zookeeper 上 /topics/topicA 这样创立一个目录而已),kafka 会把分区计划生成在这个目录中,此时 controller 就监听到了这一扭转,它会去同步这个目录的元信息,而后同样下放给它的从节点,通过这个办法让整个集群都得悉这个分区计划,此时从节点就各自创立好目录期待创立分区正本即可。这也是整个集群的管理机制。

加餐工夫

1.Kafka 性能好在什么中央?

① 程序写

操作系统每次从磁盘读写数据的时候,须要先寻址,也就是先要找到数据在磁盘上的物理地位,而后再进行数据读写,如果是机械硬盘,寻址就须要较长的工夫。kafka 的设计中,数据其实是存储在磁盘下面,一般来说,会把数据存储在内存下面性能才会好。然而 kafka 用的是程序写,追加数据是追加到开端,磁盘程序写的性能极高,在磁盘个数肯定,转数达到肯定的状况下,根本和内存速度统一

随机写的话是在文件的某个地位批改数据,性能会较低。

② 零拷贝

先来看看非零拷贝的状况

能够看到数据的拷贝从内存拷贝到 kafka 服务过程那块,又拷贝到 socket 缓存那块,整个过程消耗的工夫比拟高,kafka 利用了 Linux 的 sendFile 技术(NIO),省去了过程切换和一次数据拷贝,让性能变得更好。

2. 日志分段存储

Kafka 规定了一个分区内的.log 文件最大为 1G,做这个限度目标是为了不便把.log 加载到内存去操作

这个 9936472 之类的数字,就是代表了这个日志段文件里蕴含的起始 offset,也就阐明这个分区里至多都写入了靠近 1000 万条数据了。Kafka broker 有一个参数,log.segment.bytes,限定了每个日志段文件的大小,最大就是 1GB,一个日志段文件满了,就主动开一个新的日志段文件来写入,防止单个文件过大,影响文件的读写性能,这个过程叫做 log rolling,正在被写入的那个日志段文件,叫做 active log segment。

如果大家有看后面的两篇有对于 HDFS 的文章时,就会发现 NameNode 的 edits log 也会做出限度,所以这些框架都是会思考到这些问题。

3.Kafka 的网络设计

kafka 的网络设计和 Kafka 的调优无关,这也是为什么它能反对高并发的起因

首先客户端发送申请全副会先发送给一个 Acceptor,broker 外面会存在 3 个线程(默认是 3 个),这 3 个线程都是叫做 processor,Acceptor 不会对客户端的申请做任何的解决,间接封装成一个个 socketChannel 发送给这些 processor 造成一个队列,发送的形式是轮询,就是先给第一个 processor 发送,而后再给第二个,第三个,而后又回到第一个。消费者线程去生产这些 socketChannel 时,会获取一个个 request 申请,这些 request 申请中就会随同着数据。

线程池外面默认有 8 个线程,这些线程是用来解决 request 的,解析申请,如果 request 是写申请,就写到磁盘里。读的话返回后果。processor 会从 response 中读取响应数据,而后再返回给客户端。这就是 Kafka 的网络三层架构。

所以如果咱们须要对 kafka 进行加强调优,减少 processor 并减少线程池外面的解决线程,就能够达到成果。request 和 response 那一块局部其实就是起到了一个缓存的成果,是思考到 processor 们生成申请太快,线程数不够不能及时处理的问题。

所以这就是一个加强版的 reactor 网络线程模型。

感激大家的认同与反对,小编会继续转发《乐字节》优质文章

正文完
 0