粉丝2.9万获赞30.3万
kafka 如何处理消息的持久性?消息存储在哪里? kafkak 如何处理消息的持久性是其设计中的一个关键特性。在 kafka 中,消息被持久性地存储在磁盘上,以确保数据不会丢失。即使出现故障或异常情况。 kafkak 处理消息的持久性有以下几个方面, 一、写入持久性当生产者将消息发布到 kafka 时, kafka 会将这些消息持久化到磁盘上的主题分区中。这意味着消息不仅会存储在内存中, 还会被写入磁盘文件,从而保证消息的持久性。二、消息日志在每个主题的分区中,消息被顺序写入一个消息日志 message lock 中。消息日志是一个有序的追加写入的不可变文件。消息按照写入顺序进行存储,不允许修改或删除。这种设计保证了消息的顺序 性和不变性。三、消息复制 cufk 支持多副本复制机制每个分区的消息可以有多个副本存储在不同的 broker 上,副本之间会进行同步,以确保数据的勇于和高可用性。如果一个 broker 故障,可以从其他副本中选择新的领导者 leader 来继续服务, 从而避免数据丢失。四、持久化配置 kovk 允许根据需要进行持久化配置。您可以设置消息的持久化策略和参数。例如,可以控制消息何时写入磁盘,或者可以通过配置消息在副本间的同步方式来平衡数据可靠性和性能。 消息在 caf 卡中存储在 broker 的文件系统中,每个 broker 都有一个配置参数,指定存储消息的数据目录。 消息被写入磁盘的主题分区中,并以文件的形式保存在数据目录中。 coffer 的消息存储机制确保了数据的持久性和高可靠性,使其成为可靠的消息传递和流处理平台。
kafka 的数据复制机制是怎样的?如何确保高可用性? kafka 的数据复制机制是通过多副本复制来实现的,每个主题的每个分区可以有多个副本存储在不同的 broker 上。 这样做的目的是为了确保数据的高可用性和容错性,以防止 brok 故障导致消息丢失。以下是 coft 的数据复制机制的关键特点,一副本数量每个分区可以有多个副本,通常设置为至少有一个副本,通常还会有多个副本,例如三个副本, 副本数量通过配置来控制,您可以根据可用性和性能需求选择合适的副本数量。二领导者与追随者对于每个分区,其中一个副本被指定为领导者,其他副本被称为追随者。领导者负责处理 来自生产者和消费者的请求,而追随者则负责与领导者保持同步。三消息写入所有的写入请求都会发送到分区的领导者。领导者将消息写入到本地存储,并将消息复制到所有的追随者。 四同步复制当领导者成功将消息写入本地存储后,他将向所有追随者发送消息的副本。追随者接收到消息后会确认消息写入成功,然后通知领导者。 只有当所有追随者都成功写入消息后,领导者才会向生产者确认消息写入成功。五读取请求读取请求可以发送给任何副本,但通常建议发送给分区的领导者。领导者会立即处理读取请求并返回结果,而追随者需要从领导 者复制数据后才能处理读取请求。通过多副本复制机制, kafka 可以提供高可用性和容错性的数据存储。如果一个 broker 故障有其他副本可以代替领导者成为新的领导者,从而保持数据的可用性。这样,即使出现硬件故障或节点崩溃, 消息仍然可靠地保留在其他副本中,不会导致数据丢失。在配置 cover 时,副本数量的选择需要根据应用程序的需求来平衡可用性。数据勇于和性能 增加,副本数量会增加数据的勇于和可用性,但也会增加复制的网络开销和存储需求。因此,在设计 coffer 集群时需要仔细权衡这些因素。
大场面是最常见的,卡夫卡夺命连环五连问,最近呢,有一位五年工作间的小伙伴去某场面试,就问他这一个问题,说,请你简单说一下卡夫卡的零拷贝原理, 在使劲用开发中啊,如果我们需要把磁盘中的某个文件发送到远程服务器上的话,他必须经过几个拷贝的过程,如图所示。 第一步呢,就是从磁盘中去读取目标文件的内容,然后拷贝到内核缓冲区。第二步呢,是 cpu 控制器,再把内核缓冲区的数据复制到用户空间的缓冲区。 第三步呢,接着在应用程序中,会调用 read 方法,把用户的缓冲区的数据,然后拷贝到任何下面的 soc 的八法中。最后呢,再把任何模式下的 soco 的八法中的数据复制到网卡的缓冲区。第五步呢,网卡的缓冲区,再把数据传输到目标服务器上。 那么在这个过程中呢,我们可以发现,数据从实盘最终发出去要经历四次拷贝,而这四次拷贝过程中呢,有两次拷贝是浪费的,分别是从内存空间复制到用户空间, 从用户空间再次复制到内核空间。除此之外呢,由于用户空间和内核空间的切换,会带来 cpu 的上线纹切换的开销,那么对于 cpu 性能呢,也会造成一定的影响。 而我们说的零拷贝呢,就是把这两次多余的拷贝省略掉。应用程序呢,就可以直接把磁盘中的数据从内核中直接传输给输给他,而不再需要经过应用程序所在的用户空间。如图所示, 领导背呢,通过 dma 的技术把文件内容复制到内核空间的 redbuff, 那么接着呢,把包含数据位置的长度的信息和文件的描述符信息加载到我们 socketbuds, 那么 dma 引擎呢,就可以直接把数据从内核空间传递给网卡设备,在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且呢减少了两次 cpu 的一个上下文切换的过程,那么对于效率呢,就有了非常大的提升。 所以呢,作为零拷贝,并不是完全没有数据复制,只是相对于用户空间来说,不再需要进行数据拷贝。那么对于前面所说的整个流程来说呢,零拷贝只是减少了不必要的拷贝次数而已。 那我们在应用程序中实现领卡办的方式有三种,第一种呢,是在 netegs 中,领卡办技术依赖于我们底层的一个叫做生得 fair 的方法来实现,那么在价位中呢,可以通过 fair 签的点圈十分注入方法,他的底层呢,将用的就是生得费尔方法。那么第三个呢,就是 m map 文件的一个验收机制, 他的原理呢,是将磁盘文件映射到内存,然后呢,用户通过修改内存,就相当于是修改了磁盘文件,达到一个数据同步的目的,使用这种方式呢,就可以获取很大的一个 io 提升,从而省去了用户空间到内核空间的一个复制的开销。 那么卡不卡的零拷贝呢,它是采用声带肺尔的方式去完成拷贝的过程。以上呢,就是我对卡不卡零拷贝原理的理解,按照你对卡不卡数据存储原理的理解,我给大家来聊一聊我对这个问题的理解。 另外呢,我把往期分享的视频全部整理成了一份二十万字的文档,后续呢,还会年更,希望能够以此来提高各位粉丝的面试通过率。想获取的小伙伴可以在我的个人主页简介中找到。 要了解卡不卡的数据存储原理呢,我从以下五个方面来分析,分别是 topic 主题,他听选分区、 reflect 副本、 segment 分片以及 index 缩影。首先来看 topic 主题,在卡付卡中呢,用来存储消息的队列叫做 topic, 它是一个逻辑的概念,也可以理解成是一组消息的集合。生产者和 topic 以及 topic 和消费者是多对多的关系。一个生产者呢,可以发送消息的多个 topic, 一个消费者呢,也可以从多个 topic 去获取消息。如图所示,生产者发送消息的时候呢,如果 topic 不存在,财富上默认会自动创建 卡布卡,为了实现横向扩展,他会把不同的数据存储在不同的 blog 上。那么同时呢,为了去降低单台服务器的访问压力,他会把一个 topic 的数据分割成多个 partition, 也就是分段。 那么在服务器上呢,每个 party 型呢,都会有一个物理目录,在 topic 的名字后面加上一个数字标号,也就是代表 分区的标号。比如说,我们创建一个名为 mitobic 的主题,那么它的数据目录呢,被分布到了三台机器,如图所示, mitobic 零呢,存在 a 节点, mitobic 一呢,存在 b 节点, mitobic 二存在 c 节点。 另外呢,卡布卡为了提高分区的可靠性,又设计了一个副本机制,我们在创建 topic 的时候,可以通过指定 replection factor 副本因子来确定 topic 的副本数, 当然呢,副本因子必须要小于等于节点数,否则的话就会报错,这样就可以去保证绝对不会有一个分区的两个副本分布在同一个节点上,不然的话就失去了副本的意义了。如图所示, 我创建了一个三个分区三个副本的 topic, 它的名字叫做 a three, part three rap, 它被均匀的分布到了三个 vlog 基地上,每个 vlog 节点互为备份。那么在这些所有的副本中呢,又有两个角色,一个叫做 leader, 一个叫做 flower。 leader 呢,是负责对外提供读写的服务。而 follower 呢,它的唯一任务就是从 leader 中去一步拉取数据。 如图中所示,红色的副本呢,为绿的,也被均匀的分布在各个简历上,那这样设计呢,就可以去保证读写的均匀,也被称之为单调读一次性。 接下来就是分段卡不卡,为了去防止数据的不断追加导致文件过大,从而去影响解锁的效率, 那么当我们的拍地险超出一定大小的时候,就会被切割为多个 segment 来组织数据。那么在磁盘上呢,每个 segment 呢,由一个 log 文件和两个 index 文件组成,如图所示,这三个文件呢,是成套出现的,其中 index 呢,是用来存储我们 consumer 的 offset 偏音量 用的所有文件。 top mind x 呢,是用来存储消息的时间错的所有文件。 log 文件呢,是用来存储具体的数据文件。这些文件的名字呢,以切割时记录的 offset 值作为文件的名字,那么它的文件结构呢,是这样子的, 通过前面的介绍,我们已经了解了卡布卡的文件存储结构。我们看到有两种所有文件,一种是偏移亮的所有文件, 它记录的是 offset 和消息在 logo 文件中的位置映射关系。另一种呢,是时间出锁眼文件,它记录的是时间出和 offset 的关系。卡布卡为了去提高解锁的效率,并不会为每一条消息去建立锁眼,还是采用的稀疏锁眼,也就是说,他会隔一篇消息才会去产生一条锁眼记录。如图所示, 我们可以通过参数来设置锁眼的吸收程度,相对来说,越传媒的锁眼解锁数据就更快, 是呢,他会消耗更多的存储空间,反之,越稀疏的锁引占用的空间就越小,但是呢,他插入和删除数据的时候,维护开销也就越小。当然,卡不卡的时间出锁引也是采用的稀疏锁引设计。 由于卡夫卡的所有文件是由 offset 来命名的,所以呢,在解锁数据的时候是采用二分法查找,这样的话效率就大大提升。以上呢,就是我对卡夫卡数据存储原理的理解。谈谈你对卡夫卡副本 leader 选举原理的理解。那么今天呢,我跟大家聊一聊我对卡夫卡副本的 leader 选举原理的理解。 确实,卡布卡早期的版本就是直接用做 keep 来完成选举的,他利用了做 keeper 的 watch 机制,节点不允许重复写入以及临时节点这些特性,这样呢,实现起来也比较简单也省事。但是呢,会存在一定的弊端,比如说分区和副本数量过多的时候, 所有的副本都要直接参与选举的话,一旦某个节点出现增减,就会造成大量的握起事件被触发,猪屁股就会负载过重,从而不堪重负。所以呢,在新版本的卡布卡中就换了一种实践方式,他不是所有的副本都要参与立的选举的,而是由其中一个 book 来统一指挥。 这个 blog 的角色呢,就叫做 ctrl 控制器。卡不卡呢,要先从所有的 blog 中选出一个唯一的 ctrl。 所有的 blog 呢,就会尝试在做 caber 中创建一个临时的节点,叫做 ctrl 节点,谁先创建成功,谁就是担任了 ctrl 的角色。那如果 ctrl 挂掉或者是网络出现问题的时候,这个 club 上的临时节点呢,都会消失, 其他的 blog 呢,就会通过握起机制监听到 ctrl 下线的通知。然后呢,就会继续按照先到先得的原则选取出一个新的 ctrl 了。这个 ctrl 呢,就相当于是选举委员会的主席。当一个节点成为 ctrl 了之后,他就会承担以下职责,分别是监听 block 的变化、监听 topic 的变化、监听 particular 的变化,以及获取和管理 block topic party 的信息和管理 partition 的主充信息。 当看究了确定以后,就可以开始选举了。接下来呢,就是要去找到参与选举的候选人。 显然每个副本都想去推荐自己。但是呢,不是所有的副本都有竞选资格的,只有在 s r 中保持心跳同步的副本才有资格参与竞选。 正好比是皇帝每天都要着急皇子们来开早会,只有每天来打卡的皇子才能去加入到 s。 那些请假的迟到的是没有资格参与竞选的候选人确定了,接下来就是立的选举, 就相当于是要在众多的皇子中挑选出太子。那么在分布式选举中,有非常多的选举协议,比如说 jab, rafter 等等,他们的思想归来起来都是遵循先到先得,少数服从督促的原则。但是呢,卡不卡没有用这些算法,而是自己实现的一种算法。 卡布卡的官方解释是他的选举算法和微软的 passafi 的 a 算法最相近,大致的意思是目论让 s r 中的第一个副本变成立的,比如 s r 列表中的值是一五九, 就会优先让一成为立的。这就跟中国古代的皇帝权威是一样的,优先成为给皇长子。假设我们创建一个四个分区两个副本的托比卡,那么他的立的分布是这样的,如图所示, 第一个分区的副本呢,是立的。第一个分区的副本立的呢,落在 b 级的上。第二个分区的副本立的呢,落在 c 级的上。 三个分区的副本立德呢,落在 a 级别上。第四个分区的副本立德呢,落在 b 级别上。那如果没有更多的副本,就以此类推。我们发现立的选者的规则相当于是蛇形走位。这样设计的好处呢,是可以去提高数据副本的容灾能力。立的和副本完全错开,从而不至于一挂全挂。 以上呢,就是我对卡夫卡副本力的选举原理的理解。卡夫卡是如何避免消息重复消费的?我给大家分享一下我的思路。 我认为导致卡不卡消息重复消费有以下两个原因,第一个原因呢,是卡不卡消费端重复提交,导致消息重复消费。如图所示, 在卡不卡的 blog 上存储的消息呢,都有一个 offset 的标记,它用来标记消费者消费消息的位置,那么卡不卡的消费者呢,是通过 offset 标记来维护自己当前已经消费的数据, 每消费一批数据呢波若可就会更新 offset 的值,从而避免重复消费。而在默认情况下呢,消息消费完以后,消费者呢,会自动提交 offset 的值,从而去避免重复消费。但是呢,卡布卡的消费端自动提交以后,会有一个默认的五秒的间隔, 也就是说在五秒之后的下一次 vlog 拉取消息的时候呢,才会提交上一批消费的 offset。 所以在消费者消费的过程中,如果遇到应用程序被强制的 care 掉或者是荡机的情况,就会导致 offset 呢没有及时提交,从而产生重复提交的问题。 那么第二个原因呢,是卡佛卡服务端的 party 选的再均衡机制导致消息重复消费。如图所示,在卡佛卡中,有一个 party 选的半粮食机制,会把多个 party 选均衡的分配给多个消费者,那消费者呢,会从分配到的 party 选里面呢,去消费消息,那如果消费者在末日 的分钟内没有去处理完这批消息的话,就会触发卡不卡的 rebunnance 机制,从而导致 offset 自动提交失败。而 rebunnus 之后呢,消费者还会从之前没有提交到 offset 的位置呢开始消费,从而导致消息重复消费。 那么基于以上我们对卡不卡消息重复消费的原因分析,我认为可以通过以下三种方法来解决问题, 第一个方法呢,是提高消费单的处理性能,从而去避免触发斑点时,比如说可以用多现成的方式呢来处理消息,或者是缩短单个消息的消费时长,或者呢还可以调整消费消息的处理的超时时间,当然呢,也还可以去减少一次性从 block 中去拉取数据的条数。 第二个呢,可以使用 consumer rebenders listener 再均衡接听器,它可以用来去设定发生再均衡动作前后的一些准备,或者是一些收尾工作。第三个呢,可以去 开启卡不卡的密等性功能,像这一道代码,或者呢,可以将消息生成 m d 五,然后呢保存到 myself 或者是 ready 之中。那么在处理消息之前呢,先去 myself 或者是 ready 之中去查询来进行判断,看是否已经消费过。 以上呢,就是我对卡付卡避免消息重复消费的解决思路。今天简单说一下卡付卡为什么这么快?卡付卡呢,是一个号称能用普通的 pc 机,也能够处理超千万的消息吞吐量的实时的消息流处理平台。我认为卡付卡之所以能够支持如此大的吞吐量,而且还能够做到性能优秀的主要原因有四个, 分别是瓷盘的顺序读写、稀疏所引批量的文件压缩和零拷贝机制。下面呢我分布给大家详细介绍一下。在讲顺序读写之前呢,我们先来了解一下瓷盘的选址的过程,如图所示,这个 是磁盘的构造,那么磁盘的盘片呢?在不同的旋转石头呢,在磁盘的表面画出一个圆形的轨迹,这叫磁道,从内到外半径不同呢,会有很多的磁道,然后呢,我们用不同的半径线把磁道划分成了多个扇区,也就是两根上面之间的扇区组成了扇面。 那如果我们去读写数据,就必须要找到数据对应的散区,这个过程呢就叫寻子。那如果我们读写的多角数据在瓷盘上是分散的,那么这个寻子呢,就会很耗时,所以我们把它叫做随机 io。 那如果我们读写的数据在什么上是集中的,我们就不需要去重复的选址,这个叫做顺序 i o。 而卡不卡的消息呢,是不断的追加到本地磁盘上的末尾的,而不是随机的写入,那么这就使得卡不卡的写入的吞吐量就得到了显著的提升。如果我们在 一定条件下进行测试的话,此版的顺序读写可以达到五至三点二兆每秒,比内存的随机读写还要快。 第二个是吸收锁引,卡副卡并不是对每条消息都会建立一个锁引的,而是采用的是一种吸收锁引,如图所示。也就是说卡副卡在插入 e p 数据的时候,才会产生一条锁引记录,后续利用二分查找可以去找到对应的数据,这样的话可以大大提高减锁效率。 第三个呢是批量文件压缩,卡布卡默认是不会删除数据的,他会把所有的消息呢变成一个批量的文件,如图所示,他会把多次插入的相同的 key 对应的 value 合并成为最后一次插入的 value, 这样的话就可以对消息进行合理的批量压缩,从而减少对网络 io 的损耗。第四个呢,叫做零拷贝。我们操 系统的虚拟内存呢,分成两部分,一部分叫做内核空间,一部分叫做用户空间,这样的话就可以去避免用户进程直接去操作内核,从而去保证内核的安全。如图所示, 正常情况下,如果用户要去从磁盘夺取数据的话,就必须要把数据从磁盘拷贝到内核的缓冲区,然后呢,再从内核的缓冲区到用户的缓冲区,最后呢才能去返回给用户。 在我们的 linux 系统里面呢,提供了一个叫做 send fire 函数,它可以去实现零拷贝,意思就是说它不需要经过用户的缓冲区,就可以直接把数据发送到网卡, 而卡不卡的文件传输呢,最终利用的是 java n l 里面的圈是否处方法?实际上呢, java 的圈是否处方法最终占用的是 linux 的生态菲尔函数,所以就可以实现零拷贝。零拷贝技术呢,可以大大提高文件传输的性能。这段面试题呢,涉及到一些计算机的底层 原理,基本上也是业务程序员的支持盲区。但是我想给大家一个建议,做开发其实和建房子是一样的,想要楼层建的更高,首先要打牢基础,我是被变成耽误的王一汤,如果我的分享对你有帮助,请你动动手指,一间三年,分享给更多的人,关注我,面试不再难!
coffer 中的 booker 市值运行 cofoca 服务器的节点,每个 booker 负责管理各或多个分区,并接收生产者发送的消息和向消费者提供消息。下面是 cofoca booker 的工作原理分析。一、 分区管理布欧克维护着一个或多个主题 top, 每个主题被划分成一个或多个分区。炮踢审,每个分区在布欧克上被分配一个唯一的标识符。炮雷踢审,拿一 d 分区的数量和数据在各个布欧克上的分布情况由管理员配置。 剖腹科通过分区实现病情写入和读取,提高了系统的吞吐量和可扩展性。二、消息存储每个分区在博欧坎上有一个日志文件 logo, 费 用于持久化存储消息。每个消息在日制文件中都有一个唯一的位置标示符,奥弗赛特来表示他在分区中的位置。消息在写入时被追加到日制文件的末尾,这样就实 实现了高校的顺序写入。如果日志文件达到设定的大小限制, cove 可将启动一个日志段落,塞够了奶来存储后续的消息。三、 生产者和消费者生产者可以将消息发送到指定的主题和分区,只需要指定目标分区的标识符,消费者可以根据自己的需求定义一个或多个主题,并从指定的分区读取消息。消费者可以控制消费的起始位置,通过指定我复赛卡来决定从哪个位置开始消费。四、 副本管理 coffer 可允许为每个分区配置多个副本 rapper 一克,每个分区会有一个领导者副本里的 rapper 一克和多个追随者副本 follower apple 领导者负责处理生产者的写入请求和消费者的读取请求,而追随者主要用于数据的勇于备份和容错。追随者从领导者复制消息,保持与领导者副本的一致性。五、选举和故障挥 cuff 还是用苏 cap 来进行集群管理和故障恢复苏 cap 负责选举分区的领导者存储分区的原数据信息以及监控波克的状态。当波克发生故障时, gpa 会触发故障恢复机制。 选举新的领导者和追随者,确保数据的可用性和一致性。总的来说, coff 和 bulker 负责管理和存储消息的分区,处理生产者和消费者的请求以及维护副本之间的一致性。他通过分区副本、日制文件和追随者复制等机制,实现了高可用性、高吞吐量和容挫性。
因为五年工作经验的小伙伴,面试的时候被问到这一个问题,说谈谈你在卡夫卡数据存储原理的理解,这位小伙伴呢,一时间没有回答上来,那么今天呢,我给大家来聊一聊我对这个问题的理解。另外呢,我把往期分享的视频全部整理成了一份二十万字的文档, 后续呢,还会年更,希望能够以此来提高各位粉丝的面试通过率。想获取的小伙伴可以在我的个人主页简介中找到。 要了解卡不卡的数据存储原理呢,我从以下五个方面来分析,分别是 topic 主题,它听选分区、 replac 副本、 segment 分片以及 index 锁引。 首先来看 topic 主题,在卡副卡中呢,用来存储消息的队列叫做 topic, 它是一个逻辑的概念,也可以理解成是一组消息的集合。生产者和 topic 以及 topic 和消费者是不对路的关系。 一个生产者呢,可以发送消息的多个 topic, 一个消费者呢,也可以从多个 topic 去获取消息,如图所示。生产者发送消息的时候呢,如果 topic 不存在,谈不上默认,会自动创建 卡布卡。为了实现横向扩展,他会把不同的数据存储在不同的 blog 上。那么同时呢,为了去降低单台服务器的访问压力,他会把一个 topic 的数据分割成多个 partition, 也就是分段。 那么在服务器上呢,每个拔地险呢,都会有一个物理目录,在 topic 的名字后面加上一个数字标号,也就是代表分区的标号。比如说我们创建一个名为 mi topic 的主题,那么它的数字目录呢,被分布到了三台机器,如图所示, my topic 零呢存在 a 节点, my topic 一呢存在 b 节点, my topic 二存在 c 节点。 另外呢,卡布卡为了提高分区的可靠性,又设计了一个副本机制。我们在创建 topic 的时候,可以通过指定 replection factor 副本因子来确定 topic 的副本数。 当然呢,副本因子必须要小于等于节点数,否则的话就会报错,这样就可以去保证绝对不会有一个分区的两个副本分布在同一个节点上,不然的话就失去了副本的意义了。如图所示, 我创建了一个三个分区,三个副本的 topic, 它的名字叫做 a three, part three, rep, 它被均匀的分布到了三个 blog 节点上,每个 blog 节点互为备份。那么在这些所有的副本中呢,拥有两个角色,一个叫做 lead, 一个叫做 flower。 lid 呢,是负责对外提供读写的服务。而 follow 呢,它的唯一任务就是从 lid 中去一步拉取数据。如图中所示,红色的副本呢,为 lid, 也被均匀的分布在各个简历上,那这样设计呢,就可以去保证补血的均匀,也被称之为单调读一次性。 接下来就是分段卡不卡,为了去防止数据的不断追加导致文件过大,从而去影响解锁的效率,那么当我们的 pad 键超出一定大小的时候,就会被切割为多个 segment 来组织数据。那么在磁盘上呢,每个 segment 由一个 logo 文件和两个 index 文件组成, 如图所示,这三个文件呢,是成套出现的,其中 index 呢,是用来存储我们 consumer 的 offset 偏音量的所有文件, 他们那个时呢,是用来存储消息的时间错的所有文件。 logo 文件呢,是用来存储具体的数据文件,这些文件的名字呢,以切割时记录的 offset 值作为文件的名字,那么他的文件结果呢?是这样子的。 通过前面的介绍,我们已经了解了卡不卡的文件存储结构。我们看到有两种所有文件,一种是配音量的所有文件,它记录的是 offset 和消息在 logo 文件中的位置映射关系。另一种呢,是时间粗,所有文件,它记录的是时间粗和 offset 的关系。 卡布卡为了去提高解暑的效率,并不会为每一条消息去鉴定索引,而是采用的稀疏索引,也就是说,他会隔一篇消息才会去产生一条索引记录。如图所示, 我们可以通过参数来设置锁眼的稀疏程度,相对来说,越传媒的锁眼减少,数据就更快,但是呢,他会消耗更多的存储空间,反之,越稀疏的锁眼占用的空间就越小,但 但是呢,他插入和删除数据的时候,维护开销也就越小。当然,卡夫卡的时间出所有也是采用的系数所有设计,由于卡夫卡的所有文件是以 offset 来命名的,所以他 在解锁数据的时候是采用二分法查找,这样的话效率就大大提升。以上呢,就是我对卡不卡数据存储原理的理解,我是被变成耽误的王一汤,如果我的分享对你有帮助,请你动动手指,一键三连分享给更多的人,关注我,面试不再难!
kafka 的工作原理是什么? kafka 的工作原理是基于发布订阅模式的消息传递系统,它允许应用程序通过生产者将消息发布到一个或多个主题 topic, 并允许消费者订阅这些主题并消费消息。以下是 kafka 的主要工作原理, 一、生产者发布消息应用程序作为 cafka 的生产者将消息发布到一个指定的主题,生产者可以选择将消息发送到特定的分区中,也可以让 cafka 使用默认的分区选择策略。二、消息存储 一旦生产者将消息发送到 carfka, carfka 将这些消息持久化存储在主题的一个或多个分区中,每个分区都是一个有序的、不可变的消息日志。三、消息复制 carfka 支持多副本复制机制,每个分区的消息可以有多个副本存储在不同的 broker 上。这样 做的目的是提供高可用性和容错性,以防止 broker 故障导致消息丢失。四、消费者订阅主题应用程序作为 coverca 的消费者可以订阅一个或多个主题并从中读取消息。消费者可以以不同的消费组形式组织, 每个消费组可以有多个消费者,但一个分区的消息只能被一个消费组中的一个消费者消费。五、消费者消费消息每个消费者维护自己的偏移量 offset 表示他在分区中消费的位置。 消费者通过轮巡或订阅通知的方式从 broker 中拉取消息,并将篇一量保存在外部存储中。 消费者可以在消费过程中控制消息的提交方式,以实现至少一次和最多一次羽翼的消费。六、消费者组协调当有多个消费者组中的消费者订阅同一个主题时, coffer 将协调分配消息给每 每个消费者组中的消费者。这确保了每个分区的消息只能被一个消费者组中的一个消费者消费,实现消息的负载均衡和病情处理。七、动态扩展和水平伸缩 cofk 支持动态扩展和水平伸缩,通过增加 broker 节点或增加分区来增加吞吐量和容量。 卡福卡的工作原理使得它能够处理大规模的实时数据流,支持高吞吐量、低延迟和高可用性的数据传输和处理。其分布式架构和多副本复制机制确保了数据的安全性和可靠性。
请谈一谈卡副卡的工作流程,这是一个卡副卡常见的面试问题,那我们看一张图, 卡富卡作为消息队列也有三个要素,分别是左侧的生产者,右侧的消费者,以及中间的消息服务器不落。可那我们中间这个呢,是一个卡富卡的集群,那么这里边又有四个概念,分别是托皮壳、爬低性、 offshi 的和副本。 那首先我们看一下脱皮哥,脱皮哥呢,他是一个存储消息的抽象的逻辑的概念,不是真实存在的,可以认为这个里边就是存放消息的一个集合,可以作为消息的分类, 比如说不同的消息也可以用不同的脱皮稿来存放。好,那么爬低性这个概念呢?它是脱皮稿之下的一个概念, 在一个托闭口下边可以有一个或者是多个爬低行,爬低行也叫分区,那么这个概念很重要,爬低行是真正的存放消息的消息队列。哎,我们消息呢,就是存放在爬低行里面的,我们看一张图, 那我们左侧这个是生产者,右侧这是消费者,那么中间这个呢,就是我们的一个托闭口,托闭口的名字我们叫埋托闭口,那么这个托闭口下边就有三个 pad 型,三个分区,我们简称叫 p n、 p 一和 p 二。好,这就是我们的 pad 型。 那接下来第三个概念就是我们的欧赛的,欧赛的就是每个 party 型里边的消息有一定的顺序性,我们这里有一个序号,就代表我们消息的顺序,那么这个就是我们消息的欧赛的。好,那么最后一个概念就是副本,副本呢就是 每个 party 型的备份,一个 party 型可以有一个或者多个副本,也就是他可以有一个或者是多个备份,那么这个副本呢?他有主副本和重副本啊,主副本我们叫 lid, 从副本叫 follow, 主副本负责读写,从副本只负责从主副本同步数据。好,那这四个概念我们解释完以后,我们下面可以看一下我们这个图,我们生产者发上一个消息,他会按照一定的策略把消息来发送到脱皮壳下的某个爬地形下, 那么他肯定是发送到这个主的爬地形啊,立德的爬地形,因为虫的爬地形他是只负责同步组的数据,他是不接收读写的。然后我们消费者这边呢,他也是按照一定的策略从这个立德的 这个爬低性这个分区中来获取消息。一个爬跌性下的消息他是有顺序的,这个爬低性下他的消息有顺序,这个爬低性下他的消息也有顺序。但是如果我们跨分区的跨爬跌性的消息,他就是没有顺序的。 如果我们要想实现一个顺序消息,那这个时候把消息发送到同一个 party 形象,那么这个时候他的消息是有顺序的。我们这个立的 party 型,那么他对于有一个重的副本 follow party 型, 我们这个 lid 的爬地形,它也对于有一个虫的啊 follow 的爬地形。那么以上这个呢,就是卡副卡的工作流程。
哈喽,大家好,我是麦克,一个工作了五年的粉丝啊,在简历上写精通卡夫卡,结果在面试的时候啊,直接被打脸,为什么问他什么是 isr, 为什么设计 isr? 结果他一脸懵逼的看着面试官。关于这个问题的回答呢,我整理成了文档啊,有需要的小伙伴可以在我的主页去加微领取。 下面我们看看普通人和高手对这个问题的回答。普通的回答,嗯,呃, isrisr 好像是卡不卡里面的一个机制吧,嗯?为什么要引入? 嗯,应该是跟我记得好像是跟数据同步有关系。嗯,高速的回答,好的,关于这个问题呢,我需要从几个方面来回答,首先,发送的卡弗卡 brock 上面的一些消息啊,最终是以 party 型的一个 物理形态来存储到瓷板上面的,而卡不卡呢,为了去保证 party 选的一个可靠性,提供的 party 型的一个副本机制。然后在这些 party 选副本级里面呢,存在一些 lee 的 party 选和佛罗 party 选, 而生产者发送消息过来的时候呢,会先把消息存在 le 的 party 选里面,然后再把消息复制到 folo practice 里面。那么这样设计的好处是,一旦 lid party 型锁在了节点挂了,那么我们可以重新从剩下的 party 选副本里面去选举出新的 leader。 然后呢,消费者呢,可以继续从新的离的 p t 恤里面去获取没有被消费过的数据。而在 p t 恤的多副本设计方案里面,有两个非常关键的需求,第一个是副本数据的一个同步, 第二个是新的哩的的一个选举,而这两个需求都需要涉及到网络通信,所以卡佛卡为了避免网络通信延迟带来一个性能问题啊,以及尽可能的去保证 新选举出来的 lead petition 里面的数据是最新的,所以设计了一个 is r 这样的一个方案。那么 is r 全称叫 in single replica, 它是一个集合列表,里面保存的是和 lead petition 节点的数据最接近的所有的 follow petition 节点, 如果某一个 folo 的朋友圈里面的数据啊落后立的太多,那么这个节点就会被踢出 isr 的一个列表。简单来说呢, isa 列表里面的节点啊,同步的数据一定是最新的,所以后续新的立的选举呢,我们只需要从 isr 列表里面去筛选就好了。 所以我认为啊,引路 isr 这样一个设计方案的原因有两个,第一个是尽可能的去保证数据同步的一个效率,因为同步效率不高的节点都会被踢出 isr 的一个列表。第二个是避免数据丢失,因为 isr 里面的节点的数据和 v 的副本是最接近的。以上就是我对这个问题的一个理解,在我看来,这个问题 是非常有研究价值的。一般来说,副本数据同步无非就是同步主色或者异步非主色两种方案,但是这两种方案要么带来性能问题,要么带来数据丢失的问题,都不是特别的合适啊。而 sr 这种设计呢,就非常完美的解决这两个问题, 在实际应用中呢,我们可以借鉴类似的设计思路。好的,本期的普通人 vs 高手的面试系列视频呢,就要到结束了,喜欢我的作品的小伙伴记得点赞、收藏加关注。我是麦克,一个工作了十四年的家务程序员,我们下期再见。
面试常问的卡不卡面试题,因为六年工作经验,小办面试被问到这样一个问题,说卡不卡是如何避免消息重复消费的,他面完之后呢,这位小伙伴呢,找到我,希望我能给一个思路,那今天呢,我给大家分享一下我的思路。 另外呢,我花了一个多星期,准备了一份十万字的面试题解析,配套完档,想获取的小伙伴可以在我的个人主页简介中找到。要回答好这个问题呢,首先要分析一下导致消息重复消费的原因有哪些? 我认为导致卡不卡消息重复消费有以下两个原因,第一个原因呢,是卡不卡消费端重复提交导致消息重复消费。如图所示, 在卡不卡的 blog 上存储的消息呢,都有一个 offset 的标记,还有呢,标记消费者消费消息的位置,那么卡不卡的消费者呢,是通过 offset 标记来维护自己当前已经消费的数据, 每消费一批数据呢波若可就会更新 offset 的值,从而避免重复消费。而在默认情况下呢,消息消费完以后,消费者呢会自动提交 offset 的值,从而去避免重复消费。但是呢,卡不卡的消费端自动提交以后,会有一个默认的五秒的间隔, 也就是说在五秒之后的下一次 vlog 拉取消息的时候呢,才会提交上一批消费的 offset。 所以在消费者消费的过程中,如果遇到应用程序被强制的 care 掉或者是当机的情况,就会导致 offset 呢,没有及时提交,从而产生重复提交的问题。 那么第二个原因呢,是卡不卡服务端的 partition 的再均衡机制,导致消息重复消费。如图所示,在卡不卡中有一个 partition 的半粮食机制,会把多个 partition 均衡的分配给多个消费者,那消费者呢,会从分配到的 partition 里面呢去消费消息,那如果消费者在末日 的分钟内没有去处理完这批消息的话,就会突发卡不卡的 read bandance 机制,从而导致 offset 自动提交失败。而 red bandance 之后呢,消费者还会从之间没有提交到 offset 的位置呢开始消费,从而导致消息重复消费。 那么基于以上我们对卡不卡消息重复消费的原因分析,我认为可以通过以下三种方法来解决问题。 第一个方法呢,是提高消费单的处理性能,从而去避免触发斑点时,比如说可以用多现成的方式呢来处理消息,或者是缩短单根消息的消费时长,或者呢,还可以调整消费消息的处理的超时时间。当然呢,也还可以去减少一次性从 block 中去拉取数据的条数。 第二个呢,可以使用抗数码 rebend slice 呢再均衡接听器,它可以用来去设定发生再均衡动作前后的一些准备,或者是一些收尾工作。第三个呢,可以去 开启卡不卡的密等性功能,像这一道代码,或者呢,可以将消息生成 m d 五,然后呢保存到 mac 狗或者是 red 之中。那么在处理消息之前呢,先去 mac 狗或者是 red 之中去查询来进行判断,看是否已经消费过。 以上呢,就是我对卡夫卡避免消息重复消费的解决思路,因为五年工作经验的小伙伴面试的时候被问到这一个问题,说谈谈你对卡夫卡数据存储原理的理解,这位小伙伴呢,一时间没有回答上来,那么今天呢,我给大家来聊一聊我对这个问题的理解。 要了解卡和卡的数据存储原理呢,我从以下五个方面来分析,分别是 topic 主题,它听显分区、 replace 副本、 segment 分片以及 index 锁引。首先来看 topic 主题,在卡付卡中呢,用来存储消息的队列叫做 topic, 它是一个逻 国际的概念,也可以理解成是一组消息的集合。生产者和 topic 以及 topic 和消费者是多对多的关系。一个生产者呢,可以发送消息到多个 topic, 一个消费者呢,也可以从多个 topic 去获取消息。如图所示,生产者发送消息的时候呢,如果 topic 不存在,查不查,默认会自动创建 卡不卡。为了实现横向扩展,他会把不同的数据存储在不同的 vlog 上。那么同时呢,为了去降低单台服务器的访问压力,他会把一个 topic 的数据分割成多个 partition, 也就是分段。 那么在服务器上呢,每个八字形呢,都会有一个物理目录,在 topic 的名字后面加上一个数字标号,也就是代表分区的标号。比如说,我们创建一个名为 my topic 的主题,那么它的数字目录呢,被分布到了三台机器,如图所示, mi topic 零呢,存在 a a 节点, my topic 一呢,存在 b 节点, my topic 二存在 c 节点。 另外呢,卡布卡为了提高分区的可靠性,又设计了一个副本机制,我们在创建托本格的时候,可以通过指定 replection factor 副本因子来确定托本格的副本数, 当然呢,副本因子必须要小于等于节点数,否则的话就会报错,这样就可以去保证绝对不会有一个分区的两个副本分布在同一个节点上,不然的话就失去了副本的意义了。如图所示, 我创建了一个三个分区三个副本的 topic, 它的名字叫做 a three, part three rap, 它被均匀的分布到了三个 blog 节点上,每个 blog 节点互为备份。那么在这些所有的副本中呢,又有两个角色,一个叫做 lid, 一个叫做 flower。 lid 呢,是负责对外提供读写的服务。而 follow 呢,它的唯一任务就是从 lid 中去一步拉取数据。如图中所示,红色的副本呢,为 lid, 也被均匀的分布在各个简历上,那这样设计呢,就可以去保证读写的均匀,也被称之为单调读一次性。 接下来就是分段卡不卡,为了去防止数据的不断追加导致文件过大,从而去影响解锁的效率, 那么当我们的 party 选超出一定大小的时候,就会被切割为多个 segment 来组织数据。那么在磁盘上呢,每个 segment 由一个 log 文件和两个 index 文件组成,如图所示,这三个文件呢,是成套出现的,其中 index 呢,是用来存储我们 consumer 的 offset 偏音量的所有文件, 他们那个时呢,是用来存储消息的时间错的所有文件。 logo 文件呢,是用来存储具体的数据文件。这些文件的名字呢,以切割时 记录的 offset 值作为文件的名字。那么它的文件结构呢,是这样子的,通过前面的介绍,我们已经了解了卡不卡的文件存储结构。我们看到有两种所有文件,一种是偏移量的所有文件, 它记录的是 offset 和消息在 logo 文件中的位置映射关系。另一种呢,是时间出锁眼文件,它记录的是时间出和 offset 的关系。卡不卡为了去提高解锁的效率,并不会为每一条消息去鉴定锁眼,还是采用的稀疏锁眼,也就是说,他会隔一篇消息才会去产生一条锁眼记录。如图所示, 我们可以通过参数来设置锁引的吸收程度,相对来说,越传媒的锁引解锁数据就更快,但是呢,他会消耗更多的存储空间,反之,越吸收的锁引占用的空间就越小,但是呢,他插入和删除数据的时候,维护开销也就越小。当然, 卡不卡的时间出锁眼也是采用的系数锁眼设计。由于卡不卡的锁眼文件是以 offset 来命名的,所以呢,在解锁数据的时候是采用二分法查找,这样的话效率就大大提升。 以上呢,就是我对卡夫卡数据存储原理的理解。最近呢,有一位五年工作间的小伙伴去某场面试,就问他这一个问题,说请你简单说一下卡夫卡的零拷贝原理。然后呢,这个小伙伴突然愣住了,什么是零拷贝?零拷贝跟卡夫卡有关系吗?那么今天呢,我给大家来聊一聊我对卡夫卡零拷贝原理的理解。 在实际应用开发中啊,如果我们需要把磁盘中的某个文件发送到远程服务箱的话,它必须经过几个拷贝的过程,如图所示。第一步呢,就是从磁盘中去读取目标文件的内容,然后拷贝到内核缓冲区。第二步呢,是 cpu 控制器再把内核缓冲区的数 据复制到用户空间的缓存区。第三步呢,接着在应用程序中,会调用 read 方法,把用户的缓存区的数据,然后卡备到任何下面的 soc 的办法中。最后呢,再把任何模式下的 soco 的办法中的数据复制到网卡的缓存区。 第五步呢,网卡的防冻区,再把数据传输到目标服务器上。那么在这个过程中呢,我们可以发现,数据从实拍最终发出去要经历四次拷贝,而这四次拷贝过程中呢,有两次拷贝是浪费的,分别是从内存空间复制到用户空间, 从用户空间再次复制到内核空间。除此之外呢,由于用户空间和内核空间的切换会带来 cpu 的上限为千万的开销,那么对于 cpu 性能呢,也会造成一定的影响。而我们输的零拷贝呢,就是把这两次多余的拷贝省略掉。应用程序呢,就可以直接把 实盘中的数据从内核中直接传输给 social, 而不再需要经过应用程序所在的用户空间。如图所示,领导费呢,通过 dma 的技术把文件内容复制到内核空间的 red buff。 那么接着呢,把包含数据位置的长度的信息和文件的描述符信息加载到我们缩口的办法中。 那么 dma 引擎呢,就可以直接把数据从内核空间传递给网卡设备,在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且呢减少了两次 cpu 的一个上下文切换的过程,那么对于效率呢,就有了非常大的提升。 所以呢,作为零拷贝并不是完全没有数据复制,只是相对于用户空间来说,不再需要进行数据拷贝。那么对于前面所说的整个流程来说呢,零拷贝只是减少了不必要的拷贝次数 而已。那我们在应用程序中实现零卡贝的方式有三种,第一种呢,是在另一个词中,零卡贝技术依赖于我们底层的一个叫做生得非尔的方法来实现,那么在价位中呢,可以通过非要签的点圈十分旧方法,他的底层呢,专用的就是生得非尔方法。 那么第三个呢,就是 m map 文件的一个印售机制,它的原理呢是将磁盘文件印设的内存,然后呢,用户通过修改内存,就相当于是修改了磁盘文件,达到一个数据同步的目的, 使用这种方式呢,就可以获取很大的一个 i o 提升,从而省去了用户空间到内核空间的一个复制的开销。那么卡不卡的零拷贝呢?它是采用生态费尔的方式去完成拷贝的过程。 以上呢,就是我对卡夫卡零拷贝原理的理解。一位七年工作精神小伴,在面试的时候被问到这一道面试题,说谈谈你对卡夫卡副本 lid 选 选举原理的理解,当时他就在想说,这卡夫卡用的不就是猪 keep 的选举吗?难道卡夫卡自己又搞了一套?没错,这回卡夫卡自己又造了一个轮子。那么今天呢,我给大家聊一聊我对卡夫卡副本的立德选举原理的理解。 确实,卡夫卡早期的版本就是直接用周 k 本来完成选举的,他利用了周 k 本的 watch 机制,节点不允许重复写入以及临时节点这些特性,这样呢,实现起来也比较简单也省事。但是呢,会存在一定的弊端,比如说分区和副本数量过多的时候,所有的副本都要直接参与选举的话, 一旦某个节点出现增减,就会造成大量的卧起事件被触发,猪屁股就会负载过重,从而不堪重负。所以呢,在新版本的卡布卡中就换了一种实践方式,他不是所有的副本都要参与类的选举的,而是由其中一个 boc 来统一指挥。 这个 blog 的角色呢,就叫做 ctrl 控制器。卡不卡呢,要先从所有的 blog 中选出一个唯一的 ctrl, 所有的 blog 呢,就会尝试在做 cable 中创建一个临时的节点,叫做 ctrl 节点,谁先创建成功,谁就是担任了 ctrl 的角色。 那如果 ctrl 挂掉或者是网络出现问题的时候, qq 版上的临时节点呢,都会消失,其他的 vlog 呢,就会通过握取机制监听到 ctrl 下线的通知。然后呢,就会继续按照先到先得的原则选取出一个新的 ctrl, 这个 ctrl 呢,就相当于是选举委员会的主席。当一个节点成为 ctrl 之后,他就会承担以下职责,分别是监听 blog 的变化、监听 topic 的变化、监听 partition 的变化,以及获取和管理 block topic partition 的信息和管理 partition 的 的祖宗信息。当看究了确定以后,就可以开始选举了。接下来呢,就是要去找到参与选举的候选人,显然每个副本都想去推荐自己,但是呢,不是所有的副本都有竞选资格的,只有在 s r 中保持心跳同步的副本才有资格参与竞选。 最好别是皇帝,每天都要召集皇子们来开早会,只有每天来打卡的皇子才能去加入到 sr。 那些请假的、迟到的是没有资格参与竞选的。候选人确定了,接下来就是立的选举,就相当于是要在众多的皇子中挑选出太子。 那么在分布式选举中,有非常多的选举协议,比如说 jab, rafter 等等,他们的思想归来起来都是遵循先到先得,少数服从督促的原则。但是呢,卡不卡没有用这些算法,而是自己实现这种算法卡不卡的官方解释 四、他的全球算法和微软的 pass f x a 算法最相近,大致的意思是默认让 sr 中的第一个副本变成立的,比如 sr 列表中的值是一五九,就会优先让一成为立的。 这就跟中国古代的皇帝床位是一样的,优先呈给皇长子。假设我们创建一个四个分区两个副本的 topic, 那么他的立德分布是这样的,如图所示。 第一个分区的副本呢,是立的。第一个分区的副本立的呢路在 b 结列上。第二个分区的副本立的呢路在 c 结列上。第三个分区的副本立的呢路在 a 结列上。第四个分区的副本立的呢路在 b 结列上。那如果没有更多的副本,就以此类推。我们发现立的选者的规则相当于是蛇形走位。 这样设计的好处呢,是可以去提高数据副本的容灾能力,立德和副本完全触开,从而不至于一挂全挂。以上呢,就是我的卡夫卡副本立德选举原理的理解。
跳槽避讳 costcar 高频面试题说,谈谈你对卡夫卡副本 lid 选举原理的理解。 确实,卡布卡早期的版本就是直接用周 k 本来完成选举的,他利用了周 k 本的握起机制,节点不允许重复写入以及临时节点这些特性,这样呢,实现起来也比较简单也省事。但是呢,会存在一定的弊端,比如说分区和副本数量过多的时候,所有的副本都要直接参与选举的话, 一旦某个节点出现增减,就会造成大量的握起事件被触发,猪 people 就会负载过重,从而不堪重负。 所以呢,在新版本的卡布卡中,就换了一种实践方式,他不是所有的副本都要参与立的选举的,而是由其中一个 block 来统一指挥。这个 block 的角色呢,就叫做 ctrl 控制器。卡不卡呢,要先从所有的 blog 中选出一个唯一的 ctrl, 所有的 vlog 呢,就会尝试在这个 keep 中创建一个临时的节点,叫做 ctrl 节点,谁先创建成功,谁就是担任了 ctrl 的角色。那如果 ctrl 挂掉或者是网络出现问题的时候,这个 cable 上的临时节点呢,都会消失, 其他的 blog 呢,就会通过握取机制监听到 ctrl 下线的通知,然后呢,就会继续按照先到先得的原则选举出一个新的 ctrl。 这个 ctrl 呢,就相当于是选举委员会的主席。当一个节点成为 ctrl 之后,他就会承担以下职责,分别是监听 blog 的变化、 监听 topic 的变化、监听 particular 的变化,以及获取和管理 block topic particle 的信息和管理 particular 的组成信息。当看究了确定以后,就可以开始选举了,接下来呢,就是要去找到参与选举的 候选人,显然每个副本都想去推荐自己,但是呢,不是所有的副本都有竞选资格的,只有在 sr 中保持心跳同步的副本才有资格参与竞选。正好比是皇帝每天都要召集皇子们来开早会,只有每天来打卡的皇子才能去加入到 sr。 那些请假的、迟到的是没有资格参与竞选的候选人。确定了,接下来就是立的选举,就相当于是要在众多的皇子中挑选出太子。 那么在分布式选举中,有非常多的选举协议,比如说 job, rafter 等等,他们的思想归来起来都是遵循先到先得,少数服从督促的原则。但是呢,卡布卡没有用这些算法,而是自己实现这种算法。 卡布卡的官方解释是,他的选举算法和微软的 passafic a 算法最相近,大致的意思是默认让 sr 中的第一个副本变成立的。 比如 sr 列表中的值是一五九,就会优先让一成为立的,这就跟中国古代的皇帝权位是一样的,优先呈给皇长子。假设我们创建一个四个分区两个副本的 topic, 那么他的立的分布是这样的,如图所示, 第一个分区的副本呢,是立的。第一个分区的副本立的呢,落在 b 级的上。第二个分区的副本立的呢,落在 c 级的上。第三个分区的副本立的呢,落在 a 级的上。第四个分区的副本立的呢,落在 b 级的上。那如果没有更多的副本,就以此类推。我们发现立的选者的规则相当于是蛇形走位, 这样设计的好处呢,是可以去提高数据副本的容灾能力,立德和副本完全触开,从而不至于一挂全挂。以上呢,就是我对卡夫卡副本立德选举原理的理解。最近呢,有一位五年工作间的小伙伴去某场面试,就问他这一个问题, 说请你简单说一下卡夫卡的零拷贝原理。然后呢,这个小伙伴突然愣住了,什么是零拷贝?零拷贝跟卡夫卡有关系吗?那么今天呢,我给大家来聊一聊我对卡夫卡零拷贝原理的理解。另外呢,我把往期分享的视频全部整理成了一份二十万字的文档, 后续呢,还会连更,希望能够一直呢,提高各位粉丝的面试通过率。想获得小伙伴,可以在我的个人主页简介中找到, 在使劲用开发中啊,如果我们需要把磁盘中的某个文件发送到远程服务器上的话,他必须经过几个拷贝的过程,如图所示。 第一步呢,就是从磁盘中去读取目标文件的内容,然后拷贝到内核缓冲区。第二步呢,是 cpu 控制器,再把内核缓冲区的数据复制到用户空间的缓冲区。第三步呢,接着在应用程序中,会调用 red 方法,把用户的缓冲区 的数据,然后拷贝到内核下面的 sok 的八法中。最后呢,再把内核模式下的 sock 的八法中的数据复制到网卡的缓冲区。第五步呢,网卡的缓冲区,再把数据传输到目标服务器上。 那么在这个过程中呢,我们可以发现,数据从实拍最终发出去要经历四次拷贝,而这四次拷贝过程中呢,有两次拷贝是浪费的,分别是从内存空间复制到用户空间, 从用户空间再次复制到内核空间,除此之外呢,由于用户空间和内核空间的切换会带来 cpu 的双向纹切换的开销,那么对于 cpu 性能呢,也会造成一定的影响。 而我们说的零拷贝呢,就是把这两次多余的拷贝省略掉,应用程序呢,就可以直接把实盘中的数据从内核中直接传输给 socket, 而不再需要经过应用程序所在的用户空间。如图 数四领导费呢,通过 dma 的技术把文件内容复制到内核空间的 redbof, 那么接着呢,把包含数据位置的长度的信息和文件的描述服务信息加载到我们缩口的办法中。那么 dma 引擎呢,就可以直接把数据从内核空间传递给文卡设备, 在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且呢减少了两次 cpu 的一个上下文切换的过程,那么对于效率呢,就有了非常大的提升。 所以呢,作为零拷贝,并不是完全没有数据复制,只是相对于用户空间来说,不再需要进行数据拷贝。那么对于前面所说的整个流程来说呢,零拷贝只是减少了不必要的拷贝次数而已。那么在应用程序中,实现零拷贝的方式有三种,第一种呢,是在 linux 中,零拷贝技术越来越 我们底层的一个叫做生得 fair 的方法来实现,那么在价位中呢,可以通过 fair china 点圈十分处方法,他的底层呢,专用的就是生得 fair 方法。那么第三个呢,就是 m map 文件的一个验收机制, 它的原理呢,是将磁盘文件映射到内存,然后呢,用户通过修改内存,就相当于是修改了磁盘文件,达到一个数据同步的目的,使用这种方式呢,就可以获取很大的一个 io 提升,从而省去了用户空间到内核空间的一个复制的开销。 那么卡不卡的零拷贝呢?它是采用生态费尔的方式去完成拷贝的过程。以上呢,就是我对卡不卡零拷贝原理的理解, 那么本次的面试题呢,涉及到一些计算机底层的原理,大家平时在业务开发过程中也很少去关注,但是呢,我想提醒大家的是,如果在技术的路上想走的更远,还是要关注一些底层的时间原理,把基础打牢固做卡 卡布卡是如何避免消息重复消费的?首先分析一下导致消息重复消费的原因有哪些? 我认为导致卡不卡消息重复消费有以下两个原因,第一个原因呢,是卡不卡消费端重复提交导致消息重复消费。如图所示, 在卡夫卡的 blog 上存储的消息呢,都有一个 offset 的标记,还有呢,标记消费者消费消息的位置。 我们卡不卡的消费者呢,是通过 offset 标记来维护自己当前已经消费的数据,每消费一批数据呢波若可就会更新 offset 的值,从而避免重复消费。 在默认情况下呢,消息消费完以后,消费者呢会自动提交 offer 的值,从而去避免重复消费。但是呢,卡布卡的消费端自动提交以后,会有一个默认的五秒的间隔,也就是说在五秒之后的下一次 block 拉取消息的时候呢,才会提 提交上一批消费的 offset。 所以在消费者消费的过程中,如果遇到应用程序被强制的 care 掉或者是当机的情况,就会导致 offset 呢没有及时提交,从而产生重复提交的问题。那么第二个原因呢,是卡不卡服务端的 party 显得再均衡机制,导致消息重复消费。如图所示, 在卡不卡中有一个 party 选的伴娘时,机制会把多个 party 选均衡的分配给多个消费者,那消费者呢,会从分配到的 party 选里面呢去消费消息。那如果消费者在默认的分钟内没有去处理完这批消息的话,就会突发卡不卡的 reboundance 机制,从而导致 offer 的自动提交失败。 everybodys 之后呢,消费者还会从之前没有提交到福特的位置呢开始消费,从而导致消息重复消费。那么基于以上我们对卡不卡消息重复消费的原因分析,我认为可以通过以下 三种方法来解决问题。第一个方法呢,是提高消费单的处理性能,从而去避免触发斑点时,比如说可以用多现成的方式呢来处理消息,或者是缩短单根消息的消费时长,或者呢,还可以调整消费消息的处理的超时时间。当然呢,也还可以去减少一次性从 blog 中去拉取数据的条数。 第二个呢,可以使用 consorma rebenders lisa 再均衡接听器,他可以用来去设定发生再均衡动作前后的一些准备,或者是一些收尾工作。第三个呢,可以去开启卡不卡的密等性功能,像这一段代码 或者呢可以将消息生成 m d 五,然后呢保存到 myself 或者是 ready 之中。那么在处理消息之前呢,先去 myself 或者是 red 之中去查询来进行判断,看是否已经消费过。以上呢,就是我对卡不卡,避免消息重复消费的解决思路。因为工作了五年的小伙伴去美 美团面试以后啊,他跟我反馈说,被问到一个如何保证卡不卡消息不丢失的问题,他不知道如何回答。其实呢,这个问题真的很基础,很多小伙伴可能只会回答说消息要持久化,或者是添加消息确认机制。如果你只是这样回答的话,那你和普通程序员没什么区别。 要想让面试官感觉到你确实和其他程序不一样,你就应该有自己的理解。好了,这个问题呢,就应该从多个方面更全面的来分析和回答这个问题。今天呢,我给大家来讲明白。 首先第一个呢是服务端,我们要设置 blog 中的一个配置项,去保证副本之间的数据同步,大家可以看这个代码。同时啊,我们在 produce 将消息投递到服务器的时候,我们需要将消息进行数据化,也就是说我们要去同步到硬盘,注意同步到硬盘过程中会有同步刷盘 和翼步双盘,因为选择同步双盘,那就可以保证消息一定不会丢失,就算丢失了我们也可以及时补偿,但如果是选择翼步双盘的话,这个时候消息就有一定的丢失的概率。 网上有一种说法说卡不卡,不支持同步刷盘,这种说法呢不能说完全错,但是呢,我们可以通过参数的配置让他去变成同步刷盘,比如说这样的一个配置,他同样可以达到同步刷盘的效果。 第二呢就是生产者 produce, 我们要去使用带有回调通知的 send 方法,并且呢要设置 x 等于 or, 这样的话呢,他的消息投递方式采用的就是同步方式,不是就是要保证消息能够到达服务器,就需要使用到消息的确认机制,也就是说必须要确保消息投递到服务器 以后,并且能够得到投递成功的响应,确认服务器呢,他已经接收才会继续往下去执行。那如果不能丢时间,消息投递到服务端以后,服务器他没有来得及接收就已经登机了,那投递过来的消息那岂不是丢失了呢? 那这种情况我们应该怎么办呢?大家不要慌,在不能丢死投递消息的时候啊,他都会去记录日志,然后呢将消息投递到服务器端,就算服务器当季了,等到服务器重启之后呢,也可以根据日信息去完成消息的补偿,这样的话就可以确保消息不丢失。 第三个呢就是消费者坑数码没有设置一个自动提交为 force 在卡付卡中啊,消息消费完成之后呢,他不会立即删除,而是使用定时的清除策略,也就是我们消费者要确保消息成功以后没有手动 ac 提交,如果消息失败的情况下,我们要去不断的去从事。所以呢消费单不能设置自动提交,一定要设置为手动提交才能过去,保证消息他不丢失。 这里总结一下,卡不卡要严格意义上去保证消息不丢失的话,我们需要从三个方面来设置, 第一个呢是服务器端,他要将直觉化的设置设为同步刷盘。第二个呢是生产者要设置为同步的投递消息。第三个呢就是消费者要设置为手动提交。以上呢就是我对卡副卡保证消息不丢失的解决方案。
卡夫卡经典面试题说,谈谈你对卡夫卡副本力的选举原理的理解。确实,卡夫卡早期的版本就是直接用 joke 本来完成选举的,他利用了 joke 的 word 体机制,节点不允许重复写入 以及临时节点这些特性。这样呢,实现起来也比较简单也省事。但是呢,会存在一定的弊端,比如说分区和副本数量过多的时候,所有的副本都要直接参与选举的话, 一旦某个节点出现增减,就会造成大量的 worcy 事件被触发, zukibo 就会负载过重,从而不堪重负。 所以呢,在新版本的卡不卡中就换了一种实践方式,他不是所有的副本都要参与立的选举的,而是由其中一个 block 来统一指挥,这个 block 的角色呢,就叫做 ctrl 控制器。卡不卡呢,要先从所有的 blog 中选出一个唯一的 ctrl, 所有的 blog 呢,就会产 尝试在做 k 本中创建一个临时的节点,叫做 ctrl 节点,谁先创建成功,谁就是担任了 ctrl 的角色。那如果 ctrl 挂掉或者是网络出现问题的时候,做 k 本上的临时节点呢,都会消失, 其他的 vlog 呢,就会通过握取机制监听到 ctrl 下线的通知。然后呢,就会继续按照先到先得的原则选取出一个新的 ctrl, 这个 ctrl 呢,就相当于是选举委员会的主席。当一个节点成为 ctrl 了之后,他就会承担以下职责,分别是监听 blog 的变化、监听 topic 的变化、监听 particular 的变化以及获取和管理 block topic particular 的信息和管理 particular 的主充信息。 当看究了确定以后,就可以开始选举了,接下来呢,就是要去找到参与选举的候选人, 每个副本都想去推荐自己,但是呢,不是所有的副本都有竞选资格的,只有在 sr 中保持心跳同步的副本才有资格参与竞选。正好比是皇帝每天都要召集皇子们来开早会,只有每天来打卡的皇子才能去加入到 sr, 那些请假的,迟到的是没有资格参与竞选的。 破雪人确定了,接下来就是立的选举,就相当是要在众多的皇子中挑选出太子。那么在分布式选举中,有非常多的选举协议,比如说 java, rafter 等等, 他们的思想归来起来都是遵循先到先得,少数服从督促的原则。但是呢,卡布卡没有用这些算法,而是自己实现的一种算法。卡布卡的官方解释是他的全球算法和微软的 passenger a 算法最相近,大致的意思是默认让 sr 中的第一个副本变成立的,比如 i 撒列北中的值是一五九,就会优先让一成为立的,这就跟中国古代的皇帝床位是一样的,优先成为皇长子。假设我们创建一个四个分区两个副本的 top 口,那么他的立的分布是这样的,如图所示, 第一个分区的副本呢,是立的。第一个分区的副本立的呢,落在 b 级的上。第二个分区的副本立的呢,落在 c 级的上。第三个分区的副本立的呢,落在 a 级的上。第四个分区的副本立的呢,落在 b 级的上。那如果没有更多的副本,就以此类推。我们发现立的选者的规则相当于是蛇形走位, 这样设计的好处呢,是可以去提高数据副本的容灾能力,立德和副本完全错开,从而不至于一挂全挂。以上呢,就是我的卡夫卡副本立德选举原理的理解。最近呢,有一位五年工作间的小伙伴去某场面试,就问他这一个问题,说请你简 单说一下卡夫卡的零拷贝原理。然后呢,这个小伙伴突然愣住了,什么是零拷贝?零拷贝跟卡夫卡有关系吗?那么今天呢,我给大家来聊一聊我对卡夫卡零拷贝原理的理解。另外呢,我把往期分享的视频全部整理成了一份二十万字的文档, 后续呢,还会连更,希望能够以此来提高各位粉丝的面试通过率。想获得小伙伴,可以在我的个人主页简介中找到。 在实际应用开发中啊,如果我们需要把磁盘中的某个文件发送到远程服务区的话,它必须经过几个拷贝的过程,如图所示。 第一步呢,就是从磁盘中去读取目标文件的内容,然后拷贝到内核缓冲区。第二步呢,是 cpu 控制器,再把内核缓冲区的数据复制到用户空间的缓冲区。第三步呢,接着在应用程序中,会调用 right 方法,把用户的缓冲区的数据,然后 拷贝到任何下面的缩口的八法中。最后呢,再把任何模式下的缩口的八法中的数据复制到网卡的缓冲区。第五步呢,网卡的缓冲区,再把数据传输到目标服务器上。 那么在这个过程中呢,我们可以发现,数据从实拍最终发出去要经历四次拷贝,而这四次拷贝过程中呢,有两次拷贝是浪费的,分别是从内存空间复制到用户空间, 从用户空间再次复制到内核空间,除此之外呢,由于用户空间和内核空间的切换会带来 cpu 的上线纹切换的开销,那么对于 cpu 性能呢,也会造成一定的影响。 而我们说的零拷贝呢,就是把这两次多余的拷贝省略掉,应用程序呢,就可以直接把实盘中的数据从内核中直接传输给输给他,而不再需要经过应用程序所在的用户空间。如图所示, 领导背呢,通过 dma 的技术把文件内容复制到内核空间的 redbof, 那么接着呢,把包含数据位置的长度的信息和文件的描述符信息加载到我们缩口的办法中,那么 dma 引擎呢,就可以直接把数据从内核空间传递给文卡设备, 在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且呢减少了两次 cpu 的一个上下文切换的过程,那么对于效率呢,就有了非常大的提升。 所以呢,作为零拷贝,并不是完全没有数据复制,只是相对于用户空间来说,不再需要进行数据拷贝。那么对于前面所说的整个流程来说呢,零拷贝只是减少了不必要的拷贝次数而已。 那我们在应用程序中实现零卡牌的方式有三种,第一种呢,是在 linux 中,零卡牌技术依赖于我们底层的 一个叫做生得 fail 的方法来实现,那么在价位中呢,可以通过 fail china 点圈十分处方法,它的底层呢,占用的就是生得 fail 方法。那么第三个呢,就是 m map 文件的一个验收机制, 它的原理呢,是将磁盘文件映射到内存,然后呢,用户通过修改内存,就相当于是修改了磁盘文件,达到一个数据同步的目的。使用这种方式呢,就可以获取很大的一个 io 提升,从而省去了用户空间到内核空间的一个复制的开销。 那么卡不卡的零拷贝呢?它是采用生态费尔的方式去完成拷贝的过程。以上呢,就是我对卡不卡零拷贝原理的理解, 那么本次的面试题呢,涉及到一些计算机底层的原理,大家平时在业务开发过程中也很少去关注,但是呢,我想提醒大家的是,如果在技术的路上想走的更远,还是要关注些底层的这些原理,把基础打牢固。说卡不卡是如何 避免消息重复消费的?首先要分析一下导致消息重复消费的原因有哪些?我认为导致卡不卡消息重复消费有以下两个原因,第一个原因呢,是卡不卡消费端重复提交导致消息重复消费。如图所示, 在卡夫卡的 blog 上存储的消息呢,都有一个 offset 的标记,还用来标记消费者消费消息的位置。 我们卡不卡的消费者呢,是通过 offset 标记来维护自己当前已经消费的数据,每消费一批数据呢波若可就会更新 offset 的值, 从而避免重复消费。而在默认情况下呢,消息消费完以后,消费者呢,会自动提交 offer 这里的值,从而去避免重复消费。但是呢,卡布卡的消费端自动提交以后,会有一个默认的五秒的间隔,也就是说在五秒之后的下一次布洛克拉取消息的时候呢,才会提交上一批消 消费的 offset, 所以在消费者消费的过程中,如果遇到应用程序被强制的 care 掉或者是当机的情况,就会导致 offset 呢没有及时提交,从而产生重复提交的问题。那么第二个原因呢,是卡不卡服务端的 party 型的再均衡机制,导致消息重复消费。如图所示, 在卡不卡中有一个 party 选的伴娘时机制,会把多个 party 选均衡的分配给多个消费者,那消费者呢,会从分配到的 party 选里面呢去消费消息。那如果消费者在默认的分钟内没有去处理完这篇消息的话,就会触发卡不卡的 ready 伴娘时机制,从而导致 offer 的自动提交失败。 everybodys 之后呢,消费者还会从之前没有提交到福特的位置呢开始消费,从而导致消息重复消费。 那么基于以上我们对卡不卡消息重复消费的原因分析,我认为可以通过以下三种方法来解决 问题。第一个方法呢,是提高消费单的处理性能,从而去避免触发斑点时,比如说可以用多性能的方式呢来处理消息,或者是缩短单根消息的消费时长,或者呢,还可以调整消费消息的处理的超时时间。当然呢,也还可以去减少一次性从 block 中去拉取数据的条数。 第二个呢,可以使用康舒玛瑞半的 slice 再均衡接听器,他可以用来去设定发生再均衡动作前后的一些准备,或者是一些收尾工作。第三个呢,可以去开启卡不卡的密等性功能,像这一段代码 或者呢,可以将消息生成 md 五,然后呢保存到 myseigo 或者是 ready 之中。那么在处理消息之前呢,先去 myseigo 或者是 ready 之中去查询来进行判断,看是否已经消费过。以上呢,就是我对卡不卡,避免消息重复消费的解决思路。因为工作了五年的小伙伴去美团面试以后啊, 他跟我反馈说,被问到一个如何保证卡副卡消息不丢失的问题,他不知道如何回答。其实呢,这个问题真的很基础,很多小伙伴可能只会回答说消息要持久化,或者是添加消息确认机制。如果你只是这样回答的话,那你和普通程序员没什么区别。 要想让面试官感觉到你确实和其他程序不一样,你就应该有自己的理解。好了,这个问题呢,就应该从多个方面更全面的来分析和回答这个问题。今天呢,我给大家来讲明白。 首先第一个呢是服务端,我们要设置 blog 中的一个配置项,去保证副本之间的数据同步,大家可以看这个代码。 同时啊,我们在 produce 将消息筹递到服务器的时候,我们需要将消息进行实际化,也就是我们要去同步到硬盘,注意同步到硬盘过程中会有同步刷盘和异步刷 刷盘,因为选择同步刷盘,那就可以保证消息一定不会丢失,就算丢失了我们也可以及时补偿,但如果是选择一步刷盘的话,这个时候消息就有一定的丢失的概率。网上有一种说法说 卡不卡不支持同步刷盘,这种说法呢,不能说完全错,但是呢我们可以通过参数的配置让他去变成同步刷盘,比如说这样的一个配置,他同样可以达到同步刷盘的效果。 第二呢就是生产者 produce, 我们要去使用带有回调通知的 send 方法,并且呢要设置 x 等于 or, 这样的话呢,他的消息投递方式采用的就是同步方式,不是就是要保证消息能够到达服务器,就需要使用到消息的确认机制,也就是说必须要确保消息投递到服务器以后,并且能 能够得到投递成功的响应,确认服务器呢,他已经接收才会继续往下去执行。那如果不能定时将消息投递到服务端以后,服务器他没有来得及接收就已经荡机了,那投递过的人消息那岂不是丢失了呢? 那这种情况我们应该怎么办呢?大家不要慌,在不能丢死投递消息的时候啊,他都会去记录日志,然后呢将消息投递到服务器端,就算服务器当机了,等到服务器重启之后呢,也可以根据日信息去完成消息的补偿,这样的话就可以确保消息不丢失。 第三个呢就是消费者坑数码没有设置一个自动提交为 force, 在感不感中啊,消息消费完成之后呢,他不会立即删除,而是使用定时的清除策略,也就是说我们消费者要确保消息成功以后没有手动 atk 提交,如 消息失败的情况下,我们要去不断的去从事。所以呢,消费单不能设置自动提交,一定要设置为手动提交才能过去保证消息他不丢失。 这里总结一下,卡不卡要严格印上去,保证消息不丢失的话,我们需要从三个方面来设置,第一个呢是服务器端,他要将直觉化的设置设为同步刷盘。 第二个呢是生产者要设置为同步的投递消息。第三个呢就是消费者要设置为手动提交。以上呢就是我对卡副卡保证消息不丢失的解决方案。
卡夫卡经典面试题说,谈谈你对卡夫卡副本力的选举原理的理解。确实,卡夫卡早期的版本就是直接用 joke 本来完成选举的,他利用了 joke 的 word 体机制,节点不允许重复写入 以及临时节点这些特性。这样呢,实现起来也比较简单也省事。但是呢,会存在一定的弊端,比如说分区和副本数量过多的时候,所有的副本都要直接参与选举的话, 一旦某个节点出现增减,就会造成大量的 worcy 事件被触发, zukibo 就会负载过重,从而不堪重负。 所以呢,在新版本的卡不卡中就换了一种实践方式,他不是所有的副本都要参与立的选举的,而是由其中一个 block 来统一指挥,这个 block 的角色呢,就叫做 ctrl 控制器。卡不卡呢,要先从所有的 blog 中选出一个唯一的 ctrl, 所有的 blog 呢,就会产 尝试在做 k 本中创建一个临时的节点,叫做 ctrl 节点,谁先创建成功,谁就是担任了 ctrl 的角色。那如果 ctrl 挂掉或者是网络出现问题的时候,做 k 本上的临时节点呢,都会消失, 其他的 vlog 呢,就会通过握取机制监听到 ctrl 下线的通知。然后呢,就会继续按照先到先得的原则选取出一个新的 ctrl, 这个 ctrl 呢,就相当于是选举委员会的主席。当一个节点成为 ctrl 了之后,他就会承担以下职责,分别是监听 blog 的变化、监听 topic 的变化、监听 particular 的变化以及获取和管理 block topic particular 的信息和管理 particular 的主充信息。 当看究了确定以后,就可以开始选举了,接下来呢,就是要去找到参与选举的候选人, 每个副本都想去推荐自己,但是呢,不是所有的副本都有竞选资格的,只有在 sr 中保持心跳同步的副本才有资格参与竞选。正好比是皇帝每天都要召集皇子们来开早会,只有每天来打卡的皇子才能去加入到 sr, 那些请假的,迟到的是没有资格参与竞选的。 破雪人确定了,接下来就是立的选举,就相当是要在众多的皇子中挑选出太子。那么在分布式选举中,有非常多的选举协议,比如说 java, rafter 等等, 他们的思想归来起来都是遵循先到先得,少数服从督促的原则。但是呢,卡布卡没有用这些算法,而是自己实现的一种算法。卡布卡的官方解释是他的全球算法和微软的 passenger a 算法最相近,大致的意思是默认让 sr 中的第一个副本变成立的,比如 i 撒列北中的值是一五九,就会优先让一成为立的,这就跟中国古代的皇帝床位是一样的,优先成为皇长子。假设我们创建一个四个分区两个副本的 top 口,那么他的立的分布是这样的,如图所示, 第一个分区的副本呢,是立的。第一个分区的副本立的呢,落在 b 级的上。第二个分区的副本立的呢,落在 c 级的上。第三个分区的副本立的呢,落在 a 级的上。第四个分区的副本立的呢,落在 b 级的上。那如果没有更多的副本,就以此类推。我们发现立的选者的规则相当于是蛇形走位, 这样设计的好处呢,是可以去提高数据副本的容灾能力,立德和副本完全错开,从而不至于一挂全挂。以上呢,就是我的卡夫卡副本立德选举原理的理解。最近呢,有一位五年工作间的小伙伴去某场面试,就问他这一个问题,说请你简 单说一下卡夫卡的零拷贝原理。然后呢,这个小伙伴突然愣住了,什么是零拷贝?零拷贝跟卡夫卡有关系吗?那么今天呢,我给大家来聊一聊我对卡夫卡零拷贝原理的理解。另外呢,我把往期分享的视频全部整理成了一份二十万字的文档, 后续呢,还会连更,希望能够以此来提高各位粉丝的面试通过率。想获得小伙伴,可以在我的个人主页简介中找到。 在实际应用开发中啊,如果我们需要把磁盘中的某个文件发送到远程服务区的话,它必须经过几个拷贝的过程,如图所示。 第一步呢,就是从磁盘中去读取目标文件的内容,然后拷贝到内核缓冲区。第二步呢,是 cpu 控制器,再把内核缓冲区的数据复制到用户空间的缓冲区。第三步呢,接着在应用程序中,会调用 right 方法,把用户的缓冲区的数据,然后 拷贝到任何下面的缩口的八法中。最后呢,再把任何模式下的缩口的八法中的数据复制到网卡的缓冲区。第五步呢,网卡的缓冲区,再把数据传输到目标服务器上。 那么在这个过程中呢,我们可以发现,数据从实拍最终发出去要经历四次拷贝,而这四次拷贝过程中呢,有两次拷贝是浪费的,分别是从内存空间复制到用户空间, 从用户空间再次复制到内核空间,除此之外呢,由于用户空间和内核空间的切换会带来 cpu 的上线纹切换的开销,那么对于 cpu 性能呢,也会造成一定的影响。 而我们说的零拷贝呢,就是把这两次多余的拷贝省略掉,应用程序呢,就可以直接把实盘中的数据从内核中直接传输给输给他,而不再需要经过应用程序所在的用户空间。如图所示, 领导背呢,通过 dma 的技术把文件内容复制到内核空间的 redbof, 那么接着呢,把包含数据位置的长度的信息和文件的描述符信息加载到我们缩口的办法中,那么 dma 引擎呢,就可以直接把数据从内核空间传递给文卡设备, 在这个流程中,数据只经历了两次拷贝就发送到了网卡中,并且呢减少了两次 cpu 的一个上下文切换的过程,那么对于效率呢,就有了非常大的提升。 所以呢,作为零拷贝,并不是完全没有数据复制,只是相对于用户空间来说,不再需要进行数据拷贝。那么对于前面所说的整个流程来说呢,零拷贝只是减少了不必要的拷贝次数而已。 那我们在应用程序中实现零卡牌的方式有三种,第一种呢,是在 linux 中,零卡牌技术依赖于我们底层的 一个叫做生得 fail 的方法来实现,那么在价位中呢,可以通过 fail china 点圈十分处方法,它的底层呢,占用的就是生得 fail 方法。那么第三个呢,就是 m map 文件的一个验收机制, 它的原理呢,是将磁盘文件映射到内存,然后呢,用户通过修改内存,就相当于是修改了磁盘文件,达到一个数据同步的目的。使用这种方式呢,就可以获取很大的一个 io 提升,从而省去了用户空间到内核空间的一个复制的开销。 那么卡不卡的零拷贝呢?它是采用生态费尔的方式去完成拷贝的过程。以上呢,就是我对卡不卡零拷贝原理的理解, 那么本次的面试题呢,涉及到一些计算机底层的原理,大家平时在业务开发过程中也很少去关注,但是呢,我想提醒大家的是,如果在技术的路上想走的更远,还是要关注些底层的这些原理,把基础打牢固。说卡不卡是如何 避免消息重复消费的?首先要分析一下导致消息重复消费的原因有哪些?我认为导致卡不卡消息重复消费有以下两个原因,第一个原因呢,是卡不卡消费端重复提交导致消息重复消费。如图所示, 在卡夫卡的 blog 上存储的消息呢,都有一个 offset 的标记,还用来标记消费者消费消息的位置。 我们卡不卡的消费者呢,是通过 offset 标记来维护自己当前已经消费的数据,每消费一批数据呢波若可就会更新 offset 的值, 从而避免重复消费。而在默认情况下呢,消息消费完以后,消费者呢,会自动提交 offer 这里的值,从而去避免重复消费。但是呢,卡布卡的消费端自动提交以后,会有一个默认的五秒的间隔,也就是说在五秒之后的下一次布洛克拉取消息的时候呢,才会提交上一批消 消费的 offset, 所以在消费者消费的过程中,如果遇到应用程序被强制的 care 掉或者是当机的情况,就会导致 offset 呢没有及时提交,从而产生重复提交的问题。那么第二个原因呢,是卡不卡服务端的 party 型的再均衡机制,导致消息重复消费。如图所示, 在卡不卡中有一个 party 选的伴娘时机制,会把多个 party 选均衡的分配给多个消费者,那消费者呢,会从分配到的 party 选里面呢去消费消息。那如果消费者在默认的分钟内没有去处理完这篇消息的话,就会触发卡不卡的 ready 伴娘时机制,从而导致 offer 的自动提交失败。 everybodys 之后呢,消费者还会从之前没有提交到福特的位置呢开始消费,从而导致消息重复消费。 那么基于以上我们对卡不卡消息重复消费的原因分析,我认为可以通过以下三种方法来解决 问题。第一个方法呢,是提高消费单的处理性能,从而去避免触发斑点时,比如说可以用多性能的方式呢来处理消息,或者是缩短单根消息的消费时长,或者呢,还可以调整消费消息的处理的超时时间。当然呢,也还可以去减少一次性从 block 中去拉取数据的条数。 第二个呢,可以使用康舒玛瑞半的 slice 再均衡接听器,他可以用来去设定发生再均衡动作前后的一些准备,或者是一些收尾工作。第三个呢,可以去开启卡不卡的密等性功能,像这一段代码 或者呢,可以将消息生成 md 五,然后呢保存到 myseigo 或者是 ready 之中。那么在处理消息之前呢,先去 myseigo 或者是 ready 之中去查询来进行判断,看是否已经消费过。以上呢,就是我对卡不卡,避免消息重复消费的解决思路。因为工作了五年的小伙伴去美团面试以后啊, 他跟我反馈说,被问到一个如何保证卡副卡消息不丢失的问题,他不知道如何回答。其实呢,这个问题真的很基础,很多小伙伴可能只会回答说消息要持久化,或者是添加消息确认机制。如果你只是这样回答的话,那你和普通程序员没什么区别。 要想让面试官感觉到你确实和其他程序不一样,你就应该有自己的理解。好了,这个问题呢,就应该从多个方面更全面的来分析和回答这个问题。今天呢,我给大家来讲明白。 首先第一个呢是服务端,我们要设置 blog 中的一个配置项,去保证副本之间的数据同步,大家可以看这个代码。 同时啊,我们在 produce 将消息筹递到服务器的时候,我们需要将消息进行实际化,也就是我们要去同步到硬盘,注意同步到硬盘过程中会有同步刷盘和异步刷 刷盘,因为选择同步刷盘,那就可以保证消息一定不会丢失,就算丢失了我们也可以及时补偿,但如果是选择一步刷盘的话,这个时候消息就有一定的丢失的概率。网上有一种说法说 卡不卡不支持同步刷盘,这种说法呢,不能说完全错,但是呢我们可以通过参数的配置让他去变成同步刷盘,比如说这样的一个配置,他同样可以达到同步刷盘的效果。 第二呢就是生产者 produce, 我们要去使用带有回调通知的 send 方法,并且呢要设置 x 等于 or, 这样的话呢,他的消息投递方式采用的就是同步方式,不是就是要保证消息能够到达服务器,就需要使用到消息的确认机制,也就是说必须要确保消息投递到服务器以后,并且能 能够得到投递成功的响应,确认服务器呢,他已经接收才会继续往下去执行。那如果不能定时将消息投递到服务端以后,服务器他没有来得及接收就已经荡机了,那投递过的人消息那岂不是丢失了呢? 那这种情况我们应该怎么办呢?大家不要慌,在不能丢死投递消息的时候啊,他都会去记录日志,然后呢将消息投递到服务器端,就算服务器当机了,等到服务器重启之后呢,也可以根据日信息去完成消息的补偿,这样的话就可以确保消息不丢失。 第三个呢就是消费者坑数码没有设置一个自动提交为 force, 在感不感中啊,消息消费完成之后呢,他不会立即删除,而是使用定时的清除策略,也就是说我们消费者要确保消息成功以后没有手动 atk 提交,如 消息失败的情况下,我们要去不断的去从事。所以呢,消费单不能设置自动提交,一定要设置为手动提交才能过去保证消息他不丢失。 这里总结一下,卡不卡要严格印上去,保证消息不丢失的话,我们需要从三个方面来设置,第一个呢是服务器端,他要将直觉化的设置设为同步刷盘。 第二个呢是生产者要设置为同步的投递消息。第三个呢就是消费者要设置为手动提交。以上呢就是我对卡副卡保证消息不丢失的解决方案。
今天分享的这道面试题呢,是一个工作了两年的小伙伴私信我的,我觉得这个问题呢要简单,本来呢不打算说,但是,哎,作为一个新的二部主呢,满足粉丝基本要求才能获得更多的点赞啊,对不对?好,关于卡不卡如何保证消息不丢失这个问题呢,我们看看普通人和高手是如何回答的。 普通的回答,嗯。呃,卡夫卡如何保证消息不丢失?呃, 我觉得可以从像博客上去做考虑吧,就是我,我要保证博客他是一个高可用的,我可以搭建一个集群嘛,然后生产端的话,我要确保这小姐发送出去嘛, 所以就是我记得生产端有一个从事就通过一个什么参数去配置一个从事就可以 在网络出现问题的时候他可以重发,然后 brok 做集群,应该是可以解决这个问题的。高手的回答, 卡佛卡呢,是一个用来实现异步消息通讯的一个中间键,它的整个架构呢是由 producer, consumer 和 brook 来组成。所以啊,对于卡夫卡如何去保证消息不丢失这个问题呢,我认为啊,可以从三个方面来考虑和实现。首先是 producer 端需要去确保消息能够到达 brook, 并且实现消息的存储, 在这个层面上有可能会出现网络问题,导致消息发送失败。所以呢,针对 pro 手端可以通过两种方式来避免消息丢失。第一个 pro 丢手默认是一步发送消息的,那么这种情况下 需要确保消息是发送成功,那么这里面有两个方法,第一个是把一步发送改成同步发送,那么这样的话呢, podosa 就能够去实 实时的知道消息发送的一个结果。第二种是添加亦不回调的函数来监听消息的发送结果,如果发送失败,可以在回调中去进行从事。第三个啊 producer 本身提供了一个从事参数叫 retras, 如果因为网络问题或者 brook 故障导致发送失败,那么 pro 丢 sir 会自动从事,然后是 pro 可端, pro 可能需要确保 pro 丢色发送过来消息是不会丢失的,也就是说只需要去把这个消息持久划到磁盘就可以了。 但是啊,卡不卡为了提升性能,采用了一步批量刷盘的实现机制,比如说按照一定的消息量和时间间隔去刷盘, 而最终刷新到此番这个动作是由操作系统来调度的,所以如果在刷盘之前系统崩溃了,就会导致数据丢失。卡不卡呢,并没有提供同步刷盘的一个实现机制,所以针对这个问题需要 通过 party 型的副本机制和 ack s 机制来解决。我简单说一下 party 型的副本机制啊,它是针对每个数据分区的高可用策略。每一个 paty 型副本级呢,会包含唯一的一个 leader 和多个 follow lead, 专门去处理事物类型的请求,而否冷呢,去负责同步 lead 的数据。那么在这样一个趋势的基础上呢,卡福卡提供了一个 a c k s 的一个参数, producer 可以去设置 a c k s 参数,去结合 brook 的副本机制来共同保障数据的可靠性。 a c k s 这个参数的值呢,有几个选择,第一个是 a c s 等于零,表示 producer 不需要等待 brook 的响应, 就认为消息就发送成功了,那么这种情况下会存在消息丢失,前面已经讲过了。第二个是 ack s 等于一表示啊, brok 中的 leader perty 选收到消息之后,不等待 其他的 follow protection 的同步,就给 produce 返回了一个确认,这种情况下啊,假设 leader protection 挂了,就会存在数据丢失。第三个是 a c k s 等于负一表示 brook 中的 leader protection 收到消息之后,并且啊等待 rsr 列表中的所有佛罗同步完成,再去给 producer 返回一个确认,那么这样一个配置是可以保证数据的一个可靠性的。最后就是 ctrlmer 必须要能够消费到这个消息。 实际上,我认为啊,只要 producer 和博客的消息可靠性得到了保障,那么消费端是不太可能出现消息无法消费的问题的。除非是 说嘛,没有消费完这个消息就已经提交了这样一个 offset。 但是即便是出现这样一个情况,我们也可以通过重新调整 offset 的值来实现重新消费。以上就是 我对于这个问题的一个理解,从高手的回答中我们可以发现啊,任何的技术问题是可以按照请求的顺序或者调用关系来逐层去推导和回答的。 当然啊,技术的底子要足够厚啊,至少像卡斯卡里面的副本呐,数据同步啊,分区啊,刷盘呐等这些功能,至少要有一个深度的思考和研究。 好的,本期的普通人 vs 高手面试系列视频就到这结束了,喜欢的朋友记得点赞和收藏,另外有任何技术上的问题和职业发展有关的问题都可以私信我,我会在第一时间给大家回复。 我是麦克,一个工作了十四年的家化程序员,咱们下期再见!
一位七年工作精神小伴在面试的时候被问到这一道面试题,说谈谈你对卡夫卡副本力的选举原理的理解。当时他就在想说,这卡夫卡用的不就是猪屁股的选举吗?难道卡夫卡自己又搞了一套?没错,这回卡夫卡自己又造了一个轮子。 那么今天呢,我给大家聊一聊我对卡夫卡副本的立德选举原理的理解。另外呢,我把往期分享的视频全部整理成了一份二十万字的文档,后期呢,还会年更,希望能够以此来提高各位粉丝的面试通过率,想获取的小伙伴可以在我的个人主页点击中找到。 确实,卡布卡早期的版本就是直接用做 keep 来完成选举的,它利用了做 keeper 的 watch 机制,节点不允许重复写入以及临时节点这些特性。这样呢,使用起来也比较简单也省事。但是呢,会存在一定的弊端,比如说分区和副本数量过多的时候, 所有的副本都要直接参与选举的话,一旦某个节点出现增减,就会造成大量的握起事件被触发,猪屁股就会负载过重,从而不堪重负。所以呢,在新版本的卡布卡中,就换了一种实践方式,他不是所有的副本都要参与类的选举的, 而是由其中一个 block 来统一指挥,这个 block 的角色呢,就叫做 ctrl 控制器,卡不卡呢,要先从所有的 block 中选出一个唯一的 ctrl。 所有的 blog 呢,就会尝试在 zookiba 中创建一个临时的节点,叫做 conchila 节点,谁先创建成功,谁就是担任了 ctrl 的角色。那如果 ctrl 挂掉或者是网络出现问题的时候, zookiba 上的临时节点呢,都会消失, 其他的 vlog 呢,就会通过 watch 机制监听到 ctrl 下线的通知。然后呢,就会继续按照先到先得的原则选取出一个新的 ctrl。 这个坑出了呢,就相当于是选举委员会的主席。当一个节点成为坑出了之后,他就会承担以下职责,分别是监听 blog 的变化、监听 topic 的变化、监听 particular 的变化,以及获取和管理 block topic particular 的信息和管理 particular 的主充信息。 当看究了确定以后,就可以开始选举了。接下来呢,就是要去找到参与选举的候选人。显然每个副本都想去推荐自己,但是呢,不是所有的副本都有军选资格的, 只有在 sr 中保持心跳同步的副本才有资格参与竞选。就好比是皇帝每天都要召集皇子们来开早会,只有每天来打卡的皇子才能去加入到 sr。 那些请假的迟到的是没有资格参与竞选的候选人。确定了,接下来就是力的选举。就像 是要在众多的皇子中挑选出太子,那么在分布式选举中,有非常多的选举协议,比如说 jab, rafter 等等。他们的思想归来起来都是遵循先到先得,少数服从督促的原则。但是呢,卡不卡没有用这些算法,而是自己实现的一种算法。 卡布卡的官方解释是它的选取算法和微软的 passenger a 算法并相近,大致的意思是默认让 s r 中的第一个副本变成立的,比如 s r 列本中的值是一五九,就会优先让一成为立的。 这就跟中国古代的皇帝传位是一样的,优先传给皇长子。假设我们创建一个四个分区两个副本的 topic, 那么他的立的分布是这样的,如图所示,第一个分区的副本呢,是立的。第一个分区的副本立的呢,落在 b 级别上。第二个分区的副本立的呢,落在 c 级别上。第三 个分区的副本力的呢,落在 a 级别上。第四个分区的副本力的呢,落在 b 级的上。那如果没有更多的副本,就以此类推,我们发现力的选择的规则相当于是蛇形走位。 这样设计的好处呢,是可以去提高数据副本的容灾能力,立德和副本完全错开,从而不至于一挂全挂。以上呢,就是我的卡夫卡副本立德选举原理的理解。我是被编程耽误的文艺汤,如果我的分享对你有帮助,请你动动手指,一键三连分享给更多的人!关注我,面试不再难!