数据关联与回写的解决方案
最近项目上有一个需求,需要将两张表(A表和B表)的数据进行关联并回写入其中一张表(A表),两张表都是分区表,但是关联条件不包括分区字段。
最朴素的想法,直接关联执行,全表关联,一条SQL搞定全部逻辑。想法越简单,执行越困难。由于数据量大,服务器规模较小,尽管各台服务器内存和CPU配置都很高,关联会将数据读取到内存,内存根本放不下,而且集群配置了workload group,可使用内存更小了,方案一不可行。
可以在关联时增加分区字段对任务进行拆解,这样可以实现,但是会形成笛卡尔积,历史数据量巨大,分区较多(A表和B表都是1年),缺点也很明显。
- 执行耗时长
- 执行语句太多,操作不便
- 如果按照单分区关联,A表的每一个分区将会扫描B表全表
经过评估上述方案二不可行。
通过外部计算和存储来实现,可选的有Hive、Spark、Flink。三种方案都是可行的,但是从操作复杂度来看使用spark-sql直接读取Doris进行关联并写回Doris,除DDL外,只需要一条SQL即可搞定。
- 下载预编译的spark和spark-doris-connector
-
spark-3.4.3-bin-hadoop3.tgz
-
spark-doris-connector-3.4_2.12-1.3.2.jar
-
部署
-
启动spark-sql
-
创建映射表
-
DML语句
处理过程很简单,但是实际也是遇到了很多问题
- DML语句中不能使用分区字段进行过滤,因为Doris 2.0版本在提供的获取执行计划的API中对于引号的处理存在问题,如果传递的是"2024-06-12",则会得到数值2006,该数值无法转换为日期,如果传递"20240612"也无法得到Date("20240612")。理论上,如果调整此处的写法增加嵌套的引号配合转义字符也能实现功能,Java程序员都懂的,有兴趣可以自行验证。
- 数据动态变化,由于这两张表的数据都在不断变化,如果读取文件耗时较久,将可能出现tablet对应版本不存在的异常。我的做法是另建表,将数据写入新表,然后再执行关联。
- spark executor 内存和并行度设置,这个需要不断调整,我也是尝试了多次,才得到这个可以运行的结果。并行度设置太高了,将会对Doris形成较大的网络和IO冲击,一定要慎重。并行度低了,内存就要高一点,不然数据都已经从Doris读取出来了,关联的时候会内存溢出。
- 读取Doris的速率还是很快的,而且spark在读取doris前获取了执行计划,对数据进行了行和列的裁剪,不会将整表数据都读出来。
- 耗时,耗时主要在数据读取和数据写入,数据读取是直接访问BE读取tablet,数据写入不是文件级别的,所以写入效率并不高。
以上就是电脑114游戏给大家带来的关于数据关联与回写的解决方案全部内容,更多攻略请关注电脑114游戏。
电脑114游戏-好玩游戏攻略集合版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!