kafka 不同分区文件存储_大白话 + 13 张图解 Kafka

前言

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

一、Kafka基础

消息系统的作用

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

18019f174f30fbf79e0e2f904213b750.png

所以消息系统就是如上图我们所说的仓库,能在中间过程作为缓存,并且实现解耦合的作用。

引入一个场景,我们知道中国移动,中国联通,中国电信的日志处理,是交给外包去做大数据分析的,假设现在它们的日志都交给了你做的系统去做用户画像分析。

f4865681c85e2fc59ae66b866347bf78.png

按照刚刚前面提到的消息系统的作用,我们知道了消息系统其实就是一个模拟缓存 ,且仅仅是起到了缓存的作用 而并不是真正的缓存,数据仍然是存储在磁盘上面而不是内存。

1.Topic 主题

kafka学习了数据库里面的设计,在里面设计了topic(主题),这个东西类似于关系型数据库的表

10497d639ccccc2b8c93d38dcc8b5ec0.png

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

2.Partition 分区

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

56c330a61864115f45b6b3f16cfbb177.png

至于为什么提高了性能,很简单,多个分区多个线程,多个线程并行处理肯定会比单线程好得多

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

注意:1.分区会有单点故障问题,所以我们会为每个分区设置副本数

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

3.Producer - 生产者

往消息系统里面发送数据的就是生产者

789d74ceff3e9e785bb7ac206ee388ae.png

4.Consumer - 消费者

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

d384ddaf9c6d0f4d01175b36551abdbb.png

5.Message - 消息

kafka里面的我们处理的数据叫做消息

二、kafka的集群架构

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

ee6cdbbf1a95ffe193590a9527430046.png

需要注意:kafka在0.8版本以前是没有副本机制的,所以在面对服务器宕机的突发情况时会丢失数据,所以尽量避免使用这个版本之前的kafka

Replica - 副本

kafka中的partition为了保证数据安全,所以每个partition可以设置多个副本。

此时我们对分区0,1,2分别设置3个副本(其实设置两个副本是比较合适的)

41fe27c22a383907f55cbd8f937478e3.png

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

7c1e48f04c31932084dd0f50756acaf3.png

Consumer Group - 消费者组

我们在消费数据时会在代码里面指定一个group.id,这个id代表的是消费组的名字,而且这个group.id就算不设置,系统也会默认设置

conf.setProperty("group.id","tellYourDream")

我们所熟知的一些消息系统一般来说会这样设计,就是只要有一个消费者去消费了消息系统里面的数据,那么其余所有的消费者都不能再去消费这个数据。可是kafka并不是这样,比如现在consumerA去消费了一个topicA里面的数据。

consumerA:group.id = aconsumerB:group.id = aconsumerC:group.id = bconsumerD:group.id = b

再让consumerB也去消费TopicA的数据,它是消费不到了,但是我们在consumerC中重新指定一个另外的group.id,consumerC是可以消费到topicA的数据的。而consumerD也是消费不到的,所以在kafka中,不同组可有唯一的一个消费者去消费同一主题的数据 。

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

consumer group:aconsumerAconsumerBconsumerC
adaaf5368cbecf68fa2ab2dd9534fe3b.png

如图,因为前面提到过了消费者会直接和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用的是顺序写,追加数据是追加到末尾,磁盘顺序写的性能极高,在磁盘个数一定,转数达到一定的情况下,基本和内存速度一致

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

② 零拷贝

先来看看非零拷贝的情况

d565fbf6775788331db584aaa3cc0395.png

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

02c40bd6ec96117622d4fbba5447db21.png

2.日志分段存储

Kafka规定了一个分区内的.log文件最大为1G,做这个限制目的是为了方便把.log加载到内存去操作如果大家有看前面的两篇有关于HDFS的文章时,就会发现NameNode的edits log也会做出限制,所以这些框架都是会考虑到这些问题。

4c07cbc0bd6e2b0051c189448cb30e7f.png

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

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

3.Kafka的网络设计

kafka的网络设计和Kafka的调优有关,这也是为什么它能支持高并发的原因

0789345cb8e5e50d30bec6dd2f6e0437.png

首先客户端发送请求全部会先发送给一个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的一些基础,在之后的更新中会继续逐步推进,进行更加深入浅出的讲解。

软考学习资料需要的同学可以私信我哦

b1ec45fc44ee287455914192c87a17c2.png
1323f51f28ec7bc13fec55afce98a673.png
8a3d9b4a07664be630bfc4af2ba1157e.png

更多精彩内容请点击“了解更多”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

apache thrift_Apache Thrift快速入门教程

apache thriftThrift是一种跨语言RPC框架,最初是在Facebook上开发的,现在作为Apache项目开源。 这篇文章将描述如何以不同的模式(例如阻塞,非阻塞和异步)编写Thrift服务和客户端。 (我觉得后两种模式的文档…

如何恢复被删短信_手机便签记事本的内容如何恢复?快试试这款好用的便签

手机便签记事本是很多人日常工作和生活中都会用到的一种辅助工具,它不但可以记录我们的待办事项,经常坚持使用的话,还能养成良好的生活节奏。常在河边走哪有不湿鞋,很多人都发生过误删的情况,手机便签记事本的内容如何…

分享一些在内网操作的远程办公经验

前言大家好,我叫孙叫兽,本期内容给大家分享一群在内网操作的程序员远程办公经验。为啥说是内网呢,因为从事的开发项目比较保密,比如某银行总行的新一代智能柜台项目。这些平时开发的内容不能直接和互联网进行连接。只能通过行方的…

[刷题]算法竞赛入门经典(第2版) 4-1/UVa1589 - Xiangqi

书上具体所有题目&#xff1a;http://pan.baidu.com/s/1hssH0KO 代码&#xff1a;&#xff08;Accepted&#xff0c;0 ms&#xff09; //UVa1589 #include<iostream> #include<cmath> #define P(x,y) Pi[x].position[y] using namespace std; int N;//2<N<7…

OpenMap教程–第1部分

介绍 本系列教程将向您展示如何使用OpenMap GIS Java Swing库构建Java应用程序。 OpenMap的开发人员指南是非常有用的文档&#xff0c;描述了OpenMap的体系结构&#xff0c;但没有说明如何逐步启动和构建应用程序。 源代码附带的示例很有用&#xff0c;但还不够。 OpenMap是用…

killall 后面信号_Linux 下使用 killall 命令终止进程的 8 大用法

Linux 的命令行提供很多命令来杀死进程。比如&#xff0c;你可以向 kill 命传递一个PID来杀死进程&#xff1b;pkill 命令使用一个正则表达式作为输入&#xff0c;所以和该模式匹配的进程都被杀死。但是还有一个命令叫 killall &#xff0c;默认情况下&#xff0c;它精确地匹配…

分享一些我的远程办公经验

前言 大家好&#xff0c;我叫孙叫兽&#xff0c;本期内容给大家分享一群在内网操作的程序员远程办公经验。为啥说是内网呢&#xff0c;因为从事的开发项目比较保密&#xff0c;比如某银行总行的新一代智能柜台项目。这些平时开发的内容不能直接和互联网进行连接。只能通过行方的…

SqlServer按中文数字排序

表数据: 按名称排序 并不能得到一二三四五六的顺序 select * from LiWei order by name 找到中文数字在一二三四五六七八九十的位置 select id,name,SUBSTRING(name,2,1) as 中文数字,charindex(SUBSTRING(name,2,1),一二三四五六七八九十) as 中文数字所在位置 from LiWei 按中…

C语言--直接插入排序【排序算法|图文详解】

一.直接插入排序介绍&#x1f357; 直接插入排序又叫简单插入排序&#xff0c;是一种简单直观的排序算法&#xff0c;它通过构建有序序列&#xff0c;对于未排序的数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。 算法描述&#xff1a; 假设要排序…

python 读取sqlite存入文件_如何通过python读取sqlite数据文件

sqlite简介&#xff1a;sqlite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它的设计目标是嵌入式的&#xff0c;而且目前已经在很多嵌入式产品中使用了它(如安卓系统)&#xff0c;它占用资源非常的低&#xff0c;在嵌入式设…

分享一些前端优质的掘金小册,学完技术感觉已经超神了

大家好&#xff0c;本期内容给大家推荐一些优质的前端掘金小册&#xff0c;基本每个都是专栏小册的形式&#xff0c;比较适合初学者及工作几年的前端小伙伴&#xff0c;里面的内容讲解的比较详细&#xff0c;作者也是一线的大厂工作者。有兴趣的小伙伴快来打卡看一下吧&#xf…

sp烘焙流程_次世代86机甲战神制作全流程

1介绍Hello&#xff0c;大家好&#xff01;我叫周玉亮。首先感谢一下小左老师对我的作品的认可&#xff0c;以及给予我这次宝贵的分享机会。本次分享的是我的第一个次世代硬表面作品&#xff0c;名为《86机甲战神》&#xff0c;制作时间3周。时间还是相当紧的&#xff0c;要在3…

esper_Twitter4j和Esper:在Twitter上跟踪用户情绪

esper对于复杂事件处理和Twitter API的新手&#xff0c;我希望这是一个简短的教程&#xff0c;可以帮助他们Swift起步。 管理大数据并从中挖掘有用的信息是当前技术中最热门的讨论主题。 来自Twitter&#xff0c;Facebook和Linkedin等社交网络的半结构化数据的爆炸式增长使Hado…

前端实现流星雨特效

目录 前言 效果图&#xff1a; HTML CSS 完整代码 前言 使用htmlcss实现简单得浏览器特效&#xff0c;在编译器用导入项目&#xff0c;直接在浏览器打开即可&#xff0c;效果十分得炫酷&#xff0c;十分得哇塞&#xff0c;女朋友直呼NB! 效果图&#xff1a; HTML <!DO…

RxJava线程控制

RxJava中的线程转换主要通过下面两个方法&#xff1a; 1.subscribeOn 2.observeOn 一、subscribeOn 1.调用一次subscribeOn时&#xff1a; Observable observable; Schedulers schedulers; Observer observer; observable.subscribeOn(schedulers).subscribe(observer) 通过解析…

elementui中tabs切换item中的内容会变_中后台UX优化之道

前言“前台重体验&#xff0c;后台重逻辑”&#xff0c;B端谈 UX 有没有价值&#xff1f;一切电子化的今天&#xff0c;运营、审核、电销、账务……无数岗位依赖中后台系统来完成他们的日常工作&#xff0c;好的 UX 确实可以直接为这些产能提效当中后台的工程师们花费了巨大精力…

介体设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01; 目录 …

判断一个对象是否是空对象的处理办法

目录 前言 方法一&#xff0c;Object.keys()方法&#xff0c;返回对象的属性名组成的一个数组&#xff0c;若长度为0&#xff0c;则为空对象 方法二、for in循环 方法三&#xff1a;将对象转换成字符串&#xff0c;再判断是否等于“{}” 前言 在维护客户基本信息的时候包含…