面试官让我聊聊 MQ 的数据丢失问题,没想到水这么深。。。

2023-05-16

目录

  • 一、背景引入
  • 二、Kafka分布式存储架构
  • 三、Kafka高可用架构
  • 四、画图复现Kafka的写入数据丢失问题
  • 五、Kafka的ISR机制是什么?
  • 六、Kafka写入的数据如何保证不丢失?
  • 七、总结

一、背景引入

这篇文章,给大家聊一下写入Kafka的数据该如何保证其不丢失?

看过之前的文章《字节面试官: 让你设计一个MQ每秒要抗几十万并发,怎么做?》的同学,应该都知道写入Kafka的数据是会落地写入磁盘的。

我们暂且不考虑写磁盘的具体过程,先大致看看下面的图,这代表了Kafka的核心架构原理。

在这里插入图片描述

二、Kafka分布式存储架构

那么现在问题来了,如果每天产生几十TB的数据,难道都写一台机器的磁盘上吗?这明显是不靠谱的啊!

所以说,这里就得考虑数据的分布式存储了,其实关于消息中间件的分布式存储以及高可用架构,之前的一篇文章《程序员别死背面试八股文了,这种面试题才是未来主流。。。》也分析过了,但是这里,我们结合Kafka的具体情况来说说。

在Kafka里面,有一个核心的概念叫做“Topic”,这个topic你就姑且认为是一个数据集合吧。

举个例子,如果你现在有一份网站的用户行为数据要写入Kafka,你可以搞一个topic叫做“user_access_log_topic”,这里写入的都是用户行为数据。

然后如果你要把电商网站的订单数据的增删改变更记录写Kafka,那可以搞一个topic叫做“order_tb_topic”,这里写入的都是订单表的变更记录。


然后假如说咱们举个例子,就说这个用户行为topic吧,里面如果每天写入几十TB的数据,你觉得都放一台机器上靠谱吗?

明显不太靠谱,所以Kafka有一个概念叫做Partition,就是把一个topic数据集合拆分为多个数据分区,你可以认为是多个数据分片,每个Partition可以在不同的机器上,储存部分数据。

这样,不就可以把一个超大的数据集合分布式存储在多台机器上了吗?大家看下图,一起来体会一下。

在这里插入图片描述

三、Kafka高可用架构

但是这个时候,我们又会遇到一个问题,就是万一某台机器宕机了,这台机器上的那个partition管理的数据不就丢失了吗?

所以说,我们还得做多副本冗余,每个Partition都可以搞一个副本放在别的机器上,这样某台机器宕机,只不过是Partition其中一个副本丢失。

如果某个Partition有多副本的话,Kafka会选举其中一个Parititon副本作为Leader,然后其他的Partition副本是Follower。

只有Leader Partition是对外提供读写操作的,Follower Partition就是从Leader Partition同步数据。

一旦Leader Partition宕机了,就会选举其他的Follower Partition作为新的Leader Partition对外提供读写服务,这不就实现了高可用架构了?

大家看下面的图,看看这个过程。

在这里插入图片描述

四、Kafka写入数据丢失问题

现在我们来看看,什么情况下Kafka中写入数据会丢失呢?

其实也很简单,大家都知道写入数据都是往某个Partition的Leader写入的,然后那个Partition的Follower会从Leader同步数据。

但是万一1条数据刚写入Leader Partition,还没来得及同步给Follower,此时Leader Partiton所在机器突然就宕机了呢?

大家看下图:

在这里插入图片描述

如上图,这个时候有一条数据是没同步到Partition0的Follower上去的,然后Partition0的Leader所在机器宕机了。

此时就会选举Partition0的Follower作为新的Leader对外提供服务,然后用户是不是就读不到刚才写入的那条数据了?

因为Partition0的Follower上是没有同步到最新的一条数据的。

这个时候就会造成数据丢失的问题。


五、Kafka的ISR机制是什么?

现在我们先留着这个问题不说具体怎么解决,先回过头来看一个Kafka的核心机制,就是ISR机制。

这个机制简单来说,就是会自动给每个Partition维护一个ISR列表,这个列表里一定会有Leader,然后还会包含跟Leader保持同步的Follower。

也就是说,只要Leader的某个Follower一直跟他保持数据同步,那么就会存在于ISR列表里。

但是如果Follower因为自身发生一些问题,导致不能及时的从Leader同步数据过去,那么这个Follower就会被认为是“out-of-sync”,从ISR列表里踢出去。

所以大家先得明白这个ISR是什么,说白了,就是Kafka自动维护和监控哪些Follower及时的跟上了Leader的数据同步。


六、数据如何保证不丢失?

所以如果要让写入Kafka的数据不丢失,你需要要求几点:

  1. 每个Partition都至少得有1个Follower在ISR列表里,跟上了Leader的数据同步
  2. 每次写入数据的时候,都要求至少写入Partition Leader成功,同时还有至少一个ISR里的Follower也写入成功,才算这个写入是成功了
  3. 如果不满足上述两个条件,那就一直写入失败,让生产系统不停的尝试重试,直到满足上述两个条件,然后才能认为写入成功
  4. 按照上述思路去配置相应的参数,才能保证写入Kafka的数据不会丢失

好!现在咱们来分析一下上面几点要求。

第一条,必须要求至少一个Follower在ISR列表里。

那必须的啊,要是Leader没有Follower了,或者是Follower都没法及时同步Leader数据,那么这个事儿肯定就没法弄下去了。

第二条,每次写入数据的时候,要求leader写入成功以外,至少一个ISR里的Follower也写成功。

大家看下面的图,这个要求就是保证说,每次写数据,必须是leader和follower都写成功了,才能算是写成功,保证一条数据必须有两个以上的副本。

这个时候万一leader宕机,就可以切换到那个follower上去,那么Follower上是有刚写入的数据的,此时数据就不会丢失了。

在这里插入图片描述

如上图所示,假如现在leader没有follower了,或者是刚写入leader,leader立马就宕机,还没来得及同步给follower。

在这种情况下,写入就会失败,然后你就让生产者不停的重试,直到kafka恢复正常满足上述条件,才能继续写入。

这样就可以让写入kafka的数据不丢失。


七、总结

最后总结一下,其实kafka的数据丢失问题,涉及到方方面面。

譬如生产端的缓存问题,包括消费端的问题,同时kafka自己内部的底层算法和机制也可能导致数据丢失。

但是平时写入数据遇到比较大的一个问题,就是leader切换时可能导致数据丢失。所以本文仅仅是针对这个问题说了一下生产环境解决这个问题的方案。

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

面试官让我聊聊 MQ 的数据丢失问题,没想到水这么深。。。 的相关文章

  • 解决无法对docker容器进行端口映射的问题

    初学docker的时候 xff0c 不知道为啥 xff0c 按着教程里打的代码 xff0c 最后却出现了映射失败的情况 即 xff1a 在docker内部设置的映射端口 xff0c 外部却没有办法访问 想了想 xff0c 不外乎两个原因 x
  • K8s手工创建kubeconfig

    我们通过 kubectl 命令行连接 k8s apiserver 时需要依赖 kubeconfig 文件 kubeconfig 文件通常包含了 context xff08 上下文 xff09 列表 xff0c 每个 context 又会引用
  • grep命令总结

    grep命令总结 1 关于 nbsp ps ef grep php grep v grep wc l grep v grep 代表在查询的最终结果中去掉grep命令本身 wc l 标示统计查询到的结果数量 grep常用命令 1 grep n
  • Ubuntu 16.04安装realsense D435i SDK以及realsense-ros

    先直接上一个报错信息 xff0c 折腾了半天才解决 在使用catkin make编译realsense ros时 xff0c 报错 traversing 4 packages in topological order realsense c
  • 关于视觉SLAM的一些常识(纯小白学习笔记)

    本文只是小白对于视觉slam的一个非常泛的介绍 xff0c 对于视觉slam中的数学运算均没有提及 xff0c 适合于对没有接触过视觉slam的新人进行一个简单的科普 作者即小白 xff0c 文章如有错误 xff0c 非常非常非常欢迎指正
  • 使用CubeMX快速搭建FREERTOS

    如何使用STM32快速搭建FREERTOS 小编之前一直使用正点原子家的产品 xff0c 最近准备学习学习TOUCHGFX 要用到HAL 43 RTOS 原子家的使用起来不方便 于是琢磨着使用STM32CUBEMX直接生成FREERTOS
  • 使用DMA+SPI驱动Aliyun Things 上的ST7789H2 LCD屏幕

    目录 前言硬件CUBEMX时钟树GPIOSPI 代码部分LCD驱动中断服务函数测试代码现象 前言 1 xff1a 驱动程序参考自https blog csdn net BearPi article details 104311705 2 x
  • SLAM测试5-YGZ-Stereo-Inertial(GAAS双目视觉ygz -立体惯性SLAM)

    这篇主要测试GAAS开源无人机里用到的一种SLAM算法 xff0c 目的是先对该SLAM算法进行熟悉 xff0c 再开始入手GAAS视觉定位 GIThub上的代码地址为 xff1a https github com gaoxiang12 y
  • Linux之线程条件变量cond

    概念 xff1a 条件变量不是锁 xff0c 要和互斥量组合使用 条件变量就是生产者 生产 完成 xff0c 消费者才能 使用 xff0c 如果没有 产品 xff0c 消费者就会被条件变量cond阻塞等待生产者 生产 xff08 生产者与消
  • Linux之线程-信号量sem_*

    1 概念 信号量可理解为进化版的互斥锁 量 xff0c 允许多个线程访问共享资源 由于互斥锁的力度比较大 xff0c 如果希望在多个线程间对某一对象的部分数据进行共享 xff0c 使用互斥锁是没有办法实现的 xff0c 只能将整个数据对象锁
  • 4、树(中篇)

    前言 前节二叉树只能适用于静态查找 不能实现动态插入 删除等 如何解决以下两个问题 静态查找与动态查找 针对动态查找 数据如何组织 4 1 二叉搜索树 4 1 1 什么是二叉搜索树 二叉搜索树 BST Binary Search Tree
  • SNMP源码分析

    源码下载 http www net snmp org download html 源码目录结构 net snmp程序逻辑 xff08 1 xff09 main主函数 span class token macro property span
  • SNMP Trap的session问题

    1 前言 最近遇到了个问题 xff0c SNMPv3 Trap上报 xff0c 在snmp agent侧修改了用户密码 xff0c 管理站mibbroswer上没有修改trap用户的密码 xff0c 仍然可接收到trap上报消息 通过Wir
  • Rancher RKE K8s 集群 etcd 恢复

    背景 在 Rancher 中基于 RKE 创建的 K8s 集群 xff0c 因为服务器磁盘故障 xff0c 导致 3个 master 节点有2个节点的 etcd 数据文件损坏 xff0c 导致整个集群不可用 etcd 三个节点集群时 xff
  • PIXHAWK飞控固件及代码基础介绍

    PIXHAWK飞控 xff1a 固件 xff1a 开源固件PIXHAWK 软件 xff1a 两套固件代码 xff08 1 xff09 原生固件代码PIX4 xff0c 地面站采用QGC xff08 界面比较合理清晰 xff0c 易做修改 x
  • GAAS 无人机自动驾驶学习(01-使用机载电脑,通过OFFBOARD模式进行控制飞行)

    原文网址 xff1a https gaas gitbook io guide wu ren ji zi dong jia shi xi lie offboard kong zhi yi ji gazebo fang zhen 介绍 xff1
  • 2020-10-30

    Ubuntu nvidia显卡驱动安装 手动安装 xff1a 先在官网下载本机显卡对应支持的驱动 xff0c 一般选择run文件 xff1b 如果开启了nouveau驱动 xff0c 需要禁用 xff1b 进入tyy3命令行窗口 xff0c
  • Baxer双臂机器人Ubuntu20.04+ROS noetic开发环境配置

    目录 前言 一 新建ROS工程及初始化编译 二 在Baxter的工作空间对setup bash文件进行source 编辑 三 安装Baxter SDK 四 测试 编辑 总结 前言 Baxter simulator由ReThink Robot
  • Baxter的Gazebo仿真环境搭建

    注 xff1a 这是一篇配置失败的文章 xff0c 原因是Ubuntu20 04不支持Qt4 xff0c catkin make通不过 xff0c 不是20 04的可以尝试一下 xff0c 或者有大神能不能帮忙看下在ubuntu20 04装

随机推荐