GaussDB(DWS)中共享消息队列实现的三大功能
摘要:本文将详细介绍GaussDB(DWS)中共享消息队列的实现。
本文分享自华为云社区《GaussDB(DWS)CBB组件之共享消息队列介绍》,作者:疯狂朔朔。
1)共享消息队列是什么?
在前文中,我们讲解了SysCache的实现原理,GaussDB(DWS)通过SysCache缓存表元数据,以加速查询,然而在并发查询过程中,不可避免地会出现需要同步元数据的情况,举个简单例子,假设存在以下语句执行流程:
- Create table abc(会话1)
- Select * from abc(会话1)
- Drop table abc(会话2)
- Select * from abc(会话1)
在会话1中,会连续两次执行Select表操作(b和d),在b语句执行后,会话1将对abc的元数据进行缓存,缓存到SysCache中,以备后续使用。然而,在c语句执行后,需要对会话1中的元数据进行失效,否则,会话1将在执行d语句过程中发生错误,读取已删除的数据。
那么,会话2如何“通知”会话1失效哪些数据呢?答案是共享消息队列。
2)共享消息队列存储结构
如图所示,为共享消息队列数据结构
图示中主要包括两部分,下面部分为ThreadLocal结构,主要记录的是每个线程内部的数据,线程间数据是独立的,无法互相访问,上面部分为共享消息队列中的数据,共享消息队列存在于共享内存中,可同时被多个线程访问,共享消息队列的访问场景是典型的一写多读场景。
在共享消息队列中,核心变量有三个,nextMsgNum、minMsgNum、MaxMsgNum,其中nextMsgNum记录了每个线程消息读取到的位置,minMsgNum记录了共享消息队列中最早消息的位置,maxMsgNum记录了共享消息队列中最新消息的位置,对于每个线程而言,需要定期(在表加锁/事务开始/收到信号时触发)从共享消息队列中读取失效消息,利用失效消息(共享消息队列中的每个消息)更新线程内部数据,同时,若线程内部产生失效消息(通常DDL语句在事务提交时产生大量失效消息),则需要向共享消息队列中插入失效数据,供其他线程读取。另外,还有两个参数,hasMessages、resetState,其中hasMessages用于标记对应线程是否存在未读取的失效消息,resetState用于标记对应线程是否需要失效全部消息。
NOTE:失效数据有哪些?失效消息一共有六类(源自PG),有兴趣的同学可以研读PG源码,在此处我们不再展开,仅需知道线程需要从共享消息队列中读取/插入消息,以实现数据同步。
3)共享消息队列接口实现
共享消息队列本质上对于外部接口只需要提供三个功能:读取共享消息队列中消息、向共享消息队列中写入消息、清理共享消息队列。
3.1)读取共享消息队列
如图所示,为失效消息读取过程。在线程同步失效消息过程中,有几个关键点:
- 若共享内存中线程对应的hasMessage为True,则表示有失效消息需要读取,否则直接返回,无新的失效消息。
- 读取失效消息过程中,需要持有读共享锁,以保证读取的消息不会被清理掉。
- 若读取失效消息过程中,发现resetState被置为True,说明该线程已经无法使用共享消息队列中的消息进行追增,需要对缓存进行全失效。缓存全失效相当于追增全部数据,需要将nextMsgNum置为maxMsgNum。缓存全失效将严重降低SQL执行性能,尽量减少缓存全失效的发生频率。
- 在追增数据过程中,会推进线程自身的nextMsgNum,以标记数据追增位置。
NOTE:在读取共享消息队列过程中,每个线程推进自己的nextMsgNum位置,以方便记录数据追增情况。
3.2)向共享消息队列中写入消息
如图所示,为失效消息写入过程。有以下几个关键点:
- 写入失效消息过程,需要调用清理共享消息队列接口,以保证有足够多的空位写入失效消息。
- 在写入失效消息过程中,会更新maxMsgNum。
- 写入失效消息完毕以后,需要将其他线程的hasMessage标记为True。
- 写入失效消息过程,需要持排他写锁,阻塞其他线程写操作,但不阻塞读。
NOTE:写入失效消息过程实际上是推进maxMsgNum的过程,同时告知其他线程有新的失效消息需要读取。
3.3)清理共享消息队列
如图所示,清理共享消息队列过程中,有以下几个关键点:
- 清理共享消息队列需要持有排他读锁和排他写锁,阻塞读过程。其主要原因是,清理共享消息队列会推进minMsgNum,若不持读锁,可能导致nextMsgNum读取过期数据。
- 清理共享消息队列会推进minMsgNum。
- 清理共享消息队列过程,会将所有没有及时追增失效消息的线程执行全失效。
- 在清理共享消息队列最后步骤,会对距离minMsgNum最近的线程,发送追增信号,以确保不会频繁发生全失效。该步骤主要考虑的情况是,若线程长时间处于idle状态,需要外部信号触发其及时追增消息。
NOTE:清理共享消息队列过程,实际上是推进minMsgNum的过程,同时对所有没有及时追增失效消息的线程执行全失效。
根据以上共享消息队列接口可知,读取共享消息队列主要负责推进各个线程自身的nextMsgNum;写入失效消息主要负责推进maxMsgNum;清理共享消息队列主要负责推进minMsgNum。通过共享消息队列,可有效实现各个线程之间的数据同步。
GaussDB(DWS)中共享消息队列实现的三大功能的更多相关文章
- 工业物联网或系统集成中应用消息队列(ActiveMQ,C#的demo)的场景全面分析
1.[连载]<C#通讯(串口和网络)框架的设计与实现> 2.[开源]C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 2.应用SuperIO(SIO)和开源跨平台物联网框 ...
- C#中使用消息队列RabbitMQ
在C#中使用消息队列RabbitMQ 2014-10-27 14:41 by qy1141, 745 阅读, 2 评论, 收藏, 编辑 1.什么是RabbitMQ.详见 http://www.rabb ...
- Handler机制中的消息队列
--> 学习自蘑菇街大佬 Handler机制可以看成是一个消息阻塞队列,当有消息时立即处理消息,没有消息时则阻塞.在Android系统中APP启动后很快进入死循环,不断读取MessageQueu ...
- 在C#中使用消息队列RabbitMQ
1.什么是RabbitMQ.详见 http://www.rabbitmq.com/. 作用就是提高系统的并发性,将一些不需要及时响应客户端且占用较多资源的操作,放入队列,再由另外一个线程,去异步处理这 ...
- 如何应用.NET中的消息队列服务
建立一个队列是应用MSMQ的第一步.您可以通过Windows计算机管理控制台中的消息队列选项完成这一操作,或者自己编程建立一个队列.列表A中的C#代码建立了一个新的私有MSMQ消息队列(如果不存在队列 ...
- 在WCF中使用消息队列
在一些大型的解决方案中,假设我们的服务没有办法一直在线,或者因为这样那样的原因宕机了,有没有什么办法让客户端的影响最小化呢?答案是可以通过消息队列的方式,哪怕服务是没有在线的,客户端依然可以继续操作. ...
- .NET中的消息队列
下文参考:http://hi.baidu.com/21tian/blog/item/ce5464097ddf10cb3ac76335.html为何使用消息队列 您可能认为您能够通过一个简单的数据库表( ...
- 删除MSMQ中的消息队列时"访问被拒绝的错误"
删除MSMQ中消息队列时出现 google之,发现也没有找到解决方法,自己在琢磨一下,一般出现这种问题的都是权限问题,因此查看了一下属性,果然如此 此消息队列是使用Windows服务创建的 解决办法: ...
- [Go]TCP服务中增加消息队列与工作池
之前的处理中每一个连接都会创建一个主groutine , 每个连接中的主groutine中创建出读groutine 和写groutine 每个连接处理业务再单独开出一个groutine ,这样如果有1 ...
随机推荐
- [luogu3706]硬币游戏
(可以参考洛谷4548,推导过程较为省略) 定义$g_{i}$表示随机$i$次后未出现给定字符串的概率,$f_{k,i}$表示随机$i$次后恰好出现$s_{k}$(指第$k$个字符串)的概率,设两者的 ...
- [JS高程]JavaScript中的RegExp对象
目录 1. RegExp 1.1 表示格式: 1.2 匹配模式: 1.3 RegExp 实例属性 1.4 RegExp 实例方法 1.4.1 exec() 1.4.1.1 基本用法 1.4.1.2 e ...
- 初识XSS攻击
初识XSS攻击 本文参考于<白帽子讲Web安全>第3章跨站脚本攻击(XSS),该书出版于2014年,因而现在可能存在一些新场景或新技术而未被提及,但本文对学习和了解XSS攻击仍具有重要价值 ...
- 解决 IDEA 2021.2.3 新建maven项目只有两个archetype项目模板的问题
最近把我的 IDEA 版本更新到 2021.2.3 了,发生了一个比较有意思的问题,做个小小的记录 思路分析 在新的 IDEA 中配置完Maven之后,想要创建Maven项目的时候没有自动加载arch ...
- Java跟JavaScript两者间的关系和区别
想必很多人在刚接触和认识Java的时候,都好奇它与JavaScript之间的关系,长得这么像,难道是出自同门的升级版?嗯,他们的发明者确实颇具渊源,而且客观来说,JS确实相较Java更加简洁大众,但它 ...
- 洛谷 P4887 -【模板】莫队二次离线(第十四分块(前体))(莫队二次离线)
题面传送门 莫队二次离线 mol ban tea,大概是这道题让我第一次听说有这东西? 首先看到这类数数对的问题可以考虑莫队,记 \(S\) 为二进制下有 \(k\) 个 \(1\) 的数集,我们实时 ...
- CF1553 部分题解
CF1553D Backspace 题目传送门. 题意简述:给定 \(s,t\),现在要依次输入 \(s\) 中的字符.对于每个字符 \(s_i\),你可以选择输入 \(s_i\) 或者使用退格键,判 ...
- 解决 Ubuntu 下 gedit编辑器打开文件出现中文乱码问题
解决 Ubuntu 中 gedit编辑器打开文件出现中文乱码问题 1. 问题分析 在 windows 系统下,.txt 文件默认编码方式为 gb18030 格式的中文编码,而 gedit 默认的编码方 ...
- 【豆科基因组】普通豆/菜豆/四季豆Common bean (Phaseolus vulgaris L.) 683个自然群体重测序2020NG
目录 一.来源 二.结果 683份材料重测序 地方种landraces和育种品系breeding lines的多样性 表型和基因-环境互作(G by E) 菜豆产量潜力相关的MTAs(显著关联位点) ...
- perl练习——计算点突变
题目来源:http://rosalind.info/problems/hamm/ 一.程序目的:计算序列点突变(Point Mutations) 输入: GAGCCTACTAACGGGAT CATCG ...