Kafka详解及面试常问问题

2023-11-17

Kafka

简介

Kafka 是一个分布式流式处理平台。这到底是什么意思呢?

流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
  2. 容错的持久方式存储记录消息流: Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险·。
  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。

Kafka 主要有两大应用场景:

  1. 消息队列 :建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。
  2. 数据处理: 构建实时的流数据处理程序来转换或处理数据流。

为什么要用kafka消息队列,他的优势是什么?

  1. 解耦:读写逻辑分开
  2. 冗余:避免消息丢失
  3. 扩展性:解耦之后,增大消息入队和处理消息的频率都很容易
  4. 灵活性 & 峰值处理能力:在访问量剧增的情况下,应用仍然需要继续发挥作用
  5. 顺序保证
  6. 缓冲

核心概念

生产者(也称为发布者)创建消息,而消费者(也称为订阅者)负责消费or读取消息。

在 Kafka 中,消息以**主题(Topic)**来分类,每一个主题都对应一个 「消息队列」,这有点儿类似于数据库中的表。但是如果我们把所有同类的消息都塞入到一个“中心”队列中,势必缺少可伸缩性,无论是生产者/消费者数目的增加,还是消息数量的增加,都可能耗尽系统的性能或存储。v

Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹!(为了方便扩展-消息数量增加和提供并发)

Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。

Kafka 的多分区(Partition)以及多副本(Replica)机制的作用

  1. Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力(负载均衡)。
  2. Partition 可以指定对应的 Replica 数, 这也极大地提高了消息存储的安全性, 提高了容灾能力,不过也相应的增加了所需要的存储空间。

img

基本原理

发送数据

写入数据的时候寻找leader,followers主动pull从leader中拉取数据

img

面试常问问题

kafka如何保证有序性

img

每次添加消息到 Partition(分区) 的时候都会采用尾加法,如上图所示。Kafka 只能为我们保证 Partition(分区) 中的消息有序,而不能保证 Topic(主题) 中的 Partition(分区) 的有序。

所以,我们就有一种很简单的保证消息消费顺序的方法:1 个 Topic 只对应一个 Partition。这样当然可以解决问题,但是破坏了 Kafka 的设计初衷。

Kafka 中发送 1 条消息的时候,可以指定 topic, partition, key,data(数据) 4 个参数。如果你发送消息的时候指定了 Partition 的话,所有消息都会被发送到指定的 Partition。并且,同一个 key 的消息可以保证只发送到同一个 partition,这个我们可以采用表/对象的 id 来作为 key 。

总结一下,对于如何保证 Kafka 中消息消费的顺序,有了下面两种方法:

  1. 1 个 Topic 只对应一个 Partition。
  2. (推荐)发送消息的时候指定 key/Partition。

kafka如何保证消息不丢失

生产者(Producer) 调用send方法发送消息之后,消息可能因为网络问题并没有发送过去。

所以,我们不能默认在调用send方法发送消息之后消息消息发送成功了。为了确定消息是发送成功,我们要判断消息发送的结果。但是要注意的是 Kafka 生产者(Producer) 使用 send 方法发送消息实际上是异步的操作,我们可以通过 get()方法获取调用结果

可以采用为其添加回调函数的形式,示例代码如下:

        ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, o);
        future.addCallback(result -> logger.info("生产者成功发送消息到topic:{} partition:{}的消息", result.getRecordMetadata().topic(), result.getRecordMetadata().partition()),
                ex -> logger.error("生产者发送消失败,原因:{}", ex.getMessage()));

如果消息发送失败的话,我们检查失败的原因之后重新发送即可!

另外这里推荐为 Producer 的retries(重试次数)设置一个比较合理的值,一般是 3 ,但是为了保证消息不丢失的话一般会设置比较大一点。设置完成之后,当出现网络问题之后能够自动重试消息发送,避免消息丢失。另外,建议还要设置重试间隔,因为间隔太小的话重试的效果就不明显了,网络波动一次你3次一下子就重试完了

丢失的情况

我们知道消息在被追加到 Partition(分区)的时候都会分配一个特定的偏移量(offset)。偏移量(offset)表示 Consumer 当前消费到的 Partition(分区)的所在的位置。Kafka 通过偏移量(offset)可以保证消息在分区内的顺序性。

kafka offset

当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。

解决办法也比较粗暴,我们手动关闭闭自动提交 offset,每次在真正消费完消息之后之后再自己手动提交 offset 。 但是,细心的朋友一定会发现,这样会带来消息被重新消费的问题。比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。

如何解决重复消费的问题

通过保证消息队列消费的幂等性来保证

怎么保证消息队列消费的幂等性(同一条消息消费多次结果相同)?

我们需要结合业务来思考,比如下面的例子:

1.比如某个数据要写库,你先根据主键查一下,如果数据有了,就别插入了,update一下好吧

2.比如你是写redis,那没问题了,反正每次都是set,天然幂等性

我们需要结合业务来思考,比如下面的例子:

1.比如某个数据要写库,你先根据主键查一下,如果数据有了,就别插入了,update一下好吧

2.比如你是写redis,那没问题了,反正每次都是set,天然幂等性

3.对于消息,我们可以建个表(专门存储消息消费记录)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kafka详解及面试常问问题 的相关文章

随机推荐

  • ROS noetic tf demo错误处理及python版本切换

    文章目录 报错描述及解决 ubuntu20 04下python版本切换 报错描述及解决 ubuntu版本 20 04 ROS版本 noetic roslaunch turtle tf turtle tf demo launch 报错信息 t
  • 04-JavaWeb-使用Servlet+JSP+JDBC实现CRUD

    一 介绍 在掌握了JavaAPI HTML Servlet JSP JDBC等知识后 咱们利用这些知识点 打通从前端页面到后端Java 再到数据库的各个环节 通过实现一个员工的CRUD来巩固一下相关知识 项目架构如下 实现功能如下 员工列表
  • CMD之拷贝文件夹

    左右无空格 SET srcdir protobuf IDL SET dstdir install proto Y 取消提示以确认要覆盖 E 复制目录和子目录 包括空目录 I 如果目标不存在 且要复制多个文件 则假定目标必须是目录 Q 复制时
  • ES6知识点总结一:const、let、箭头函数

    1 ES6常量及变量的声明const let ES6 新增了let命令来声明变量 const用来声明常量 ES6新增的let和const拥有 块级作用域 ES5只有 全局作用域 和 函数作用域 const与var区别 var声明的变量可以重
  • 如何将本地项目上传到git仓库中

    如何将本地项目上传到git仓库中 1 打开github 新建一个仓库用来存放项目 2 复制创建仓库链接 https github com WQ181 qiji git 3 找到要上传的项目文件 比如 qj consult就是我要上传到仓库上
  • python-turtle画图

    认识Turtle Turtle是一个渲染器 基于底层图形编程结构 API 构建 主要用于场景的构建以及3D物体的绘制 3D游戏 虚拟场景等 Turtle是一个窗体程序 Turtle是Python语言中的一个很流行的绘制图像的函数库 想象一个
  • js表单案例

    js表单案例 包括阻止提交的默认行为 添加节点操作以及删除节点操作等等
  • 逻辑思维训练1200题-蓝桥杯计算思维参考

    黑格尔曾说过 逻辑是一切思考的基础 逻辑思维能力强的人能迅速 准确地把握住问题的实质 面对纷繁复杂的事情能更容易找到解决的办法 逻辑思维训练1200 题 介绍了排除法 递推法 倒推法 作图法 假设法 计算法 分析法 类比法 推理法 判断法
  • 记录下:解决fatal error: sqlite3.h: No such file or directory

    编译sqlite3数据库c语言程序时出现fatal error sqlite3 h No such file or directory 找不到头文件的问题 原来是系统没有安装函数库 执行下面语句解决 sudo apt get install
  • Linux服务器上配置Jupyter并在后台运行

    使用工具 Xshell作为终端 Python3 版本 Xmanager打开Linux图形浏览器 第一步 安装Jupyter pip3 install i https pypi douban com simple jupyter 如果己安装好
  • 用户信息表(查询数据 、 修改密码 、 添加数据)

    效果 列表的数据 添加用户的效果 修改用户表
  • Excel读取返回List<Map>工具方法

  • cocos2d-x

    http www myexception cn operating system 1222879 html http www tuicool com articles zQ3Q7n http www myexception cn opera
  • 服装商城小程序制作:打造便捷购物体验和提升销售额的利器

    随着移动互联网的发展 服装商城小程序成为各大服装品牌推广销售的重要工具 它不仅能够为用户提供便捷的购物体验 还能帮助服装商城实现更高效的销售和管理 下面给大家介绍下服装商城小程序的优点以及制作流程 让您了解并充分利用这一利器 优点 便捷购物
  • 云端部署code-server

    code server下载地址 GitHub coder code server VS Code in the browser 操作环境 本文配置环境为 aliyun ECS Debian 11 5 准备工作 Xftp 阿里云ECS云服务器
  • 算法--吃火锅

    题目 和朋友一起吃火锅 有m个菜品 你的手速是n 即吃完一道菜 要经过时间n才能再去夹菜 任一菜品下锅后 都需要经过对应时间才能熟 过时就不可口了 怎样可以吃到最多的可口的菜 输入 第1行 菜品数量m 手速n 第2 m行 每行两个数字 第一
  • 所有的USB C 设备都需要CC芯片吗

    所有的DFP 如电源适配器 所有的DRP 如电脑 手机 平板 移动电源 所有需要检测DFP电流输出能力的UFP 所有支持PD的设备 都需要CC逻辑检测与端口控制芯片 换句话说 只有因为功耗较低而不需要检测电流能力的UFP U盘 耳机 鼠标等
  • 第五届蓝桥杯校内选拔赛试题java组_2014年第五届蓝桥杯国赛试题(JavaA组)

    1 结果填空 满分15分 2 结果填空 满分45分 3 代码填空 满分30分 4 程序设计 满分30分 5 程序设计 满分80分 6 程序设计 满分100分 1 标题 海盗分金币 有5个海盗 相约进行一次帆船比赛 比赛中天气发生突变 他们被
  • 【经典分割网络】网络+模块+数据集+实验结果(整理中。。

    KolektorSDD数据集中包 含了 50组电子换向器图片 其中每组包含 8张图 片以及对应的语义分割标签 图像宽均为 500像 素 高为 1 240 1 273像素 1 FCN 2 U net 3 PSPnet 4 deeplab 5
  • Kafka详解及面试常问问题

    Kafka 简介 Kafka 是一个分布式流式处理平台 这到底是什么意思呢 流平台具有三个关键功能 消息队列 发布和订阅消息流 这个功能类似于消息队列 这也是 Kafka 也被归类为消息队列的原因 容错的持久方式存储记录消息流 Kafka