【消息队列】MQ—总章_yzzheng_60125的博客-程序员秘密

技术标签: 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

智能推荐

基于CentOS 7.2的CDH 6.3.2 Flink编译源码_SmallScorpion的博客-程序员秘密

基于CentOS 7.2的CDH6.3.2离线安装https://blog.csdn.net/qq_40180229/article/details/108755530基于CentOS 7.2的CDH 6.3.2完整集群添加https://blog.csdn.net/qq_40180229/article/details/108756561基于CentOS 7.2的CDH 6.3.2 Hadoop配置https://blog.csdn.net/qq_40180229/article/details

ADB的三者通信原理_adb通信原理_QA小小的博客-程序员秘密

黑窗口敲ADB命令时给服务端 服务端也是在PC里面,它专门监听ADB命令,但它不能执行 它只能把命令传给手机的守护进程 守护进程再把命令传给xxx bootstrap.jar来操作手机比如删除进程 启动进程...

boosting-adaboost、GBDT、xgboost、lightGBM_SimpleIsBetter的博客-程序员秘密

提升方法,是将多个专家的判断进行适当的综合所得出的判断,要比其中任何一个专家单独的判断好。 Kearns和Valiant提出了“强可学习”和“弱可学习”的概念 强可学习:在概率近似正确学习的框架中,一个概念(一个类),如果存在一个多项式的学习算法能够学习它,并且正确率很高,这个概念被称为强可学习 弱可学习:一个概念,如果一个多项式学习算法能够学习它,学习的正确率仅比随机猜测略好 Schap

攻防世界Reverse进阶区-IgniteMe-writeup_igniteme write up_y4ung的博客-程序员秘密

1. 介绍本题是xctf攻防世界中Reverse的进阶区的题IgniteMe题目来源: 高校网络信息安全运维挑战赛2. 分析$ file fac4d1290e604fdfacbbe06fd1a5ca39.exe fac4d1290e604fdfacbbe06fd1a5ca39.exe: PE32 executable (console) Intel 80386, for MS WindowsC:\Users\hzy\Downloads>fac4d1290e604fdfacbbe06fd1

OAuth2登录模式获取TOKEN_智Min的博客-程序员秘密

参考链接:OAuth2密码模式获取Token注:在进行本地搭建测试时,出现一个pom中 <artifactId>spring-cloud-dependencies<artifactId> 版本问题,导致maven命令执行不了。去Maven仓库官网查看对应版本信息如下(无Finchley.M7 版本):最后将版本修改为:<version>Fi...

随便推点

5G LAN — Overview_范桂飓的博客-程序员秘密

目录文章目录目录5G LAN5G LAN5G LAN 主要针对行业网客户提供安全高质量的私有移动局域网服务,实现本地或跨域互联,同时 5G LAN 支持指定的终端组基于 Ethernet 或 IP 进行点对点通信,满足工业互联网、企业办公、车联网等业务需求。5G LAN 提供了一个园区无线局域网。UPF 变成 SDN 交换机的角色,而 SMF 变成 SDN 控制器,控制着接入 5G 设备之间的数据转发。园区内设备间可相互通信 M2M,数据不用去远端的 DN 中转,可有效降低时延。运营商对 5G

分布式--BASE原则_bigeyescute的博客-程序员秘密

分布式–BASE原则概念BASE 是基本可用(Basically Available)、软状态(Soft State)和最终一致性(Eventually Consistent)三个短语的缩写。BASE 理论是对 CAP 中一致性和可用性权衡的结果,它的理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。基本可用(Basically...

题目内容: 一个正整数的因子是所有可以整除它的正整数。而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数。例如6=1+2+3(6的因子是1,2,3)。 现在,你要写一个程序,读入两个正整数n和_#FOR KD#的博客-程序员秘密

题目内容: 一个正整数的因子是所有可以整除它的正整数。而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数。例如6=1+2+3(6的因子是1,2,3)。 现在,你要写一个程序,读入两个正整数n和m(1<=n<m<1000),输出[n,m]范围内所有的完数。提示:可以写一个函数来判断某个数是否是完数。输入格式:两个正整数,以空格分隔。输出格式:其间所有的完数,以空格分隔,最后一个数字后面没有空格。如果没有,则输出一个空行。输入样例:1 10输出样例:6完数pack

解决Use ‘docker scan‘ to run Snyk tests against images to find vulnerabilities_docker_scan_suggest_gusijin的博客-程序员秘密

解决Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

antd datepicker 添加默认值_antd datepicker设置默认值_lcqbug001的博客-程序员秘密

参考: https://www.jianshu.com/p/1aa165255697https://momentjs.com/https://www.antdv.com/components/date-picker-cn/首先,有一个datepicker组件(需要先安装好antd环境)<template> <div> <a-date-picker :default-value="moment('2015/01/01', dateFormat)" :form

dataimagepng;base64的用法详解_data:image/png;base64,/9j/4aaqskzjrgabagaaaqabaad/_Mastersheaven的博客-程序员秘密

data:image/png;base64的用法详解查看前端代码时,发现了一个字符传可以转化,比如data:image/png;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQk...

推荐文章

热门文章

相关标签