当前位置: 首页 > news >正文

分布式数据库中的“分布式连接”(Distributed Joins)

这段文字讲的是 分布式数据库中的“分布式连接”(Distributed Joins),特别是针对 Apache Ignite 这类分布式内存数据库的处理方式。下面我将逐段解释这段内容,帮助你更好地理解。


一、什么是分布式连接(Distributed Joins)

原文:

A distributed join is a SQL statement with a join clause that combines two or more partitioned tables.

解释:

  • 分布式连接指的是在 分布式数据库 中,对两个或多个分布在不同节点上的表进行 JOIN 操作。
  • 这些表是“分区的”(partitioned),也就是说数据被分片存储在多个节点上。

二、Colocated Join(共置连接)和 Non-Colocated Join(非共置连接)

原文:

If the tables are joined on the partitioning column (affinity key), the join is called a colocated join. Otherwise, it is called a non-colocated join.

解释:

  • Colocated Join(共置连接):

    • 如果两个表是根据相同的列(称为分区列或亲和键 affinity key)进行分区的,并且你在该列上做 JOIN,那么这两个表的数据会在同一个节点上。

    • 这样就可以在每个节点上 本地执行 JOIN,效率很高。

    • 举例:表 A 和表 B 都按 customer_id 分区,查询 SELECT * FROM A JOIN B ON A.customer_id = B.customer_id 就是 Colocated Join。

      在这里插入图片描述

      执行流程:

      步骤描述说明
      1. 查询分发(Q)查询被发送到集群中所有相关的节点每个节点收到相同的 SQL 查询语句
      2. 本地执行(E(Q))每个节点只在自己的本地数据上执行查询无需跨节点拉取数据
      3. 结果汇总(R)所有节点执行完后,结果被发送回客户端节点进行汇总客户端节点负责最终结果合并

      举个例子:

      假设你有两个表:

      • Customer(客户表):按 customer_id 分区
      • Order(订单表):也按 customer_id 分区

      你执行如下查询:

      SELECT * FROM Customer c JOIN Order o ON c.id = o.customer_id WHERE c.region = 'US'
      
      • Ignite 会把这条查询发送到所有节点。
      • 每个节点只处理自己本地的 CustomerOrder 数据(因为它们按 customer_id 共置)。
      • 每个节点返回本地匹配的结果。
      • 客户端节点把所有结果合并后返回给用户。

      总结

      概念含义
      Colocated JoinJOIN 的字段是分区字段,数据在同一个节点上
      Q(Query)查询语句被发送到所有相关节点
      E(Q)(Execution of Query)每个节点在本地执行查询
      R(Result)结果被汇总到客户端节点
  • Non-Colocated Join(非共置连接):

    • 如果 JOIN 的列不是分区列,那么两个表的数据可能分布在不同的节点上。

    • 这时就需要从其他节点 拉取数据,效率较低。

      在这里插入图片描述
      这段话讲的是 非共置连接(Non-Colocated Join) 在 Apache Ignite 这样的分布式数据库中是如何执行的,以及为什么它效率较低。我们可以逐步理解它的含义:

      执行过程详解

      ✅ 第一步:SQL 引擎在每个节点上执行查询

      • 每个节点执行查询时,只处理自己本地的数据。
      • 比如,节点 A 有部分 Table A 的数据,但它没有对应的 Table B 数据。

      ❌ 第二步:节点发现缺少数据,需要从其他节点获取

      • 如果 JOIN 的字段是 主键或亲和键,节点知道去哪个节点取数据 → unicast(单播)
      • 否则,不知道去哪个节点取数据 → broadcast(广播)

      📦 第三步:批量请求优化

      • 为了避免频繁的网络请求,Ignite 会把多个请求 打包成一批发送,减少网络开销。

      📌 举个例子说明

      假设你有两个表:

      • Customer(客户表),按 customer_id 分区。
      • Order(订单表),按 order_id 分区(不是 customer_id)。

      现在你执行:

      SELECT * FROM Customer c JOIN Order o ON c.id = o.customer_id
      
      • 因为 Order 是按 order_id 分区的,不是按 customer_id,所以两个表不是共置的。
      • Ignite 无法在本地完成 JOIN,需要从其他节点获取 Order 表中对应的数据。
      • 如果 customer_id 是主键或亲和键,节点知道去哪个节点取数据(unicast)。
      • 否则,只能广播请求,效率低。

      📊 对比:Colocated vs Non-Colocated Join

      特性Colocated JoinNon-Colocated Join
      JOIN 字段分区字段(affinity key)不是分区字段
      数据位置相同 JOIN 键的数据在同一个节点数据可能在不同节点
      执行方式每个节点只处理本地数据每个节点需要远程获取数据
      网络开销小(只有最终结果汇总)大(需要远程拉取数据)
      是否需要设置不需要必须设置 setDistributedJoins(true)
      性能✅ 高效❌ 低效

      最佳实践建议

      1. 尽量使用 Colocated Join

        • 设计表结构时,确保要 JOIN 的字段是分区字段(affinity key)。
        • 例如:Customer(customer_id)Order(customer_id) 都按 customer_id 分区。
      2. 非共置 JOIN 时要显式启用

        SqlFieldsQuery query = new SqlFieldsQuery("SELECT ...");
        query.setDistributedJoins(true); // 启用分布式 JOIN
        
      3. 避免 Broadcast JOIN

        • Broadcast 会增加网络负载,降低性能。
        • 如果 JOIN 的字段不是主键或亲和键,尽量避免。
      4. 批量请求优化

        • Ignite 会自动将请求打包发送,但仍应尽量减少不必要的跨节点访问。

三、为什么 Colocated Join 更高效?

原文:

Colocated joins are more efficient because they can be effectively distributed between the cluster nodes.

解释:

  • 因为数据在同一个节点上,JOIN 操作可以 在每个节点上独立完成,不需要跨网络传输大量数据。
  • 这样减少了网络开销,提高了性能。

四、Ignite 默认如何处理 JOIN?

原文:

By default, Ignite treats each join query as if it is a colocated join and executes it accordingly (see the corresponding section below).

解释:

  • Ignite 默认假设你执行的是 Colocated Join。
  • 如果不是,可能会导致 查询结果不正确,因为 Ignite 可能只在本地节点查找数据。

五、如何处理 Non-Colocated Join?

原文:

If your query is non-colocated, you have to enable the non-colocated mode of query execution by setting SqlFieldsQuery.setDistributedJoins(true); otherwise, the results of the query execution may be incorrect.

解释:

  • 如果你执行的是 Non-Colocated Join,必须手动启用分布式连接模式:
    SqlFieldsQuery query = new SqlFieldsQuery("SELECT ...");
    query.setDistributedJoins(true); // 启用非共置连接模式
    
  • 启用后,Ignite 会将查询发送到所有相关节点,并合并结果,虽然效率较低,但保证结果正确。

六、建议

原文:

If you often join tables, we recommend that you partition your tables on the same column (on which you join the tables).
Non-colocated joins should be reserved for cases when it’s impossible to use colocated joins.

解释:

  • 如果你经常需要做 JOIN 操作,建议将这些表按照 JOIN 的列进行分区(即使用相同的 affinity key)。
  • 这样可以尽量使用高效的 Colocated Join。
  • 只有在无法使用 Colocated Join 的情况下,才使用 Non-Colocated Join。

总结

概念含义是否高效是否需要特殊设置
Colocated JoinJOIN 的列是分区列,数据在同一节点✅ 高效❌ 不需要设置
Non-Colocated JoinJOIN 的列不是分区列,数据可能在不同节点❌ 效率低✅ 必须设置 setDistributedJoins(true)

如果你有具体的 SQL 示例或者使用场景,我也可以帮你分析是否是 Colocated Join 或者如何优化 JOIN 性能。

http://www.xdnf.cn/news/1204399.html

相关文章:

  • 轻资产革命:连合直租如何用DaaS模式重塑企业资产逻辑
  • 阿里云 【免费试用】MCP 赋能可视化 OLAP 智能体应用
  • 网络安全第14集
  • React与Rudex的合奏
  • KubeSphere理论及实战
  • ros2的package.xml和rosdep
  • 正则表达式 速查速记
  • haproxy原理及实验演示(实现服务器集群的负载均衡)
  • ubuntu资源共享samba 安装与配置 mac/windows共享ubuntu文件资源
  • 无人机喷洒系统技术要点与难点解析
  • AR眼镜:工业4.0时代高风险作业的安全守护者
  • 【WRF-Chem教程第七期】闪电-NOx 参数化方案详解
  • 自学嵌入式 day36 数据库
  • 前段面试题新版
  • 【华为机试】5. 最长回文子串
  • 数据结构——图(二、图的存储和基本操作)
  • 数据结构 | 队列:从概念到实战
  • Rust 最短路径、Tide、Partial、Yew、Leptos、数独实践案例
  • Nginx HTTP 反向代理负载均衡实验
  • Docker笔记(基本命令、挂载本地gpu、Dockerfile文件配置、数据挂载、docker换源)
  • Ettus USRP X410/X440 运行 ADC 自校准
  • easyexcel填充方式导出-合并单元格并设置边框
  • 解构远程智能系统的视频能力链:从RTSP|RTMP协议接入到Unity3D头显呈现全流程指南
  • MVSNet系列网络概述
  • 把振动数据转成音频并播放
  • C++模板初阶
  • C++模板进阶:从基础到实战的深度探索
  • 短剧小程序系统开发:连接创作者与用户的桥梁
  • vue3【组件封装】超级表单 S-form.vue
  • django ManyToManyField 如何添加数据