如何设计好分布式数据库,这个策略很重要(GaussDB)

news/2024/11/27 11:06:03/文章来源:https://www.cnblogs.com/xxxmut/p/18571932


数据库是应用和计算机的核心组成,试想,如果没有数据库,就像人的大脑没有了记忆一样,信息也得不到共享,那么,对开发者来说,如何设计一款高效易用的数据库至关重要。

GaussDB是企业级分布式数据库,具备分布式强一致、有效降低容灾成本、支持PB级海量数据、智能诊断等优点,是当下炙手可热的主流数据库,那么如何更好的设计分布式数据库的数据分布策略呢?

首先介绍一下GaussDB的基本架构,便于理解后面的分析。
在这里插入图片描述

图 逻辑架构

这个是一个典型的基于数据分片的分布式架构(share nothing),底层数据通过一定的规则比如hash、list或者range等让数据打散分布到不同的数据节点上,计算时底层多个节点共同参与计算。同时数据节点可以扩展,上层由协调节点进行SQL解析和转发。

从图中可以看到,主要包括三类节点:协调节点、数据节点、集群类节点(最重要的是全局事务管理器)。协调节点负责SQL解析转发,充当的是类似proxy的角色,数据节点负责计算和数据存储,全局事务管理器负责全局事务读一致性的保证。

在这里插入图片描述

表 关键角色

分布式SQL执行过程
在这里插入图片描述

大致执行过程:

业务应用下发SQL给Coordinator ,SQL可以包含对数据的CRUD操作;
Coordinator利用数据库的优化器生成执行计划,每个DN会按照执行计划的要求去处理数据;
数据基于一致性Hash算法分布在每个DN,因此DN在处理数据的过程中,可能需要从其他DN获取数据,GaussDB提供三种stream流(广播流、聚合流和重分布流)实现数据在DN间的流动;
DN将结果集返回给Coordinate进行汇总;
Coordinator将汇总后的结果返回给业务应用。
数据分布策略场景实践
拿电子商城来举例,一个完整的商城会包括很多信息,例如用户、产品、订单、仓库、物流、支付等等很多信息。以下用订单、支付方式、快递公司这3个信息为例,这3个信息也只列出少量关键属性来举例。

step1、数据库逻辑模型设计
在这里插入图片描述

step2、功能设计
常用场景一、查看子订单列表

Select sn, status, money, product_id, product_mount from order t1, suborder t2 where t1.id = t2.order_id and t1.sn=’xxx’;

常用场景二、查看子订单详情

Select product_id, product_mount, t2.name as shipping_name, t3.name as pay_type_name from suborder t1, shipping_com t2, pay_type t3 where t1.id=’xx’ and t1.shipping_id=t2.id and t1.pay_type_id=t3.id;

step3、物理数据模型设计
电子商城每天的订单量非常巨大,使用传统的主备库模式显然无法满足如此大数据量的请求和存储需要。而跨节点、可横向扩展的分布式数据库可以很好解决大规模海量数据的计算存储问题。GaussDB分布式模式最大可以支持1000+节点,PB级存储,分布式事务强一致等特性可以很好地满足政府、交通、金融、能源等行业的互联网+的诉求。

这个场景中,订单表和支付方式表代表着两类数据,前者同客户数、时间正相关,一个中型的商城每天的数据可能就达到了百万条记录,暂记为A类数据;后者数据变化较小,往往是配置类的数据,暂记为B类数据。功能模块中存在A类数据之间的相互关联以及A与B类数据的关联。那么在分布式数据库下,当数据分布在不同的节点上,以上能否直接关联呢?如果能够关联的话,怎么样设计才能更好的达到性能上的要求呢?

对于分布式数据库而言,如何使得以上的场景能够得到更好的性能,关键的是把表的数据分布策略选择好,而像分区、索引等设计同传统的单机差别不大。因此要回答这个问题,我们需要先了解GaussDB的数据分布策略。

数据分布策略
GaussDB支持的数据分布策略
分布存储和并发查询是MPP架构数据库的主要优势所在。将一个大数据量表中的数据,按合适分布策略分散存储在多个DN实例内,可极大提升数据库性能。

GaussDB V5支持如下表所示的数据分布策略:
在这里插入图片描述

下面这张图可以帮忙我们清晰地理解复制表和分布表,前者每个DN上都是一个完整的表,而后者每个DN上只是一个分片。

在这里插入图片描述

语法:

创建复制表
create table region1(ctid_value int) distribute by replication;
创建分布表
create table region2(ctid_value int) distribute by hash(ctid_value);
说明:当不指定分布方式,创建表默认为(第一个可以作为分布列的列为分布键)分布表

看到这里这里,很多人马上就会明白,订单表和子订单表适合用分布表,支付方式表和快递公司表适合用复制表,那么是为什么呢? 让我们先了解下分布表及复制表的关联过程。
在这里插入图片描述

分布表及复制表关联过程
(1)分布表和复制表的关联查询
在这里插入图片描述

T1为hash表,T2为复制表。
T1表的每一部分在各DN上分别与T2表进行连接。
各DN上的连接结果集在CN上进行汇聚,产生最终输出的结果集。
(2)分布表与分布表关联查询

在这里插入图片描述

T1表和T3表都为分布表。
在DN1实例上,T1表的p1部分与T3表的T1部分进行关联。
T3表的p2、p3、p4复制到DN1上,与T1的p1部分进行关联。
DN2、DN3、DN4实例操作与DN1类似。
CN节点对各DN生成的结果集进行汇聚,生成最终数据结果集。
注:细心的朋友可能看到,不同的DN之间可能会进行数据同步,在这种情况下,执行效率会就变差,如何避免这种情况,下面会讲到。

分布键的选择
在这里插入图片描述

尽量选择distinct值比较多的列,保证数据均匀分布。分布均匀是为了避免木桶效应,各个主机对等执行。
尽量选择Join列或group 列做分布列。尽量选择Join列或group 列是为了避免数据节点之间数据流动, 提高性能。
避免数据广播
在分布表关联分布时,分布列不同时,存在Streaming(type: BROADCAST)广播,不同DN节点之间数据存在交互,会增加网络开销,而分布列相同或关联复制表数据时,不存在DN节点间数据交互。下面我们进行下实际测试:

例如对于表t1,t2,我们使用不同的分片列进行关联:select * from t1, t2 where t1.a = t2.b;

方式1:t1、t2都选择a做分布列

create table t1 (a int, b int) distribute by hash (a);
create table t2 (a int, b int) distribute by hash (a);

其执行计划如下:
在这里插入图片描述

方式2:将a作为t1的分布列,将b作为t2的分布列:

create table t1 (a int, b int) distribute by hash (a);
create table t2 (a int, b int) distribute by hash (b);

重新查看执行计划如下:
在这里插入图片描述

分析:方式1由于存在“Streaming”,导致Datanode之间存在较大通信数据量。

避免数据倾斜
判断是否已发生数据倾斜现象

SELECT a.count,b.node_name FROM (SELECT count(*) AS count,xc_node_id FROM tablename GROUP BY xc_node_id) a, pgxc_node b WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC;

如果各DN内元组数目相差较大(如相差数倍、数十倍),则表明已发生数据倾斜现象,请按照下面原则调整分布列。

重新选择分布列,重新建表
当前不支持通过ALTER TABLE语句调整分布列,因此,调整分布列时需要重新建表。

选择原则如下: 分布列的列值应比较离散,以便数据能够均分布到各个DN。

例如,考虑选择表的主键为分布列,如在人员信息表中选择身份证号码为分布列。 在满足上面原则的情况下,考虑选择查询中的连接条件为分布列,以便Join任务能够下推到DN中执行,且减少DN之间的通信数据量。

总结

GaussDB是分布式架构,数据分布在各个DN上,设计好的数据分布策略是分布式数据库设计中最关键的环节。本文结合电子商城场景讲述了支持的数据分布策略、分布键的选择以及关联过程,还讲述了应该规避的问题。理解了以上这些内容后,相信你可以结合自己的业务场景,设计出最佳的数据分布策略。





详情参考: https://support.huaweicloud.com/gaussdb/index.html

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

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

相关文章

[Linux]缓冲区的理解

缓冲区的理解 先来看这段代码 #include <stdio.h> #include <unistd.h> #include <string.h>int main() {//C接口printf("hello printf\n");fprintf(stdout, "hello fprintf\n");fputs("hello fputs\n", stdout);//系统接口co…

Ollama本地部署Qwen2.5 14B(使用docker实现Nvidia GPU支持)

通过docker部署支持Nvidia GPU加速的本地大模型前提条件:已经本地安装好了Ollama。 如果没有安装Ollama或者想部署其他的模型或者不想使用docker,,可以参考之前的这篇文章: https://www.cnblogs.com/Chenlead/p/18571005 安装过程参考:https://docs.openwebui.com/getting…

Jmeter 临界部分控制器 Critical Section Controller

Jmeter必知利器-临界部分控制器-腾讯云开发者社区-腾讯云 Jmeter之临界部分控制器使用-CSDN博客 使用前,线程执行顺序随机 使用后,线程执行顺序从上到下

dedecms提示500错误解决方法

查看网站程序版本:打开 /data/admin/ver.txt 文件查看 查看主机PHP版本:在主机面板查看或创建一个 p.php 文件,内容为 <?php phpinfo(); ?>,上传到网站根目录,访问 http://域名/p.php 查看PHP版本,完成后删除 p.php 低版本织梦(2014、2015、2016、2017开头)无法…

自动检测工作人员工服穿戴规范行为

自动检测工作人员工服穿戴规范行为利用现场安装的高清摄像机,自动检测工作人员工服穿戴规范行为对采集到的视频进行预处理,识别出图像中的员工,并检测其工服穿戴情况,一旦系统判断出工服穿戴异常,将立即发出警报,通知管理人员或自动启动相应的安全措施。通过实时监测,及…

Docker Logs清理

查看docker日志路径 docker inspect --format={{.LogPath}} <container_name_or_id>清理docker日志 echo |sudo tee $(docker inspect --format={{.LogPath}} <container_name_or_id>).zstitle { width: 280px; text-align: center; font-size: 26px } .zsimgwei…

hhdb数据库介绍(9-9)

高可用服务 读写分离 计算节点支持读写分离功能,并且支持配置读写分离权重 读写分离功能说明 要使用读写分离功能,需在数据节点中配置主备存储节点。 读写分离功能默认设置为关闭。开启读写分离功能,可在计算节点的配置文件server.xml中,将strategyForRWSplit属性设置为大于…

调制与解调(AM和DSB)

调制 调制 调制大信号 小信号 小信号>100mV, <100mV <100mVAM 数学原理 开关函数 平方律弧度区器件形式 二极管(非环)↓ 三极管(基极集电极调幅)↓ 场效应管 差分放大器 二极管 三极管 场效应管(平方律器件)DSB 数学原理 开关函数 双曲正切->线性区器件形式 二极管…

编写bash脚本快速kill或启动tomcat

​假设tomcat安装路径为 /home/tomcat,示例如下: 1. kill tomcat进程 vim kill-tomcat-force.sh set fileformat=unix path=/home/tomcat/binecho"exec $path/shutdown.sh" $path/shutdown.shsleep3s#kill -9 pid ps -ef|grep $path|grep tomcat|awk {print $2}|xar…

网页本地预览正常, 上传服务器后乱码、错位是怎么回事

网站本地预览正常, 如果上传后出现错位和乱码, 大概率是css或者js没有正确引入导致的。 这种情况处理比较简单, 检查文件路径并修复即可。 但有一种特殊情况, 各种文件路径都对, 通过浏览器也可以正常访问, 但前端页面就是错位。 那你检查一下, 网页源代码中是否存在以…

问EBS R12中怎样实现输出格式是多sheet页excel报表,不用excel模板实现,而是在sqlplus中用xml或者html代码来实现

https://www.itpub.net/thread-2094848-1-1.html 来源手工创建一个EXCEL,放一些数据进去,然后另存为xml表格,用notepad打开看看,里面有代码。把代码用SQL拼接起来。<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?>&l…

postman: 提交的文本中有+加号时在服务端变成了空格

一,现象:如果填写参数时使用的是params类型,而value中包含+,则此时的值在提交到线上时会被替换成空格,原因是:使用params类型参数和值会拼接在url中二,解决:在body标签下,使用form-data类型,此时的各项值不会被拼接到url中,+也就不会被替换成空格了