解锁数据库运维秘籍:掌握AntDB-T动态共享内存,提升进程间通信效率

动态共享内存是AntDB数据库通信的重要手段,本文主要阐述AntDB-T数据库动态共享内存的实现原理、实现方式与使用方法。

AntDB-T数据库是一款企业级通用分布式关系型数据库,其数据库内核是基于进程模型实现的,因此进程间通信(IPC)是实现分布式架构间进行任务协作和数据共享的关键。

实现进程间通信的方式有多种,例如管道、消息队列、信号量、共享内存等。在程序运行过程中,AntDB-T数据库为了实现进程之间更高效的通信和数据传输,采用了共享内存的方式。例如,AntDB-T数据库在并发任务需要创建多个工作进程的情况下,工作进程与后端进程之间的通信和数据传输将通过动态创建的共享内存来实现。       

(一)AntDB-T动态共享内存实现原理

那接下来本部分内容就为各位小伙伴慢慢解析AntDB-T数据库动态共享内存的原理。

AntDB-T动态共享内存是什么    

动态共享内存(dynamic shared memory):简称 DSM,在数据库运行期间可以动态创建出来的共享内存,动态共享内存允许AntDB-T在运行时动态地分配和释放内存,从而提高系统的性能和可伸缩性。

 AntDB-T中动态共享内存实现方式            

在AntDB-T中动态共享内存的实现方式有多种,由dynamic_shared_memory_type参数控制,默认是posix是指使用shm_open分配的POSIX shared memory。

图片

图1:dynamic_shared_memory_type 配置参数

dynamic_shared_memory_type参数定义如下表:

参数名称

dynamic_shared_memory_type

数据类型

enum

默认值

posix

取值范围

{posix,sysv,mmap,windows}  

其中posix,sysv,mmap适用于Linux平台;

windows适用于Windows平台

参数含义

指定PostgreSQL使用的dynamic shared memory的实现方式。

posix是指使用shm_open分配的POSIX shared memory;

sysv是指使用shmget分配的System V shared memory;

windows是指Windows shared memory;

mmap是指使用存在的data directory中的memory-mapped files模拟的shared memory。

通常不鼓励使用mmap值,这在任何平台上都不是默认值,因为操作系统可能会反复将修改过的页面写回磁盘,从而增加系统I/O负载;但是,当pg_dynshmem子目录存储在RAM磁盘上,或者其他共享内存工具不可用时,它可能对调试有用。        

是否可session级修改

修改后何时生效

重启AntDB-T instance生效

启用动态内存共享之后,当AntDB-T数据库启动后会在/dev/shm目录下有所体现,关了AntDB-T数据库之后,这些文件就没有了:

图片

图2:AntDB-T数据库启动后/dev/shm目录情况

图片

图3:AntDB-T数据库关闭后/dev/shm目录情况

AntDB-T为什么要引入动态共享内存

动态共享内存可以在运行时动态地分配和释放内存,从而使得内存管理更加灵活和高效,并且动态共享内存还可以实现延迟初始化(lazy initialization)和重新配置(reconfiguration)等特性,从而提高了系统的性能和可伸缩性。

在实际AntDB-T数据库中,动态共享内存在很多地方会用到,举个例子比如动态共享内存在并行中会用到,因为对于并行查询而言,执行时创建的DN worker进程与 DN leader进程通过共享内存实现数据交互。但这部分内存无法像普通的共享内存那样在系统启动时预先分配,毕竟直到真正执行时才知道有多少 DN worker进程,以及需要分配多少内存。动态共享内存,即在执行时动态创建,用于 DN leader与 DN worker间通信,执行完成后释放。    

(二)AntDB-T动态共享内存实现方式

下面将针对动态共享内存机制进行源码说明。本次以AntDB-T的代码为例,来解析动态共享内存的实现方式。

在AntDB-T源码中,dsm.c、dsm_impl.c文件提供了动态共享内存的功能,实现了共享内存的动态申请和释放。动态共享内存通过一个handle(typedef uint32 dsm_handle;)与一块内存进行映射,这个handle是一个32位无符号整数。在创建动态共享内存时,需要指定一个handle作为标识符,而访问动态共享内存时也是通过这个handle进行访问。不同进程之间通过传递handle来告知对方动态共享内存的位置,其他进程则通过handle来访问该动态共享内存。       

1.基础数据结构

dsm_control_header和dsm_control_item是动态共享内存里最基础的2个数据结构。定义如下图所示:    

图片

图4:dsm_control_header和dsm_control_item数据结构

dsm_control_header是动态共享内存的控制结构头,dsm_control_item记录每个分配的动态共享内存的状态,字段nitems表示动态共享内存当前已经使用的数量,字段maxitems表示动态共享内存的最大数量,字段refcnt表示 /* 2+ = active, 1 = moribund, 0 = gone */,字段impl_private_pm_handle表示仅在Windows上需要,字段pinned表示是否固定动态共享内存段,dsm_handle表示动态共享内存段的名字。

dsm_segment表示申请的一个共享内存段,对于动态共享内存的api来说这是代表共享内存的最小单位,定义如下图所示:

图片

图5:dsm_segment数据结构    

每个后端进程都可以通过使用dsm_segment来访问共享内存,dsm_segment包含了内存分配和释放等操作所需的信息,并提供了一组函数来管理和操作共享内存,每个会话(session)可以有一个或多个dsm_segment。其中字段mapped_address代表需要返回的当前映射共享内存的起始地址,字段resowner表示该动态共享内存段资源所有者,control_slot表示在控制动态共享内存段(dsm_control_header)里面的第几个item。      

2.初始化AntDB-T动态共享内存(DSM)

在 postmaster 主进程启动时,调用dsm_postmaster_startup(PGShmemHeader *shim)函数,进行动态共享内存相关的初始化,其主要逻辑如下:

 1)计算 dsm_control 结构所需要的内存大小:

1>计算所需共享内存的最大数量maxitems,

maxitems=PG_DYNSHMEM_FIXED_SLOTS+ PG_DYNSHMEM_SLOTS_PER_BACKEND * MaxBackends =64+5* MaxBackends

其中:PG_DYNSHMEM_FIXED_SLOTS为64,PG_DYNSHMEM_SLOTS_PER_BACKEND为5

该值(maxitems)与 MaxBackends大小有关,MaxBackends为最大的backend进程的数量,和配置的最大连接数(max_connections)、autovacuum worker进程的最大个数(autovacuum_max_workers)、并发进程的最大数量(max_worker_processes)、wal sender process的最大数量有关。

2>根据maxitems计算dsm_control 结构所需要的内存大小segsize,

segsize = dsm_control_bytes_needed(maxitems);

其中函数dsm_control_bytes_needed定义:  ​​​​​​​

static uint64dsm_control_bytes_needed(uint32 nitems){      return offsetof(dsm_control_header, item)            + sizeof(dsm_control_item) * (uint64) nitems;}

2)调用 dsm_impl_op() 函数,该函数根据dynamic_shared_memory_type参数调用不同的接口创建用于dsm_control 结构的动态共享内存,地址赋值给 dsm_control 变量,该变量的类型为 dsm_control_header 。

3)初始化 magic、nitems、maxitems变量,其中maxitems 表示AntDB-T该DN节点所有进程能够申请的动态共享内存的最大数量,nitems 表示当前已使用的动态共享内存数量,每一次动态共享内存申请,对应一个 dsm_control_item。

其函数大致调用关系如下:​​​​​​​

main(int argc, char *argv[])PostmasterMain(int argc, char *argv[])reset_shared(void)CreateSharedMemoryAndSemaphores(void)dsm_postmaster_startup(PGShmemHeader *shim)

3. 清理AntDB-T动态共享内存(DSM)

在 postmaster 主进程关闭时,会调用 dsm_postmaster_shutdown() 函数进行 dsm 的清理,这个函数是在初始化动态共享内存(dsm_postmaster_startup())时就指定了on_shmem_exit(dsm_postmaster_shutdown, PointerGetDatum(shim));

清理动态共享内存的主要逻辑:首先检查动态共享内存段是否已经损坏,如果损坏了就记录错误日志直接返回,如果没有损害时就遍历 dsm_control->nitems 数组,对其中正在使用的 item 对应的动态共享内存(DSM)进行销毁 ,最后再销毁 dsm_control 自身对应的 动态共享内存(DSM) 内存 。

(三)AntDB-T动态共享内存实践分享

使用动态共享内存之前,需要先对其进行创建。AntDB-T启动时已经初始化好了动态共享内存,后面使用的时候只需要创建动态共享内存,挂载动态共享内存,解除挂载动态共享内存,销毁共享内存。AntDB-T数据库使用动态共享内存的地方有很多,下面举个最简单的并行查询的例子来解说下如何使用动态共享内存,举例的表字段和并行查询的执行计划如下图所示:

图片

图6:AntDB-T 并行查询的例子

可以从上图的执行计划里面明确看到有使用到了并行查询,并且并行的worker个数是2。先进行简单的并行查询的原理介绍,图如下所示:DN backend主进程拉起从进程,DN backend主进程在处理时,发现需要进行并行处理,就会在启动从进程时,会调用 LaunchParallelWorkers 函数,这个函数会调用RegisterDynamicBackgroundWorker ,此时会给 Postmaster 进程发一个信号,请求 Postmaster 进程启动一个 background 进程,Postmaster 进程收到信号后就会启动一个新后台进程来处理查询。

图片

    图7:AntDB-T 并行查询的流程        

在 AntDB-T 的源码中,上述SQL例子在并行查询中使用动态共享内存(DSM),其主要逻辑如下:

1.DN backend主进程在判断需要进行并行处理时,就会初始化并行执行计划ExecInitParallelPlan,在ExecInitParallelPlan函数中,会评估共享内存大小:通过使用shm_toc_estimate_chunk、shm_toc_estimate_keys宏定义向estimate中增加数据结构,可以多次调用,然后使用shm_toc_estimate得出需要创建的动态共享内存的总大小,最后调用 dsm_create()函数 创建动态共享内存(DSM)。创建并行的工作进程时,将动态共享内存(DSM)对应的 handle 作为参数传递给 并行的worker 进程,其调用关系如下:

ExecGather(PlanState *pstate)ExecInitParallelPlan(PlanState *planstate, EState *estate,                               Bitmapset *sendParams, int nworkers,                               int64 tuples_needed)InitializeParallelDSM(ParallelContext *pcxt)dsm_create(Size size, int flags)LaunchParallelWorkers(ParallelContext *pcxt)worker.bgw_main_arg = UInt32GetDatum(dsm_segment_handle(pcxt->seg));

2.并行的子进程(DN worker 进程)先调用 dsm_attach() 函数挂载到动态共享内存,然后调用函数ParallelQueryMain处理查询业务该函数里面使用了动态共享内存,当并行的子进程执行结束时,会调用 dsm_detach() 函数解除挂载的 dsm 共享内存,其大致的调用关系如下:​​​​​​​

ParallelWorkerMain(Datum main_arg)seg = dsm_attach(DatumGetUInt32(main_arg));ParallelQueryMain(dsm_segment *seg, shm_toc *toc)area = dsa_attach_in_place(area_space, seg);dsa_detach(area)dsm_detach(area->segment_maps[i].segment);

总结

本文主要讲述了AntDB-T动态共享内存的基本概念、引入动态共享内存带来的能力提升、基本数据结构、动态共享内存机制原理和使用方法。限于篇幅,动态共享内存的其他函数接口比如:dsm_pin_mapping、dsm_unpin_mapping、dsm_pin_segment、其他使用动态共享内存的场景、动态共享内存中涉及的锁等相关内容没有涉及,小伙伴们请持续关注AntDB数据库公众号。            

关于AntDB数据库

AntDB数据库始于2008年,在运营商的核心系统上,为全国24个省份的10亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔电信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/154202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Appium移动自动化测试—如何安装Appium

前言 Appium 自动化测试是很早之前就想学习和研究的技术了,可是一直抽不出一块完整的时间来做这件事儿。现在终于有了。 反观各种互联网的招聘移动测试成了主流,如果再不去学习移动自动化测试技术将会被淘汰。 web自动化测试的路线是这样的&#xff1…

基于单片机的公共场所马桶设计(论文+源码)

1.系统设计 本课题为公共场所的马桶设计,其整个系统架构如图2.1所示,其采用STC89C52单片机为核心控制器,结合HC-SR04人体检测模块,压力传感器,LCD1602液晶,蜂鸣器,L298驱动电路等构成整个系统&…

1445 雉兔同笼

Tint(input()) for i in range(T):s input().split()head int(s[0])foot int(s[1])rabbitfoot/2-headchicken2*head-foot/2if rabbit>0 and chicken>0 and rabbit.is_integer():print(int(chicken),int(rabbit))else:print(-1)

多协议数据库管理软件 Navicat Premium 16 mac中文版功能

Navicat Premium 16 mac是一款跨平台数据库管理工具,支持多种数据库类型,如MySQL、MariaDB、Oracle、SQLite、PostgreSQL等等。它提供了丰富的数据库管理功能和工具,可以帮助开发人员和数据库管理员快速地创建、管理和维护数据库。 Navicat P…

比赛倒计时4天,快来做做2023年小学生古诗文大会复赛在线模拟题

2023年第八届上海小学生古诗文大会复选(复赛)定于11月25日上午举办(即本周六),具体安排和操作手册、注意事项请看我之前发布的文章:2023年11月25日小学生古诗文大会复选(复赛)答题操…

中石油勘探院张弢:从业务到架构全面探讨中国石油的数字化转型之路

引言:OSDU论坛的诞生与壮大,对油气行业的数字化有极大的推动力,国内油气行业正在紧锣密鼓地开展数字化转型、智能化发展。当前油气上游业务数字化转型正在轰轰烈烈的开展,一些明星油田的数字化率无限接近100%,基于业务…

ITIL® 4 Foundation​,即将开课~想了解点击查看

ITIL 4 Foundation 即将开课~ 想报名的必须提前预约啦 👇👇👇 2 0 23 年 培训地点: 远程直播:线上平台学习 开课时间: 周末班:11月25日、26日; 什么是ITIL? 信息技…

磐舟CI-Web前端项目

整体介绍 磐舟作为一个devops产品,它具备基础的CI流水线功能。同时磐舟的流水线是完全基于云原生架构设计的,在使用时会有一些注意事项。这里首先我们要了解磐舟整体的流水线打包逻辑。 文档结构说明 一般来说,磐舟推荐单个业务的标准git库…

C#实现观察者模式

观察者模式是一种软件设计模式,当一个对象的状态发生变化时,其所有依赖者都会自动得到通知。 观察者模式也被称为“发布-订阅”模式,它定义了对象之间的一对多的依赖性,当一个对象状态改变时,所有依赖于它的对象都会得…

SpringSecurity+JWT权限认证

SpringSecurity默认的是采用Session来判断请求的用户是否登录的,但是不方便分布式的扩展 虽然SpringSecurity也支持采用SpringSession来管理分布式下的用户状态,不过现在分布式的还是无状态的Jwt比较主流 一、创建SpringBoot的项目 spring-boot-starte…

Elasticsearch 和 LangChain 合作开发可用于生产的 RAG 模板

作者:Aditya Tripathi 在过去的几个月里,我们一直与 LangChain 团队密切合作,他们在推出 LangServe 和 LangChain 模板方面取得了进展! LangChain Templates 是一组用于构建生产质量的生成式 AI 应用程序的参考架构。 你可以在此处…

运动装备经营小程序商城效果如何

运动装备可包含服装、帐篷、渔具、箱包鞋帽等,对喜欢外出的人来说,靠谱的装备是关键,往往更容易选择品牌和信得过的商家。 而对商家来说,如何打造品牌提升卖货经营效率和提升营收是重中之重;互联网时代需要商家拓展线…

C语言19弹--交换数组元素

使用C语言实现交换数组元素 思路:使用头尾下标通过使用三方变量实现交换,注意头尾变量相等时单独进行交换。 1.头交换 int tmp1 arr1[left]; arr1[left] arr2[left]; arr2[left] tmp1;2.尾交换 int tmp2 arr1[right]; arr1[right] arr2[right];…

串口工作流程硬核解析,没有比这更简单的了!

串口通信,就是我们常说的串口通讯,是一种短距离、点对点的数据传输方式。它基于串行通信协议,通过串口线连接设备进行数据交互。串口在很多硬件系统中广泛使用,是工控机、单片机、外设设备之间信息交换的重要接口。 那串口是怎么工作的呢?我们举个形象的例子。假设A和B是两台…

SQL优化——如何写出高效率SQL

一.在查询SQL尽量不要使用select *,查询具体字段 1、反例 SELECT * FROM user 2、正例 SELECT id,username,tel FROM user 3、理由 节省资源、减少网络开销。 可能用到覆盖索引,减少回表,提高查询效率。 二、避免在where子句中使用 o…

【查找与排序】快速排序

一.改进冒泡排序 在冒泡排序中,记录的比较和移动是在相邻单元中进行的,记录每次交换只能上移或下移一个单元,因而总的比较次数和移动次数比较多。 改进的着眼点: 1.减少总的比较次数和移动次数 2.增大记录的比较和移动距离 3.较大…

Linux中路由route

一、Linux路由表 Linux路由表是一个内核数据结构,用来描述Linux主机与其它网络设备之间的路径,以及如何将数据包从源地址路由到目标地址。Linux路由表的主要组成部分包括:目的网络、下一跳、子网掩码和接口等信息。 (一&#xff…

Wireshark的数据包它来啦!

通过Wireshark工具,可以轻松的看到网卡的数据信息。通过Wireshark显示的数据包内容信息,通常分七栏,介绍一下: 1No.: 数据包编号。 2.Time Time显示时间,以1号数据包发生开始计时。 3.Source Source显示内容…

探秘TikTok社群:短视频中的共同体验

社交媒体平台TikTok成为全球用户分享创意、表达自我、建立连接的重要场所。在这个数字化的时代,TikTok社群不仅是个人创作者的聚集地,更是成千上万用户共同参与、体验的独特社交现象。 本文将深入探讨TikTok社群的形成、特点以及其中的共同体验&#xf…

[java进阶]——泛型类、泛型方法、泛型接口、泛型的通配符

🌈键盘敲烂,年薪30万🌈 目录 泛型的基础知识: ♥A 泛型的好处: ♠A 泛型擦除: ♣A 泛型的小细节: 泛型的使用: ①泛型类: ②⭐泛型接口: ③泛型方法&…