Kafka总结问题

Kafka

  • Kafka

Kafka

Kafka的核心概念/ 结构

  • topoic

    • Topic 被称为主题,在 kafka 中,使用一个类别属性来划分消息的所属类,划分消息的这个类称为 topic。topic 相当于消息的分配标签,是一个逻辑概念。主题好比是数据库的表,或者文件系统中的文件夹。
  • partition

    • partition 译为分区,topic 中的消息被分割为一个或多个的 partition,它是一个物理概念,对应到系统上的就是一个或若干个目录,一个分区就是一个 提交日志。消息以追加的形式写入分区,先后以顺序的方式读取。
    • 注意:由于一个主题包含无数个分区,因此无法保证在整个 topic 中有序,但是单个 Partition 分区可以保证有序。消息被迫加写入每个分区的尾部。Kafka 通过分区来实现数据冗余和伸缩性
    • 分区可以分布在不同的服务器上,也就是说,一个主题可以跨越多个服务器,以此来提供比单个服务器更强大的性能。
  • producer

    • 生产者,即消息的发布者,其会将某 topic 的消息发布到相应的 partition 中。生产者在默认情况下把消息均衡地分布到主题的所有分区上,而并不关心特定消息会被写到哪个分区。不过,在某些情况下,生产者会把消息直接写到指定的分区。
  • consumer

    • 消费者,即消息的使用者,一个消费者可以消费多个 topic 的消息,对于某一个 topic 的消息,其只会消费同一个 partition 中的消息
    • 图片
  • broker

    • Kafka 集群包含一个或多个服务器,每个 Kafka 中服务器被称为 broker。broker 接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。broker 为消费者提供服务,对读取分区的请求作出响应,返回已经提交到磁盘上的消息。

      broker 是集群的组成部分,每个集群中都会有一个 broker 同时充当了 集群控制器(Leader)的角色,它是由集群中的活跃成员选举出来的。每个集群中的成员都有可能充当 Leader,Leader 负责管理工作,包括将分区分配给 broker 和监控 broker。集群中,一个分区从属于一个 Leader,但是一个分区可以分配给多个 broker(非Leader),这时候会发生分区复制。这种复制的机制为分区提供了消息冗余,如果一个 broker 失效,那么其他活跃用户会重新选举一个 Leader 接管。

Kafka的应用场景

  1. 作为mq, 异步解耦削峰
  2. 活动跟踪, 实时检测, 将用户活动发布到中心topic上, 然后使用检测技术检测用户行为
  3. 日志聚合, 收集日志后, 提取出来进行流处理, 这样我们就可以自定义流来抽象我们的日志消息流

kafka为什么快

  1. 磁盘顺序读, 使得磁盘顺序寻址, 减少了时间

  2. 零拷贝 ->这个地方貌似还比较重要, 之后单独写一篇文章研究一下

  3. 消息可以分批发送,减少了网络传输和磁盘IO读写

    • 在生产者生辰的时候, 消息不会立刻发送到kafka, 而是发送到生产者缓冲区, 封装成一个批次batch, 之后sender线程会从缓存中取出这些批次, 发送给kafka(batch有三个参数进行控制 : 累计消息数量+累计时间间隔+累计数据大小)
    • 消费者消费的时候pull模式也可以自主决定是否批量从kafk拉取数据(但是如果kafka本身现在没有消息, 这个时候消费者会空转, kafka提供了参数可以让consumer阻塞直到新消息到达)
  4. 消息批量压缩

  5. 分区分段+索引

Kafaka中的Topic如何分区放置到不同的Broker

首先第一个分区放置的位置是从BrokerList中随机选择的

其他分区的位置, 会依次在这个位置向后偏移

Kafka中的topic中的partition数据是如何存储到磁盘

Topic中的partition是以文件夹的形式保存到Broker, 每个分区号从0递增, 且消息有序, Partition文件下有多个Segment(xxx.index, xxx.log), 分段, segment文件的大小和配置文件大小一致, 如果大小大于了1G, 就会滚动一个新的segment并且以上一个segment最后一条消息的偏移量命名

kafka为什么分区

  1. 方便在集群中扩展, 每个partiotion可以通过调整适应所在的机器, 而一个topic可以由多个partition组成, 所以整个集群可以适应任意大小的数据
  2. 提高并发, 因为可以通过partition为单位进行读写
  3. 为了提高Kafka处理消息吞吐量。假如同一个topic下有n个分区、n个消费者,每个分区会发送消息给对应的一个消费者,这样n个消费者就可以负载均衡地处理消息。同时生产者会发送消息给不同分区,每个分区分给不同的brocker处理,让集群平坦压力,这样大大提高了Kafka的吞吐量。

Consumer如何消费指定分区消息

Consumer消费消息的时候,可以发出fetch请求消费特定分区, 而且可以通过指定消息在日志中的偏移量offset, 可以从这个地方开始消费消息, 也可以消费以前消费过的消息, 甚至跳过一部分消息

kafka的ack的三种机制

request.required.acks有三个值0 1 -1(all)

1(默认):这意味着producer在ISR的leader已成功收到数据并得到确认,如果Leader宕机,则会丢失数据

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

-1:producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。但是这样也不能保证数据不丢失。比如当ISR中只有leader时,(ISR的成员由于某些情况会增加也会减少,最后就剩下一个leader),这样就变成ack=1的情况。

Kafka的手动提交和异步提交

partition中的offset用来记录我们消费的消息, 假设某一个消费者挂了, 这时候它所订阅的分区分摊给其他消费者, 如果分区中的offset因为没来得及消费就提交了offset或者消费了还没来得及提交offset, 就会导致消息重复消费/消息丢失

所以决定提交的时刻是十分重要的

  • 自动提交偏移量

    • 当enable.auto.commit被设置为true,提交方式就是让消费者自动提交偏移量,每隔5秒消费者会自动把从poll()方法接收的最大偏移量提交上去:
    • 如果刚好到了5秒时提交了最大偏移量,此时正在消费中的消费者客户端崩溃了,就会导致消息丢失
    • 如果成功消费了,下一秒应该自动提交,但此时消费者客户端奔溃了提交不了,就会导致其他分区的消费者重复消费
    • Spring中使用commitSync()提交偏移量,commitSync()将会提交poll返回的最新的偏移量,所以在处理完所有记录后要确保调用了commitSync()方法。
  • 手动提交

    • 当enable.auto.commit被设置为false可以有以下三种提交方式
    1. 提交当前偏移量(同步提交) : 在broker对请求做出回应之前,客户端会一直阻塞,这样的话限制应用程序的吞吐量

    2. 异步提交 : 不会有吞吐量的问题。不过发送给broker偏移量之后,不会管broker有没有收到消息, 如果服务器返回提交失败,异步提交不会进行重试。如果同时存在多个异步提交,进行重试可能会导致位移覆盖。所以异步提交不会进行重试

    3. 同步和异步组合提交

      先异步提交, 如果失败, 就trycatch兜底使用同步提交, 保证offset准确

kafka生产者生产过程, 消费模式

  1. 生产过程

    • 消息首先会被封装成一个ProduceRecord对象
    • 然后对消息进行序列化处理
    • 对消息进行分区处理, 决定消息发向哪个主题的哪个分区
    • 分好区后在Batch缓存中等待
    • Sender线程启动将缓存中的数据批量发送到kafka---->发送的时候也是分为同步发送和异步发送的, 同步发送会等待结果, 异步发送会调用回调(异步回调可以在消息发送失败的时候记录日志)
  2. 消费模式

    • 当Producer将消息推送到Broker之后, Consumer就会从Broker中获取消息
    • 设置ConsumerConfig.DEFAULT_FETCH_MAX_WAIT_MS_CONFIG 阻塞等待消息

kafka怎么保证消息顺序性

Kafka分布式的单位是partition,同一个partition用一个write ahead log组织,所以可以保证FIFO的顺序。

不同partition之间不能保证顺序。因为同一个key的Message可以保证只发送到同一个partition。

Kafka中发送1条消息的时候,可以指定(topic, partition, key) 3个参数。partiton和key是可选的。如果你指定了partition,那就是所有消息发往同1个partition,就是有序的。

并且在消费端,Kafka保证,1个partition只能被1个consumer消费。或者你指定key(比如order id),具有同1个key的所有消息,会发往同1个partition。

Kafka如何实现延迟队列

  1. 使用kafka本身做延迟队列

    • kafka本身没有延迟功能, 只是使用offset当作记录消息消费的位置
    • 可以通过不断消费, 检测延时的时间有没有到达, 到达就消费数据, 没到达就把消息重新投递到partition中
    • 但是这个消费不准确, 如果partiotion中的数据很多, 重新投递到分区的消息再次消费的时候可能远比设置的时间更久了
  2. 另外的方法并不是基于kafka本身实现的延迟队列

    • 比如使用时间轮+kafka实现
    • kafka+java delayqueue实现
    • kafka+rockdb

Kafka的消息不漏发是如何实现的

  • 个人认为消息完全不漏发是很难保证的, 毕竟从生产者到消费者消费的整个过程中, 存在着很多不确定因素
  • 但是上面所说的, offset机制, 为了保证offset准确性而提到的手动提交,手动异步提交+同步提交
  1. 如果生产者发送到服务端kafka的时候, 失败了, 如何解决?

    • 生产者使用异步回调, 记录失败的消息
    • 使用消息确认机制, 确认所有partition的leader副本同步到消息之后, 才认为本次生产者发送消息成功
    • 并且需要设置消息失败后生产者重试次数
    • 本地也可以通过异常来定义消息日志表, 定期扫描这个表作为补偿
  2. 服务端broker如何保证消息不丢失?

    • 服务端会将消息数据持久化保存到磁盘, 一般是先写入缓存然后刷盘, 如果刷盘失败, 消息丢失
    • 这个时候可以使用同步刷盘(当生产者发送消息到broker端的时候,需要等待broker端把消息进行落盘之后,才会返回响应结果给生产者), 但是影响性能
    • partition副本机制, 确保不止一个partition保存了消息
  3. 消费者端使用自动提交offset, 导致offset错误

    • 设置手动提交
    • 同时消费者端也需要进行幂等处理,防止重复消费 ->比如设置业务在数据库中的唯一约束, 或者在业务层面给消息加一个id, 作为去重
  • 这里我们再想一个问题, 假如我整个kafka作为消息队列都挂了怎么办?那消息不是全部丢了吗?
    • 这个时候一般会临时增加降级存储, 比如先起一个缓存, 把这些消息存储起来, 这个时候不断重试将消息推送到kafka中, 这样能够保证kafka能够第一时间消费到消息

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

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

相关文章

C++进阶之路---C++11相关特性 | 左值引用 | 右值引用 | 完美转发

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1),使得C03这个名字已经取代了C98称为C11之…

全球大型语言模型(LLMS)现状与比较

我用上个博文的工具将一篇ppt转换成了图片,现分享给各位看官。 第一部分:国外大语言模型介绍 1,openai的Chatgpt 免费使用方法1:choose-carhttps://share.freegpts.org/list 免费使用方法2:Shared Chathttps://share…

【Java】Map和Set

文章目录 一、Map和Set的概念二、模型三、Map的说明3.1 Map.Entry<K, V>的说明3.2 Map 的常用方法 四、Set的说明4.1 Set的常用方法 一、Map和Set的概念 Map和set是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关&#xff0c…

redis和rabbitmq实现延时队列

redis和rabbitmq实现延时队列 延迟队列使用场景Redis中zset实现延时队列Rabbitmq实现延迟队列 延迟队列使用场景 1. 订单超时处理 延迟队列可以用于处理订单超时问题。当用户下单后&#xff0c;将订单信息放入延迟队列&#xff0c;并设置一定的超时时间。如果在超时时间内用户…

Ollama 运行 Cohere 的 command-r 模型

Ollama 运行 Cohere 的 command-r 模型 0. 引言1. 安装 MSYS22. 安装 Golang3. Build Ollama4. 运行 command-r 0. 引言 Command-R Command-R 是一种大型语言模型&#xff0c;针对对话交互和长上下文任务进行了优化。它针对的是“可扩展”类别的模型&#xff0c;这些模型在高…

CTF题型 Http请求走私总结Burp靶场例题

CTF题型 Http请求走私总结&靶场例题 文章目录 CTF题型 Http请求走私总结&靶场例题HTTP请求走私HTTP请求走私漏洞原理分析为什么用前端服务器漏洞原理界定标准界定长度 重要!!!实验环境前提POST数据包结构必要结构快速判断Http请求走私类型时间延迟CL-TETE-CL 练习例题C…

代码随想录阅读笔记-栈与队列【用栈实现队列】

题目 使用栈实现队列的下列操作&#xff1a; push(x) -- 将一个元素放入队列的尾部。 pop() -- 从队列首部移除元素。 peek() -- 返回队列首部的元素。 empty() -- 返回队列是否为空。 示例: MyQueue queue new MyQueue(); queue.push(1); queue.push(2); queue.peek(); …

GPT实战系列-智谱GLM-4的模型调用

GPT实战系列-智谱GLM-4的模型调用 GPT专栏文章&#xff1a; GPT实战系列-实战Qwen通义千问在Cuda 1224G部署方案_通义千问 ptuning-CSDN博客 GPT实战系列-ChatGLM3本地部署CUDA111080Ti显卡24G实战方案 GPT实战系列-Baichuan2本地化部署实战方案 GPT实战系列-让CodeGeeX2帮…

docker仓库登录及配置insecure-registries的方法

docker仓库登录及配置insecure-registries的方法 这篇文章主要介绍了docker仓库登录配置insecure-registries的方法,docker客户端如果配置中添加了insecure-registary配置&#xff0c;就不需要在docker 客户端配置上对应证书&#xff0c;如果不配置要在/etc/docker/certs.d/目…

vue3与Electron构建跨平台应用(webpack)

一、创建vue3项目 vue create vue3_webpack_electron 二、安装Electron npm install --save-dev electron Electron 三、vue add electron-builder vue add electron-builder

优维全面可观测产品能力分解⑥:运维状态可观测

本文是《优维全面可观测产品能力分解》系列文章的第六篇&#xff1a;『运维状态可观测』。基于可观测的数据体系&#xff0c;「运维状态可观测」是实现于运维状态的一次深入可观测。 在日常运维场景中&#xff0c;系统/应用运维人员重点关注的是系统/应用是否可用&#xff0c;…

视频素材库哪个好?这8个短视频相关的优质素材网推荐看看

在这个数字化时代&#xff0c;视频内容的创作变得前所未有地重要。无论是短视频的快速制作&#xff0c;还是专业影片的精心编辑&#xff0c;找到合适的素材资源是每个视频创作者的基本需求。从高清视频片段、无水印的图片&#xff0c;到富有情感的音效&#xff0c;以下精选的网…

LeetCode---126双周赛

题目列表 3079. 求出加密整数的和 3080. 执行操作标记数组中的元素 3081. 替换字符串中的问号使分数最小 3082. 求出所有子序列的能量和 一、求出加密整数的和 按照题目要求&#xff0c;直接模拟即可&#xff0c;代码如下 class Solution { public:int sumOfEncryptedInt…

《剑指 Offer》专项突破版 - 面试题 88 : 动态规划的基础知识(C++ 实现)

目录 前言 面试题 88 : 爬楼梯的最少成本 一、分析确定状态转移方程 二、递归代码 三、使用缓存的递归代码 四、空间复杂度为 O(n) 的迭代代码 五、空间复杂度为 O(1) 的迭代代码 前言 动态规划是目前算法面试中的热门话题&#xff0c;应聘者经常在各大公司的面试中遇到…

JAVA——volatile,wait,notife

文章目录 volatile关键字简识jvm内存模型内存上的优化问题的产生volatile的作用 wait&#xff08;&#xff09;wait()的作用 notify&#xff08;&#xff09;notify的唤醒顺序 volatile关键字 volatile关键字可以保证内存的可见性&#xff0c;什么是内存的可见性呢&#xff1f…

Jenkins中支持maven构建遇到仓库报错问题

目的 Jenkins中支持maven构建(Jenkins使用docker安装&#xff09; 问题 1.构建一个maven项目 2.执行报错 /var/lib/jenkins/local_maven_repo/com/sx/root/1.0.4/root-1.0.4.pom.part.lock (No such file or directory) Failed to transfer Could not transfer artifact co…

Unity发布webgl之后打开PDF文件,不使用js,不和浏览器交互

创建一个按钮&#xff0c;然后点击就会打开 在webgl下要使用这样的路径拼接&#xff0c;不然就会报错。 btnBook.onClick.AddListener(() >{var uri new System.Uri(Path.Combine(Application.streamingAssetsPath "/Books", "文档.pdf"));Debug.Log…

是德科技keysight N1912A双通道功率计

181/2461/8938产品概述&#xff1a; Keysight(原Agilent) N1912A P系列双通道功率计可提供峰值、峰均比、平均功率、上升时间、下降时间、最大功率值、最小功率值以及宽带信号的统计数据。 Keysight(原Agilent) N1912A P系列双通道功率计, 可提供峰值、峰均比、平均功率、上升…

53、Qt/信号与槽、QSS界面设计20240322

一、使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是…

机器学习 - 训练模型

接着这一篇博客做进一步说明&#xff1a; 机器学习 - 选择模型 为了解决测试和预测之间的差距&#xff0c;可以通过更新 internal parameters, the weights set randomly use nn.Parameter() and bias set randomly use torch.randn(). Much of the time you won’t know what…