背景

最近项目上有一个需求,需要将两张表(A表和B表)的数据进行关联并回写入其中一张表(A表),两张表都是分区表,但是关联条件不包括分区字段。

分析过程

方案一

最朴素的想法,直接关联执行,全表关联,一条SQL搞定全部逻辑。想法越简单,执行越困难。由于数据量大,服务器规模较小,尽管各台服务器内存和CPU配置都很高,关联会将数据读取到内存,内存根本放不下,而且集群配置了workload group,可使用内存更小了,方案一不可行。

方案二

可以在关联时增加分区字段对任务进行拆解,这样可以实现,但是会形成笛卡尔积,历史数据量巨大,分区较多(A表和B表都是1年),缺点也很明显。

  • 执行耗时长
  • 执行语句太多,操作不便
  • 如果按照单分区关联,A表的每一个分区将会扫描B表全表

经过评估上述方案二不可行。

方案三

通过外部计算和存储来实现,可选的有Hive、Spark、Flink。三种方案都是可行的,但是从操作复杂度来看使用spark-sql直接读取Doris进行关联并写回Doris,除DDL外,只需要一条SQL即可搞定。

详细过程

  1. 下载预编译的spark和spark-doris-connector
  1. 部署

    将上述安装文件上传至Hadoop集群的其中一台机器,放置到任意目录,比如/opt,请保证使用的用户可以向Yarn提交任务。

    解压缩spark-3.4.3-bin-hadoop3.tgz得到spark-3.4.3-bin-hadoop3目录

    将spark-doris-connector-3.4_2.12-1.3.2.jar放到spark-3.4.3-bin-hadoop3/jars/

  2. 启动spark-sql

bin/spark-sql --master yarn --num-executors 40 --executor-memory 7G --name Spark-SQL:Doris
  1. 创建映射表
-- 用于读取A表数据
CREATE
TEMPORARY VIEW spark_doris_a
USING doris
OPTIONS(
"table.identifier"="mydb.table_a",
"fenodes"="10.*.*.1:9030,10.*.*.2:9030,10.*.*.3:9030",
"user"="root",
"password"="$YOUR_DORIS_PASSWORD"
);
-- 用于读取B表数据
CREATE
TEMPORARY VIEW spark_doris_b
USING doris
OPTIONS(
"table.identifier"="mydb.table_b",
"fenodes"="10.*.*.1:9030,10.*.*.2:9030,10.*.*.3:9030",
"user"="root",
"password"="$YOUR_DORIS_PASSWORD"
);
-- 用于向A表部分列写入数据
CREATE
TEMPORARY VIEW spark_doris_a_sink
USING doris
OPTIONS(
"table.identifier"="mydb.table_a",
"fenodes"="10.*.*.1:9030,10.*.*.2:9030,10.*.*.3:9030",
"user"="root",
"password"="$YOUR_DORIS_PASSWORD",
"sink.properties.partial_columns"="true",
"sink.properties.column"="'column_a','column_b','column_c'"
);
  1. DML语句
set enable_unique_key_partial_update=true;
set enable_insert_strict=false; insert into spark_doris_a_sink
(column_a,column_b,column_c)
select a.column_a,b.column_b,b.column_c from spark_doris_a a left join spark_doris_b b on a.colum_d = b.column_e;

遇到的问题

处理过程很简单,但是实际也是遇到了很多问题

  1. DML语句中不能使用分区字段进行过滤,因为Doris 2.0版本在提供的获取执行计划的API中对于引号的处理存在问题,如果传递的是"2024-06-12",则会得到数值2006,该数值无法转换为日期,如果传递"20240612"也无法得到Date("20240612")。理论上,如果调整此处的写法增加嵌套的引号配合转义字符也能实现功能,Java程序员都懂的,有兴趣可以自行验证。
  2. spark executor 内存和并行度设置,这个需要不断调整,我也是尝试了多次,才得到这个可以运行的结果。并行度设置太高了,将会对Doris形成较大的网络和IO冲击,一定要慎重。并行度低了,内存就要高一点,不然数据都已经从Doris读取出来了,关联的时候会内存溢出。
  3. 读取Doris的速率还是很快的,而且spark在读取doris前获取了执行计划,对数据进行了行和列的裁剪,不会将整表数据都读出来。

使用spark-sql处理Doris大表关联的更多相关文章

  1. Oracle\MS SQL Server Update多表关联更新

    原文:Oracle\MS SQL Server Update多表关联更新 一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表 ...

  2. Hive中小表与大表关联(join)的性能分析【转】

    Hive中小表与大表关联(join)的性能分析 [转自:http://blog.sina.com.cn/s/blog_6ff05a2c01016j7n.html] 经常看到一些Hive优化的建议中说当 ...

  3. Oracle SQL性能优化 - 根据大表关联更新小表

    需求: 小表数据量20w条左右,大表数据量在4kw条左右,需要根据大表筛选出150w条左右的数据并关联更新小表中5k左右的数据. 性能问题: 对筛选条件中涉及的字段加index后,如下常规的updat ...

  4. 【SQL】在SQL Server中多表关联查询问题

    好久没有写SQL语句的多表连接查询,总在用框架进行持久化操作.今天写了一个多表关联查询,想根据两个字段唯一确定一条数据 失败的案例如下: SELECT cyb.id,ad.name FROM [Gen ...

  5. Databricks 第6篇:Spark SQL 维护数据库和表

    Spark SQL 表的命名方式是db_name.table_name,只有数据库名称和数据表名称.如果没有指定db_name而直接引用table_name,实际上是引用default 数据库下的表. ...

  6. 【Spark调优】大表join大表,少数key导致数据倾斜解决方案

    [使用场景] 两个RDD进行join的时候,如果数据量都比较大,那么此时可以sample看下两个RDD中的key分布情况.如果出现数据倾斜,是因为其中某一个RDD中的少数几个key的数据量过大,而另一 ...

  7. hive两大表关联优化试验

    呼叫结果(call_result)与销售历史(sale_history)的join优化: CALL_RESULT: 32亿条/444G SALE_HISTORY:17亿条/439G 原逻辑 Map: ...

  8. sql中修改多表关联的字段

    表1:USERID USERNAME USERREMARK 表2:ROLEID USERID ROLENAME 其中表1的USERID与表2的USERID为关联字段. 若现在只知道ROLEID,要修改 ...

  9. mysql数据库-初始化sql建库建表-关联查询投影问题

    下面是一个简易商城的几张表的创建方式 drop database if exists shop ; create database shop CHARACTER SET 'utf8' COLLATE ...

  10. SQL精华总结索引类型优化SQL优化事务大表优化思维导图❤️

    索引类型 从数据结构角度: B+树索引, hash索引,基于哈希表实现,只有全值匹配才有效.以链表的形式解决冲突.查找速度非常快 O(1) 全文索引,查找的是文本中的关键词,而不是直接比较索引中的值, ...

随机推荐

  1. 动态尺寸模型优化实践之Shape Constraint IR Part II

    简介: 在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考.本次分享的是我们最近开展的有关shape constraint IR的工作,Part II 中我们将 ...

  2. Spring Boot Serverless 实战系列“架构篇” | 光速入门函数计算

    ​简介:如何以 Serverless 的方式运行 Spring Boot 应用? ​ 作者:西流(阿里云函数计算专家) Spring Boot 是基于 Java Spring 框架的套件,它预装了 S ...

  3. Spring Boot Serverless 实战系列“架构篇” 首发 | 光速入门函数计算

    ​简介:如何以 Serverless 的方式运行 Spring Boot 应用? ​ 作者 | 西流(阿里云函数计算专家) Spring Boot 是基于 Java Spring 框架的套件,它预装了 ...

  4. 数据可视化之matplotlib模块

    一.简介 Matplotlib是一个强大的Python绘图和数据可视化的工具包.数据可视化也是我们数据分析的最重要的工作之一,可以帮助我们完成很多操作,例如:找出异常值.必要的一些数据转换等.完成数据 ...

  5. 野火 STM32MP157 开发板 UBOOT 编译烧写

    一.环境 编译环境:Ubuntu 版本:20.4.1 交叉编译工具:arm-none-eabi-gcc 版本:10.3.1 开发板:STM32MP157 pro 烧写软件:STM32CubeProgr ...

  6. 学会使用 NumPy:基础、随机、ufunc 和练习测试

    NumPy NumPy 是一个用于处理数组的 Python 库.它代表"Numerical Python". 基本 随机 ufunc 通过测验测试学习 检验您对 NumPy 的掌握 ...

  7. cesium教程7-官方示例翻译-模型要素选择

    源代码示例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  8. java后台@RequestBody和@RequestParam

    RequestBody 接收的是请求体里面(body)的数据 RequestParam接收的是key-value里面的参数,所以它会被切割进行处理从而可以是普通元素.数组.集合.对象等接收 get-- ...

  9. html布局浅谈

    现在布局方式主要分为三种 传统css布局方案(position,float,line-height等配合).实现复杂,需要多种属性配合使用,兼容性最好. flex布局方案.弹性布局,实现方便,兼容性较 ...

  10. 《最新出炉》系列入门篇-Python+Playwright自动化测试-46-鼠标滚轮操作

    1.简介 有些网站为了节省流量和资源,提高加载效率,采用的是动态加载(懒加载)的,也就是当拖动页面右侧滚动条后会自动加载网页下面的内容,不拖动就不会加载的或者通过鼠标滚轮操作. 2.wheel模拟鼠标 ...