ETL为什么经常变成ELT甚至LET?

2023-11-17

ETL是将数据从来源端经过清洗(extract)、转换(transform)、加载(load)至目的端的过程。正常的 ETL 过程应当是 E、T、L 这三个步骤逐步进行,也就是先清洗转换之后再加载进目标端(通常是数据库),最后在数据库中的只是合理的结果数据。这个过程本来很合理,但实际过程中经常被执行成ELT甚至LET,即源端数据先装载进目标库再进行清洗和转换。

出现这种现象是因为源端数据可能来源多处,数据库、文件、web等等,不仅数据源多样数据质量也参差不齐,由于E和T这两个步骤会涉及大量数据计算,除了数据库以外,其他数据源并不具备多少的计算能力,想要完成这些计算就要先加载到数据库再进行,这就形成了LET。而且,即使源端是数据库也会面临多库的场景,跨库完成数据清洗和转换远没有先装载到目标库再处理方便,同样会造成ELT或LET。

那么ETL变成ELT/LET会带来哪些问题呢?

首先是时间成本增加。大量未经清洗和转换的原始(无用)数据装载进数据库会带来过长的时间消耗。而且数据库的计算资源有限,完成额外的E、T计算势必要消耗很长时间,进一步增加时间成本。ETL通常是有时间限制的,一般会在业务空闲的时间进行,比如前一天22点到第二天5点,如果在指定时间段没有完成就会影响第二天的业务,这就是常说的ETL时间窗口。ETL时间过长会导致时间窗口不足,影响正常业务。

此外,从数据库容量的角度来看,存储大量没有经过清洗转换的原始数据会占用过多数据库空间造成数据库容量过大,导致数据库面临扩容压力。现代应用经常使用的JSON或XML格式的多层数据入库还要在数据库中建立多个关联的表来存储,会进一步加剧数据库容量问题。任务越来越多、资源越来越少、时间窗口有限,这样就陷入了恶性循环。

那么,为什么要把数据加载数据库后才能做E和T这两个动作呢?如前所述,是因为数据库外的计算能力不足,先入库再计算是为了利用数据库的计算能力,如果能够提供库外计算能力,那么这个问题也就迎刃而解了,回归合理的ETL过程。

使用开源集算器SPL可以实现这个目标。

SPL是一款独立的开源数据计算引擎,提供了不依赖数据库的计算能力,可以对接多种数据源完成数据处理。基于SPL丰富的计算类库、敏捷语法和过程计算可以很方便地完成复杂数据计算任务,在数据库外完成数据清洗(E)和转换(T),将整理后数据加载(L)到目标库中实现真正的ETL。

库外计算实现真正ETL

多源支持与混合计算

SPL可以对接多种数据源,这样来源端数据源无论有无计算能力都可以通过SPL完成数据清洗和转换。

特别地,SPL还能实现多源混合计算,将多源数据统一清洗转换后加载到库,不需要再借助数据库的计算能力就能完成ETL工作。尤其是对JSON和XML等多层数据格式提供了很好支持,简单一个函数就能完成解析,非常方便。

举个简单的例子,将json与数据库混合计算后更新到数据库的过程:

A
1 =json(file("/data/EO.json").read()) 解析JSON数据
2 =A1.conj(Orders)
3 =A2.select(orderdate>=date(now())) 过滤当日数据
4 =connect(“sourcedb”).query@x(“select ID,Name,Area from Client”) 数据库数据
5 =join(A3:o,Client;A4:c,ID) 关联计算
6 =A5.new(o.orderID:orderID,…)
7 =connect(“targetdb”).update(A6,orders) 装载到目标库

强计算能力与过程控制

SPL提供了专业的结构化数据对象及其上的丰富运算。不仅分组汇总、循环分支、排序过滤、集合运算等基础计算可以进行,位置计算、排序排名、不规则分组也提供直接支持。

SPL还提供了专门用于大数据计算的游标支持,通过游标就可以处理超过内存容量的数据,计算实现与全内存方式几乎完全一样。比如通过游标读取文件并进行分组汇总:

=file(“persons.txt”).cursor@t(sex,age).groups(sex;avg(age))

与全内存读取计算:

=file(“persons.txt”).import@t(sex,age).groups(sex;avg(age))

除了丰富的计算类库,SPL还支持过程计算,可以按自然思维思维分步编写代码,适合完成原本在数据库中使用存储过程实现的ETL复杂计算。而SPL计算在数据库外,不会对数据库造成负担,同时兼具灵活性和高性能,实现“库外存储过程”的效果,是传统存储过程的很好替代。库外计算还可以为数据库充分减负。以往要借助数据库完成的ET计算现在都在库外完成,既不需要额外消耗数据库的计算资源,也无需存储未经清洗的大量原始数据,空间占用也少,数据库的资源和容量问题都能得到很好解决。

同时,SPL的语法体系比SQL和Java等也更为敏捷,涉及E和T计算尤其是复杂计算,算法实现更简洁代码更短,开发效率更高。比如在实现某保险公司车险保单ETL业务时,使用SPL不到500格(网格式编码)代码就实现了原本2000行存储过程的计算,工作量减少了1/3以上。(案例详情:开源 SPL 优化保险公司跑批优从 2 小时到 17 分钟

从技术栈的角度来看,基于SPL还可以获得一致的语法风格,面对多样性数据源ETL时可以获得通用一致的计算能力。不仅技术路线统一,开发维护也很方便,程序员无需掌握不同数据源数据的处理方法,学习成本也更低。特别的,统一的技术路线具备更强的移植性,ETL数据源变化只需要更改取数代码即可,主要的计算逻辑无需更改,具备很强的移植性。

高性能保障时间窗口

对于源数据读取,SPL能很方便地进行并行处理,充分发挥多CPU的优势加速数据读取和计算速度。比如并行取数:

A B
1 fork to(n=12) =connect("sourcedb")
2 =B1.query@x("SELECT * FROM ORDERS WHERE MOD(ORDERID,?)=?", n, A3-1)
3 =A1.conj()

类似的,读取大文件时也可以并行:

=file(“orders.txt”).cursor@tm(area,amount;4)

使用 @m 选项即可创建多路并行游标,SPL 会自动处理并行以及将结果再汇总。SPL还有很多计算函数也提供并行选项,如过滤A.select()、排序A.sort()等增加@m选项后都可以自动完成并行计算。

在ELT任务中还经常出现数据落地的情况,无论是中间数据还是最后的计算结果,这都涉及数据存储。SPL提供了两种二进制存储形式,不仅存储了数据类型不必再次解析效率更高,而且还采用了适合的压缩机制可以有效平衡CUP和硬盘时间,同时提供了行式和列式存储方式适应更多场景,采用独有的倍增分段技术还可以实现单文件可追加分块方案更方便并行计算。这些高性能存储机制为计算性能提供了基础保障,要知道高性能计算依靠的就是存储和算法。

SPL提供了众多高性能算法,仍是上述案例(开源 SPL 优化保险公司跑批优从 2 小时到 17 分钟)中,使用SPL不仅把代码量减少到1/3,还将计算时间从2小时缩短到17分钟。其中主要使用了SPL特有的遍历复用技术,可以在对大数据的一次遍历过程中实现多种运算,有效地减少外存访问量。而关系数据库中用SQL无法实现这样的运算,有多种运算就需要遍历多次。在本例中就涉及对一个大表进行三次关联和汇总的运算,使用SQL要将大表遍历三次,而使用SPL只需要遍历一次,所以获得了巨大的性能提升。

在ETL业务中还经常出现巨大主子表关联的情况,比如订单和订单明细,这些关联是通过主键(或部分主键)的一对多关联,如果事先按照主键排序,那么关联计算可以使用有序归并算法,相对常规HASH JOIN算法,复杂度可以从O(N*M)降到O(M+N),性能将大幅提升。但数据库基于无序集合理论,SQL也很难利用数据有序来提高性能。在上面案例中也涉及这种主子关联运算,使用SPL的有序归并算法大幅提升了关联性能。

将具备强计算能力的SPL作为ETL过程中的ET引擎,将数据计算从源端和目标端独立出来不与任何一端耦合在一起,这样可以获得更强的灵活性和更高的移植性,同时不对源和目标造成过大压力,享受库外计算的便利,实现了真正的ETL过程。同时基于SPL的高性能存储、高性能算法与并行计算又充分保障了ETL效率,这样就可以在有限的时间窗口内完成更多ETL任务。

SPL资料

欢迎对SPL有兴趣的加小助手(VX号:SPL-helper),进SPL技术交流群

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ETL为什么经常变成ELT甚至LET? 的相关文章

  • 带路径压缩算法的加权 Quick-Union

    有一种 带路径压缩的加权快速联合 算法 代码 public class WeightedQU private int id private int iz public WeightedQU int N id new int N iz new
  • TreeMap 删除所有大于某个键的键

    在项目中 我需要删除键值大于某个键的所有对象 键类型为Date 如果重要的话 据我所知TreeMapJava中实现的是红黑树 它是一种二叉搜索树 所以我应该得到O n 删除子树时 但除了制作尾部视图并一一删除之外 我找不到任何方法可以做到这
  • 如何在 JavaFX 中连接可观察列表?

    我所说的串联是指获得一个新列表 该列表侦听所有串联部分的更改 方法的目的是什么FXCollections concat ObservableList
  • 与 Eclipse 中的 Java Content Assist 交互

    作为我的插件项目的一部分 我正在考虑与 Eclipse 在 Java 文件上显示的内容辅助列表进行交互 我正在尝试根据一些外部数据对列表进行重新排序 我看过一些有关创建新内容辅助的教程 但没有看到有关更改现有内容辅助的教程 这可能吗 如果是
  • 如何调试“com.android.okhttp”

    在android kitkat中 URLConnection的实现已经被OkHttp取代 如何调试呢 OkHttp 位于此目录中 external okhttp android main java com squareup okhttp 当
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • Android studio - 如何保存先前活动中选择的数据

    这是我的代码片段 这Textview充当按钮并具有Onclicklistner在他们 当cpu1000时Textview单击它会导致cpu g1000其代码如下所示的类 public class Game 1000 extends AppC
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • 提供节点名或服务名,或未知 Java

    最近我尝试运行我的 Java 项目 每当我运行它并将其打开到我得到的服务器地址时 Unable to determine host name java net UnknownHostException Caused by java net
  • 在 Java 中如何找出哪个对象打开了文件?

    我需要找出答案哪个对象在我的 Java 应用程序中打开了一个文件 这是为了调试 因此欢迎使用工具或实用程序 如果发现哪个对象太具体了 这class也会很有帮助 这可能很棘手 您可以从使用分析器开始 例如VisualVM http visua
  • Java 中如何将 char 转换为 int? [复制]

    这个问题在这里已经有答案了 我是Java编程新手 我有例如 char x 9 我需要得到撇号中的数字 即数字 9 本身 我尝试执行以下操作 char x 9 int y int x 但没有成功 那么我应该怎么做才能得到撇号中的数字呢 ASC
  • 将人类日期(当地时间 GMT)转​​换为日期

    我正在服务器上工作 服务器正在向我发送 GMT 本地日期的日期 例如Fri Jun 22 09 29 29 NPT 2018在字符串格式上 我将其转换为日期 如下所示 SimpleDateFormat simpleDateFormat ne
  • Akka 与现有 java 项目集成的示例

    如果我已经有现有的javaWeb 应用程序使用spring and servlet容器 将 Akka 集成到其中的正确方法是什么 就像我将会有Actor1 and Actor2互相沟通的 开始使用这些演员的切入点是什么 例如 1 把它放在那
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • 手动设置Android Studio的JDK路径

    如何为 Android Studio 使用自定义 JDK 路径 我不想弄乱 PATH 因为我没有管理员权限 是否有某个配置设置文件允许我进行设置 如果您查看项目设置 您可以从那里访问 jdk 在标准 Windows 键盘映射上 您可以在项目
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • 在java中以原子方式获取多个锁

    我有以下代码 注意 为了可读性 我尽可能简化了代码 如果我忘记了任何关键部分 请告诉我 public class User private Relations relations public User relations new Rela
  • Java RMI - 客户端超时

    我正在使用 Java RMI 构建分布式系统 它必须支持服务器丢失 如果我的客户端使用 RMI 连接到服务器 如果该服务器出现故障 例如电缆问题 我的客户端应该会收到异常 以便它可以连接到其他服务器 但是当服务器出现故障时 我的客户端什么也
  • MiniDFSCluster UnsatisfiedLinkError org.apache.hadoop.io.nativeio.NativeIO$Windows.access0

    做时 new MiniDFSCluster Builder config build 我得到这个异常 java lang UnsatisfiedLinkError org apache hadoop io nativeio NativeIO
  • Spring RESTful控制器方法改进建议

    我是 Spring REST 和 Hibernate 的新手 也就是说 我尝试组合一个企业级控制器方法 我计划将其用作未来开发的模式 您认为可以通过哪些方法来改进 我确信有很多 RequestMapping value user metho

随机推荐

  • 文件系统---代码层次深入分析文件系统

    文件系统对用户来说 最重要的就是创建目录 创建文件 打开文件 和 文件读写 对通常的硬盘文件系统来说 涉及硬盘的读写和硬盘空间管理 从读写文件系统层一直到通用设备层再到硬盘驱动 为了简化 我们给出最简单文件系统 通过这个例子导入文件系统的概
  • uniapp 在app和小程序端使用webview进行数据交互

    结论 app端支持比较好可以做到实时传递 微信小程序支持比较差 小程序向url传参只能通过url url向app传参需要特定时机 后退 组件销毁 分享 复制链接 触发才能收到消息 以下是代码 app端 需要使用nvue
  • 数组建堆(heapify)

    将一个数组调整为最大堆 根据堆的性质 只要保证部分有序即可 即根节点大于左右节点的值 将数组抽象为一个完全二叉树 所以只要从最后一个非叶子节点向前遍历每一个节点即可 如果当前节点比左右子树节点都大 则已经是一个最大堆 否则将当前节点与左右节
  • React中的组件以及组件实例的三大属性(详细类的复习)

    前言 我们为什么要模块化 是因为要复用编码 提高效率 react就是面向组件编程 函数式组件 函数不能中作为react的节点 就跟正常写函数一样 需要注意的是首字母需要大写 把函数封装为组件 所以把组件渲染到页面上时要使用组件的形式 因为开
  • Smart Tools 网站的架构之美

    本文将简要介绍Smart Tools工具箱网站的架构设计 带领大家一起领略架构之美 Smart Tools是一款实用的在线工具箱网站 地址 https smart tools cn 总体架构 Smart Tools工具箱网站是采用前后端分离
  • 为什么无法用数组名输出数组的的首地址

    当我们直接输出其他类型数组的数组名时 打印的都是一串地址 而字符数组打印的是字符串 为什么 因为字符串中 0 这个结束符 计算机可以知道在哪里读取结束 所以打印数组名就代表输出里面存储的字符串 其他类型没有结束符 计算机不知道从哪里停止 所
  • vue组件生命周期有哪些?vue2和vue3的生命周期图牢记于心,附面试题1

    单选题 关于vue组件生命周期说法错误的是 A 在data中的对象的某个属性和input双向绑定 修改input的值 在beforeDestroy中获取的值是修改过后的值 B ajax请求可以放在created钩子函数中 C 在create
  • Flutter每次进界面都刷新数据

    前言 需求 每次进去消息中心需要请求接口刷新数据 点击打开子界面返回也要请求数据改变状态 解决方法一 1 在initState方法加载数据 override void initState super initState 加载数据 loadD
  • git基础介绍与GitKraken操作简记

    刚开始尝试使用git的时候 简直是被弄得生不如死啊 写了半天的代码一下子被删了 那时候的心情简直想SHI 后来没办法 抽了点时间学习了一下git的原理 其实就是你的文件现在到底在什么状态 这么一个问题 由于只是了解 所以不知道具体的操作 具
  • Redis有效时间设置及时间过期处理

    本文对redis的过期处理机制做个简单的概述 让大家有个基本的认识 Redis中有个设置时间过期的功能 即对存储在redis数据库中的值可以设置一个过期时间 作为一个缓存数据库 这是非常实用的 如我们一般项目中的token或者一些登录信息
  • 打开PowerPoint提示:PowerPoint上次起送时失败。以安全模式启动PowperPoint将帮助您纠正或发现启动中的问题

    PowerPoint 无法打开 1 问题 PowerPoint 上次启动时失败 以安全模式启动PowerPoint 将帮助您纠正或发现启动中的问题 以便下一次成功启动应用程序 但是在这种模式下 一些功能被禁用 是否使用 安全模式 启动Pow
  • 数学计算模拟类问题:加法,除法和幂,注意越界问题。题 剑指Offer,Pow(x, n) ,Divide Two Integers

    数学计算的模拟类题目 往往是要求实现某种计算 比如两数相除 实现的过程中会有所限定 比如不允许乘法等等 这类题目首先要注意计算过程中本身的特殊情况 比如求相除 则必须首先反映过来除数不能为0 其次要记得考虑负数的情况 如果计算范围不单单是整
  • 简单的matlab分布式计算

    matlab的分布式计算可以理解为一台机器作为client 主控机 其他的机器分别作为计算的结点 要由client进行控制和操作 如果把单机上的 m文件直接放到client运行 是不会产生分布式计算的效果的 只相当于在主控机进行了计算 而其
  • 【JavaScript】defer和async的区别

    转载自 https segmentfault com q 1010000000640869 先来试个一句话解释仨 当浏览器碰到 script 脚本的时候 没有 defer 或 async 浏览器会立即加载并执行指定的脚本 立即 指的是在渲染
  • 华为性格测试通关指南

    一 华为性格测试关键要点 前后一致 积极乐观 吃苦耐劳 二 华为喜欢的人才性格画像 服从领导 能够按部就班按时完成工作 能够死命干活 没有太多性格 比如有野心 好胜 想当领导 坚持己见 坚持自己做事方式 别人有错当面硬刚这些类似的性格 喜欢
  • java实现航班信息查询管理系统

    一 任务概述 二 目录结构 三 详细代码 JDBC工具类模块 package com kaikeba task task010404 utils import com alibaba druid pool DruidDataSource i
  • python打包编译成pyd或者,Python .py生成.pyd文件并打包.exe 的注意事项说明

    最近用python写了一个小程序 想发布出去让人试用又不想暴露源码 搜索了一下发现将py文件编译成pyd文件就能达到目的 转换过程很简单 但是在调用pyd文件并且打包为单个exe文件的时候遇到一个坑 搞了一天才解决 在这里分享一下 首先安装
  • 使用post请求建立长连接实现sse,接收后端主动发来的消息,实现chat-gpt的弹字效果,EventSource的应用

    每日鸡汤 每个你想要学习的瞬间都是未来的你向自己求救 最近在做一个chat相关的功能 然后由于接口返回特别特别慢 所以需要搞一个慢慢等待的效果 就是接口一个单词一个单词的返回 然后前端收到一个展示一个 提升用户体验 说实话我是第一次做这类需
  • 消费者不用手机凭一张脸就能完成支付和转账

    以前出门要看钱包交易完成的节点 而商业活动发生于诸多场景中 商家若想为消费者提供更好的服务 就必须更深入地了解消费人群 赢得消费者的青睐 蜻蜓二代推出的AI刷脸会员功能 帮助商家完成顾客的会员一键开卡 不涉及填表 确认 签字等繁琐的流程 只
  • ETL为什么经常变成ELT甚至LET?

    ETL是将数据从来源端经过清洗 extract 转换 transform 加载 load 至目的端的过程 正常的 ETL 过程应当是 E T L 这三个步骤逐步进行 也就是先清洗转换之后再加载进目标端 通常是数据库 最后在数据库中的只是合理