分布式场景怎么Join

背景

最近在阅读查询优化器的论文,发现System R中对于Join操作的定义一般分为了两种,即嵌套循环、排序-合并联接。

考虑到我的领域是在处理分库分表或者其他的分区模式,这让我开始不由得联想我们怎么在分布式场景应用这个Join逻辑,对于两个不同库里面的不同表我们是没有办法直接进行Join操作的。查阅资料后发现原来早有定义,即分布式联接算法。

分布式联接算法

跨界点处理数据即分布式联接算法,常见的有四种模型:Shuffle Join(洗牌联接)、Broadcast Join(广播联接)、MapReduce Join(MapReduce联接)、Sort-Merge Join(排序-合并联接)。

接下来将进行逐一了解与分析,以便后续开发的应用。

Shuffle Join(洗牌联接)

先上原理解释:

Shuffle Join的核心思想是将来自不同节点的数据重新分发(洗牌),使得可以联接的数据行最终位于同一个节点上。

通常,对于要联接的两个表,会对联接键应用相同的哈希函数,哈希函数的结果决定了数据行应该被发送到哪个节点。这样,所有具有相同哈希值的行都会被送到同一个节点,然后在该节点上执行联接操作。

可能解释完还是有点模糊,举个例子,有两张表,分别以id字段进行分库操作,且哈希算法相同(为了简单,这里只介绍分库场景,分库分表同理。算法有很多种,这里举例是hash算法),那么这两张表的分片或许可以在同一个物理库中,这样我们不需要做大表维度的处理,我们可以直接下推Join操作到对应的物理库操作即可。

在ShardingSphere中,这种场景类似于绑定表的定义,如果两张表的算法相同,可以直接配置绑定表的关系,进行相同算法的连接查询,避免复杂的笛卡尔积。

这样做的好处是可以尽量下推到数据库操作,在中间件层面我们可以做并行处理,适合大规模的数据操作。

但是,这很理想,有多少表会采用相同算法处理呢。

Broadcast Join(广播联接)

先上原理解释:

当一个表的大小相对较小时,可以将这个小表的全部数据广播到所有包含另一个表数据的节点上。

每个节点上都有小表的完整副本,因此可以独立地与本地的大表数据进行联接操作,而不需要跨节点通信。

 举个例子,有一张非常小的表A,还有一张按照ID分片的表B,我们可以在每一个物理库中复制一份表A,这样我们的Join操作就可以直接下推到每一个数据库操作了。

这种情况比Shuffle Join甚至还有性能高效,这种类似于ShardingSphere中的广播表的定义,其存在类似于字典表,在每一个数据库都同时存在一份,每次写入会同步到多个节点。

这种操作的好处显而易见,不仅支持并行操作而且性能极佳。

但是缺点也显而易见,如果小表不够小数据冗余不说,广播可能会消耗大量的网络带宽和资源。

MapReduce Join(MapReduce联接)

先上原理解释:

MapReduce是一种编程模型,用于处理和生成大数据集,其中的联接操作可以分为两个阶段:Map阶段和Reduce阶段。

  • Map阶段:每个节点读取其数据分片,并对需要联接的键值对应用一个映射函数,生成中间键值对。
  • Reduce阶段
    • 中间键值对会根据键进行排序(在某些实现中排序发生在Shuffle阶段)和分组,然后发送到Reduce节点。
    • 在Reduce节点上,具有相同键的所有值都会聚集在一起,这时就可以执行联接操作。

MapReduce Join不直接应用于传统数据库逻辑,而是适用于Hadoop这样的分布式处理系统中。但是为了方便理解,还是用SQL语言来分析,例如一条SQL:

SELECT orders.order_id, orders.date, customers.name
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id;

会被转换为两个SQL:

SELECT customer_id, order_id, date FROM orders;
SELECT customer_id, name FROM customers;

这个过程就是Map阶段,即读取orderscustomers表的数据,并为每条记录输出键值对,键是customer_id,值是记录的其余部分。

下一个阶段可有可无,即Shuffle阶段。如果不在这里排序可能会在Map阶段执行SQL时候排序/分组或者在接下来的Reduce阶段进行额外排序/分组。在这个阶段主要将收集到的数据按照customer_id排序分组,以确保相同的customer_id的数据达到Reduce阶段。

Reduce阶段将每个对应的customer_id进行联接操作,输出并返回最后的结果。

这种操作普遍应用于两个算法完全不相同的表单,也是一种标准的处理模型,在这个过程中,我们以一张逻辑表的维度进行操作。这种算法可能会消耗大量内存,甚至导致内存溢出,并且在处理大数据量时会相当耗时,因此不适合需要低延迟的场景。

额外补充

内存溢出场景普遍在如下场景:

  1. 大键值对数量:如果Map阶段产生了大量的键值对,这些数据需要在内存中进行缓存以进行排序和传输,这可能会消耗大量内存。

  2. 数据倾斜:如果某个键非常常见,而其他键则不那么常见,那么处理这个键的Reducer可能会接收到大量的数据,导致内存不足。这种现象称为数据倾斜。

  3. 大值列表:在Reduce阶段,如果某个键对应的值列表非常长,处理这些值可能会需要很多内存。

  4. 不合理的并行度:如果Reduce任务的数量设置得不合适(太少或太多),可能会导致单个任务处理不均匀,从而导致内存问题。

我能想到的相应解决方案:

  • 内存到磁盘的溢写:当Map任务的输出缓冲区满了,它会将数据溢写到磁盘。这有助于限制内存使用,但会增加I/O开销。

  • 通过设置合适的Map和Reduce任务数量,可以更有效地分配资源,避免某些任务过载。具体操作可以将Map操作的分段比如1~100,100~200,Reduce阶段开设较少的并发处理。

  • 优化数据分布,比如使用范围分区(range partitioning)或哈希分区(hash partitioning)来减少数据倾斜。

Sort-Merge Join(排序-合并联接)

先上原理解释:

在分布式环境中,Sort-Merge Join首先在每个节点上对数据进行局部排序,然后将排序后的数据合并起来,最后在合并的数据上执行联接操作。

这通常涉及到多阶段处理,包括局部排序、数据洗牌(重新分发),以及最终的排序和合并。

举个理解,还是上面的SQL。

SELECT orders.order_id, orders.date, customers.name
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id;
  1. orders表按customer_id进行排序。
  2. customers表按customer_id进行排序。
  3. 同时遍历两个已排序的表,将具有相同customer_id的行配对。

这个就有点类似于原生的排序-合并联接了。也是数据库场景的标准处理办法。

对于已经排序的数据集或数据分布均匀的情况,这种方法非常有效。如果数据未预先排序,这种方法可能会非常慢,因为它要求数据在联接之前进行排序。

当然,这个算法也会造成内存溢出的场景,解决方案如下:

  1. 当数据集太大而无法一次性加载到内存中时,可以使用外部排序算法。外部排序算法会将数据分割成多个批次,每个批次单独排序,然后将排序后的批次合并。这种方法通常涉及到磁盘I/O操作,因此会比内存中操作慢。
  2. 对于合并步骤,可以使用流式处理技术,一次只处理数据的一小部分,并持续将结果输出到下一个处理步骤或存储系统。这样可以避免一次性加载大量数据到内存中。
  3. 当内存不足以处理数据时,可以使用磁盘空间作为临时存储。数据库管理系统通常有机制来处理内存溢出,比如创建磁盘上的临时文件来存储过程中的数据。
  4. 在分布式系统中,可以将数据分散到多个节点上进行处理,这样每个节点只需要处理数据的一部分,从而减少单个节点上的内存压力。

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

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

相关文章

《Linux C编程实战》笔记:管道

从这节开始涉及进程间的通信,本节是管道。 管道是一种两个进程间进行单向通信的机制。因为管道传递数据的单向性,管道又称之为半双工管道。。管道的这一特点决定了其使用的局限性。 数据只能由一个进程流向另一个进程;如果要进行全双工通信…

计算机组成原理学习| Day1

学习目标: 博主介绍: 27dCnc 专题 : 计算机组成原理 👍👍👍👍👍👍👍👍👍👍👍👍 ☆*: .。. o(≧▽≦)o .&#x…

分享4款不能错过的修改照片尺寸的软件!

在当今这个数字化时代,照片已经成为我们分享生活、表达观点的重要方式。但是,你是否曾遇到过这样的问题:一张精美的照片因为尺寸不合适而无法在朋友圈中展现出最佳效果?不用担心,今天我们就来聊聊那些可以帮助你轻松修…

获取鼠标点击图片时候的坐标,以及利用html 中的useMap 和area 实现图片固定位置的点击事件

一 编写原因 应项目要求,需要对图片的固定几个位置分别做一个点击事件,响应不同的操作,如下图,需要点击红色区域,弹出不同的提示框: 二 获取点击图片时候的坐标 1. 说明 实现这以上功能的前提是需要确定需…

JVM-类的生命周期

类的生命周期概述 类的生命周期描述了一个类加载、使用、卸载的整个过程。整体可以分为: 加载 连接,其中又分为验证、准备、解析三个子阶段 初始化 使用 卸载 加载阶段 加载(Loading)阶段第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方…

【JavaScript】fetch

fetch Response Headers ajax&axios&fetch的关系: ajax:ajax 是一种基于原生 JavaScript 的异步请求技术。它使用 XMLHttpRequest 对象来发送请求和接收响应。 axios:axios 是一个基于 Promise 的 HTTP 客户端,可以在浏览器和 Node…

STM32——中断系统和外部中断EXTI

一、中断 1.1中断系统 中断系统是管理和执行中断的逻辑结构; 1.2中断 系统在执行主程序过程中,出现了特定的触发条件(触发源),系统停止执行当前程序,转而去执行中断程序,执行完毕后&#xf…

什么是原型链?如何继承?

原型: 每个对象都可以有一个原型_proto_,这个原型还可以有它自己的原型,以此类推,形成一个原型链。查找特定属性的时候,我们先去这个对象里去找,如果没有的话就去它的原型对象里面去,如果还是没…

OllyDebug的使用方法. IDA Pro分析程序的控制流图,可以找到不同的函数入口点. 在汇编代码中定位特定函数可能是一个耗时且复杂的过程

实战 “OllyDbg” 是一个流行的Windows平台上的汇编级调试器,用于调试和分析二进制程序,尤其是用于逆向工程目的。使用OllyDbg的基本步骤如下: 安装和打开OllyDbg:首先,您需要在您的计算机上安装OllyDbg。完成安装后&…

HCIA学习作业五

拓扑图: PC端 PC1>ipconfig PC2>ipconfig PC3>ipconfig PC4>ipconfig PC>ping PC1>ping 192.168.1.125 PC1>ping 192.168.1.254 PC1>ping 192.168.1.253 PC2>ping 192.168.1.125 PC2>ping 192.168.1.253 PC3>ping 192.168.1.126…

java程序员怎么完善自己各个方面的能力?

java程序员怎么完善自己各个方面的能力? 在开始前我分享下我的经历,刚入行时遇到一个好公司和师父,给了我机会,两年时间从3k薪资涨到18k的, 我师父给了一些java学习方法和资料,让我不断提升自己,感谢帮助…

Python计算机二级/Python期末考试 刷题(一)

收集了一些经典Python计算机二级和Python期末考试题库 整理不易,大家点赞收藏支持一下 祝大家计算机二级和期末考试都高分过 目录 一、填空 二、选择 三、程序设计 一、填空 1.序列元素的编号称为索引,索引值从【1】开始,访问序列元素时将…

vue 使用 v-viewer 用于图片浏览的Vue组件,支持旋转、缩放、翻转等操作,基于viewer.js。

作者连接 npm: npm install v-viewerlegacy viewerjs main.js 引入: // 引入Viewer插件 import VueViewer, { directive as viewerDirective } from v-viewer; // 引入Viewer插件的图片预览器的样式 import viewerjs/dist/viewer.css; // 使用Viewer图片…

Pull模式和Push模式

Pull模式是一种消息消费模式,其中客户端主动从服务端拉取数据。 优点:客户端可以根据自己的消费能力来消费数据,不存在消息堆积的情况。 缺点:消息处理可能不及时,可能存在大量无效请求,客户端需要考虑拉取…

python对图片或文件的操作

一. base64 与图片的相互转换 1. base64 转图片 import base64 from io import BytesIO from PIL import Image# base64 编码的图像数据(示例) base64_data "iVBn9DHASKJDjDsdSADSf8lgg"# 将 base64 编码的字符串解码为二进制数据 binary_d…

不同的强化学习模型适配与金融二级市场的功能性建议

DQN ES DDPG A2C TD3 SAC QMIX MADDPG PPO CQL IMPALA 哪个模型适合进行股票操作 在考虑使用哪种模型进行股票操作时,需要考虑模型的特点、适用场景以及实现复杂度等因素。以下是对您列出的几种强化学习模型的简要概述,以帮助您做出选择: DQ…

【C++】类与对象(二)特殊成员函数

前言 类与对象(二) 文章目录 一、特殊成员函数二、构造函数三、析构函数四、拷贝构造函数五、拷贝赋值运算符 一、特殊成员函数 如果在类的声明中未显式提供某个成员函数的定义,编译器会自动生成一个默认实现。 这包括默认构造函数、默认析构…

Android studio打包apk比较大

1.遇到的问题 在集成linphone打包时发现有118m,为什么如此之大额。用studio打开后发现都是c不同的pu架构。 2.解决办法 增加ndk配置,不选配置那么多的cpu结构,根据自己需要调整。 defaultConfig { applicationId "com.matt.linphoneca…

备战蓝桥杯---数据结构与STL应用(基础3)

今天我们主要介绍的是pair,string,set,map pair:我们可以把它当作一个结构体&#xff1a; void solve(){pair<int int> a;//创建amake_pair(1,2);//添加元素cout<<a.first<<endl<<a.second<<endl;}//输出 当然&#xff0c;它也可以嵌套&#…

51单片机点灯

51单片机点灯 1.点亮LED灯 #include "reg52.h"sbit ledOne P3^7;void main() {//灯亮&#xff0c;给一个P3.7低电平ledOne 0; }给LED1对应标号的P3^7一个低电平&#xff0c;就能点亮LED灯2.LED灯闪烁 #include "reg52.h"sbit ledOne P3^7;void Delay…