首页 > 其他分享 >消息队列详细介绍、工作原理,kafka与RocketMQ的比对

消息队列详细介绍、工作原理,kafka与RocketMQ的比对

时间:2024-10-11 14:18:49浏览次数:9  
标签:队列 broker kafka topic 处理 消息 leader RocketMQ

消息队列:

当一个服务处理量为100,而另一个服务发送量为200,这时候多余的消息会被丢弃,如果想要全部处理,我们必须加入队列,这个队列用来存储消息的信息,通过offset表示当前处理的位置。注意此时队列还位于进程中,也就是服务进程,我们的进程一旦挂掉,未被处理的消息会直接丢失,我们不希望这样,所以独立出来单独一个进程,用来存放队列,这样避免了受服务端的影响。

这个独立出来的用来存放消息的队列,就是我们说的消息队列。

消息中间件:

要想把消息队列变得更高性能,并且高可用,还可扩展,我们需要将他进化为消息中间件。一个强大的消息中间件例如kafka这种的可以流量削峰,完成大多数业务场景所需要的功能,

那么一个满足高可用性,高性能以及可扩展的消息队列进程,也就是一个成熟的消息中间件。

为什么时候需要用到消息中间件?

当我们维护A服务和B服务两个进程,B服务每秒只能处理100个请求,而A服务每秒发送200个请求时,在B进程当中写一个队列,用于存放无法处理的请求,在之后能处理多少处理多少,处理不掉的我们进行报错或者直接丢弃。这时候如果B服务宕机,那么消息队列中的数据就会直接丢失,想避免这种情况,我们将消息队列独立出来单创一个进程。

队列说白了就是一个链表,每个消息对应一个节点,每个节点有自己的序号offset值,记录消息的位置。消费者线程依据自己的能力,消费链表里的消息,能处理多少处理多少,当消费者服务处理一条消息后,不断更新offset代表已处理消息的个数。

这时候有一个问题,队列里面的消息存储在消费者线程的内存里,如果来不及处理就宕机了,这些消息就会丢失,所以我们将队列挪出来,变成一个单独的进程,这时候就算B服务重启,也不会被影响,这个独立出来的队列进程就是消息队列。

而像A服务这样发送数据到消息队列的角色就是生产者producer,而B服务这样负责处理消息队列中数据的角色就是消费者consumer

这时候消息队列虽然不受其他进程影响,但是太基础了,如果数据量过大也无法发挥其作用,无法保证高可用性,高性能,高扩展性,怎么去保证,需要用到消息中间件,我们一步一步去过渡。

什么是高可用性,高性能,高扩展性呢?

首先,我们可以给消费队列两端加入更多的消费者和生产者,提高请求产生和处理效率。

其次,我们给消息队列进行分片,先将消息分类成不同的topic,每个topic被分配到对应的position,当单机存有多个position的时候,容易占用cpu和内存较高的情况,影响性能,这时候分给不同的机器,这每个机器对应一个broker,依据是根据请求的类型去划分为不同的topic,相同topic存放在一个broker进行处理,保证了请求消息的规律性。

最后,加入持久化,在数据丢失时我们确保能保留大部分信息即可,持久化是通过broker的备份,leader用来正常处理消息请求,follower只负责记录leader的备份信息,当leader挂了以后,会推举一个follower作为新的leader,以此实现消息的持久化。

同时,通过zookeeper组件来监控各个组件的状态,定时去判断broker的状态,保证程序正常运行。

这样一来,在做好了消费者生产者集群,分区分片进行部署,消息的持久化以后,消息中间件就完成了。

当然,每个请求通过唯一的UUID来保证幂等性,由于网络原因产生的多个请求操作,也只会产生一次影响。

总结一下:

partition:队列分片 ,备份即为follower,正常处理消息则是leader。

broker:部署的机器,上面有多个partition,增加broker可实现可扩展性。

consumer group:多个消费者形成的消费者组,处理对应类型的topic可提高性能。

topic:消息类型,通过key或者其他值来计算,对应的类型由对应的partition传给consumer group。

死信队列:处理重复失败的消息,包含确认机制。

replication:由partition,一个leader和多个follower组成(分布在不同的机器上),当一个leader挂了,由其余follower推举出新的leader,实现高可用。

高性能:通过partition队列分片,以及多台机器broker,同时增加消费者组consumer group,提升处理消息的能力,增大吞吐量。

高可用:通过不同broker上面的replication完成,还有当所有broker挂了时,消息也会持久化在硬盘里,也就是服务器中,实现高可用性。

可扩展性:不仅可以增加消费者线程,还可以增加生产者,提升吞吐量,而且可以增加机器broker来实现队列的扩充,只需要分配对应的topic即可。

最后是应用场景:相较于RocketMQ,kafka的topic也就是消息类型较少,而且无死信队列,所以他只负责高并发的处理消息而不负责检查消息是否正确被处理,所以在一些抢购的场景我们需要使用RocketMQ,死信队列可以解决失败消息的处理。

标签:队列,broker,kafka,topic,处理,消息,leader,RocketMQ
From: https://blog.csdn.net/m0_60715044/article/details/142819014

相关文章

  • C++ 算法学习——1.8 单调队列算法
    单调队列(MonotonicQueue)是一种特殊类型的队列,通常用于解决一些数组或序列相关的问题。和单调栈类似,单调队列也具有一些特定的性质,在解决一些问题时非常有用。以下是关于单调队列的一些重要点:定义:单调队列是一种数据结构,队列中的元素满足单调递增或单调递减的性质。应用:单......
  • kafka集群升级新策略,Cloudera运维专家来揭秘:助你轻松应对大数据挑战
    项目背景我们团队负责维护的Kafka集群承载了公司大部分实时数据的收集与传输任务。然而,目前存在一些问题,严重影响了集群的稳定性、用户体验以及管理员的运维效率:当前集群版本较低,且低版本的bug频繁出现,导致集群稳定性受到威胁。例如,violet集群最近因触发bug而出现不可......
  • kafka基础学习
    Kafka系列的阶段性总结(万字长文,做好准备)这是Java极客技术的第265篇原创文章初识Kafka什么是KafkaKafka是由Linkedin公司开发的,它是一个分布式的,支持多分区、多副本,基于Zookeeper的分布式消息流平台,它同时也是一款开源的基于发布订阅模式的消息引擎系统。Kaf......
  • 算法训练营第十天|232.用栈实现队列 ,225. 用队列实现栈,20. 有效的括号,1047. 删除字符
    前置知识栈和队列都是以deque为缺省底部结构,实际上可以自己指定vector,deque,list都可以栈和队列都被归类为containeradapter(容器适配器)使用栈实现队列的操作:push(x)--将一个元素放入队列的尾部。pop()--从队列首部移除元素。peek()--返回队列首部的元素。empty()......
  • 快速排序的非递归实现:借助栈实现、借助队列实现
    目录用栈实现快速排序1.用栈实现非递归快速排序的思路步骤1.1.思路步骤2.用栈实现非递归快速排序的代码3.用栈实现非递归快速排序的整个工程3.1.QuickSortNonR.h3.2.QuickSortNonR.c3.3.Stack.h3.4.Stack.c用队列实现非递归快速排序1.用队列实现非递归快速排序的思......
  • 谈kafka
    作者:京东科技徐拥导读:当今大数据时代,高吞吐、高可靠成为了分布式系统中重要的指标。而ApacheKafka作为一个高性能、分布式、可扩展的消息队列系统,被越来越多的企业和开发者所关注和使用。在本文中,我们将介绍Kafka的基本概念,包括Kafka的架构、消息的存储和处理方式、Kafka的......
  • 安全线程队列 — C++
    一、安全队列#pragmaonce#include<queue>#include<memory>#include<mutex>#include<condition_variable>template<typenameT>classSafeQueue{private:  mutablestd::mutexmMutex;  std::queue<T>mQueue;  std::condition_va......
  • 线程池监控2-监控线程池状态、线程数量和队列任务数量等
    1.实现原理这篇博文是基于线程池监控1-监控任务执行时间,原理是:创建一个固定时间间隔执行的线程,来记录线程池的池状态、线程数量和队列任务数量等,具体方案:使用单例类缓存所有创建的线程池对象,类创建时启动定时任务线程,定期遍历缓存中线程池,记录线程池信息。2.实现代码packa......
  • 代码随想录算法训练营day10| 232.用栈实现队列 225. 用队列实现栈 20. 有效的括
    学习资料:https://programmercarl.com/栈与队列理论基础.html栈与队列学习记录:232.用栈实现队列(两个栈(stack_in,stack_out)实现一个队列的行为)点击查看代码classMyQueue(object):def__init__(self):self.stack_in=[]self.stack_out=[]d......
  • codeforces round 974(div.3)E(优先队列实现dijstra算法,devc++的优先队列用greater报
    解题历程:看到两边同时移动,计算最终的相遇时间,我就想到两边同时计算各点到起点的最短距离,就是使用dijstra算法,最后所有节点取两次计算的最大值,再对所有节点取最小值,就是最终答案了,可是这个思路没有考虑有马的情况,思考一番后发现可以多列一个数组记录有马的情况下的行走最短路,然后......