消息队列

1、消息队列的使用场景(作用、优点)

消峰
异步
解耦

2、消息队列会带来哪些缺点

  1. 系统可用性降低:
    需要保证MQ不能挂掉

  2. 系统复杂度提高:
    引入MQ,怎么保证消息的重复消费?怎么处理消息丢失的情况?

  3. 一致性问题:
    A服务发送的消息被BCD消费,BC成功D失败,导致数据不一致。

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

特性 ActiveMQ RabbitMQ RocketMQ Kafka
单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响 topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性 ms 级 微秒级,这是 RabbitMQ 的一大特点,延迟最低 ms 级 延迟在 ms 级以内
可用性 高,基于主从架构实现高可用 同 ActiveMQ 非常高,分布式架构 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性 有较低的概率丢失数据 基本不丢 经过参数优化配置,可以做到 0 丢失 同 RocketMQ
功能支持 MQ 领域的功能极其完备 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

3、kafka目前的使用场景:

应用日志收集分析、消息系统、用户行为分析、运行指标、流式处理(Spark、storm)

image.png

4、kafka的高吞吐原因:

1. 顺序读写

kafka的消息是不断追加到文件中的,这个特性使kafka可以充分利用磁盘的顺序读写性能,
顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写

2. 零拷贝
3. 批量发送

kafka允许进行批量发送消息,producter发送消息的时候,可以将消息缓存在本地,等到了固定条件发送到kafka

(等消息条数到固定条数,一段时间发送一次)

https://www.jianshu.com/p/6287868c8462?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

5、消息发送的三种确认方式(发送端可靠性)

生产者发送消息到broker,有三种确认方式:

  • acks = 0:producer不会等待broker(leader)发送ack 。效率高,但可能丢失也可能会重发数据
  • acks = 1:当leader收到消息后会发送ack确认收到(follower不管),如果丢失则会重发。
  • acks = -1:需要等所有follower都同步消息成功后在返回ack,可靠性最高。

6、消息存储方式(存储端可靠性)

每一条消息被发送到broker中,会根据partition规则选择被存储到哪一个partition。如果partition规则设置的合理,所有消息可以均匀分布到不同的partition里,这样就实现了水平扩展。

在创建topic时可以指定这个topic对应的partition的数量。在发送一条消息时,可以指定这条消息的key,producer根据这个key和partition机制来判断这个消息发送到哪个partition。

如果Broker有多台负载,那么topic的partition会平均分配到每一台上,所以发送的消息也会平均分配到每一台上。

但是这样带来个问题:如果某个Broker单点故障了,这台broker上的partition就不可用了;

kafka的高可靠性的保障来自于另一个叫副本(replication)策略,通过设置副本的相关参数,可以使kafka在性能和可靠性之间做不同的切换。

7、副本机制

sh kafka-topics.sh --create --zookeeper 192.168.11.140:2181 --replication-factor 3 --partitions 3 --topic MyTopic

--replication-factor表示的副本数
image.png
ISR(副本同步队列)

维护的是有资格的follower节点

副本的所有节点都必须要和zookeeper保持连接状态

副本的最后一条消息的offset和leader副本的最后一条消息的offset之间的差值不能超过指定的阀值,这个阀值是可以设置的(replica.lag.max.messages)

image.png

10. 如何保证消息没有被重复消费

为什么会出现消息被重复消费

其中很大的一个原因就是网络不稳定,比如kafka在处理完消息准备commit时出现网络波动(或者重启了)提交失败,那么服务端是不知道这条消息已经被消费了.

怎么避免重复消费

没有根本的解决办法,只能从以下两个层面尽量规避:

  1. 消费端处理消息的业务逻辑保持幂等性
    就是不管来多少重复消息,最终的处理结果都一样,比如:一个金额累加的消息,不能设计成每次只传一个增加的金额,这样同一个消息重复N次,那么总金额也会累加N次;应该在消息体里传入增加的金额和增加后的金额.

  2. 保证每条消息都一个唯一编号并且消息的处理成功和去重表的记录同时出现
    消费端每消费一条消息记录一次,可以通过数据库的唯一索引,如果这个编号是自增的可以通过redis等方式,同一条消息消费时,查询数据库发现已经消费则过滤掉;这种方式势必会对消息队列的吞吐量和性能带来影响,如果不是特别重要的业务可以不用处理,因为重复消息的概率很低.

11. 如何处理消息丢失的问题

为什么会出现消息丢失

消息丢失的问题,可能出现在生产者、MQ、消费者,以RabbitMQ为例:


image.png
消费端弄丢了数据

出现的情况可能是由于消费端获得了消息后自动提交了offset,让kafka以为你已经消费好了这条消息,但是你正准备处理这条消息时,挂掉了,消息就丢失了.

解决办法是:关闭自动提交offset,在出来完之后手动提交;
这可能带来重复消费的问题,所以必须要的话,需要自己保证幂等性.

kafka弄丢了数据

出现的情况可能是由于某个broker挂掉了,然后重新选举partition的leader,但是有可能follower数据还没同步好,这时候就会丢数据

解决办法是:生产端设置acks=all,即必须是写入所有 replica 之后,才能认为是写成功了;然后设置retries=MAX,要求一旦写入失败,就无限重试,卡在这里了;当然这会影响kafka写的性能.

生产端弄丢了数据

如果按照上述的思路设置了 acks=all,一定不会丢

12. 让你来设计一个消息队列,你会怎么做?

  • 首先这个 mq 得支持可伸缩性吧,就是需要的时候快速扩容,就可以增加吞吐量和容量,那怎么搞?设计个分布式的系统呗,参照一下 kafka 的设计理念,broker -> topic -> partition,每个 partition 放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给 topic 增加 partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了?
  • 其次你得考虑一下这个 mq 的数据要不要落地磁盘吧?那肯定要了,落磁盘才能保证别进程挂了数据就丢了。那落磁盘的时候怎么落啊?顺序写,这样就没有磁盘随机读写的寻址开销,磁盘顺序读写的性能是很高的,这就是 kafka 的思路。
  • 其次你考虑一下你的 mq 的可用性啊?这个事儿,具体参考之前可用性那个环节讲解的 kafka 的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务。
  • 能不能支持数据 0 丢失啊?可以的,参考我们之前说的那个 kafka 数据零丢失方案。

13. 事务消息

13.1 Rocketmq

RocketMQ 的事务消息也可以被认为是一个两阶段提交,简单的说就是在事务开始的时候会先发送一个半消息给 Broker。

半消息的意思就是这个消息此时对 Consumer 是不可见的,而且也不是存在真正要发送的队列中,而是一个特殊队列。

发送完半消息之后再执行本地事务,再根据本地事务的执行结果来决定是向 Broker 发送提交消息,还是发送回滚消息。

image.png

1、生产者发送事务消息给 broker时序

image

2、broker发送消息给生产者询问本地事务是否执行成功,生产者告知broker本地事务执行结果

image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容