kafka和mysql内存机制_一文五分钟让你彻底理解Kafka架构原理

对于kafka的架构原理我们先提出几个问题?

1.Kafka的topic和分区内部是如何存储的,有什么特点?

2.与传统的消息系统相比,Kafka的消费模型有什么优点?

3.Kafka如何实现分布式的数据存储与数据读取?

一、Kafka架构图

8eb2a5b55dd7

1.kafka名词解释

在一套kafka架构中有多个Producer,多个Broker,多个Consumer,每个Producer可以对应多个Topic,每个Consumer只能对应一个ConsumerGroup。

整个Kafka架构对应一个ZK集群,通过ZK管理集群配置,选举Leader,以及在consumer group发生变化时进行rebalance。

名称

解释

Broker

消息中间件处理节点,一个Kafka节点就是一个broker,一个或者多个Broker可以组成一个Kafka集群

Topic

主题,Kafka根据topic对消息进行归类,发布到Kafka集群的每条消息都需要指定一个topic

Producer

消息生产者,向Broker发送消息的客户端

Consumer

消息消费者,从Broker读取消息的客户端

ConsumerGroup

每个Consumer属于一个特定的Consumer Group,一条消息可以发送到多个不同的Consumer Group,但是一个Consumer Group中只能有一个Consumer能够消费该消息

Partition

物理上的概念,一个topic可以分为多个partition,每个partition内部是有序的

2.Topic和Partition

在Kafka中的每一条消息都有一个topic。一般来说在我们应用中产生不同类型的数据,都可以设置不同的主题。一个主题一般会有多个消息的订阅者,当生产者发布消息到某个主题时,订阅了这个主题的消费者都可以接收到生产者写入的新消息。

kafka为每个主题维护了分布式的分区(partition)日志文件,每个partition在kafka存储层面是append log。任何发布到此partition的消息都会被追加到log文件的尾部,在分区中的每条消息都会按照时间顺序分配到一个单调递增的顺序编号,也就是我们的offset,offset是一个long型的数字,我们通过这个offset可以确定一条在该partition下的唯一消息。在partition下面是保证了有序性,但是在topic下面没有保证有序性。

8eb2a5b55dd7

在上图中在我们的生产者会决定发送到哪个Partition。

1.如果没有Key值则进行轮询发送。

2.如果有Key值,对Key值进行Hash,然后对分区数量取余,保证了同一个Key值的会被路由到同一个分区,如果想队列的强顺序一致性,可以让所有的消息都设置为同一个Key。

3.消费模型

消息由生产者发送到kafka集群后,会被消费者消费。一般来说我们的消费模型有两种:推送模型(psuh)和拉取模型(pull)

基于推送模型的消息系统,由消息代理记录消费状态。消息代理将消息推送到消费者后,标记这条消息为已经被消费,但是这种方式无法很好地保证消费的处理语义。比如当我们把已经把消息发送给消费者之后,由于消费进程挂掉或者由于网络原因没有收到这条消息,如果我们在消费代理将其标记为已消费,这个消息就永久丢失了。如果我们利用生产者收到消息后回复这种方法,消息代理需要记录消费状态,这种不可取。如果采用push,消息消费的速率就完全由消费代理控制,一旦消费者发生阻塞,就会出现问题。

Kafka采取拉取模型(poll),由自己控制消费速度,以及消费的进度,消费者可以按照任意的偏移量进行消费。比如消费者可以消费已经消费过的消息进行重新处理,或者消费最近的消息等等。

4.网络模型

4.1 KafkaClient --单线程Selector

8eb2a5b55dd7

单线程模式适用于并发链接数小,逻辑简单,数据量小。

在kafka中,consumer和producer都是使用的上面的单线程模式。这种模式不适合kafka的服务端,在服务端中请求处理过程比较复杂,会造成线程阻塞,一旦出现后续请求就会无法处理,会造成大量请求超时,引起雪崩。而在服务器中应该充分利用多线程来处理执行逻辑。

4.2 Kafka--server -- 多线程Selector

8eb2a5b55dd7

在kafka服务端采用的是多线程的Selector模型,Acceptor运行在一个单独的线程中,对于读取操作的线程池中的线程都会在selector注册read事件,负责服务端读取请求的逻辑。成功读取后,将请求放入message queue共享队列中。然后在写线程池中,取出这个请求,对其进行逻辑处理,即使某个请求线程阻塞了,还有后续的县城从消息队列中获取请求并进行处理,在写线程中处理完逻辑处理,由于注册了OP_WIRTE事件,所以还需要对其发送响应。

5.高可靠分布式存储模型

在Kafka中保证高可靠模型的依靠的是副本机制,有了副本机制之后,就算机器宕机也不会发生数据丢失。

5.1高性能的日志存储

kafka一个topic下面的所有消息都是以partition的方式分布式的存储在多个节点上。同时在kafka的机器上,每个Partition其实都会对应一个日志目录,在目录下面会对应多个日志分段(LogSegment)。LogSegment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为segment索引文件和数据文件。这两个文件的命令规则为:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充,如下,假设有1000条消息,每个LogSegment大小为100,下面展现了900-1000的索引和Log:

8eb2a5b55dd7

由于kafka消息数据太大,如果全部建立索引,即占了空间又增加了耗时,所以kafka选择了稀疏索引的方式,这样的话索引可以直接进入内存,加快偏查询速度。

简单介绍一下如何读取数据,如果我们要读取第911条数据首先第一步,找到他是属于哪一段的,根据二分法查找到他属于的文件,找到0000900.index和00000900.log之后,然后去index中去查找 (911-900) =11这个索引或者小于11最近的索引,在这里通过二分法我们找到了索引是[10,1367]然后我们通过这条索引的物理位置1367,开始往后找,直到找到911条数据。

上面讲的是如果要找某个offset的流程,但是我们大多数时候并不需要查找某个offset,只需要按照顺序读即可,而在顺序读中,操作系统会对内存和磁盘之间添加page cahe,也就是我们平常见到的预读操作,所以我们的顺序读操作时速度很快。但是kafka有个问题,如果分区过多,那么日志分段也会很多,写的时候由于是批量写,其实就会变成随机写了,随机I/O这个时候对性能影响很大。所以一般来说Kafka不能有太多的partition。针对这一点,RocketMQ把所有的日志都写在一个文件里面,就能变成顺序写,通过一定优化,读也能接近于顺序读。

可以思考一下:1.为什么需要分区,也就是说主题只有一个分区,难道不行吗?2.日志为什么需要分段

5.2副本机制

Kafka的副本机制是多个服务端节点对其他节点的主题分区的日志进行复制。当集群中的某个节点出现故障,访问故障节点的请求会被转移到其他正常节点(这一过程通常叫Reblance),kafka每个主题的每个分区都有一个主副本以及0个或者多个副本,副本保持和主副本的数据同步,当主副本出故障时就会被替代。

8eb2a5b55dd7

在Kafka中并不是所有的副本都能被拿来替代主副本,所以在kafka的leader节点中维护着一个ISR(In sync Replicas)集合,翻译过来也叫正在同步中集合,在这个集合中的需要满足两个条件:

节点必须和ZK保持连接

在同步的过程中这个副本不能落后主副本太多

另外还有个AR(Assigned Replicas)用来标识副本的全集,OSR用来表示由于落后被剔除的副本集合,所以公式如下:ISR = leader + 没有落后太多的副本; AR = OSR+ ISR;

这里先要说下两个名词:HW(高水位)是consumer能够看到的此partition的位置,LEO是每个partition的log最后一条Message的位置。HW能保证leader所在的broker失效,该消息仍然可以从新选举的leader中获取,不会造成消息丢失。

当producer向leader发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别:

1(默认):这意味着producer在ISR中的leader已成功收到的数据并得到确认后发送下一条message。如果leader宕机了,则会丢失数据。

0:这意味着producer无需等待来自broker的确认而继续发送下一批消息。这种情况下数据传输效率最高,但是数据可靠性确是最低的。

-1:producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。但是这样也不能保证数据不丢失,比如当ISR中只有leader时(其他节点都和zk断开连接,或者都没追上),这样就变成了acks=1的情况。

以上就是我的分享,看完的朋友记得点赞噢!想学习更多的Java技术方面的知识的朋友们,可以进我的Java高级架构师交流群,里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料,群号:680075317,也可以进群一起交流,比如遇到技术瓶颈、面试不过的,大家一些交流学习!

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

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

相关文章

centos mysql 互为主从_centos7 mysql互为主从+keepalived

一、互为主从配置1.1、资源情况192.168.11.177 server1192.168.11.180 server2192.168.11.210 VIP1.2、server1配置# vi /etc/my.cnf[mysqld]server-id1log-binmysql-binrelay_logmysql-realy-binrelay_log_indexslave-mysql-realy-bin.indexexpire_logs_days15binlog_formatmi…

手机apk签名工具安卓版_小飞鱼APK签名工具使用方法

小飞鱼APK签名工具是小飞鱼旗下的一款APK签名软件。是移动开发者必备的一款软件。使用方法1、双击运行小飞鱼APK签名工具.exe文件,出现如下界面:2、点击“功能”,没有签名证书的选择证书制作,制作完证书再选择APK签名,有证书的直接…

React 路由传参

引言 在上一篇中&#xff0c;我们学习了 React 中使用路由技术&#xff0c;以及如何使用 MyNavLink 去优化使用路由时的代码冗余的情况。 这一节我们继续上一篇 React 路由进行一些补充 1. Switch 解决相同路径问题 首先我们看一段这样的代码 <Route path"/home&q…

mysql 5.5 client 字符集_rhel4 mysql5.5 字符集_character set

和oracle字符集一样,有些晕,太细了小结:1,字符集分为:服务器,数据库,表,连接,列等对应参数为:mysql> show variables like chara%;------------------------------------------------------| Variable_name | Value |---------------------…

mysql heartbeat lvs_mysql+heartbeat+DRBD+LVS实现mysql高可用二

上一节&#xff0c;讲述了DRBD的安装&#xff0c;因为要利用heartbeatDRBDmysql实现mysql的高可用&#xff0c;所以这一节讲述安装mysql和heartbeat的安装分别在各个节点安装mysql&#xff0c;文本使用的是二进制的安装包mysql-5.5.33-linux2.6-x86_64.tar.gz[rootdrbd1 usr]# …

mysql 嵌入式 性能_database – 在mySQL中优化嵌入式SELECT查询

好的,这是我现在正在运行的一个查询,它有45,000条记录,大小为65MB ……并且即将变得越来越大(所以我也要考虑未来的性能)&#xff1a;SELECT count(payment_id) as signup_count,sum(amount) as signup_amountFROM payments pWHERE tm_completed BETWEEN 2009-05-01 AND 2009-0…

mysql执行语句后回退_MySQL命令学习笔记(八)

1 安全管理1.1 访问控制MySQL服务器的安全基础是&#xff1a; 用户应该对他们需要的数据具有适当的访问权&#xff0c;既不能多也不能少1.2 管理用户MySQL用户账号和信息存储在名为mysql的MySQL数据库中。获得所有用户账号列表时&#xff0c;可使用以下代码&#xff1a;USE mys…

mysql怎样dao出数据库_mysql怎么导出数据库?

mysql怎么导出数据库&#xff1f;下面本篇文章就来给大家介绍3种mysql导出数据库的方法&#xff0c;希望对你们有所帮助。mysql导出数据库的方法&#xff1a;方法一cmd 到mysql bin目录下用如下命令&#xff1a;mysqldump --opt -h192.168.0.156 -uusername -ppassword --skip-…

mac 安装mysql怎么卸载不干净_CleanMyMac卸载不干净怎么办?如何彻底删除Mac上的CleanMyMac?...

CleanMyMac for mac是非常受欢迎的系统清理、软件卸载软件&#xff0c;但是想要卸载CleanMyMac的有些用户发现不能完全卸载&#xff0c;那么CleanMyMac卸载不干净怎么办&#xff1f;如何彻底删除CleanMyMac&#xff1f;这里带来两种可以彻底删除CleanMyMac的方法&#xff0c;有…

mysql判断是否为null_MySQL如何判断字段是否为null

相信很多用了MySQL很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问: 我字段类型是not null,为什么我可以插入空值 为什么not null的效率比null高 判断字段不为空的时候,到底要 select * from table where column <> 还是要用 select * from table w…

mysql修改表的字段_mysql修改表字段学习笔记

--修改表字段CREATE TABLE register (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR (10) DEFAULT NULL UNIQUE KEY,age tinyint UNSIGNED DEFAULT 18,regisTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP (),fund DOUBLE (9, 2) DEFAULT 1000000.00,tel CHAR (11) NOT NULL);--…

python 条件概率_使用Pymc3的条件概率

我的问题是如何使用PYMC3包来实现条件概率模型。在我有一组数据a_观察到&#xff0c;b棼u观察到&#xff0c;并且我想找出它们之间的关系。我怀疑a&#xff0c;b&#xff0c;c都是正态分布&#xff0c;b依赖于a&#xff0c;c依赖于a&#xff0c;b。我需要找到参数。在到目前为止…

python如何导入自定义模块_【python】导入自定义模块

一、直接import1.当执行文件与要导入的py文件在同一目录下时假设要在wangyi.py中导入weibo.py文件import weibo2.当执行文件与要导入的py文件所在文件夹在同一目录下时假设要在wangyi.py中导入post packaging中的method.py(1)from post_packaging import method(2)from post_pa…

python给视频加背景音乐_python中加背景音乐如何操作

在python中加背景音乐的方法&#xff1a;1、导入pygame资源包&#xff1b;2、修改音乐的file路径&#xff1b;3、使用init()方法进行初始化&#xff1b;4、使用load()方法添加音乐文件&#xff1b;5、使用play()方法播放音乐流即可。下面的代码直接复制粘贴到自己的代码即可实现…

python能和wincc一起用_搬家第二天-41.Wincc V7.3 利用Inputbox和Msgbox做权限管理和二次确认设计...

有时候我们希望做某个操作时&#xff0c;有密码管理或者二次确认。密码管理可以通过用户管理方式设置权限&#xff0c;也可以通过弹窗输入密码的方式&#xff1b;二次确认主要是使用弹窗然后捕获用户点击的按钮编号来进行。下面通过一个简单的日子记录一下如何实现。一 准备工作…

mysql中的函数编程_MySQL

12.2. 控制流程函数CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END在第一个方案的返回结果中&#xff0c; valuecompare-v…

python画窗口_pyqt中图案如何画在子窗口上

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼基本思路是从QWidget派生出一个类重写paintEvent&#xff0c;在里面画图。UI部分代码是这样的class Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(1008, 693)self.widget QtWidgets…

twisted mysql_Twisted MySQL adbapi返回字典

有没有办法把adbapi查询的字典结果返回到MySQL&#xff1f;在[name: Bob, phone_number: 9123 4567]默认返回元组。在^{pr2}$对于简单的Python&MySQL&#xff0c;我们可以使用MySQLdb.cursors.dictcursors。但是如何与扭曲的adbapi一起使用呢UPD:我解决了&#xff0c;但我认…

win 10 java 安装_win10---Java安装及环境变量配置

一、Java安装给出的下载地址已经是1.8.0及以上的版本&#xff0c;只需要进去根据操作系统位数选择所对应的包即可&#xff0c;我的是Windows x64&#xff0c;所以我选择的是第二个。注意⚠️&#xff1a;下载jdk时&#xff0c;需要登录Oracle账户&#xff0c;如果没有&#xff…

java 生成bat_java实现生成windows可执行的批处理文件(.bat)

/*** 下载压缩包**paramid 商户id*paramrequest*paramresponse*returnvoid*authorchen.bing* Date 2019/11/4 17:35*/RequestMapping(value "downloadzip")public voiddownloadzip(String id, HttpServletRequest request, HttpServletResponse response) {if(String…