【消息队列】MQ—总章_aq mq-程序员宅基地

技术标签: java  kafka  分布式  # 消息队列  

第一季

1. MQ

为什么使用MQ?MQ的优缺点?MQ的选型?

1.1为什么使用MQ?

考点:为什么要用这个技术?为了用而用,或者别人设计的架构,没有自己思考

解耦、异步、削峰

解耦

异步化:

削峰。这其实是MQ一个很重要的应用。假设系统A在某一段时间请求数暴增,有5000个请求发送过来,系统A这时就会发送5000条SQL进入MySQL进行执行,MySQL对于如此庞大的请求当然处理不过来,MySQL就会崩溃,导致系统瘫痪。如果使用MQ,系统A不再是直接发送SQL到数据库,而是把数据发送到MQ,MQ短时间积压数据是可以接受的,然后由消费者每次拉取2000条进行处理,防止在请求峰值时期大量的请求直接发送到MySQL导致系统崩溃。

短暂高峰期,造成消息积压,这样依然会导致其他消息没有及时处理啊?

高峰期过后,consumer依然具有消费能力。

1.2 MQ有什么优点和缺点?

技术是一把双刃剑,有好有坏?有哪些坑?

【引入MQ的问题】
(1)系统可用性降低,如果A发送MQ,B、C、D订阅这个MQ,当MQ跪了,整个系统就跪了。

(2)producer发送多个消息到MQ中 或者 msg丢失了 或者 本来发送有序的msg到mq变成无序的了、consumer跪了导致消息大量积压。

(3)一致性问题。这种情况可能是ABCD四个系统,依赖MQ,要求ABCD全都执行成功,结果ABC成功,D失败,此时返回给用户的状态是成功,但是真个逻辑链条因为D失败导致数据不一致。

1.3 Kafka、aq、rabbitmq、rocketmq都有什么区别以及使用哪些场景?

调研每一个mq使用场景
MQ对比,这个是石衫讲的笔记

rocketmq:java + 分布式 + 扩展性好

kafka:功能简单、在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准,吞吐量超高,

Kafka

kafka:分布式流式平台,三个关键能力:(1)订阅发布记录流(2)以容错的方式记录流(3)实时记录流

kafaka应用:(1)消息系统(2)存储系统(3)作为流处理器

三个基本组件:producer(发布消息的客户端)----Message Broker(生产者接受并存储消息的客户端)----consumer(消费者从Broker中读取消息)

Kafka运行在一个或者多个数据中心的服务器上作为集群运行

Kafka cluster存储消息记录的目录被称为 topics

每条消息记录包含三个要素:键、值、时间戳

【4个核心API】

Producer API:允许应用程序向一个或者多个topic上发送消息记录

Consumer API:允许应用程序订阅一个或者多个topic并处理为其生成的记录流

Streams API:允许应用程序作为流处理器,从一个或者多个topic中消费输入流,并为其生成输出流,有效的将输入流转换为输出流

Connector API:允许构建和运行将Kafka主题连接到现有应用程序或者数据系统的可用生产者和消费者。

Fig-Kafka
Kafka的基本概念:
它是高度可扩展可容错的消息系统

topic:主题,逻辑概念

partition:分区,topic中的msg会被分割成一个或者多个partition,parittion是物理概念

注意:由于一个主题包含无数个分区,因此无法保证在整个 topic 中有序,但是单个 Partition 分区可以保证有序。消息被迫加写入每个分区的尾部。Kafka 通过分区来实现数据冗余和伸缩性

segment:段,把分区进一步细分成若干个segment,每个segment大小相等

broker:broker接收producer的消息,为msg设置偏移量,并提交msg到disk保存。broker还为consumer提供服务,对读取partition的请求作出响应,返回已经提交到disk上的msg。

在Kafka集群中有一个或多个broker,每个cluster中都会有1个broker作为Leader集群控制器,通过集群中活跃成员选举出来的,每个broker都可能作为Leader,Leader负责管理工作,包括将分区分配给broker和监控broker。

RabbitMQ

RabbitMQErlang开发,实现了AMQP(高级消息队列协议)
可靠、灵活的分发消息策略。。这应该是RabbitMQ的一大特点。在消息进入MQ前由Exchange(交换机)进行路由消息。分发消息策略有:简单模式、工作队列模式、发布订阅模式、路由模式、通配符模式、集群、多种协议、多语言客户端、可视化管理、插件机制

它的broker由exchange和queue组成
RabbitMQ

MQ的进阶

1.4 消息队列的高可用?

(1)RabbitMQ的高可用行
rabbitmq是集群的,但不是分布式的

普通集群不是高可用的,镜像集群是高可用的

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

  • 普通集群模式, 数据的queue放在一台机器M上,但是queue的元数据会在集群其他机器 O 1 、 O 2 , . . . . , O n O_1、O_2,....,O_n O1O2,....,On 。当consumer连接到 O 1 、 O 2 , . . . . , O n O_1、O_2,....,O_n O1O2,....,On时, O i O_i Oi会从M上拉,M机器会把数据给到 O i O_i Oi。这种模式不是啥分布式、高可用,只是consumer的请求分发到多个pod上。
    缺点:在rabbitmq cluster中产生大量的数据传输;毫无可用性,当M跪了,整个mq系统不可用。
  • 镜像集群模式(06-02)。 每个pod都有queue的完整数据,cluster中会同步数据
    consumer可以到任何一个pod去消费数据,cluster中数据都是同步的。producer在写数据的时候,cluster中写入的pod会同步其他pod
    任何一个pod跪掉了,其他pod包含queue的完整数据别的consumer可以到其他的pod消费数据

缺点是:它不是分布式的。遇到的情况,queue的数据量很大,大到pod的磁盘容量无法容纳,该怎么办?

rabbitmq如何开启镜像集群模式,搞个策略即可。

RabbitMQ

(2)Kafka的高可用
Kafka是分布式的,可以把数据分布在不同的partition上的

Kafka部署在多个pod上,在每个pod上启动一个broker进程。

每个机器+broker进程就相当于一个kafka节点

0.8版本是没有HA的,为了实现高可用,所以实现了repica副本。

Kafka
当leader跪了,follower会被选举为leader。然后producer和consumer会自动去新的leader进行消费和生产

1.5 如何保证消息不被重复消费(如何保证消息消费时的幂等性)

背景:消息被重复消费的问题,消息重发的问题,mq不保证只发1次。

consumer要定期提交offset。消费着提交offset,告诉kafka已经消费到offset=n的这条数据了,zk就会记录consumer消费的offset=n的记录,kafka从zk感知到consumer提交的offset。

坑:当consumer准备提交的时候跪掉了,此时代表着consuemr丢失了offset,于是导致kafka发送上一次的offset的后面的消息,导致消息重发,可能导致重复消费问题。
Kafka的消息重发

solution:
保证幂等性,f(x) = f(f(x)),多次请求打过来,只能保证数据库存在1条记录。

保证幂等性插件操作,往一个地方去插入一条消费记录,然后同样的数据过来去查一下之前是否消费。

(1)根据数据库主键去查一下,存在就不insert,直接update
(2)如果是用写redis,每次都是set,天然幂等性?????
(3)生产者发送每条数据的时候,里面加一个全局唯一的id,类似订单id之类的东西,然后消费到之后,现根据这个id去redis查一下,判断是否消费,消费过了就不处理,没消费过就处理。

还有方案就是基于数据库的唯一键来保证重复数据不会重复插入多条。所以当kafka中的consumer没来得及提交offset,这个时候就只需要保证唯一键约束就可以防止数据库插入脏数据。

实现MQ的幂等性,需要根据业务来。

1.6 保证消息的可靠性传入(保证出力消息丢失的问题)

背景:使用mq传递核心消息,比如计费,

(1)rabbitMQ

  • rabbitmq可能存在着数据丢失的问题
    • producer写数据到mq可能会丢
      rabbitMQ支持消息的事务,producer先打开一个事务。
      保证消息不丢,一般用confirm机制,异步的模式,发送消息之后不会被阻塞。
      rabbitMQ走confirm模式保证消息不丢
    • mq自己挂了没有持久化可能会丢
      让rabbitmq持久化,
    • consumer消费没来得及处理就跪了,但是rabbitmq以为这个消费者已经处理完了
      消费者丢失,打开了消费者的autoAck的这么一个机制。消费之后,consumer自动通知rabbitmq,完成消费,但是consumer却跪掉了。
      rabbitmq数据丢失问题

(2)kafka丢失数据

  • 消费端丢失数据
    consumer消费到这个消息,然后自动提交了offset,让kafka以为已经消费好了这个消息,其实真实场景就是在处理过程中,consumer给跪掉了,此时这条消息却没处理完,消息丢失。
    解决方案:把自动提交offset改成手动提交offset,保证消息不丢。但是还是存在重复消费,如处理完消息,还没提交offset,结果自己跪了,此时肯定会重复消费一次,需要自己保证幂等性

  • Kafka丢失数据
    当producer写入leader时候,leader跪掉了,follwer被选举为leader,但是没有producer刚写入的msg。
    所以这个时候起码设置4个参数:

    • 给这个topic设置replication.factor参数,这个值必须大于1,要求每个partition必须有至少2个副本。
    • 在kafka服务端设置min.insync.replicas参数:这个值必须大于1,这便要求一个leader至少感知到一个follwer跟自己在同步,确保leader挂了,还会有follower顶上。
    • 在producer端设置ack=all,保证leader同步到follower后才能认为写成功。
    • 在producer端设置retries=MAX,要求一旦写入失败,就无限重试,卡在这里

Kafka保证消息不丢

1.7 保证消息的顺序性

mysql中的binlog作用:

  • 数据恢复,只要数据库在某个时刻的备份以及此时后的所有binlog,就可以恢复数据库的数据。
  • 主从复制,从库监控主库的binlog日志,同步写库的所有更改操作

背景:mysql把binlog日志发送到MQ,到消费出来一次执行,所以得保证顺序性;

(1)rabbitmq
rabbitmq发送的每条数据,只会被一个consumer消费到;

rabbitmq
rabbitmq如何保证消息的顺序性

把数据都写到1个queue里面,让1个消费者去消费,然后刷到库里面
在这里插入图片描述

(2)Kafka

写入到一个partition中的数据是有一定的顺序性的

生产者在写的时候,可以指定一个key,比如订单id

这个订单相关的数据一定会被分发到一个partition中

而且partition中的数据一定是有顺序的

因此,想要保证有序性,就保证producer写入一个partition,消费着从partion中取出数据的时候,一定有顺序的。

consumer中用单线程没问题,但是多线程去读partition就会出问题

多线程消费partition出现问题

  • Kafka如何保证消息的顺序性
    使用内存队列,在consumer端中不同的线程读取不同的内存队列
    在这里插入图片描述

1.8 消息积压

如何解决MQ的延时以及过期失效问题?消息队列满了以后如何处理?几百万条消息持续积压几个小时,怎么解决?

(1)快速处理积压的消息

在MQ里面积压几百万数据,假设有3个consumer,现在消费者好了,可以正常消费,如何让消费者快速消费

修复思路

  • 先修复consumer的问题,确保它恢复消费速度,然后将现有consumer都停掉
  • 新建一个topic,partition时原来的10倍,临时建原先10被或者20倍的queue数量
  • 然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时处理,直接均匀轮询写入临时建立好的10倍数量的queue
  • 接着临时征用10倍机器来部署consumer,没一批consumer消费一个临时的queue的数据
  • 积压的消息搞完后,在恢复原先consumer的功能,将临时的consumer下掉
    在这里插入图片描述

(2)如何解决MQ过期失效问题
rabbitmq中设置了过期时间,就是TTL,消息在MQ中积压一定时间后会被rabbitmq给清理掉,这个数据就没了,造成数据丢失。

这种情况,只能是批量重导数据,重新把数据查出来,然后在灌入到mq中,把白天丢失的数据补回来。

(3)消息积压,把磁盘空间积压满了

开发一个MQ,架构设计

(1)MQ得支持扩容,可伸缩。需要的时候快速扩容,增加吞吐量和容量。设计个分布式的系统,参考Kafka的设计理念, b r o k e r → t o p i c → p a r i t i o n broker \to topic \to parition brokertopicparition
每个partition放一个机器,就存一部分数据。资源不够,给topic增加partition,做数据迁移,增加机器,可以放更多数据,提高吞吐量。

(2)持久化。mq要落盘,顺序写,不需要随机读写导致IO速度慢问题,Kafka就是顺序写的

(3)HA可用性。Leader-Follower,用Follower保证Leader的副本,Leader挂了,用Follower作为Leader重新对外提供服务

(4)数据不丢、数据不重、拿到数据按照顺序执行

MQ的面试技巧

(1)RabbitMQ 和 Kafka基础
(2)

  • https://www.bilibili.com/video/BV1gE411M7cs?p=24
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Alearn_/article/details/124687821

智能推荐

Could NOT find SDL (missing: SDL_LIBRARY SDL_INCLUDE_DIR)-程序员宅基地

文章浏览阅读5.9k次,点赞2次,收藏6次。linux sdl2 cmake安装How to use SDL2 and SDL_image with cmakehttps://stackoverflow.com/questions/23850472/how-to-use-sdl2j-and-sdl-image-with-cmakeUsing SDL2 with CMakehttps://trenki2.github.io/blog/2017/06/02/using-sdl2-with-cmake/我没有按照上面的编译,结..._could not find sdl (missing: sdl_library sdl_include_dir)

Ajax跨域请求COOKIE无法带上的解决办法_options带不上cookie-程序员宅基地

文章浏览阅读430次。原生ajax请求方式:var xhr = new XMLHttpRequest(); xhr.open("POST", "http://xxxx.com/demo/b/index.php", true); xhr.withCredentials = true; //支持跨域发送cookiesxhr.send();jquery的ajax的post方法请求: $.aj_options带不上cookie

【Python入门基础】PEP8规范与Python之禅_thou shall follow pep8 python-程序员宅基地

文章浏览阅读370次。PEP8规范 PEP时Python Enhancement Proposal的缩写,通常翻译为“Python增强提案”。每个PEP都是一份为Python社区提供的指导Python往更好的方向发展的技术文档,其中的第8号增强提案(PEP 8)是针对Python语言编订的代码风格指南。一.命名规范 PEP8倡导用不同的命名风格来命名Python不同的标识符,以便在阅读代..._thou shall follow pep8 python

深度学习:深度复数网络(Deep Complex Networks)-从论文到pytorch实现-程序员宅基地

文章浏览阅读1.8w次,点赞40次,收藏235次。实数网络在图像领域取得极大成功,但在音频中,信号特征大多数是复数,如频谱等。简单分离实部虚部,或者考虑幅度和相位角都丢失了复数原本的关系。论文按照复数计算的定义,设计了深度复数网络,能对复数的输入数据进行卷积、激活、批规范化等操作。在音频信号的处理中,该网络应该有极大的优势。这里对论文提出的几种复数操作进行介绍,并给出简单的pytorch实现方法。_deep complex networks

jdk1.8中文手册_jdk中文手册-程序员宅基地

文章浏览阅读448次,点赞10次,收藏7次。jdk1.8中文手册_jdk中文手册

解决chrome升级中碰到的0x80040902错误_chrome 0x80040902-程序员宅基地

文章浏览阅读1.5w次。升到62%时碰到0x80040902号错误:只找到了英文说明:https://www.trishtech.com/2017/08/fixing-chrome-update-error-code-0x80040902/按照方法测试了一下:1、在windows10下运行cmd2、键入如下命令:taskkill /im chrome.exe /ftaskkill /im goo..._chrome 0x80040902

随便推点

IT行业常用网站与平台汇总(持续更新...)_it行业网站-程序员宅基地

文章浏览阅读3.6k次。文章目录前言一、知乎二、CSDN三、掘金网四、Hacker News五、推酷网六、互联网的一些事七、美国项目管理协会总结前言IT行业常用网站与平台汇总,供大家使用。提示:以下是本篇文章正文内容,下面案例可供参考一、知乎知乎网址是一个大型互动知识分享社区,汇集了不少项目管理行业知识、经验和见解。二、CSDNCSDN网址是一个程序员专属平台,其实不然,这里不仅仅为软件开发者提供知识传播、在线学习,还有职业发展、转行就业、职业规划等全生命周期服务,是一个老牌社区。它2019年开始,尝试了_it行业网站

面向对象七大原则_任何方法都不应该覆写它的任何基类中的已经实现的方法-程序员宅基地

文章浏览阅读319次。我们都知道面向对象有三大特性:封装、继承、多态。所以我们在实际开发过程中,子类在继承父类后,根据多态的特性,可能是图一时方便,经常任意重写父类的方法,那么这种方式会大大增加代码出问题的几率。比如下面场景:类C实现了某项功能F1。现在需要对功能F1作修改扩展,将功能F1扩展为F,其中F由原有的功能F1和新功能F2组成。新功能F由类C的子类C1来完成,则子类C1在完成功能F的同时,有可能会导致类C的原_任何方法都不应该覆写它的任何基类中的已经实现的方法

db2pd命令详解-程序员宅基地

文章浏览阅读2.5k次。db2监控工具 db2pd (最推荐使用) snapshot 命令行监控 (受监视器开关控制) snapshot 管理视图 (受实例级监视器开关控制) db2top 监视器表函数 MON_ (受DB参数 MON_REQ_METRICS,MON_ACT_METRICS,MON_OBJ_METRICS 控制) 事件监控器 (不建议使用)–db2pd 独立运行于数据库引擎之外的工具–db2pd 监控的优势,相对快照,事件监视器来说,1)db2pd 直接从DB2内..._db2pd

w3af漏扫的基本使用_无法定位软件包 w3af-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏12次。一、安装apt安装 apt-get update apt-get install -y w3af出现无法定位软件包源码安装sudo apt-get install gitsudo apt-get install python-pipgit clone https://github.com/andresriancho/w3af.gitcd w3af/./w3af_c..._无法定位软件包 w3af

Python 多线程编程-03-threading 模块 - Condition_threading.condition-程序员宅基地

文章浏览阅读2.4k次,点赞11次,收藏25次。Python 多线程编程Python 多线程编程-01-threading 模块初识Python 多线程编程-02-threading 模块-锁的使用1. 复杂线程同步 前面两章已经说过 threading 模块中互斥锁的使用,不管是 threading.Lock 还是 threading.RLock,这种互斥锁是最简单的线程同步机制,在实际工作中会有很多复杂情况是互斥锁无法解决的。而Python 提供的 Condition对象提供了对复杂线程同步问题的支持。1.1 ..._threading.condition

《普林斯顿计算机公开课》总结(一) 硬件部分_普林斯顿计算机公开课pdf-程序员宅基地

文章浏览阅读4.2k次。前几天读到一本非常好的书 ,《普林斯度计算机公开课》 【美】 布莱恩 W.克尼汉(Brian W. Kernighan)著 机械工业出版社在此总结其中非常好的话语和知识。前言本书英文版网站 kernighan.com第1章阿达.洛夫莱斯被认为是世界上第一个程序员,Ada语言以其名字命名。第一个由电器组成的计算机是ENIAC{}第一个真正将程序和数据存储在一起的计算..._普林斯顿计算机公开课pdf

推荐文章

热门文章

相关标签