已有40人围观 来源:架构师 发布于:2021-04-22 22:55:05
架构师(JiaGouX)
我们都是架构师!
架构未来,你来不来?



一、Kafka基本

资讯体系的作用

应当大部份小伙伴都清晰,用机油装箱举个例子
所以资讯体系就是如上图我们所说的仓库,能在中间进程作为缓存,并且实现解耦合的作用。
引入一个场景,我们知道中国移动,中国联通,中国电信的日志处置,是交给外包去做大数据剖析的,假设现在它们的日志都交给了你做的体系去做用户画像剖析。
依照刚刚前面提到的资讯体系的作用,我们知道了资讯体系其实就是一个模仿缓存 ,且仅仅是起到了缓存的作用 而并不是真正的缓存,数据仍然是存储在磁盘上面而不是内存。
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就算不设置,体系也会默认设置
conf.setProperty("group.id","tellYourDream")

我们所熟知的一些资讯体系一般来说会这样设计,就是只要有一个花费者去花费了资讯体系里面的数据,那么其余所有的花费者都不能再去花费这个数据。可是kafka并不是这样,比如现在consumerA去花费了一个topicA里面的数据。
consumerA:    group.id = aconsumerB:    group.id = a
consumerC: group.id = bconsumerD:    group.id = b
再让consumerB也去花费TopicA的数据,它是花费不到了,但是我们在consumerC中重新指定一个另外的group.id,consumerC是可以花费到topicA的数据的。而consumerD也是花费不到的,所以在kafka中,不同组可有唯一的一个花费者去花费同一主题的数据 。
所以花费者组就是让多个花费者并行花费信息而存在的,而且它们不会花费到同一个资讯,如下,consumerA,B,C是不会互相关扰的
consumer group:a    consumerA    consumerB    consumerC

如图,因为前面提到过了花费者会直接和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加载到内存去操作
00000000000000000000.index00000000000000000000.log00000000000000000000.timeindex
00000000000005367851.index00000000000005367851.log00000000000005367851.timeindex
00000000000009936472.index00000000000009936472.log00000000000009936472.timeindex

这个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网络线程模型。


finally

集群的搭建会再找时光去提及。这一篇简略地从角色到一些设计的方面讲述了Kafka的一些基本,在之后的更新中会持续逐步推动,进行更加深刻浅出的讲授。

如果您爱好本文,欢迎点击右上角,把文章分享到朋友圈~~
如果有想懂得和学习的知识点或技巧点,也可以留言给若飞支配分享

·END·


相关浏览:


作者:说出你的欲望吧

起源:https://juejin.cn/post/6844903999066341384


版权声名:内容起源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告诉,我们会立即删除并表示歉意。谢谢!


架构师

我们都是架构师!



关注架构师(JiaGouX),添加“星标”

获取每天技巧干货,一起成为牛逼架构师

技巧群请加若飞:1321113940 进架构师群

投稿、合作、版权等邮箱:admin@137x.com