粉丝2923获赞1.1万

我们上节课给大家介绍了 cafa 的一个机器安装与验证啊,那上节课呢,我们给大家通过 cafa 给我们提供的一个脚本工具啊,嗯,演示了一下 cafa 的一个 top kit 创建,还有一个生产者如消费啊, 那么这节课呢,我们,嗯做一个快速热门,快速热门里面内容是什么呢?就直接只是通过我们的加号代码去集成卡不卡的一个客户端,然后实现咱们的一个生产日消费啊。好,废话不多说,我们直接进入正题啊。 好,我们首先如果要需要切成卡夫卡的一个工具的话,我们需要引入他的一个依赖啊,判断依赖啊,判断依赖的话,我们直接复制这个就行了啊, 然后我们这节课啊是用咱们最基本的加油单码去直接去实践啊,我们接下后面一节课的话,我们会使用会介绍一下卡布卡是如何在斯本布的中的一个使用方式啊。我们首先复制这个依赖啊,然后呢 复制这个依赖之后呢,我用我这里直接这复制好了啊,直接放丢在把,把咱们的依赖可爱呢放在这里就行了啊。然后我们再继续写我们的生产者啊,生产者的话,这个方式啊,其实和那也差不多,对不对啊?我们需要定义几个,嗯,配置啊,定义几个?配置 好,第一个的话,我们定义他一个服务端就是卡不卡的一个,呃,一个服务地址对不对?如果你有多个的话,你可以直接用逗号分割,然后写多个,然后我们再去要定义一个 topic, 因为我们需要生产者是需要 把那个消息发送到纸巾那个 top 课里面的,因为我们上节课啊,已经通过我们这个 creat 命令啊,已经创建了咱们的一个 咱们的这个 topic, 所以呢我这里面直接去,嗯,复用这个 topic 名称就好了。好,然后呢,这两个创建好之后啊,我们就需要去构建一个 prop protiss 啊,然后把这些内容放进去。好,关键的,最主要的大家看啊, 这里面有一个序列,一个序列化器啊,序列化啊,序列化的话这个东西一定要填,不然的话你不填的话就有可能会报错,因为这里面要填两个,一个 t 和 v 的这个序列化啊,序列化好,然后我们当我们把这个序列化,这个是,嗯,都穿进好了, 嗯,我们就可以创建我们的生产者对象啊,生产的对象 produce, 对不对? produce。 然后呢,这里面会丢入咱们的一个配置的一个信息,把它丢到这里面去,丢到这里面之后呢,然后我们会构造一个 pro 卡不卡 produce 的这个对象, 这对象之后啊,我们就会可以教用他的一个肾的方法啊,这叫用肾的方法,默认的话,他这他这个是一个一步发松的啊,一步发松的,我们需要调用 get 的方法进行一个同步等待,进行同步等待好,然后这里面割造了一个 realcode record, 这里面其实一个消息封窗底啊,消息封窗底,然后这里面,嗯,构造哪一 信息呢?就有 topic, 还有一个咱们的一个数据啊,好消息好默认的,往哪分去分分呢?我们上节课之前课程也讲过,就是他会根据他的 k 啊进行按照一定的规则进行一个计算。 好,然后我们来看消费者,消费者同样的我们这前面几个参数都是一样的,需要构造,嗯,而且也是进行了做一个 k 的一个反序列化,大家只要搞清楚这里是一个反序列化,不要弄错了啊,反序列化不要搞成也是序列化了,他就会导致我们的消费者起不起来的。嗯,好, 然后配置完之后呢,我们还要需要配这个消费组啊,嗯,因为大家这,嗯,大家现在还不清楚,就是卡不卡的话,他是嗯把所有消息他会往不同的组里面发啊,就是一个组里面他只会发一个,然后呢一个组里面也只会有一个消费者进行一个消费的。好,那么消费组这 里面要有唯一区别的。嗯,地方,这个设备组的话,这个 id 啊可以是是你一个随意的任何任意的一个 id 啊,任意的一个数值就行了啊。然后这个做完之后呢,我们需要各自 ctrl, ctrl, 然后我需要去订阅啊,订阅这个 topic, 我们同样的是我们生产者的一个 topic, 订阅这个 topic 第二套笔之后呢,我们在这里面搞一个死循环,对不对?搞个死循环,然后一直从咱们的这个里面破拉取消息,然后呢这个超时时间是一秒啊,一秒 拿取消息之后,如果是不为空的话,那么我就可以进一个便利这个消息,便利消息之后,然后把它打印出来啊,这就是一个简单的生产日消费。好,那么我们现在把大码跑一下,看一下是什么样的效果啊? 首先啊,我们需要启动咱们的消费者啊,因为不然的话你生产的话就消息就没了啊,就他就不会从那开始了,需要你指定他 offset 啊。好, 我们生产消费者是已经启动起来了,我们接下来我们启动我们的生产厂,我们看下生产者发的内容是什么?嗯,我们这里发一个 demo, 是不是?好,我们点一下,看一下他是什么效果?好,这个已经结束了,是不是结束之后,然后你发会发现这个已经亮了,亮了就说明咱们已经收到这个消息了。好,那我们再发一次,看一下是什么样? 再发一次。好,我们又收到了一个消息,是不是?好,我们再来一次,对不对?再来一次。 ok, 这个已经发完,发完之后这个绿了,绿了之后呢?这就收到消息了, 所以呢,咱们的这个生产使用加法代码继承咱们的客服卡斯 dk 啊,这已经是成功了,实现了咱们的生产和消费啊,这只是一个简单一个 demo 啊,后续的话会讲解更加的一个深入,按照生产的消费者的 接动一下,然后会结合他的一些原理啊,原码进行个讲解。好, ok, 那么今天的内容就到呃,这里啊,下节课我们来讲 smile boot 如中,如何去使用卡普卡。好,谢谢大家。

今天我们来学习一下卡夫卡是如何实现自定分区器,我们前面的课程啊,我们讲过分区的概念,是不是啊?当我们一个消息发出的时候啊,他会根据咱们的一个呃 key 或者是其他作案进行一个呃计算他的分区, 如果你指定分区那就更好,对不对?那直接发往到哪个分区是不是好?那么我们这节课我们首先来看一下呃默认的分区有哪几种实现规则啊?默认他有两种啊,第一个就是如果你消息指定了把提成 k 啊, 爬梯爬梯圣字段就是你的分区字段,对不对?那么就会直接发到那个分区啊,直接发到分区,那么就不需要经过分区器了,这是一种啊,这是一种啊,要代码视力的话就这么去写了啊,就直接是你指定了分区,看我分区二是不是? 大家注意啊,这个分区器啊,就是从那个零一二开始的啊啊, ok, 这里面啊不同的, 当指定了指定 party 升,对不对?好,然后我们再看一下消息,如果没有指定 party 认字段啊, party 认字段 认知端的话,那么有又分为两种情况,第一个就是当我们的 k 为空的时候啊,如果 k 为空,那么就会通过人选的方式发送各个消息消息到各个分区啊,这时候就无法保证顺序,因为他每次发送的消息啊,都没有带 k, 他 居然没有 k, 他这个分区啊,他是不同的,那么他发的消息也是直接发到了各个分区的,你无法保证顺序性的啊,这个就是这个原因啊。好,我们这个使用方式呢,我们就直接是在这里面加 top 加 k 了,加 v 六了啊啊,没有指定 k 啊,那么对于呢,还有另外一种情况叫 k 不为空的时候, 那么当 k 不有空的呢,那么我就会对默认的一个 k 啊进行个哈吸啊,那哈吸的话就是采用 more 哈吸哈吸就 算法啊。好,最终根据哈西指计算分区号,如果指定了相同的 t 啊,那么就会他们得到最终的哈西,这个值啊,其实就是一样的,也就是得到了对应的一个分区号,那么消息就会发到相同的分区啊,但是这些分区啊有可能不可用啊,因为卡不卡是不会干涉你指定的分区,不关心他是否可用啊。 好, ok, 好,那么我们指定相同的 k 对不对?好,按照这个去计算了啊。然后呢,我们再看一下指定不同的 k 呢?指定不同的 k 啊,这指定不同的 k, 这 k 如果不一样呢,看它的哈西就会不一样,是不是不一样?好,那么 前面这那个知识点我们给大家讲了,然后我们现在来说一下怎么去实现自定义分区啊,默认是根据 k 来记怎么分区号,是不是我们现在打破这 这个规则,那么我们应该怎么做呢?我们首先来看一下他那个默认分区器的,他实现的分区接口时就是这个就,否则爬提升呢啊,有三,他有三个重要的方法,一个是爬提升 分区,就是我们用来计算他应该往哪个分区走啊,路由到哪个分区啊,这个反过来的值就是他的分区号啊,那么 close 回收一些资源, configer, configer 就是有一些配置智化的数据啊。啊, 好,那我们现在有个需求啊,我就是想根据 v 六值来计算分区号,那应该怎么做呢?那应该怎么做啊?主要是实现法题式方法啊,实现计算逻辑,看我这段代码的逻辑啊, 大冒逻辑啊,我们首先拿到这个 v 六,如果不为空啊,我们才会进行处理啊。好,我们对,我们首先取到所有的分区啊,你看我取的是可用的,所有的可用的分区啊,可用的分区啊,也就是说 is 字耳里面的一些,嗯嗯,有哪些分区?是不是总共有多少分区?好,然后呢?可用的分区是不是?然后呢,我们再看一下,我们通过这个值啊进行一个取取余,取余是不是我把它变成整形了,因为我传过来这个是我自定义的一个类型啊,是整形啊,它是整形啊,所以呢,我把它转换成 n t 类型 啊,安心的写呢,当然你这里面不能,应该一般都不会这么这么去写啊,我这只是指定了一个例子啊。好,那么我们再来看一下啊, 好,然后呢,这里面会最终呃得到他的一个分区,然后把这个分区号返回回去是不是?好,那么我们这里面如果他这里面是为空的话,那么我们就给他默认的分区零了。好, 那么基本逻辑就是这样,然后我们来瑞,嗯,来修改一下咱们的一个配置啊,生产者的一个配置啊,好, ok, 那我们看一下这个配置应该怎么去修改呢?我们在发送消息的时候 应该怎么去去处理一下呢?在这里面我们需要去指定咱们的一个分区啊,排第三这个分区配置啊,这样就行了啊,然后我们再发送消息的,还是正常发送啊。那么我们现在来运行一下这段代码啊,看一下他是否胜效啊?我们找到我们的自定义分区,这个是咱们的代码卡斯特,我们把这个跑一下, 然后我们这里面呢,我只要问一下,我首先来看一下我们的服务有没有起起来啊?这个 docker 啊,起来了,对不对?起来了,然后我只想跑一下卖方法。 好, ok, 我们可以看到啊,咱们这里面当前值为零,选择分区是零,是不是?当前值一选择分区一,当前值二选择分区二,当前值三选择分区还是零,当前值是四,选择分区还是一,是不是?也就是四除以三是多少 于一,是不是这个三除以三于零,是不是?好,那么我们来看一下他这里面相 所爱分区一一零零二是不是跟上面,其实一一零零二跟上面其实是对应起来的,对应起来的好,好,那么我们这节课啊,就给大家演示到这里啊,这里给大家演示了如何实现自定分区啊。好,我们下节课来介绍一下,是拦截器的一个使用啊,好,谢谢大家。

嗯,卡夫卡里面的消息它是怎么样去保证它不会丢的?嗯,我记得里面是有副本机制的,还有什么 i s r 机制来保证数据不丢失的?那么这个问题呢,其实需要从生产端、 log 端和消费端三个维度啊去保证,因为任何一个环节都有可能发生数据丢失。如果你担心简历上的东西讲不出来, 我已经把面试经常问到的一些技术站场景图都整理在两百万字的面试文档了,里面针对每个知识点都有很详细的解析思路, 只要你是我的粉丝,留言六六六就可以打包带走。首先呢,生产端我们要确保消息它成功地发送到 blog 了。关键呢,就是有两个配置,一个是 s k s 啊,就是 ask, 设置为 or 或者说负一,意味着消息啊,不仅要写入 delete 副本,还要等待 i s r 列表里面所有的副本都确认收到以后呢,才算发生成功。 第二个呢,就是 request, 就是 重试的次数,避免因网络的抖动等临时故障导致发生失败。那么这个呢,是生产端。其次呢, block 端,也就是我们的 m q 服务,我们要保证消息持久化且不丢失。一方面呢,我们可以通过副本机制来保证高可用,建议啊,副本因子至少为三个。那么这样呢,即使某一个 block 宕机了,其他的副本呢,仍能够提供服务。 另外一个方面呢,我们可以去设置啊,就是 ming 啊, incico replicate 为二,就是表示至少要有两个副本同步成功以后才认为写入成功,配合我们刚刚的 s k s。 然后呢,同时要避免 unclean 取菌,防止非 i s r 的 一个副本被血为零的导致数据丢失。最后呢,消费端它是最容易丢失消息的,因为很多丢失就是发生在处理的过程里面。 核心原则就是先处理业务逻辑,再提交备料,一定要关闭,自动提交,改为手动提交。在消息处理成功了以后,我才提交 offset, 如果处理失败,那么可以重试,但绝对不能提交 offset, 导致消息看似已经被消费了,实则是处理失败的。另外啊,消费端呢,也要保证密等性,避免重复消费导致的一个业务问题。除了这三端的配置啊,业务层面呢,最好也做好 兜底,比如说在发送消息的时候呢,我记录日期或者说漏库,一旦发现消息丢失了,可以通过离线的一些任务去对比去修复,虽然不能实时的去保证不丢,但是可以作为最后一道防线。 总结一下,卡不卡。消息不丢失就是从生产端, rok 端,消费端闲同工作,通过合理的配置和业务的补偿,可以最大限度的去降低我们的丢失风险。当然可能性和性能需要去平衡,要根据业务场景选择一些合适的参数。

kafk 中的主题和分区是什么?它们的作用是什么?在 kafka 中,主题和分区适用于组织和管理消息的两个重要概念。主题一,主题是消息的逻辑分类,它是 kafka 中数据的最高层级, 类似于数据库中的表。每个主题都有一个唯一的名称,用于标识消息的类型和目的。二,生产者将消息发布到一个指定的主题中,而消费者可以订阅一个或多个主题来接收消息。 三,主题是逻辑上的概念,他将一类相关的消息归类到一个命名空间下,方便数据的组织和管理。分区一, 分区是主题的物理划分,每个主题可以被划分成一个或多个分区,每个分区是主题的一个物理子级。二,分区使得 cafka 能够处理大量数据,并支持水平扩展。每个分区在不同的 broker 上进行 副本复制,以实现负载均衡和故障容错。三,每个分区都有一个唯一的标识符,称为分区号。分区号从零开始,逐个递增。四,每个分区在消息日志中都是一个有序的不可变的消息序列,消息按照写入顺序进行存储,不允许修改或删除。 主题和分区的作用是,一数据组织与存储主题将相关的消息进行逻辑分类和组织,每个主题可以包含一个或多个分区, 这样使得消息的存储和管理更加灵活和高效。二并行处理与负载均衡分区允许 coffer 对消息进行并行处理,每个分区可以由不同的 broker 和消费者来处理, 这样可以实现高吞吐量和负债均衡。三,数据勇于与容错每个分区可以有多个副本存储在不同的 broker 上。这样做的目的 是提供高可用性和数据用于以防止 brok 故障导致消息丢失。四、消息顺序性在每个分区中,消息是有序存储的。对于同一个分区的消息, 他们的顺序将按照写入的顺序保持一致。总的来说,主题和分区的设计使得 cafka 能够处理大规模的实时数据流,支持高吞吐量、低延迟和高可用性的数据传输和处理,他们是 cafka 强大功能的基础。

啊,你项目里面用到了卡不卡,就是你来跟我讲一下,他是怎么去保证消息是顺序消费的哦,卡不卡的 top 可以 设置分区,然后那个同一个分区的消息是有序的啊,去保证消息的顺序消费啊。我们 要先看一下哪些情况下面会导致消息的信息问题在卡不卡里面啊,导致消息信息问题呢,主要有三个,如果你担心简历上的东西讲不出来,我已经把面试经常问到的一些技术站场景图都整理在两百万字的面试文档了,里面针对每个知识点都有很详细的解析思路, 只要你是我的粉丝,留言六六六就可以打包带走。第一个,他消息发送到了不同的 party, 如果生产者将消息分散到不同的分区,那么这些消息在消费的时候必然是没法去保证全区顺序的,因为每个分区他是独立消费的。那么第二个场景就同一个分区内,如果消费端多卸层处理, 即使你消息啊在同一个分区,如果消费者采用的是多现成并发处理消息,那么现成执行的时候呢?先后顺序他没法控制,就可能出现后消费的消息先处理完的情况, 导致业务信息错乱。而第三个场景呢,就是卡不卡的异常处理机制,比如说消费失败后存是跳过某些消息,或者开启了自动提交配音量,都可能会导致消息虽然按顺序拉取了,但实际处理的信息是会被破坏掉的。那么知道场景以后呢,我们针对性的去解决就可以了啊。第一个,我们要确保有序要求的消息它进入同一个 party 省, 比如说同一个订单的消息,那你要放到同一个 party 省里面去啊,我们可以通过指定分区发送或者微消息设置相同的 key, 让卡夫卡根据 key 的 哈希值路由到同一个分区去实现。只要分区固定啊,消息的存储顺序就有了保障。当然第二个我们要保证消费端它的一个并发症。如果业务对信息要求很严格,那么消费者最好采用单线层的处理消息,或者至少确保同一个业务的 key 的 消息呢,有同一个线层处理。同时啊,可以在业务层面增加一些兜底 的逻辑,比如说通过状态机制来去判断当前消息是否有被处理过,防止乱序。而第三种呢,就是去处理一些异常情况, 比如说可以进入自动提交改为手动提交配音量,并且在消息处理成功以后呢,才提交。同时呢,避免跳过失败的消息,必要的时候呢,将失败的消息放入死讯队列,而不是直接忽略。最后要强调一点,强顺序性和高性能往往是冲突的,为了保证顺序,我们可能不得不牺牲一定的病发能力 检查。在实际的工作里面,我们需要结合具体的业务场景去权衡,如果业务必须严格按照顺序,那么就采用我们刚刚讲的一些方案,如果允许短暂的一些顺序错乱,或者说我只要保证最终一致性的话呢,我们可以去适当的放宽一些要求,提高我的吞吐量。

卡芙卡到底怎么保证消息的顺序消费呢?你答,卡芙卡同一个分区的消息就是有序的。这种回答只能算入门皮毛,根本经不起深挖。面试官马上就会连环追问,那为什么有时候同分区还会乱序呢?生产、消费、异常重试,分别是在什么场景下打乱顺序的呢? 真实项目里到底该怎么落地解决这些问题呢?如果你还不知道怎么准备面试,建议参考我整理的 java 高频面试题,查看市面上百分之九十的技术场景题,短时间内快速提升面试通过率。你 还有近期很火的 java 加 ai 实战技巧,只要你是我的粉丝,扣八八八打包带走。首先,我们先搞明白核心前提,想解决顺序消费,先要知道到底哪些情况会导致卡付卡消息乱序。 主要呢就三种场景,第一种,生产者把消息发到了不同分区有顺序的要求的业务消息,如果生产者随机分发到多个 partition, 每个分区都是独立存储,独立消费,天然就做不到全局顺序,这就是最常见的乱序根源。 第二种,哪怕消息进了同一分区,被顺序拉取,只要消费端用多,县城并发处理,县城执行快慢不受控制,很容易出现后拉取的消息先业务处理完成,直接造成业务乱序。第三种呢,就是卡夫卡的异常容错机制引发乱序, 消息失败,频繁重试,随意跳过异常消息,再或者开启了自动提交批量,都会出现消息。明明拉取是有序的,实际业务处理顺序却被彻底打乱。搞懂了乱序的三大根源,对应的解决方案就非常清晰了,针对性搞定就行。 第一,有顺序要求的业务消息强制绑定同一分区,可以手动指定分区发送,也可以给同一业务标识设置相同消息的 key, 卡夫卡会根据 key 做哈西路,由自动落到同一个分区,只要分区固定,消息的存储顺序就从根源锁住了。 第二,消费端严控并发,避免多县城乱处理。对强社区业务,最简单稳妥的方法就是单县城消费,如果要兼顾性能,也要保证同一个业务 key 的 消息固定交给同一个县城处理,还可以在业务层加状态机,避免乱序消息违规执行业务逻辑。 第三,规范异常处理机制,杜绝重复式和偏移量带来的乱序直接进入自动提交,偏移量改成业务处理成功之后再手动提交,不要随意丢弃跳过失败的消息,处理异常时统一投递到死信对链做事后复盘,从机制上守住顺序底线。 最后再给大家说一个面试加分的关键点,卡夫卡。强顺序和高吞吐量本身就是相互冲突的,要严格保证消息顺序,就得牺牲部分病发性能。 如果业务能接受最终一致性短暂乱序就可以放宽规则,换取更高的吞吐期。开发一定要结合业务场景做权衡,不能死搬理论。以上就是我针对卡芙卡保证消息的顺序消费的答题思路,如果你还有不懂的面试题,欢迎一起讨论哟!

大家好,下面我们给大家讲核心概念的解析,我要给大家强调一下,那本节内容呢,是我们打卡系列课程里面既基础,然后又非常重要的一节,我希望大家呢能够认真的去揣摩这一节的内容 啊,本节的内容呢,几乎都是卡不卡消息对列最核心的理论知识,那初学者呢,请务必的去研究揣摩,然后呢如果一遍看不懂的话呢,大家可以反复的去多看一看。 先来看一下卡卡里面的这个概念,这个概念呢叫做代理商不认可,在我们之前呢,已经向大家介绍过,生产者是向我们的 消息堆列中去投递消息,消费者呢是从这个消息堆列中去拉取消息。那在卡不卡消息最烈里面呢,有一个非常 重要的概念叫做 broker 啊,这个 broker 呢,翻译成中文的话呢,他叫代理商,那大家可以想象一下,在我们生活中这个代理商是做什么的?代理商一般就是进货、存货、销货,卡不卡的这个消息对列里面呢啊,他承担着啊,几乎同样的这样一个作用,就是接收消息, 保存消息,然后呢为消费者去提供消息,他的这个作用几乎是和我们生活中这个代理商是同样一个概念,这个叫做 broke, 大家记住他 来看下面的这样一张图,那具体到我们卡夫卡的这个架构层面呢,我们可以认为一个卡夫卡的这个 broker 就是一个卡夫卡的服务实力,那一个卡夫卡的集群呢,可以启动多个服务实力,就像我画的这张图里面啊,大 可以看到一个卡夫卡集群启动三个服务实力,通常来说呢,一个卡夫卡集群里面的 broker 越多,然后呢他集群的吞吐能力也就越强, 这个呢也好理解,就是说现实生活中呢,也是我们一个产品的这个代理商越多,我们的销售能力就越强, 这个就是集群里面包含多个代理。那通常情况下,我们一个物理的服务器上,也就是说我们的一个操作系统上只部署一个卡福卡实力,也就是说我们这个不认可, 那在这种情况下呢,我们的这个补口也可以当成另一种概念去理解,他就是我们的卡不卡的福气啊, 大家可以这样去理解,那我们啊来探讨下一个问题,就是说我们可不可以一个服务器呢去部署多个卡夫卡实力, 这个也是可以的。那一般来说呢,我们一个卡夫卡的实力会开一个九零九二的这样一个端口,那如果这个端口在同一个机器上去启动的话呢,可能就是需要把这个端口去修改一下,然后呢就能在一个服务器上去启动多个卡夫卡的这个实力的这样一个进程。 但是呢这样非常不好,因为我们的这个卡布卡分布式的部署都是考虑高可用的,一旦一台机器这个档机呢,我们要保证整个卡布卡集群是在可用的这样一个状态, 那如果你把多个实力部署到一个服务器上,那一旦这台服务器当机,那影响面就非常非常大了,有可能去 直接就将整个的这个卡夫卡集群给拖垮。所以说呢,一般我们建议就是一个 bro 科部署在一台服务器上,这个就是代理商,他和部署的这样一个关系。 那我们下面来看一下这个主题和分区。那代理商 broke 他可以帮助厂家进行这个商品的进销存, 但是呢,他有一个问题,他没有进行商品的分类,所以说呢,我们为了将这个商品进行分类,我们有了一个新的概念叫做 topic, 这个 topic 呢,就是要对消息进行分类,每一个分类被称为一个 topic。 比如说呢,我们的这个第一个 topic 叫做酒类的 topic, 然后第二个 topic 叫做卤制品,然后第三个 topic 叫做零食啊,这样三个 topic, 我要跟大家强调一下,我画的这个虚线呢,它不再是 block 的概念, 我们这些主题里面,他包含若刚的分区,每一个主题呢,有若刚的分区,涛皮克呢,是一个逻辑的概念,所以说呢,我用虚线呢去给他画,但是这个分区呢,他就是一个物理的概念啊, 他是一个实实在在存在的这样一个啊,数据结构,也就是说我们的对列,也就是说大家看到的这一小条九类渠道分区代理 啊,那这个一个分区呢,他是一个实实在在存在的这样一个数据结构,消息对联,他占用系统内存以及实盘存储资源,所以说他是一个物理上的概念 啊,一个 topic 可以包含多少个分区呢?是取决于这个主题下面的商品处理能力、吞吐量的这样一个需求啊。比如说呢,我们酒类消费量比较大,你就给他多建几个分区,那如果我们零食类的这个消费量比较小,那你就给他少建几个分区, 这个呢分区的数量是可以去建的,然后呢我们的这个每一个分区是分布在不同的这个 broke 上面的, 也就是说啊,九类的四个分区有可能平均的分布在这三台机器上,这个是主题和分区,需要总结一下的就是 主题是对消息进行分类,然后呢一个分类下面可以建多个分区,然后呢我们的生产者 和消费者实际上是向这个分区里面去发消息和消费消息,这个是主题与分区的概念,那我们下面来看一下分区与消费者主的概念,分区和消费者主 我们卡不卡?有了主题和分区之后呢,我们消息处理的这个能力增强了,也就说我们消息可以分类了,然后呢我们分区是多个消息对列吞吐量也上来了, 然后呢生产者可以大量的向着卡夫卡啊消息略略,也就是我们那个分区里面去发消息。但是这里呢我们需要注意的一件事是什么呢?和现实生活中不太一样的,就是一个分区 只能面向一个消费者进行消费。那我们下面来仔细的看一下这张图,这张图里面呢体现的是三个逃避可九类,这个逃避可里面有四个分区,那我们成人的这个消费端呢,这个消费者主里面有五个消费者, 那其中一个消费者处于空闲的状态,然后呢其他四个消费者去消费这个九类的分区,因为呢他只有四个分区。然后呢我们五个消费者 啊,其中四个消费者进行消费,有一个消费者呢处于空闲状态,那乳制品这个 topic 里面有五个分区,正好呢有五个成人的消费者,正好一人一个全部分配了。 那我们重点来看一下当这个乳制品的这个 topic 啊,它里面有五个分区,而我们的儿童的这个消费者主里面只有三个消 消费者的时候,那必然有一些消费者会承担多个分区的消费,也就是说呢,我们一个分区面向的是一个消费者,但是呢,我们一个消费者当数量不够的时候,在消费者主里面他可以去消费多个分区。 当然呢,我们在这个系统卡不卡进行控制这个分区与消费者的这个绑定关系的时候,他会尽量的啊平均分配或者是粘性分配。所谓的粘性分配是什么呢?就是上一次你消费的是这个分区, 下一次你出现故障恢复的时候,你还消费原来的那个分区,这个是他有一个固定的绑定,或者是一个平均的这样一个分配,这个是分区和消费者主的这样一个关系。那我们今天的内容就给大家讲到这里,我们下一节再见。

不管是日常工作、家务设计,还是面试高频提问,有一个问题永远绕不开,那就是卡不卡?到底怎么保证消息不丢失的?很多朋友呢?被问到这个问题,只能说出有副本机制还有 s r 机制。一旦面试官往深的去追问,具体分哪些环节,该怎么配置,底层原理是什么,就瞬间说不上来了。 这里有一个绝大多数人都会踩的误区,觉得消息丢失只是 blog 服务端的问题,实际上生产端、 blog 服务端、消费端这三个环节,任何一个环节配置不到位,逻辑没把控好,都有可能造成消息丢失。另外,我已经把面试经常问到的一些基础站场景题都整理在了一个面试文档里面,里面针对每个知识点都有很详细的解析思路, 只要你是我的粉丝,扣六六六打包带走。我们逐个环节来讲。首先说生产端,这是消息的源头,首要目标就是保证消息能稳定的发送到 broke。 核心就两个关键配置,第一个是 a c k 参数, 把它设置成二或者负一,意思是消息不止写入 le 的 副本,还要等待 i s r 集合,里面所有的副本都同步确认,才算真正的发送成功,可能性是最高的。 第二个就是开启重试机制,配置合理的重试次数,专门应对网络抖动、临时链路故障这类突发情况,避免一次性发送失败就直接丢失消息。再来说说 bug 服务端,也就是卡不卡,本身是怎么守住数据的,最核心的就是副本高可用机制, 日常开发建议副本因此至少设为三,就算其中一台 bug 档机,其他副本也能正常承接服务,不会造成数据丢失。同时还要搭配 一个参数, mean in sync then replicas 设为二,至少保证两个副本同步完成才认定写入生效。还要杜绝非 i s r 副本参与首例选举,防止因为错误的副本切换造成数据错乱和丢失。最后也是最容易出问题的就是消费端。说实话,很多消息丢失都 出现在消费消费的环节,最大的坑呢,就是大部分人习惯开启自动提交,偏移量自动提交就会提前标记消息已消费,可是你的业务逻辑还没处理完,一旦程序宕机,异常中断,这条消息就直接丢了,再也找不回来了。 正确的做法就很简单,关闭自动提交,改成手动提交。一定要遵循先处理完业务逻辑,确认流程没问题之后再手动提交 offscreen, 就 算处理失败也可以重试,绝对不提前标记消费完成。 同时啊,消费端还要做好密等新的设计,就算出现重复推送,也不会影响业务的正常运行。除了技术层面的配置,业务上最好也加一层兜底 发送消息,做好日记记录,甚至落库保存,后续可以通过离线任务对账教教验,就算极端情况出现消息缺失,也能及时的排查修复。总结一下,网卡保证消息不丢失从来不是靠某一个单机制, 而是生产端、 logo 端、消息端三方协调配合,再加上合理的参数配置和业务都抵,要根据自身业务的场景,平衡好可能性和性能,就能把消息丢失的一个风险降到最低。以上就是针对于卡夫卡消息丢失的解析思路,如果是你,你遇到这个问题,你会怎么解决呢?欢迎一起讨论。

今天面了一个后端工程师,简历写精通 kaufka, 做过 ai 对 话系统。我问他,用户在聊天窗口提问,你把消息发到 kaufka, 消费者拿到后调用 ai 服务,再把结果通过 redback 推回给用户。 你会怎么设计这个消费者?他自信地说,简单一个循环,拉消息,调 ai 接口,推送,提交 offset, 完事。我点点头,接着问,好。那如果 ai 服务偶尔超时或返回五 x x 错误,你怎么保证这条消息不丢,直接重试? 假如 ai 服务慢了,单次调用要五秒钟,你的 kf 卡消费者处理一条消息就花了五秒。分区只有一个消费者,你会发生什么?他愣了一下, 呃,那就多开几个消费者并行跳 ai, 多开消费者。 ai 服务本身已经慢了,你开十个消费者,十个请求同时打到 ai, 他 直接融转给你看。而且 kf 分 区数是固定的,你加消费者也加不过分区数。我问的是如何在不压垮 ai, 不 导致消费者也加不过分区数。我问的是如何在不压垮 ai, 不 导致消费者严重滞后的消费模型。 他沉默了。兄弟,你以为写个 while consumer paul co, ai and w s 就 完事了? ai 服务一抖动,你的消费者赖个蹭蹭涨运维半夜给你打电话, kofa 堆积了几百万条用户,全都卡在正在输入中。 真正能驾驭 kfk 加 ai 这种慢消费者场景的人,得从三个层面建立策略。你记好了,如果这道题你也不会,我整理了让大厂 hr 沉默的必考题库,包含 kfk 深度调优、 ai 服务治理、 webc 本高可用点个赞,评论区甩七七七,打包带走。第一层,理解风险本质, kfk 消费者的处理速度必须大于等于消息生产速度, 但 ai 调用是不可预测的慢操作,耗时长几百毫秒到几十秒不等,失败率高,模型过载、限流、超时都可能,重试会进一步增加耗时。 后果,单,县城消费整体吞吐被 ai latency 卡死,消费者 like, 消息延迟越来越大,用户等到花儿都谢了。 幽默点,你拍着胸脯说我们 kufka 吞吐量杠杠的,每秒几万条,结果 ai 一 限流,你的消费者变成每秒处理零点二条,这速度记性都比你快。第二层,基础方案到异步加县城池核心思想, po, 县城只负责拉消息,不跳 ai, 消费者,县城拉一批消息丢给一个工作县城池。工作县城调 ai 调完后推送 webspot, 消费者县城立即提交 upset。 好 处, poll 不 会被 ai 堵塞, flag 不 会爆炸。问题,县城池多大?太大压垮, ai 太小,吞吐不够,消息处理失败怎么办?工作县城里重试会导致队列堆积, 消费者崩溃,已分配给工作县城,但未处理完成的消息会丢。追问,如果你使用自动提交 upset, 工作县城还没调完, a, 消费者崩溃挂了,那条消息就永远丢了,你怎么解决? 答案,手动提交,但必须等待所有工作现成确认该批消息处理完才能提交。这就引出了下一层。第三层,可靠重试与提交策略,设计一个有可能性和可重试性的模型,不自动提交,而是记录每个消息的 offsite 和处理状态。 对于失败的消息不提交其 offsite, 而是放回一个内部重试队列,延迟一段时间后重试,重试达到上限仍然失败,则写入死信队列人工介入, 只有消息被成功推送给用户,才提交对应的 offset。 关键点,重试不能在同一个工作县城里同步循环,那样会阻赛该县城, 要用延迟队列或定时重试,且控制重试的频率。幽默点,你写了个 while call ai, ai 服务挂了,你的县城就在那疯狂重试, 每重试一次等五秒,超时一条消息搞了三十秒,其他消息全堵在他后面。兄弟,你这不叫重试,叫自残式堵塞。所以这道题念的是什么?念的是你有没有能力在慢 i o 依赖下设计一个不崩溃不堆积,可重试,有被压的咖啡卡消费者 普通开发写个限性消费 ai, 一 慢全队卡死。高级工程师异步现成时加手动提交,加内部重置队列,加动态限流,加分区合理规划。最后我问那个后人,现在你还觉得消费卡 f 卡调 ai 就是 写个负循环吗?他默默掏出手机给我点了个赞,评论区打了个七七七。

本节课我们来讨论一下 kufka 的 体系架构。 kufka 是 由 apache 软件基金会开发的一个开源流处理平台,它是一种高吞吐量的分布式发布订阅消息系统。它具有以下的特点,一、高吞吐量, kufka 每秒可以处理数以千计的消息。二、 支持数据的持久化 kufka 使用分布式提交,日制消息被写入到本地磁盘,以保证数据的持久性。三、 支持数据并行处理。 kufka 的 topic 由分区组成,每个分区被不同的节点处理。这样的设计允许 kufka 并行处理数据。四、容易向外扩展, kufka 允许添加更多的服务器到集群中。五、 支持数据复制 kufka 支持数据复制,可以跨数据中心进行数据的复制。六、支持实时处理 kufka 可以 与流处理框架集成,如 spark 和 flink 已进行实施处理。了解到了基本的知识后,下面详细讨论一下 kufka 的 体系架构。在 kufka 的 体系架构中,主要包含两种不同的角色, 一、生产者 producer, 他 负责生产消息,消息可以是自扶串,也可以是对象。在 kufka 集群中可以有多个生产者。二、消费者 consumer, 他 负责消费处理消息,如前面提到的 spark 和 flink 都可以看成是 kofker 的 消费者。 kofker 采用消费者组管理消费者,例如这里有两个消费者组,消费者组一和消费者组二。消费者组一中包含两个成员, 消费者组二中包含一个成员。在一个 kofker 集群中可以包含多个 message server, 这里可以将 message server 看成是一个物理机,在每一个 message server 上可以运行 一个或者多个 broker。 同一个集群中的 broker 具有不同的 id 号,例如这里的 broker 零 broker 一 broker 二 broker 是 真正用于接收生产者消息,将消息持久化存储,并最终将消息转发给消费者的。组建 kufka 需要将其原信息存储在 zookkeeper 中。但从二点八版本开始, cafter 逐步放弃对 zookkeeper 的 依赖,生产者将消息发布到 broker 上,消费者从 broker 上订阅消息。由于 cafter 只支持 topic 类型的广播消息 解,同一个分区中的消息只能被一个消费者组中的一个成员消费处理。例如,当消费者组 e 中的消费者 a 消费处理了一条消息,那么消费者 b 就 不能消费处理该条消息了,但该条消息仍可以被消费者 c 消费处理。 当消费者 a 出现了宕机的情况,消费者 b 可以 接替消费者 a 进行消息的消费处理,通过这样的方式实现了消费者的高可用功能。现在你已经知道 kofk 的 体系架构了,那你知道 kofk 的 数据模型吗?欢迎评论区留言讨论,好了,记得点加号关注赵玉强老师!

今天我们讲的是卡福卡。卡福卡到底能干啥?简单说,又是一个处理海量数据的消息队列,双十一抢购时极易订单同时涌来,后端服务器根本扛不住卡福卡就像中间缓冲层,让请求先排队,服务器在慢慢处理,既不会崩也不会丢数据。 那它比传统消息队列强在哪呢?能扛超高并发系统,各自从卡福卡取数据,互不干扰。 卡不卡快是因为顺序写词盘零拷贝技术,还能把数据分到不同的分区,并行处理消息落盘,多副本备份,保证不丢数据。实际应用也很广,像实时库存、共享、单车定位、新闻推荐都靠它。说白了,卡不卡就是搞定服务器高并发的关键技能。

大家好,欢迎来到咱们今天的深度探讨啊。首先呢,特别感谢波面 app 为我们提供的啊,非常优质的面试知识点。没错,非常感谢 今天的节目呢,我们会为你全面剖析一个很有意思也很有深度的后端知识点,就是 costco 的 脑裂,英文也叫 split jam brain 问题。嗯嗯,这是一个非常经典的波恩式系统问题。 对的,我们会带你穿越早期的 zookeeper 时代,一直聊到最新的 kraft 时代的底层机制,当然,还有非常关键的面世答题逻辑。是的,掌握这个底层机制, 呃,对你来说真的非常重要。在面试的时候,如果你能把脑裂问题清晰的拆解开,就能向面试官完美展示出你对分布式系统容错设计的深邃理解。确实如此,为了让你能有个直观的感受啊,我们我们先想象这么一个生活力的场景。 假设呢,一家公司原来的 ceo 突然因为生病住进重症监护室,完全失联了,也就是系统里常说的,遇到了网络分区,或者,呃,或者说是经历了非常长时间的垃圾回收停顿,也就是底层的某个工作线沉卡死了,对,就是那种节点假死的状态。 然后,这个时候董事会没办法嘛,总不能群狼无首,就赶紧选了一位新 ceo 来稳定大局。没毛病,这是很正常的故障转移逻辑。但是呢,戏剧性的一幕来了,就在新 ceo 刚上任不久,原 ceo 突然康复出院了,直接杀回公司。哈哈,这就尴尬了。是啊, 两个人同时开始发号施令,邮件满天飞,底下的人直接蒙了,公司上下乱作一团。在卡夫卡的世界里啊,这种集群里同时出现了两个发号施令的控制器的情况,就使我们今天要讲的脑裂。这个比喻非常生动。 其实不仅是卡夫卡,比如大家平时用微服务框架,像是搭布之类的,在某些特定的集群管理场景下,也会有类似的一致性挑战。虽然细节不同,但呃,核心的难题都是到底该听谁的?对的。 所以说,既然出现了刚才比喻里的那种僵尸 ceo, 那 底下的员工就是 kaufha 里的 broker 节点,总不能谁的声音大就听谁的吧?当然不能。在在还没有解除对 zooker 口核的那个旧时代, kaufha 构建防线的核心武器叫做 controller epoch。 controller epoch 翻译过来就是技员好机制,对吧?没错,你可以把它通俗地理解为 ceo 的 任期借数。 每次集群重新选举了新的 controller, 这个 e park 的 值啊,就会强制加一哦,强制加一, 也就是说,当新 controller 上任的时候,他带着比如说 e park 等于二的身份去发请求。对,而那个刚刚苏醒的旧 controller 手里拿的还是 e park 等于一的旧令牌。就是这个逻辑, 只要 broker 发现呃,你这个请求里的借术小于我本地记录的最新借术,他就会直接拒绝。哇,那 broker 端其实是有非常严格的版本号教样拦截机制的。是的,这就是防线的核心。 那当旧的 controller 收到拒绝响应之后呢?他就会意识到,哦,原来我已经我已经不是当前版本的领导了,已经被时代淘汰了。然后他就会主动退位。对的,主动退位,不再瞎指挥。这就把脑裂的影响控制住了。 等等。据我所知,随着卡弗卡价架构的多次迭代,它从三点三版本开始默认就已经采用了 craft 架构了,对吧?没错,已经彻底把 zuki 堡移除了。那我就有个疑问了,如果连颁发纪元号的这个,嗯,这个 第三方权威纪稿都没了,那岂不是很容易再次天下打乱?哈哈,这其实就是架构眼筋的精妙之处了, 不仅没有天下大乱,反而系统变得更加稳固了。啊,怎么做到的?因为 krf 的 底层换成了大名鼎鼎的 raft 公式算法,它利用的是多数派选举原则。多数派选举,也就是 quora 机制,对吧?对, quora 这个机制从物理层面上直接杜绝了脑裂的发生。你想啊,在 raft 算法里,要成为 leader, 你必须获得集群里半数以上节点的投票。嗯,半数以上,比如五个节点就得拿三票。没错,在一个发生网络分区的集群里面,选票的总数是固定的, 你绝不可能,绝对不可能同时凑齐两个半数以上的选票,对吧?哦,我明白了,连多数派都凑不起,那自然就不可能诞生第二个发号施令的人了。 这数学逻辑简直无懈可击呀。是的,直接在摇篮里就扼杀了。那那类似之前 zookkeeper 时代的机源号那种版本交易机制在当前的 krf 里还有保留吗?保留了, 在 raft 算法里,它被称为 term, 也就是任期机制。 term 机制听起来和 controller epoch 差不多,底层运作逻辑其实是如出一者的, 依然用那种呃,单调递增的版本号来作为权力的决的时间戳,也就是永远只认最新的,一旦有更高的 term 出现,旧的 leader 就 会立刻被强制降级。对,强制降级, 不管是哪个时代,底层都在用这种不可逆的时间戳来确认权威,这是最核心的设计哲学。确实, 理解了设计哲学,再去背那些具体的实现,就就完全是顺理成章的事情了。没错,说到这里啊,还有一个面试时非常容易漏掉的加分项哦。什么加分项?快给大家展开说说。就是脑裂这个问题,它不仅仅发生在局的 controller 层面, 不仅仅是 controller, 对 普通 partition, 也就是分区级别的 leader, 同样会遇到这种假死后复活的情况。哇,原来如此,那普通分区要是遇到这种僵尸 leader 该怎么处理? kufka 为此专门设计了 leader epoch 机制。 leader epoch 和 controller epoch 名字很像啊,原理也很像,同样用单调递增的版本号来隔离那些旧的分区 leader, 从而严格保护数据的一致性。明白了, 那让我们把今天聊的这些内容啊拆解成面试的实战逻辑。如果大家在面试中碰到了关于脑裂的问题,要怎么回答才能拿高分呢?我建议你采用这样一个逻辑框架来组织回答。首先先讲问题背景, 就是先把那个僵尸 ceo 的 场景给面试官抛出来,说明脑裂到底是个什么事。 对,然后第二步讲 sukipper 时代的方案,把 controller epoch 和版本拦截机制讲清楚。嗯嗯,第三步呢? 第三步就是对比 kf 的 时代的方案,重点突出多数派选举机制和 term 任期。最后一步肯定就是抛出刚才说了那个隐藏加分项了,对吧?没错,最后补充普通分区的 leader epoch 细节, 按照这个问题背景,到 jk 时代方案,再到 kf 的 时代方案,最后是分区级方案的框架打下来,这简直就是降维打击, 这个结构真的太清晰了,为了帮大家巩固啊,我们最后快速进行一个五道高平面式题的速达演练,你可以把这当成一个知识点的验收,没问题,你来问,我来答。好嘞,第一题,什么是卡夫卡脑裂? 简单来说就是两个 broker 节点同时认为自己是 controller, 并且都在向集群发送管理指令的异常状态,漂亮!第二题, zookkeeper 时代的防脑裂核心是什么? 核心就是单调递增的 controller epoch 机制,配合上 broker 端严格的版本,好叫眼拦截。明白了。第三题,那到了 kft 时代是如何彻底解决脑裂的? 依靠的是 raft 算法的多数派选举原则,也就是绝不可能凑齐两个半数以上的选票,同时配合 term 任期机制来进行版本控制。 第四题,面试官如果问什么是僵尸控制器,怎么解释最精准?僵尸控制器就是那些因为网络延迟或者系统卡顿被剥夺的身份,但自己还没意识到恢复之后依然自任是 controller 并发送旧指令的节点。最后一题, 脑裂只发生在 controller 身上吗?当然不是, partition 的 leader 也会发生脑裂, kufka 是 通过 leader epoch 机制来兜地解决的。 太棒了,只要大家记住,永远只认最新版本的指挥官这个核心逻辑,不管那个僵尸 ceo 怎么闹腾,系统的运转依然稳如泰山。没错,把这种底层逻辑吃透,相信你在面试中绝对能游刃有余。确实是这样, 今天我们对卡弗卡脑裂机制的深度剖析就到这里了,希望能给正在准备面试的你带来启发。祝你在接下来的技术面试中大放异彩,自信拿下心仪的 offer, 我 们下次节目再见!拜拜!

很多人一聊卡不卡,消息不丢,张口就是 a c k 机制啊。但说实话,只有初学者才会有这种想法。别着急反驳,先听我讲完这六十秒,你对于这块内容的理解,可能会直接升一个段位。很多人理解的卡发的可能性特别简单,商家发消息,博克返回 a c k, 完美,仿 佛只要把 a c k 设置为 o, 系统就天下太平了。但问题是, a c k 机制真正保证的其实只有一件事,博克收到了消息,而不是消费者把业务处理成功了。这俩可差的太远了。 比如订单服务发消息扣库存,卡不卡返回 a c k 了,很多人就觉得稳了,稳个锤子。因为可能出现的情况是,消费者还没收到这条消息就宕机了。所以,真正成熟的基础方案,根本不是发完消息等 a c k 就 结束,而是分布式事务中的本地消息表。什么意思? 比如订单创建成功时,先写订单表,再写本地消息表,然后发送消息。这样即使卡不卡的 port 和消费者出现了问题,消息也不会丢。因为在本地消息表的分布式事务中,还有后台任务不断重试发送的 同时,消费者把库存扣减成功了,还会对生产者进行回调通知,告诉他业务处理完成了,变更本地消息表中的消息状态。反之,如果库存扣减失败了,也会回掉生产者进行回滚。这才叫真正意义上的闭环。否则,你只知道 plop 收到了,但消费者到底有没有真正处理成功,你根本就不知道。 然后再说消费者,这才是最经典的坑。卡不卡的消费者不是有 offside 的 偏音量提交吗?问题来了,如果你先提交了, offside 的 还没执行业务逻辑,这时候突然宕机,卡不卡会认为这条消息你消费过了,结果漏消费了, 这也是一个大坑。那很多人又说,那我先做业务,再提交 offside 的 不就行了?没错,但新的问题又来了,如果业务刚执行完, offside 的 还没提交,系统宕机了,那重启之后,卡不卡会再次投递那条消息,于是出现了重复消费的情况。 看到这里,很多人开始崩溃了,那到底先提交还是后提交?答案其实很简单,我们宁愿重复消费,也不要漏消费,因为漏消费的数据可能永远就丢了,但重复消费可以做逆等。 真正成熟的系统一般都是先执行业务,再提交 offside, 然后在数据库层面把消息 id 作为唯一锁芯判重。这样即使卡不卡重复投递,数据库也会直接拦住业务,不会重复执行。这才是真正成熟的卡不卡的可信方案。所以最后总结一句, a c k 机制只能保证商户的到 bro 这一个尽量不丢,但真正难的从来不是发消息,而是防止漏消费加重复消费。 而真正成熟的系统,往往都是本地消息表加先业务后提交 offside, 加上唯一锁、隐蔽等控制一起配合。最后留个问题,你觉得卡不卡中最恶心的问题是重复消费还是漏消费?