kafka和RabbitMQ

本文介绍了Kafka和RabbitMQ在消息队列中的应用,包括Kafka的日志储存、数据持久化、高可用特性以及顺序写入的高效策略。同时,讨论了RabbitMQ的发布/订阅和点对点模式,以及其集群模式的优缺点。文章还涉及面试中常见的问题,如重复消费、幂等性保证、消息丢失处理和顺序消费的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本概念

如何实现高效

使用mq主要原因:

1,解耦,主要是发布订阅模式,系统间解耦

2,异步,主要是串行改成并行,不需要等待,比如:发送邮件服务

3,削峰,主要是突然涌入大量数据,导致数据库挂掉。可以主动去拉数据。

kafka基本概念

kafka主要用于,日志储存,顺序非常严格

数据持久化,动态扩容,支持事务 ,消息自动平衡

架构基本认识:由多个Broker组成,每个Broker是一个节点,创建一个topic,一个topic分成多个partition,每个partition分布在不同的节点Broker上面

topic是逻辑概念,topic包含一个 或多个partition,不同的partition,采用顺序写入磁盘。这是重要的速度

Broker物理概念,kafka集群每个服务器节点

partition是物理逻辑,一个文件夹

比如我们给topic=test发送3条消息,可能分布在3个broker节点,每个节点一个partition上面

kafka是高可用

有副本,如果主节点挂了,还有副本,只有主节点负责读写操作,如果主节点挂了,会自动选举副节点作为主节点,达到高可用

如何实现高效

1.将写磁盘的过程变为顺序写,可极大提高对磁盘的利用率。

Kafka的整个设计中,Partition相当于一个非常长的数组,而Broker接收到的所有消息顺序写入这个大数组中。同时Consumer通过Offset顺序消费这些数据,并且不删除已经消费的数据,从而避免了随机写磁盘的过程。

由于磁盘有限,不可能保存所有数据,实际上作为消息系统Kafka也没必要保存所有数据,需要删除旧的数据。而这个删除过程,并非通过使用“读-写”模式去修改文件,而是将Partition分为多个Segment,每个Segment对应一个物理文件,通过删除整个文件的方式去删除Partition内的数据。这种方式清除旧数据的方式,也避免了对文件的随机写操作。

2.充分利用Page Cache

activemq

两种模式

首先看一下发布/订阅模式(即观察者模式),观察者模式

还有是,点对点P2P

RabbitMQ

不是分布式的,但是可以做集群达到高可用。

三种模式:单机模式/普通集群模式/镜像集群模式

普通集群模式:每个节点存储索引元数据,但是真实数据只存在一个节点。消费的时候如果没有连接到数据的机器,会真是存储数据的节点拉数据。缺点:可能会存在大量数据传输,不是高可用!!可以提高吞吐量!!

镜像集群模式:高可用,每个节点都有queue的完整镜像,包含数据。消费的时候任何一个节点都有数据,即使挂了一个节点也不丢失数据。缺点:不是分布式

面试题:

重复消费问题?

kafka的消息是有offset类似于唯一标识的,消费也是根据offset来顺序消费,消费后会提交offset,zk会记录消费进度,如果消费者重启了,不需要重头发送,zk是知道进度的。还是会重复的。

如何保证幂等性?

也就是保证数据库不能有重复数据,借助redis或者set来判断

消息丢失如何处理?消息的可靠性传输,就是发出去了,mq没收到,如何处理?

rabbitmq消息丢失三种可能性:1.生产者->mq 2.mq自身,在缓存中丢失 3.消费者 都可能出现

解决方案:

生产者:1.rabbitmq是可以开启事务的,保证生产者-》mq 是一个事务,可以回滚(事务是同步的,导致吞吐量下降,不推荐)

生产者:2. 开启confirm回调机制,发送成功或者失败,mq会回调生产者

mq:3.开启持久化,这样就不会在内存丢失了,重启也不会丢失(内存还没持久化到硬盘的时候,挂了,还是会丢失部分数据)

消费端丢失:4.关闭自动ack ,改成手动的。(mq会消费的时候,自动给发消息说已经完成,实际有可能挂了,改成成功后再手动)

kafka的解决方案:

消费端丢失:消费者自动提交offset,kafka以为消费好了实际上未消费失败了,关闭自动提交offset,改成手动提交,就不会丢失了

生产者丢失:  Kafka 的 leader 机器宕机了,将 follower 切换为 leader 之后,就会发现说这个数据就丢了。

所以此时一般是要求起码设置如下 4 个参数:

  • 给 topic 设置 replication.factor 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。
  • 在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。
  • 在 producer 端设置 acks=all,这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了
  • 在 producer 端设置 retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。

生产环境就是按照上述要求配置的,这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。

保证消息的顺序消费问题?

rabbitmq :一个queue,多个消费者消费数据会出现顺序不一致,

解决方案:拆分多个queue队列,需要排序的消息都放到一个队列,这样就只给一个消费者,一定是顺序的

kafka:

partition中的数据是顺序的,放数据指定key,就会放到一个partition中

一个消费者只能消费一个partition,所以一定是顺序的

但是,如果一个消费者有多个线程并发处理,结果也会乱,如何处理?

中间在加一层内存队列,同样的key放入内存队列。。

消息积压如何处理?

kafka消费者故障,就会出现消息积压,增加消费者服务器。。

rabbitmq 可以设置过期时间,积压时间长就会丢失,最好不设置。

让你设计一个消息队列,考虑哪些?

1.支持分布式,可扩容

2.考虑持久化,要不要落入磁盘,防止数据丢失

3.高可用,挂了选举新节点,数据迁移等

4.重复消费/顺序消费/丢失数据,都需要考虑

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值