前言

在本文开始之前,作者一直有个疑惑,就是面试题是只写写问题和答案就草草了事,还是应该深入分析一下其背后发生的一些原理。和朋友探讨以后作者还是决定采用后者的方式,因为我认为不仅要做到知其一,更要知其二,所以我们就用讲解原理的方式来看看 Kafka 常见的面试题吧。另外避免文章过长,我打算接下来使用几篇文章来详解每道题背后的原理。好了废话有点多,直接开干。

文章概览

  • kafka 如何保证数据的可靠性和一致性?

  • kafka 为什么那么快?

  • Kafka 中的消息是否会丢失和重复消费?

  • 为什么要使用 kafka,为什么要使用消息队列?

  • 为什么 Kafka 不支持读写分离?

kafka 如何保证系统的高可用、数据的可靠性和数据的一致性的?

kafka 的高可用性:

  1. Kafka 本身是一个分布式系统,同时采用了 Zookeeper 存储元数据信息,提高了系统的高可用性。

  2. Kafka 使用多副本机制,当状态为 Leader 的 Partition 对应的 Broker 宕机或者网络异常时,Kafka 会通过选举机制从对应的 Replica 列表中重新选举出一个 Replica 当做 Leader,从而继续对外提供读写服务(当然,需要注意的一点是,在新版本的 Kafka 中,Replica 也可以对外提供读请求了),利用多副本机制在一定程度上提高了系统的容错性,从而提升了系统的高可用。

Kafka 的可靠性:

  1. 从 Producer 端来看,可靠性是指生产的消息能够正常的被存储到 Partition 上且消息不会丢失。Kafka 通过 request.required.acksmin.insync.replicas 两个参数配合,在一定程度上保证消息不会丢失。

  2. request.required.acks 可设置为 1、0、-1 三种情况。

request.required.acks=1

设置为 1 时代表当 Leader 状态的 Partition 接收到消息并持久化时就认为消息发送成功,如果 ISR 列表的 Replica 还没来得及同步消息,Leader 状态的 Partition 对应的 Broker 宕机,则消息有可能丢失。

request.required.acks=0

设置为 0 时代表 Producer 发送消息后就认为成功,消息有可能丢失。

request.required.acks=-1

设置为-1 时,代表 ISR 列表中的所有 Replica 将消息同步完成后才认为消息发送成功;但是如果只存在主 Partition 的时候,Broker 异常时同样会导致消息丢失。所以此时就需要min.insync.replicas参数的配合,该参数需要设定值大于等于 2,当 Partition 的个数小于设定的值时,Producer 发送消息会直接报错。

上面这个过程看似已经很完美了,但是假设如果消息在同步到部分从 Partition 上时,主 Partition 宕机,此时消息会重传,虽然消息不会丢失,但是会造成同一条消息会存储多次。在新版本中 Kafka 提出了幂等性的概念,通过给每条消息设置一个唯一 ID,并且该 ID 可以唯一映射到 Partition 的一个固定位置,从而避免消息重复存储的问题(作者到目前还没有使用过该特性,感兴趣的朋友可以自行在深入研究一下)。

Kafka 的一致性:

  1. 从 Consumer 端来看,同一条消息在多个 Partition 上读取到的消息是一直的,Kafka 通过引入 HW(High Water)来实现这一特性。

消息同步图

从上图可以看出,假设 Consumer 从主 Partition1 上消费消息,由于 Kafka 规定只允许消费 HW 之前的消息,所以最多消费到 Message2。假设当 Partition1 异常后,Partition2 被选举为 Leader,此时依旧可以从 Partition2 上读取到 Message2。其实 HW 的意思利用了木桶效应,始终保持最短板的那个位置。

从上面我们也可以看出,使用 HW 特性后会使得消息只有被所有副本同步后才能被消费,所以在一定程度上降低了消费端的性能,可以通过设置replica.lag.time.max.ms参数来保证消息同步的最大时间。

kafka 为什么那么快?

kafka 使用了顺序写入和“零拷贝”技术,来达到每秒钟 200w(Apache 官方给出的数据) 的磁盘数据写入量,另外 Kafka 通过压缩数据,降低 I/O 的负担。

  1. 顺序写入

大家都知道,对于磁盘而已,如果是随机写入数据的话,每次数据在写入时要先进行寻址操作,该操作是通过移动磁头完成的,极其耗费时间,而顺序读写就能够避免该操作。

  1. “零拷贝”技术

普通数据拷贝流程图

普通的数据拷贝流程如上图所示,数据由磁盘 copy 到内核态,然后在拷贝到用户态,然后再由用户态拷贝到 socket,然后由 socket 协议引擎,最后由协议引擎将数据发送到网络中。

"零拷贝"流程图

采用了“零拷贝”技术后可以看出,数据不在经过用户态传输,而是直接在内核态完成操作,减少了两次 copy 操作。从而大大提高了数据传输速度。

  1. 压缩

Kafka 官方提供了多种压缩协议,包括 gzip、snappy、lz4 等等,从而降低了数据传输的成本。

Kafka 中的消息是否会丢失和重复消费?

  1. Kafka 是否会丢消息,答案相信仔细看过前面两个问题的同学都比较清楚了,这里就不在赘述了。

  2. 在低版本中,比如作者公司在使用的 Kafka0.8 版本中,还没有幂等性的特性的时候,消息有可能会重复被存储到 Kafka 上(原因见上一个问题的),在这种情况下消息肯定是会被重复消费的。

这里给大家一个解决重复消费的思路,作者公司使用了 Redis 记录了被消费的 key,并设置了过期时间,在 key 还没有过期内,对于同一个 key 的消息全部当做重复消息直接抛弃掉。 在网上看到过另外一种解决方案,使用 HDFS 存储被消费过的消息,是否具有可行性存疑(需要读者朋友自行探索),读者朋友们可以根据自己的实际情况选择相应的策略,如果朋友们还有其他比较好的方案,欢迎留言交流。

为什么要使用 kafka,为什么要使用消息队列?

先来说说为什么要使用消息队列?

这道题比较主观一些(自认为没有网上其他文章写得话,轻喷),但是都相信大家使用消息队列无非就是为了 解耦异步消峰

系统调用图

随着业务的发展,相信有不少朋友公司遇到过如上图所示的情况,系统 A 处理的结构被 B、C、D 系统所依赖,当新增系统 E 时,也需要系统 A 配合进行联调和上线等操作;还有当系统 A 发生变更时同样需要告知 B、C、D、E 系统需要同步升级改造。

引入消息队列图

引入消息队列后有两个好处:

  1. 各个系统进行了解耦,从上图也可以看出,当系统 A 突然发生热点事件时,同一时间产生大量结果,MQ 充当了消息暂存的效果,防止 B、C、D、E 系统也跟着崩溃。

  2. 当新系统 E 需要接入系统 A 的数据,只需要和 MQ 对接就可以了,从而避免了与系统 A 的调试上线等操作。

引入消息队列的坏处:

万事皆具备两面性,看似引入消息队列这件事情很美好,但是同时也增加了系统的复杂度、系统的维护成本提高(如果 MQ 挂了怎么办)、引入了一致性等等问题需要去解决。

为什么要使用 Kafka?

作者认为采用 Kafka 的原因有如下几点:

  1. Kafka 目前在业界被广泛使用,社区活跃度高,版本更新迭代速度也快。

  2. Kafka 的生产者和消费者都用 Java 语言进行了重写,在一定程度降低了系统的维护成本(作者的主观意见,因为当下 Java 的使用群体相当庞大)。

  3. Kafka 系统的吞吐量高,达到了每秒 10w 级别的处理速度。

  4. Kafka 可以和很多当下优秀的大数据组件进行集成,包括 Spark、Flink、Flume、Storm 等等。

为什么 Kafka 不支持读写分离?

这个问题有个先决条件,我们只讨论 Kafka0.9 版本的情况。对于高版本,从 Partition 也可以承担读请求了,这里不多赘述。

Kafka 如果支持读写分离的话,有如下几个问题。

  1. 系统设计的复杂度会比较大,当然这个比较牵强,毕竟高版本的 Kafka 已经实现了。

  1. 从上图可以看出,从从 Partition 上读取数据会有两个问题。一、数据从主 Partition 上同步到从 Partition 有数据延迟问题,因为数据从生产到消费会经历 3 次网络传输才能够被消费,对于时效性要求比较高的场景本身就不适合了。二、数据一致性问题,假设主 Partition 将数据第一次修改成了 A,然后又将该数据修改成了 B,由于从主 Partition 同步到从 Partition 会有延迟问题,所以也就会产生数据一致性问题。

分析得出,通过解决以上问题来换取从 Partition 承担读请求,成本可想而知,而且对于写入压力大,读取压力小的场景,本身也就没有什么意义了。

Kafka系列9:面试题是否有必要深入了解其背后的原理?我觉得应该刨根究底(上)相关推荐

  1. 对接kafka_Kafka系列9:面试题是否有必要深入了解其背后的原理?我觉得应该刨根究底(上)...

    ​前言 在本文开始之前,作者一直有个疑惑,就是面试题是只写写问题和答案就草草了事,还是应该深入分析一下其背后发生的一些原理.和朋友探讨以后作者还是决定采用后者的方式,因为我认为不仅要做到知其一,更要知 ...

  2. Kafka系列10:面试题是否有必要深入了解其背后的原理?我觉得应该刨根究底(下)...

    前言 在今天文章开始之前,想和粉丝朋友们先分享一个好消息,作者坚持以原创的态度去努力写好每一篇文章,同时得到了一小部分粉丝朋友们的认可和 InfoQ 写作平台的支持.在此非常感谢粉丝朋友的支持,同时也 ...

  3. 大厂经典面试系列之三:唯品会大数据开发面试【建议关注收藏订阅,你早晚会用上】掌握了这些面试题,余生不在怕面试

    前言 上一篇文章总结了大厂经典面试系列之一:京东Java面试.接下来的文章我将陆续献上大厂的经典面试系列,所列的题目不代表所有,只是从面试者的口中总结的几次面试题,也是万千面试题的缩影,诣在帮助即将面 ...

  4. 2020年11个Redis系列高频面试题,哪些你还不会?

    前言 现在大家的工作生活基本已经是回归正轨了,最近也是迎来了跳槽面试季,有些人已经拿到了一两个offer了. 这段时间收集了阿里.腾讯.百度.京东.美团.字节跳动等公司的Java面试题,总结了Redi ...

  5. Kafka系列一之架构介绍和安装

    Kafka架构介绍和安装 写在前面 还是那句话,当你学习一个新的东西之前,你总得知道这个东西是什么?这个东西可以用来做什么?然后你才会去学习它,使用它.简单来说,kafka既是一个消息队列,如今,它也 ...

  6. 面试官系统精讲Java源码及大厂真题 - 34 只求问倒:连环相扣系列锁面试题

    34 只求问倒:连环相扣系列锁面试题 自信和希望是青年的特权. 引导语 面试中,问锁主要是两方面:锁的日常使用场景 + 锁原理,锁的日常使用场景主要考察对锁 API 的使用熟练度,看看你是否真的使用过 ...

  7. Kafka系列之-Kafka监控工具KafkaOffsetMonitor配置及使用

    KafkaOffsetMonitor是一个可以用于监控Kafka的Topic及Consumer消费状况的工具,其配置和使用特别的方便.源项目Github地址为:https://github.com/q ...

  8. Kafka系列之-Kafka Protocol实例分析

    本文基于A Guide To The Kafka Protocol文档,以及Spark Streaming中实现的org.apache.spark.streaming.kafka.KafkaClust ...

  9. Kafka系列 —— 生产实践分享

    Kafka系列文章: Kafka系列 -- 入门及应用场景 & 部署 & 简单测试 Kafka系列 -- Kafka核心概念 Kafka系列 -- Kafka常用命令 Kafka系列 ...

  10. Kafka系列之:增加Kafka节点扩展Kafka集群

    Kafka系列之:增加Kafka节点扩展Kafka集群 一.增加Kafka节点 二.分区重新分配工具三种工作模式 三.自动将数据迁移到新机器 四.自定义分区分配和迁移 五.增加复制因子 六.在数据迁移 ...

最新文章

  1. 【机器学习课程01】李宏毅2020年机器学习课程开课啦!!!
  2. hibernate4调用mysql存储过程_hibernate调用存储过程
  3. Spring+Spring Security+JSTL实现的表单登陆的例子
  4. c语言将链表写入二进制文件_通过逐级遍历将二进制树转换为单链表的C程序
  5. 数据科学和人工智能技术笔记 八、特征选择
  6. 基于节点类的二叉树实现及部分操作函数
  7. 关于html中利用jQuery选择子节点方法总结——待续
  8. 计算机网络同传步骤,HP网络同传使用方法Word版
  9. buck 与ldo效率
  10. android ndk standalone,Android NDK Standalone Toolchain(中文翻译)
  11. 【计算机网络】第六部分 应用层(25) 域名空间
  12. 利用反正切函数展开计算∏的近似值
  13. 光年SEO日志分析系统2.0
  14. Windows 10 资源管理器使用深色主题
  15. 神奇宝贝光是无限远服务器,Pokémon Online
  16. PX4多传感器优先级判断
  17. 抖音巨量引擎1 创建广告计划
  18. 博客园有一段时间登不上
  19. 假装搞运维,MySQL让我哭
  20. 学习 Google Gadgets (一)

热门文章

  1. 揭开股票量化投资策略的神秘面纱
  2. SSD讲堂三(视频)_SSD_tensorflow_imageio方法_视频检测_附源码
  3. AWS简介(Amazon Web Services )
  4. 【历史上的今天】10 月 27 日:世界上第一次网络瘫痪;网络广告的诞生;短视频鼻祖 Vine 关闭
  5. gstBuffer的 data 和 meta
  6. 计算机课程设计心得,课程设计心得体会450字
  7. WIFI系列协议--802.11ac--增强非常高吞吐量简称VHT--1Gbit
  8. win10 myeclipse2017安装教程(附安装包)
  9. java 自动补全_eclipse自动补全的设置
  10. phpnow 升级 php 5.4,PHPnow 升级 php 5.4 的方法