1,浅析音讯队列面经
这里咱们通过解说一些常见的面试题和其变种的问法来相熟音讯队列中的一些外围的概念,而后深挖其中知识点,以此来进行拓展,在这个文档中最好只是做简略但确的总结性质的语言来讲述,其余残缺的答复,依据相应的模块整顿起来即可:
1.1,音讯队列利用场景?
- 为什么应用音讯队列?
- 应用音讯队列有哪些益处和害处?
- 音讯队列的优缺点?
1.2,常见的音讯队列有哪些,以及他们的比照?
- MQ 的技术选型?
- 1.3,音讯模型有哪些?
- 1.4,MQ 框架是如何实现高吞吐量的?
- 2.1,如何解决 MQ 的音讯失落?
2.2,如何解决音讯的反复生产?
- ExactlyOnce 语义?
- 音讯的幂等性?
- 反复呈现的起因是什么?
- 2.3,如何保障 MQ 的音讯是有序的?
- 3,如果呈现音讯积压,应该怎么办?
- 4,如何保证数据的一致性问题?
- 5,事务音讯是如何实现的?
- 6,MQ 框架如何做到高可用?
(1), 音讯队列利用场景?
音讯队列中的一些其余的特点等信息须要查看另外的文档,做了具体的整顿。
- 异步解决:将一个申请链路中的非核心流程,拆分进去,异步解决,缩小主流程链路的解决逻辑,晋升吞吐量。
- 限流消峰:能够通过音讯队列长度管制申请量;能够缓解短时间内的高并发申请。广泛应用于秒杀或抢购流动中,防止某一刻流量过导致利用零碎挂掉的状况;
- 利用解耦:多利用通过音讯队列对同一音讯进行解决,防止调用接口失败导致整个过程失败;
- 音讯通信:音讯队列中内置了高效的通信机制,因而也能够用在纯的音讯通信。比方实现点对点音讯队列,或者聊天室等。
- 日志解决:解决大量的日志传输
(2), 常见的几种音讯队列,以及技术选型?
-
常见的音讯队列:
- RabbitMQ
- Kafka
- RocketMQ
- … …
-
技术选型,次要能够通过以下几个维度:
- 以后零碎中次要技术栈,以及团队中对哪个框架更加相熟;
- 数据的吞吐量(Kafka)
- 对事务支持性(RabbitMQ)
- 社区的沉闷水平
- … …
(3), 如何解决音讯的反复生产?
-
1,首先剖析音讯队列自身都是保障的 ” 至多一次(At least Once)” 的语义,所以如果要通过 MQServer 配置和业务代码配合来解决。
另外其余几种常见的语义,咱们须要保障
Exactly Once
语义。- 最多一次(At most once)
- 至多一次(At least once)
- 仅一次(Exactly once)
-
2,剖析呈现反复生产起因
-
(1),生产者发送了反复的音讯:
个别为了保障音讯的可靠性,生产者在发送了信息后须要期待 Broker 的响应,此时如果呈现网络稳定等状况,响应超出了工夫之后,会导致数据的反复发送,
-
(2),消费者在生产音讯的反复的:
当消费者在生产音讯的时候,尽管根本的业务逻辑曾经走完了,然而在提交 Offset 的时候,消费者服务挂了,那么这条被生产然而没有被提交的音讯会发送到其余消费者中,导致这条音讯被反复生产。
- (3),补充“幂等性”的概念:艰深的说,同样的接口或者数据去调用同一个接口的时候,无论反复调用多少次,总能保证数据的正确性,不能出错,这里特指的是接口的幂等性。
-
-
3,解决反复的生产的问题
-
(1), 基于业务侧的调整:
- 生产者:能够在发送音讯的时候,增加一个惟一的字段,在插入数据的时候在数据库中进行惟一校验即可;然而这样在肯定的水平上会影响数据库的性能,个别是须要强测验的场景中会应用。
- 消费者:首先是开始 手动提交 Offset,独自创立一个生产记录表,将提交 Offset、执行插入动作的 sql 和插入生产记录表惟一 key 的操作都放在同一个 事务 中,那么当插入之前先判断这个惟一的 key 是否曾经在生产记录表中,只有不存在的才持续生产。
-
(4), 如果呈现音讯积压,应该怎么办?
-
1,剖析:呈现音讯积压个别是是音讯的生产速度比不上生产的速度,从而导致了音讯沉积。
-
(1), 导致呈现音讯积压的状况可能有以下集中状况:
- 磁盘写满了,导致数据写入磁盘的时候无奈写入,进而导致的音讯的积压。
- 数据写入 MySQL,然而此时 MySQL 的服务呈现了异样,也可能间接服务 down 掉等等,导致的音讯积压。
- 有可能是因为程序中某步操作时时候,线程耗时过长,导致的音讯沉积
-
-
2,解决办法:
-
消费者:
-
(1), 能够适当减少消费者组的机器数量,以晋升整体的生产能力;如果是线上的紧急任务,咱们能够通过创立一个 Topic,Partition 是原来的十倍,而后长期写一个 Consumer 程序,并启动多个线程去进行生产,生产的数据只是长期存储,期待解决生产完积压的数据之后,复原原先部署的架构,从新用原先 Consumer 机器来生产音讯。
如果能够的话,尽量保留局部现场环境,便于排查生产能力降落的起因。
- (2), 排查出问题之后,咱们不仅要解决问题,也要对集群的生产能力再进行一次评估,防止是因为生产能力不够引起的音讯沉积,尤其是针对一些顺发的流量,比方大促流动之类的。
- (3), 优化每条音讯的生产过程,从业务的角度思考优化。
-
- 生产者:生产者要能及时感知到消费者的能力有余,呈现音讯积压的时候,能够适当放缓音讯放入的速度,能够间接给前端页面提醒排队等等。
-
-
3,补充:数据积压的工夫太长了,导致是音讯队列中设置了过期工夫的的数据失落问题
答:如果呈现音讯的失落问题,想方法找到失落的局部数据,从新发送到 MQ 集群里。
(5), 如何保证数据的一致性问题?
对于数据的一致性问题,这里通过“解耦”场景举例:比方电商场景中,下单胜利之后,再告诉库房扣减库存。
那么这个时候,咱们在同一个事务空间中,先解决下单的数据库操作,而后发送 MQ 音讯;剩下的扣减库存的操作交给消费者进行。
另外在生产的环节,也可能会呈现数据不统一的状况,那么咱们能够采纳最终一致性准则,减少重试的机制。
(6),MQ 框架是如何实现高吞吐量的?
- 音讯能够批量解决
- 对音讯体进行压缩,从而节俭传输的带宽和存储空间
- 程序写入磁盘(Kafka):每个分区内是有序的。
- 零拷贝(Kafka):间接在内核层将音讯的内容传递给网络 Socket,从而防止了应用层之间的拷贝。
- 采纳页缓存(Page Cache),应用操作的零碎的内存,而不是应用 JVM 的内存,可能防止占用堆内存和 GC 问题。
- 采纳分区的设计,在每个分区中放弃是有序的,另外每个分区能够针对不同的机器生产信息,能够用于并发解决。
(7),MQ 事务音讯是如何实现的?
这里的实现形式相似于“两阶段提交”,在 MySQL 的事务中也是解决的。
2,浅析 Kafka 面试题
(1),Kafka 为什么不反对读写拆散?
如果应用读写拆散的策略,必然会有主和正本之间数据同步,要保障其一致性,另外正本在同步的时候如何保障实时性。
- 数据一致性:如果采纳一主多从的形式,Leader 正本的数据在同步到 Follower 正本的时候会存在肯定的提早,那么 Follower 正本的音讯位移也不一样,然而消费者须要通过生产位移来管制音讯拉取的进度,多个正本之间要保护对立生产位移的一致性。那么如果要解决这个问题,就须要引入分布式锁,保障锁的平安,十分消耗性能。
- 实时性:如果网络提早比拟大,在同步的过程中难免会影响效率,从而可能无奈满足实时性业务的需要。
(2),MQ 如何实现高可用?
这里间接以 Kafka 举例的,其余根本是相似的。
简略来说,就是几个节点之间,选举出主节点 (Leader),那么这个时候如果主节点宕机了,能够从其余的节点中进行从新选举。另外每个节点在保留的数据的时候,会在从节点(Follower) 中保留相应的正本,通过多正本机制,又是另一个高可用的体现。
(3), 如何保障 MQ 的音讯是有序的?
这里的解说次要是以 Kafka 为例进行解说的。
- 形式 1,能够强制只有一个分区,那么在一个分区中就是有序的,那么整体就是有序的。然而只有一个分区 kafka 的吞吐量就不高了。
-
形式 2,从业务的角度思考,能够通过自定义分区的策略 (
org.apache.kafka.clients.Partitioner
) 将满足指定规定的数据存储在同一个分区中,从而实现有序:- (1), 比方,同一个订单的不同状态的音讯存储在同一个分区中
- (2), 或者,同一个登录的用户的各类操作存储在同一个分区中
(4), 如何解决 MQ 的音讯失落?
这里是针对 Kafka 进行剖析的,其余的框架也会有相似的:
-
1,剖析可能呈现音讯失落的几种状况:
- (1),音讯队列自身:在写数据的过程中,咱们如果只保障写入 Leader 节点,而不论正本是否同步胜利就算写入胜利的话,这种状况下是存在单点故障的,即如果 Leader 节点挂了那么就会呈现失落数据的状况;
- (2),生产者:因为网络的提早,导致数据呈现发送失败状况,也能够了解为数据失落的一种状况;
- (3),消费者:应用主动提交 Offset 的形式,会呈现数据在解决实现之前就把 Offset 提交了,这样也会呈现数据失落的状况;
-
2,针对以上几种状况提出具体的解决方案:
-
生产者:
- (1), 配置
acks=1 或者 acks=all
参数,在 Leader 节点写入胜利之后,将音讯同步到正本列表中 - (2), 数据发送失败了之后,能够指定重试 (
retries
) 的次数,在一些强校验的场景下能够设置为 Integer.MAX_VALUE
- (1), 配置
-
能够从 Broker 的角度思考:
保障消费者生产到数据之后,再删除 Broker 中的暂存的信息。
如果是 kafka 的话,在 Broker 层面,应用到了
ISR 列表 + HW 高水位 + Leader Epoch
来避免数据失落。 -
消费者端:
敞开主动提交,依据回调函数正当解决音讯,并手动提交 Offset。
-
(5), 补充一些常见的面试题
这里次要是题目形容一下,而后简答写一些答复的关键字。
墙裂举荐大家仔细阅读,并能够关注其公众号。:从面试角度一文学完 Kafka
1), 什么是分布式消息中间件?
简略说是一个音讯流的管道。
2), 消息中间件的作用是什么?
解耦、异步、削峰。
3), 消息中间件的应用场景是什么?
除了上述抽象的说法,从理论的业务中形容的话,能够用在一些秒杀的场景中、两个零碎的耦合性太高的话,能够去做拆分。
4), 消息中间件选型?
次要看业务场景是谋求数据的可靠性(事务),还是谋求吞吐量。
5), 简略讲下 Kafka 的架构?
生产者 –> Broker 集群(Topic、Partition(Leader、Follower)、Zookeeper 集群) –> 消费者
6),Kafka 中 Zookeeper 的作用?
起到一个注册核心的作用,其自身也是一个分布式的集群管理工具,次要的作用便是治理集群、负责 Leader 节点的选举;
Zookeeper 是怎么作用 Leader 选举的?
相似与 FIFO,也就是先到先得;另外如果主节点挂掉了之后,会从 Follower 节点中从新进行一轮筛选。
了不理解 Zab 协定?
原子·解体协定 :其中的 原子 ,是指原子播送协定,用来保障 Server 之间的同步,从而保证数据的一致性; 解体,是指反对解体复原,即如果呈现服务器宕机重启之后,从新选举主节点,同时 Follower 节点与 Leader 节点的同步,来实现解体复原。
Zookeeper 存储形式?
基于 ACL 的策略管制形式实现树状的存储,另外他是存储在内存中,并以此来保障高吞吐和低提早。
7),Kafka 是推模式还是拉模式,推拉的区别是什么?
生产者是推模式,消费者是拉模式;
区别的话,次要就是一个被动拉取数据,另一个是被动接收数据把,通过被动拉取数据的形式能够本人治理生产的 Offset,从而进步可控性和读取的性能。
8),Kafka 的 Offset 是什么?
这里的 Offset 即音讯的位移,或者说是偏移量,其本质上是有两种含意:
一是,Broker 当中最新消息的 Offset 的值;
二是,消费者生产到了哪一条的数的 Offset 的值。
9),Kafka 如何播送音讯?
播送 是指发送音讯给所有的消费者,也就是消费者组的概念。
同一条音讯只能被同一个消费者组中一个消费者生产,然而能够被多个消费者组同时生产。
10),Kafka 的音讯是否是有序的?
Topic 是无序的,然而每个分区内是有序的。
11),Kafka 是否反对读写拆散?
不反对,所有的读写操作都在 Leader 节点上;
Follower 节点做镜像节点,负责同步和备份数据,当主节点 Down 掉后,会从 Follower 节点中从新选举主节点,从而实现 HA;
12),Kafka 如何保障高可用?
高可用体现在集群的高可用和数据的高可用两个方面:
- 集群的高可用体现 Leader 节点在 Down 之后能够从新从 Follower 节点中从新抉择;
数据的高可用体现在“多正本机制”、“ISR 列表”、“HW”、“Leader Epoch”
- 通过配置 acks=all 实现多个正本都复制胜利的时候才算数据接管胜利;
- ISR 列表指的是达到数据同步规范的 Follower 节点;
- HW 是 High Water Mark 高水位,避免消费者读到未同步的数据;
Leader Epoch 是解决的 HW 错位导致的数据不统一的问题:
- 1,Epoch:是一个枯燥递增的版本号;
- 2,Start Offset:是咱们下一次须要从哪开始拜访的位移;
13), 是否反对事务?
在 0.11 之后是反对事务的。
14), 分区数是否能够缩小?
不能啊,会导致数据失落。
15),Kafka 有哪些命令行工具?你用过哪些?
/bin 目录下的脚本文件;
治理 kafka 集群、治理 topic、模仿生产者和消费者等等
16),Kafka Producer 的执行过程?
1,Producer 生产音讯 –> 2,从 Zookeeper 找到 Partition 的 Leader –> 3,推送音讯 –> 4,通过 ISR 列表告诉给 Follower –> 5,Follower 从 Leader 拉取音讯,并发送 ack –> 6,Leader 收到所有正本的 ack,更新 Offset,并向 Producer 发送 ack,示意音讯写入胜利。
17),Kafka Producer 有哪些常见配置?
acks 的配置 (
acks=all
)、异样重试的配置(retries
)、晋升音讯吞吐量(设置缓冲区的大小、开启消息压缩(compression.typ
)) 的配置
18), 如何让 Kafka 的音讯有序?
Kafka 在 Topic 级别自身是无序的,只有 partition 上才有序,所以为了保障解决程序,能够自定义分区器,将需程序解决的数据发送到同
19), 一个 Partition Producer 如何保证数据发送不失落?
ack 机制(
acks=all
),重试机制
20), 如何晋升 Producer 的性能?
批量,异步,压缩
21), 如果同一 group 下 consumer 的数量大于 part 的数量,kafka 如何解决?
多余的 consumer 将处于无用状态,不生产数据。
22),Kafka Consumer 是否是线程平安的?
不平安;所以在 Consumer 端采纳的是 单线程生产,多线程解决
23), 讲一下你应用 Kafka Consumer 生产音讯时的线程模型,为何如此设计?
Thread-Per-Consumer Model,这种多线程模型是利用 Kafka 的 topic 分多个 partition 的机制来实现并行:每个线程都有本人的 consumer 实例,负责生产若干个 partition。各个线程之间是齐全独立的,不波及任何线程同步和通信,所以实现起来非常简单。
其余的详细信息能够看上述连贯;
24),Kafka Consumer 的常见配置?
心跳工夫的配置、一次 Poll 返回数据的最大条数、是否主动提交位移 等等
25),Consumer 什么时候会被踢出集群?
解体,网络异样,解决工夫过长提交位移超时
26), 当有 Consumer 退出或退出时,Kafka 会作何反馈?
进行 Rebalance
27), 什么是 Rebalance,何时会产生 Rebalance?
组成员发生变化;
订阅的主题产生变更;
定于主题的分区数产生变更;
28),Kafka 的交付语义?
- at most once:最多一次,即不会产生反复数据,但可能会丢数据
- at least once:至多一次,即可能会产生反复数据,但不会丢数据
- exactly once:精确的一次,不多也不少
29),Replic 的作用?
通过 Replic(正本)来保证数据的高可用性
30), 为什么 Follower 正本不提供读服务?
这个问题,实质上来说是对性能和一致性的取舍。假如 follower 也提供读写服务,固然会进步性能,然而同时也会呈现相似于数据库中幻读、脏读等问题。呈现这一状况,次要是因为他们之间的同步的不肯定是完全一致的。
31),Leader 和 Follower 是什么?
Partition 分区中,分为两种节点:Leader、Follower,这两者之间是主备关系,当 Leader 节点挂了的时候,会通过抉择在 Follower 节点中生成新的 Leader 节点。
- Leader:所有的读写操作都产生在 Leader 分区上。
- Follower:所有的 Follower 节点都须要从 Leader 节点上同步音讯,并做为 Leader 的备份节点。
32), 什么是 AR,ISR?
AR:All Replication,所有调配的正本列表
ISR:In-Sync Replication 治理的 Follower 正本同步的列表,咱们会配置一个可容忍的提早数量,只有大于等于这个数量的 Follower 才会进入到 ISR 列表中,同时如果 Leader 节点挂掉之后,会从 ISR 列表中从新选举新的 Leader。
33),Kafka 中的 LSO、LEO、LW、HW 等别离代表什么?
LSO:是
log Start Offset
,示意第一音讯的 offsetLEO:是
Log End Offset
日志末端位移的概念,指的是每个正本最初一个 offset + 1LW:是
Low Watermark
的缩写,俗称“低水位”,代表 AR 汇合中最小的 logStartOffset 值HW:是
High Watermark
的缩写,俗称“高水位”,指的是消费者能见到的最大的 offset,ISR 列表中最小的 LEO。
35),Kafka 为保障优越的性能做了哪些解决
- Partition 并发
- 程序读写磁盘:每个分区文件在本地履行分段 (Segment) 存储,每个段都采纳 append 追加的形式存储。
- 零拷贝:是指缩小了一次数据从内核区到用户缓冲区的拷贝。
- PageCache:页缓存
- 批量读写
- 消息压缩
3,餐饮零碎音讯队列利用专题剖析
本局部的整顿内容是来自《苏三说技术 - 我用 kafka 两年踩过的非比寻常的坑》,墙裂举荐大家仔细阅读,并能够关注其公众号。
-
1,保障音讯的程序性,这里一个订单的不同状态举例:
阐明:比方“下单”->“领取”->“实现”->“撤销”等,须要保障不能呈现,“下单”的音讯还没有读到,就先读到“领取”或者“撤销”的音讯吧,所以是有必要保障音讯的 有序性 的。
理论解决:通过每一个
订单编号
路由到同一个Partition
分区中,而后部署雷同分区数的消费者节点,从而一个分区对应一个消费者节点,从而保障同一个订单的不同状态的音讯是有序的。 -
2,尽管写入同一个分区是能够保障有序的,然而如果呈现网络超时的状况,导致“下单”的音讯始终没有发送胜利,然而收到了“领取”的订单音讯,那么这个时候,一来音讯是错乱的,二是没有下单信息,页面中无奈显示残缺的音讯。
理论解决:根底的想法是采纳 重试 的机制
- (1), 同步重试:在生产信息的时候,呈现网络失败等状况,立马重试 3~5 次;然而这样会重大的影响消费者的生产速度,升高他的吞吐量。
-
(2), 异步重试:将失败的音讯保留在 重试表 中,而后有个定时工作一直的拉取重试:
Todo:
1,这里是须要补充重试表得设计规定,以及相干数据是如何保留的,是否须要搁置在同一个事务中解决。
2,对于一些常见重试的理论编程,比方
spring-retry
的应用3,对于
elastic-job
的应用消费者在解决音讯的时候,首先判断以后的订单号是否在重试表中,如果存在,则执行将以后音讯保留在重试表中;如果没有,再失常进行业务解决,当呈现了异样的时候,才把音讯保留在重试表中。
补充:另外博文中提到:起初应用用
elastic-job
建设了 失败重试机制,如果重试了 7 次后还是失败,则将该音讯的
状态标记为 失败,发邮件告诉开发人员。
-
3,解决音讯积压的问题:
在业务中将音讯积压的问题体现很显著,后盾厨房可能很长一段时间看不到客户下的单据,就会导致餐品上的不及时。
-
(1), 从磁盘网络传输的角度登程:音讯在传输的过程中如果音讯体的内容过多,导致音讯的多,无论是在网络的传输还是数据落地到磁盘,再从磁盘中获取这两个方面思考,效率都是低下的。
理论解决:
- 1), 订单零碎发送的音讯中只蕴含:订单 id、状态等要害的信息。
- 2), 后厨显示零碎在生产到信息之后,通过 id 去查问订单零碎对应的置信数据(存在两个服务之间的近程调用)。
- 3), 后厨零碎中判断数据库是否有该订单的数据,如果有则更新,没有则间接入库(同时能够避免出现音讯反复生产的状况)。
- (2), 留神查看路由规定设计是否正当
- (3), 对于高并发的设计要正当的应用线程池
- (4), 对于单表的数据量如果过大,能够依据理论的状况进行分表处理即可。
-
-
4,数据库的主从复制
最常见的形式就是在发现处从复制的有肯定的提早的时候,告诉 DBA 进行解决,同时业务数据在查问不到后果的时候,将对应的查问 id 落地到重试表中,进行相干的重试操作。
-
5,数据的反复生产问题:
在以后场景下是在插入保留的时候,须要保障是幂等的。于是能够在保留数据的时候应用
insert into ... on duplicate key update
管制存在的时候更新,不存在的时候插入。
参考连贯
1,MQ 那点破事!音讯失落、反复生产、生产程序、沉积、事务、高可用 ….
2,MQ 音讯队列的反复生产问题的通用解决办法以及幂等性的原理
3,苏三说技术 - 我用 kafka 两年踩过的非比寻常的坑
4,从面试角度一文学完 Kafka
首先很感激一些博主的分享,也代表着本文局部参考其余博主的一些文档,如果有侵权,还请及时揭示,我会踊跃配合!!谢谢您~~~
“本文参加了 SegmentFault 思否征文「如何“反杀”面试官?」,欢送正在浏览的你也退出。”