前言应一大半的同伴的门槛,在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就算不设置,系统也会默认设置
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.timeindex00000000000005367851.index00000000000005367851.log00000000000005367851.timeindex00000000000009936472.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的有的基本,在之后的更新中会继续逐步推进,进行更加深入浅出的教学。
作者:说出你的愿望吧丷链接: