应大部分的小伙伴的要求,今天这篇咱们用大白话带你认识 Kafka。
应大部分的小伙伴的要求,今日这篇咱们用大白话带你知道 Kafka。
图片来自 Pexels
Kafka 根底
音讯体系的作用
大部分小伙伴应该都清楚,这儿用机油装箱举个比方:
所以音讯体系便是如上图咱们所说的库房,能在中心进程作为缓存,并且完成解耦合的作用。
引进一个场景,咱们知道中国移动,中国联通,中国电信的日志处理,是交给外包去做大数据剖析的,假定现在它们的日志都交给了你做的体系去做用户画像剖析。
依照刚刚前面说到的音讯体系的作用,咱们知道了音讯体系其实便是一个模仿缓存,且仅仅是起到了缓存的作用而并不是真实的缓存,数据仍然是存储在磁盘上面而不是内存。
Topic 主题
Kafka 学习了数据库里边的规划,在里边规划了 Topic(主题),这个东西类似于联络型数据库的表:
此刻我需求获取中国移动的数据,那就直接监听 TopicA 即可。
Partition 分区
Kafka 还有一个概念叫 Partition(分区),分区详细在服务器上面体现起先便是一个目录。
一个主题下面有多个分区,这些分区会存储到不同的服务器上面,或者说,其实便是在不同的主机上建了不同的目录。
这些分区首要的信息就存在了 .log 文件里边。跟数据库里边的分区差不多,是为了进步功能。
至于为什么进步了功能,很简略,多个分区多个线程,多个线程并行处理必定会比单线程好得多。
Topic 和 Partition 像是 HBase 里的 Table 和 Region 的概念,Table 仅仅一个逻辑上的概念,真实存储数据的是 Region。
这些 Region 会分布式地存储在各个服务器上面,对应于 Kafka,也是相同,Topic 也是逻辑概念,而 Partition 便是分布式存储单元。
这个规划是确保了海量数据处理的根底。咱们能够比照一下,假如 HDFS 没有 Block 的规划,一个 100T 的文件也只能独自放在一个服务器上面,那就直接占满整个服务器了,引进 Block 后,大文件能够涣散存储在不同的服务器上。
留意:
分区会有单点故障问题,所以咱们会为每个分区设置副本数。
分区的编号是从 0 开端的。
Producer 生产者
往音讯体系里边发送数据的便是生产者:
Consumer 顾客
从 Kafka 里读取数据的便是顾客:
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=a
- consumerB:
- group.id=a
- consumerC:
- group.id=b
- consumerD:
- group.id=b
再让 ConsumerB 也去消费 TopicA 的数据,它是消费不到了,可是咱们在 ConsumerC 中从头指定一个别的的 group.id,ConsumerC 是能够消费到 TopicA 的数据的。
而 ConsumerD 也是消费不到的,所以在 Kafka 中,不同组可有仅有的一个顾客去消费同一主题的数据。
所以顾客组便是让多个顾客并行消费信息而存在的,并且它们不会消费到同一个音讯。
如下,ConsumerA,B,C 是不会相互搅扰的:
- consumergroup:a
- consumerA
- consumerB
- consumerC
如图,由于前面说到过了顾客会直接和 Leader 树立联络,所以它们别离消费了三个 Leader,所以一个分区不会让顾客组里边的多个顾客去消费,可是在顾客不饱和的状况下,一个顾客是能够去消费多个分区的数据的。
Controller
熟知一个规矩:在大数据分布式文件体系里边,95% 的都是主从式的架构,个别是对等式的架构,比方 ElasticSearch。
Kafka 也是主从式的架构,主节点就叫 Controller,其他的为从节点,Controller 是需求和 Zookeeper 进行合作办理整个 Kafka 集群。
Kafka 和 Zookeeper 怎么合作作业
Kafka 严峻依赖于 Zookeeper 集群,一切的 Broker 在发动的时分都会往 Zookeeper 进行注册,意图便是推举出一个 Controller。
这个推举进程十分简略粗犷,便是一个谁先谁当的进程,不触及什么算法问题。
那成为 Controller 之后要做啥呢,它会监听 Zookeeper 里边的多个目录,例如有一个目录 /brokers/,其他从节点往这个目录上**注册(便是往这个目录上创立归于自己的子目录罢了)**自己。
这时命名规矩一般是它们的 id 编号,比方 /brokers/0,1,2。注册时各个节点必定会露出自己的主机名,端口号等等的信息。
此刻 Controller 就要去读取注册上来的从节点的数据(经过监听机制),生成集群的元数据信息,之后把这些信息都分发给其他的服务器,让其他服务器能感知到集群中其它成员的存在。
此刻模仿一个场景,咱们创立一个主题(其实便是在 Zookeeper 上 /topics/topicA 这样创立一个目录罢了),Kafka 会把分区计划生成在这个目录中。
此刻 Controller 就监听到了这一改动,它会去同步这个目录的元信息,然后相同下放给它的从节点,经过这个办法让整个集群都得知这个分区计划,此刻从节点就各自创立好目录等候创立分区副本即可。这也是整个集群的办理机制。
加餐时刻
Kafka 功能好在什么地方?
①次序写
操作体系每次从磁盘读写数据的时分,需求先寻址,也便是先要找到数据在磁盘上的物理方位,然后再进行数据读写,假如是机械硬盘,寻址就需求较长的时刻。
Kafka 的规划中,数据其实是存储在磁盘上面,一般来说,会把数据存储在内存上面功能才会好。
可是 Kafka 用的是次序写,追加数据是追加到结尾,磁盘次序写的功能极高,在磁盘个数必定,转数到达必定的状况下,根本和内存速度共同。
随机写的话是在文件的某个方位修正数据,功能会较低。
②零复制
先来看看非零复制的状况:
能够看到数据的复制从内存复制到 Kafka 服务进程那块,又复制到 Socket 缓存那块,整个进程消耗的时刻比较高。
Kafka 利用了 Linux 的 sendFile 技能(NIO),省去了进程切换和一次数据复制,让功能变得更好。
日志分段存储
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 也会做出约束,所以这些结构都是会考虑到这些问题。
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 网络线程模型。
总结
集群的建立会再找时刻去提及。这一篇简略地从人物到一些规划的方面叙述了 Kafka 的一些根底,在之后的更新中会持续逐步推进,进行愈加浅显易懂的解说。
知优网 » 面试问Kafka,这一篇全搞定(kafka面试问题)