首页 > 其他分享 >百日筑基第十九天-一头扎进消息队列2

百日筑基第十九天-一头扎进消息队列2

时间:2024-07-12 23:31:13浏览次数:18  
标签:协议 存储 文件 队列 筑基 第十九 消息 数据

百日筑基第十九天-一头扎进消息队列2

在这里插入图片描述

消息队列的通讯协议

目前业界的通信协议可以分为公有协议和私有协议两种。公有协议指公开的受到认可的具有规 范的协议,比如 JMS、HTTP、STOMP 等。私有协议是指根据自身的功能和需求设计的协 议,一般不具备通用性,比如 Kafka、RocketMQ、Puslar 的协议都是私有协议。

大多数消息队列为了自身的功能支持、迭代速度、灵活性考虑,在核心通信协议的选择上 不会选择公有协议,都会选择自定义私有协议

从技术上来看,私有协议设计一般需要包含三个步骤。

  1. 网络通信协议选型,指计算机七层网络模型中的协议选择。比如传输层的 TCP/UDP、应用 层的 HTTP/WebSocket 等。 从功能需求出发,为了保证性能和可靠性,几乎所有主流消息队列在核心生产、消费链路的协 议选择上,都是基于可靠性高、长连接的 TCP 协议。
  2. 应用通信协议设计,指如何约定客户端和服务端之间的通信规则。比如如何识别请求内容、 如何确定请求字段信息等。 从应用通信协议构成的角度,协议一般会包含**协议头(数据源信息)和协议体(业务数据)**两部分。
  3. 编解码(序列化 / 反序列化)实现,用于将二进制的消息内容解析为程序可识别的数据格式(或反过来用于传输)。

消息队列的网络模块

网络模块:对消息队列来说,网络模块是核心组件之一,网络模块的性能很大程度上决定了消息传输的能力和整体性能。

消息队列是需要满足高吞吐、高可靠、低延时,并支持多语言访问的基础软件,网络模块最需要解决的是性能、稳定性、开发成本三个问题。

从技术上来看,高性能网络模块的设计可以分为如何高效管理大量的 TCP 连接如何快速处理高并发的请求如何提高稳定性和降低开发成本等三个方面。

  1. 高效处理大量 TCP 连接:在消息队列中主要有**单条 TCP 连接的复用(RabbitMQ)IO多路复用(Kakfa、RocketMQ、Pulsar )**两种技术思路。
  2. 快速处理高并发的请求:Reactor 模型是一种处理并发服务请求的事件设计模式,当主流程收到请求后,通过多路分离处理的方式,把请求分发给相应的请求处理器处理。
  3. 提高稳定性和降低开发成本:在消息队列的网络编程模型中,为了提高稳定性或者降低成本,选择现成的、成熟的 NIO 框架是一个更好的方案(kafka如是)。

消息队列的存储模块

存储模块作为消息队列高吞吐、低延时、高可靠特性的基础保证,可以说是最核心的模块。

消息队列中的数据一般分为元数据消息数据。元数据是指 Topic、Group、User、ACL、Config 等集群维度的资源数据信息,消息数据指客户端写入的用户的业务数据。

  1. 元数据信息的存储:元数据信息的特点是数据量比较小,不会经常读写,但是需要保证数据的强一致和高可靠,不允许出现数据的丢失。基于第三方组件来实现元数据的存储是目前业界的主流选择。比如 Kafka ZooKeeper 版本、 Pulsar、RocketMQ 用的就是这个思路,其中 Kakfa 和 Pulsar 的元数据存储在 ZooKeeper 中,RocketMQ 存储在 NameServer 中。另一种思路,集群内部实现元数据的存储是指在集群内部完成元数据的存储和分发。也就是在 集群内部实现类似第三方组件一样的元数据服务,比如基于 Raft 协议实现内部的元数据存储 模块或依赖一些内置的数据库。目前 Kafka 去 ZooKeeper 的版本、RabbitMQ 的 Mnesia、 Kafka 的 C++ 版本 RedPanda 用的就是这个思路。

  2. 数据消息的存储:第一个思路,每个分区对应一个文件的形式去存储数据(kafka如是)。因为消息队列在大部分情况下的读写是有序的,所以这种机制在读写性能上的表现是最高的。第二种思路,每个节点上所有分区的数据都存储在同一个文件中,这种方案需要为每个分区维护一个对应的索引文件,索引文件里会记录每条消息在 File 里面的位置信息,以便快速定位到具体的消息内容。(目前 RocketMQ、RabbitMQ 和 Pulsar 的底层存储 BookKeeper 用的就是这个方案)

数据分段的规则一般是根据大小来进行的,比如默认 1G 一个文件,同时会支持配置项调整分段数据的大小。

从技术上来看,当数据段到达了规定的大小后,就会新创建一个新文件来保存数据。

如果进行了分段,消息数据可能分布在不同的文件中。所以我们在读取数据的时候,就需要先 定位消息数据在哪个文件中。为了满足这个需求,技术上一般有根据偏移量定位或根据索引定位两种思路。

  1. 根据偏移量(Offset)来定位消息在哪个分段文件中,是指通过记录每个数据段文件的起始偏 移量、中止偏移量、消息的偏移量信息,来快速定位消息在哪个文件。
  2. 如果用索引定位,会直接存储消息对应的文件信息,而不是通过偏移量来定位到具体文件。(RabbitMQ 和 RocketMQ 如是)

消息数据存储格式一般包含消息写入文件的格式和消息内容的格式两个方面。

  1. 消息写入文件的格式指消息是以什么格式写入到文件中的,比如 JSON 字符串或二进制。从 性能和空间冗余的角度来看,消息队列中的数据基本都是以二进制的格式写入到文件的。
  2. 消息内容的格式是指写入到文件中的数据都包含哪些信息。对于一个成熟的消息队列来说,消 息内容格式不仅关系功能维度的扩展,还牵涉性能维度的优化。(如Kafka 的消息内容包含了业务会感知到的消息的 Header、Key、Value,还包含了时间戳、偏移量、协议版本、数据长度和大小、校验码等基础信息,最后还包含了压缩、事 务、幂等 Kafka 业务相关的信息)

消息队列中的数据最终都会删除,时间周期短的话几小时、甚至几分钟,正常情况一天、三 天、七天,长的话可能一个月,基本很少有场景需要在消息队列中存储一年的数据

消息队列的数据过期机制一般有手动删除和自动删除两种形式。从实现上看主要有三种思路: 消费完成执行 ACK 删除、数据根据时间和保留大小删除、 ACK 机制和过期机制相结合。

标签:协议,存储,文件,队列,筑基,第十九,消息,数据
From: https://blog.csdn.net/qq_45477639/article/details/140390632

相关文章

  • 7-循环队列的基本操作
    顺序队列的操作#include<stdio.h>#include<stdlib.h>#include<stdbool.h>typedefintElemType;#defineMaxSize50/*顺序队列的类型定义*/typedefstruct{/*用一维数组存放队列元素*/ElemTypedata[MaxSize];/*队头指针*/intfront;/*......
  • 数据结构(Java):队列&集合Queue&力扣面试OJ题
    1、队列1.1队列的概念队列是一个特殊的线性表,只允许在一端(队尾)进行插入数据操作,在另一端(对头)进行删除数据。队列具有先进先出FIFO(FirstInFirstOut)的特性。入队:数据只能从队尾进队列    出队:数据只能从对头出队列即:队尾进队头出我们可以把队列想象为一个排队......
  • 「代码随想录算法训练营」第九天 | 栈与队列 part1
    232.用栈实现队列题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/题目难度:简单文章讲解:https://programmercarl.com/0232.用栈实现队列.html视频讲解:https://www.bilibili.com/video/BV1nY4y1w7VC题目状态:看视频讲解后通过思路:通过两个栈来实现队......
  • 代码随想录算法训练营第10天 | 复习队列和栈
    2024年7月12日题232.用栈实现队列两边倒即可,要出队列就倒到右边去,然后再回来。classMyQueue{Stack<Integer>s1;Stack<Integer>s2;intsize;publicMyQueue(){s1=newStack<>();s2=newStack<>();size=0;}......
  • Day9(栈与队列) | **232.用栈实现队列** **225. 用队列实现栈** **20. 有效的括号**
    232.用栈实现队列请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现MyQueue类:voidpush(intx)将元素x推到队列的末尾intpop()从队列的开头移除并返回元素intpeek()返回队列开头的元素booleanempty()如果队列为......
  • 队列+二叉树广度优先
    题目出自力扣-n叉树的层序遍历我是原始人,递归写出一道题就只有递归思路,开始的想法是写深搜函数,传一个随着层数递增的int参数q,节点空就return,否则遍历所有节点,每个子节点又以q+1为层数递归,然后收集每一层的val即可代码;/*//DefinitionforaNode.classNode{public......
  • Qt开发: 推荐一个缓冲队列操作类的实现
    一.缓冲队列的背景    缓冲队列主要应用在生产者和消费者之间,保证数据的准确不丢失,提高效率。举个例子:如上图,假设点击按钮生成一个方块,方块生产出来需要耗时1s,生成完毕后显示在界面上;然后点击10下按钮,要生产10个按钮预计耗时10s。二.分析问题    点击按......
  • 代码随想录算法训练营Day11 | 栈与队列基础 232.用栈实现队列 225. 用队列实现栈 20.
    栈与队列栈:先进后出   empty-push-push-pop队列:先进先出Tips: 栈和队列是STL(C++标准库)里面的两个数据结构。STL最旁边的三个版本:HPSTL、P.J.PlaugerSTL、SGISTL232.用栈实现队列题目:232用栈实现队列在python中,in主要负责push,out主要负责pop初始:self.......
  • 信息学奥赛初赛天天练-43-CSP-J2020基础题-链表、连通图、2进制转10进制、栈、队列、
    PDF文档公众号回复关键字:202407102020CSP-J选择题单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项)7.链表不具有的特点是()A.可随机访问任一元素B.不必事先估计存储空间C.插入删除不需要移动元素D.所需空间与线性表长度成正比8.有10个顶点的无向图至少......
  • Day9 用栈实现队列,用队列实现栈,有效的括号,删除字符串中相邻项
     用栈来实现队列#include<iostream>usingnamespacestd;#include<stack>stack<int>input,output;voidpush(intx){ input.push(x);}intpop(){ while(!input.empty()) { intp=input.top(); output.push(p); input.pop(); } intrsuul......