DCM:中间件家族迎来新成员

B站影视 2025-01-22 00:55 2

摘要:现代应用无时无刻不在与数据打交道,数据计算无处不在,报表统计、数据分析、业务处理不一而足。当前数据处理的主要手段仍然是以关系数据库为代表的相关技术,虽然使用高级语言(如 Java)硬编码也能实现各类计算,但远不如数据库(SQL)方便,数据库在当代数据处理中仍然

现代应用无时无刻不在与数据打交道,数据计算无处不在,报表统计、数据分析、业务处理不一而足。当前数据处理的主要手段仍然是以关系数据库为代表的相关技术,虽然使用高级语言(如 Java)硬编码也能实现各类计算,但远不如数据库(SQL)方便,数据库在当代数据处理中仍然发挥举足轻重的作用。

不过,随着信息技术的发展,存储与计算分离、微服务、前置计算、边缘计算等架构与概念的兴起,过于沉重、封闭的数据库在应对这些场景时越来越显得捉襟见肘。数据库要求数据入库才能计算,但面对丰富的多样数据源时,数据入库不仅效率低资源消耗大,实时性也无法保障,而有的数据只是临时使用却要入库持久化就更得不偿失了。另外对于微服务、边缘计算等需要将计算能力前置到应用端的场景,数据库也很难嵌入使用。

在这样的背景下,如果有一种不依赖数据库、具备开放计算能力、能够与应用嵌入集成使用的数据计算处理技术,那么这些问题就都能够很好地解决,这就是数据计算中间件(Data Computing Middleware,简称 DCM)。DCM 的应用场景非常广泛,可以说无处不在,在优化应用开发、微服务实现、存储过程替代、数据库解耦、ETL 辅助、多样性数据源计算、BI 数据准备等等多方面都能发挥重要的作用,几乎所有涉及应用数据交互的场景都可以通过 DCM 来改善应用结构,提升开发与计算效率。

应用中数据处理逻辑只能通过编码实现,使用原生的 Java 实现由于缺少必要的结构化计算类库往往比较困难,即使用新增加的 Stream/Kotlin 也并没有明显改善。借助 ORM 技术可以一定程度缓解开发困境,但仍然缺乏专业的结构化数据类型,集合运算不够方便,同时读写数据库时代码繁琐,复杂计算也难以实现。ORM 的这些缺点经常导致业务逻辑的开发效率不仅没有明显提升,甚至还大幅降低。此外,这些实现方式还会导致应用结构问题。Java 实现的计算逻辑必须与主应用一起部署导致紧耦合,同时由于不支持热部署开发运维也很麻烦。

如果借助 DCM 的敏捷计算、易集成、热切换等特性,在应用中替代 Java 实现数据处理逻辑,就可以很好解决上述问题,不仅开发效率提升,还可以优化应用结构,实现计算模块的解耦,同时支持热部署。

多样性数据源计算

现代应用还经常面临多样性数据源问题,通过数据库处理不仅需要数据入库,效率低下,还无法保障数据的实时性。不同数据源有各自的优势,RDB 计算能力较强,但 IO 吞吐能力弱;NoSQL 的 IO 效率高,但计算能力很弱;而文本等文件数据完全没有计算能力,但使用非常灵活。强迫这些数据入库就会丧失这些原数据源的优势。

通过 DCM 的多源混算能力,不仅可以直接对 RDB、文本、Excel、JSON、XML、NoSQL 以及其他网络接口数据进行混合计算,保证数据与计算的实时性,而且还能同时保留各类数据源的优点,充分发挥其效力。

当前微服务实现时仍然大量依赖 Java 和数据库实施数据处理,Java 的缺点在于实现复杂、无法热切换;而数据库由于有“库”的限制,多源数据要入库才能计算,灵活性很低,不仅数据时效性无法保证,也无法充分发挥各类数据源的优势。

将可集成的 DCM 分别嵌入中台或微服务的各个环节完成数据采集整理、数据处理以及前置的数据计算任务,利用开放的计算体系可以充分发挥多数据源自身的优势,灵活性增强。多源数据处理、实时计算、热部署这些问题均能迎刃而解。

存储过程替代

以往为了实现复杂计算或整理数据常常会使用存储过程,存储过程在库内计算有一定优势,但缺点也很明显。存储过程缺乏可移植性,编辑调试困难,创建和使用存储过程需要较高权限存在安全问题,为前端应用服务的存储过程还会造成数据库与应用紧耦合。

通过 DCM 将存储过程外置到应用中,可以实现“库外存储过程”,数据库则主要用于存储,将存储过程从数据库中解耦出来就可以很好解决存储过程带来的各类问题。

为报表提供数据准备是 DCM 的重要场景,以往使用数据库为报表准备数据存在实现难度高、耦合性强等问题,而报表本身计算能力不足又无法完成很多复杂计算。通过 DCM 的库外强计算能力就可以为报表提供一个专门的数据计算层,不仅可以解耦数据库为数据库减负,还可以弥补报表工具自身的计算能力不足。逻辑上分层后,报表开发维护都很清爽。

有时为了加快查询效率事先将要查询的数据加工成结果表存储在数据库中,这就是中间表。另外,有些复杂计算需要保存中间结果也会存成中间表;多样数据源也要先存成中间表才能在数据库中混合计算。与存储过程类似,中间表一旦建立就可能被多个应用(模块)使用,造成应用与数据库的紧耦合,同时由于中间表无法轻易删除,数量会越积越多。中间表数量过多会引发数据库容量和性能问题,存储中间表需要空间,加工中间表则需要数据库计算资源。

通过 DCM 可以将中间表外置到文件系统,利用 DCM 实施计算,解耦数据库减轻数据库存储和计算负担。这里的关键是 DCM 使得文件也拥有了计算能力,所以才能将库内的中间表置于库外,原来中间表放在库内主要为了获得数据库的计算能力,现在有 DCM 的计算能力中间表存成什么形式就不重要了,外置到文件系统反而更优。

T+0 查询

数据量积累到一定程度时基于生产库查询会影响交易,这时就会将大量的历史数据剥离到其他历史数据库中,进行冷热数据分离。这时如果要查询全量数据就要完成跨库查询、冷热数据路由等工作。数据库对于跨库查询尤其是跨异构库存在很多问题,不仅效率低下,还存在数据传输不稳定、可扩展性低等很多不足,无法很好实现 T+0 全量数据查询。

而这些问题都可以通过 DCM 来解决,由于具备独立且完善的计算能力,可以分别从不同的数据库取数计算,因此可以很好适应异构数据库的情况,还可以根据数据库的资源状况决定计算是在数据库还是 DCM 中实施,非常灵活。在计算实现上,DCM 的敏捷计算能力还可以简化 T+0 查询中的复杂计算,提升开发效率。

ETL

ETL 需要对数据清洗转换再加载到目标端,但由于源端数据可能来源多处(文本、数据库、web)加上数据质量参差不齐,因此 E 和 T 这两个步骤会涉及大量数据计算。目前除了数据库以外,其他数据源并不太具备这样的计算能力,想要完成这些计算就要先加载到数据库再进行,这就形成了 LET。大量无用的数据存储在数据库中会占用大量存储空间,极易引发容量问题。而将清洗和转换的计算工作都压给数据库又会增加数据处理时间,再叠加大量未经清洗转换的原始数据入库时间,有限的 ETL 时间窗口很可能不够,如果无法在规定时间完成 ETL 工作就会影响第二天的业务。

在 ETL 任务中引入 DCM 就可以按顺序完成清洗 E、转换 T、加载 L,解决 LET 面临的各种问题。借助 DCM 的开放计算能力,在库外对多源数据实施清洗转换,DCM 拥有强计算能力可以应对各类复杂计算,最后将整理后数据装在到目标端,实现真正的 ETL。

DCM 特性

可以看到,DCM 的应用场景非常广泛。那么要很好应对这些场景,一个优秀的 DCM 应该具备哪些特点呢?

首先 DCM 需要具备很好的兼容性,可以跨平台使用,各类操作系统、云平台、应用服务器下均可以很好运行,这决定了 DCM 的使用范围。

此外,兼容性还意味着可以兼容多样性数据源,无论何种数据源都可以直接使用并进行混合计算,这要求 DCM 拥有足够强的开放性。

数据处理是一种高频且稳定性较差的场景,在业务开展过程中经常要新增修改计算任务,这就要求 DCM 应该具备热部署特性,修改数据处理逻辑无需重启应用(服务)就能生效。

计算性能是数据计算场景重点关注的方面,有时会成为最主要的关注点,所谓天下武功无快不破。DCM 应该能够高效处理数据,提供诸如高性能计算库、高性能存方案、并行计算等高性能保障机制。

敏捷性(Agile)

敏捷性要求 DCM 能够快速实现数据处理逻辑,具备完备的计算能力,尤其面对复杂计算场景通过足够简单的编码就能完成数据处理,同时可以高效运行。这需要 DCM 提供敏捷编程机制和易于使用的开发环境等支持。

扩展性(Scalable)

当计算容量无法满足需要时,DCM 应该具备灵活的横向扩展能力。扩展性对当代应用十分重要,扩展能力的好坏决定了 DCM 的上限。

DCM 应该能够很好与应用集成嵌入使用,在应用内充当计算引擎,作为应用的一部分随应用一起打包部署。这样应用本身就获得了强计算能力,不再强依赖数据库后,可以很好应对存储与计算分离、微服务和边缘计算等场景。并且,良好的集成性还是敏捷性的另一方面体现,DCM 很轻,随时随地都能嵌入与应用结合使用。

如果将 DCM 这几个特性的首字母组合起来,与 CHEESE(奶酪)很接近(CHEASE),而 DCM 的作用就像夹在汉堡里的奶酪一样,如果缺少,味道和营养都会差很多。

这样能否作为理想的 DCM 就可以使用 CHEASE 的标准去考察。这里不妨看一下一些主流技术对 DCM 的满足情况。

现有技术的情况SQL

数据库是使用 SQL 的主要阵地,数据库通常具备较强的计算能力,一些头部数据库的计算性能也很强,基本可以满足高性能(E)的需要。而且数据库过于封闭,数据要入库才能计算,无法很好满足多样性数据源场景的需要,兼容性(C)较差。

对于集成性(E),由于绝大部分数据库都是独立使用的,极少数(如 SQLite)支持嵌入的数据库往往功能和性能都达不到要求,因此数据库几乎不满足集成性的要求。

而 SQL 作为专用的集合计算语言,实现简单计算很方便,但复杂计算用 SQL 表达很繁琐,经常要嵌套多层,实际业务中经常能看到几千行的“长”SQL,不仅难写,维护也不方便,所以 SQL 不太符合敏捷性(A)的要求。

与数据库类似的 Hadoop 相关技术也存在同样的问题,封闭性导致兼容性差、敏捷性不足、基本不具备集成性等缺点,虽然在扩展性方面表现要优于数据库,但总体并不符合 DCM 的要求。Spark 的表现要略好,但 Scala 不支持热部署,实现复杂计算也不够方便,而 Spark SQL 仍然存在 SQL 的那些问题。这些技术都过于沉重,很难满足 DCM 在敏捷性、集成性、热部署等方面的需要。

Java

Java 作为原生的编程语言可以很好跨平台运行,也可以通过编码完成多数据源计算任务,因此兼容性(C)很好。而且对于大部分都采用 Java 开发的应用来说,集成性(E)也不在话下。

但 Java 的缺点也很明显,作为编译型语言无法实现热部署(H)。由于缺少必要的结构化计算类库完成简单的分组汇总也要几十行代码,就别提复杂计算了。虽然现在微服务架构中也经常使用 Java 硬编码完成数据处理,但其实计算实现要比 SQL 复杂得多,没办法,计算前置就不能再用数据库,难写也得挺着,因此敏捷性(A)极其不足。虽然在 Java8 以后引入了 Stream,但计算能力并没有实质改善(Kotlin 也存在类似的问题)。

使用 Java 虽然理论上也能实现各类高性能算法,但是如果只是为某个应用 / 项目服务,要实现这些高性能算法封装投入就太大了,因此从实际应用角度来看,Java 并不具备高性能(E)特性。扩展性(S)也存在同样的问题。因此综合来看,Java 很难作为优秀的 DCM 技术使用。

Python 作为大火的一类计算技术不得不提一下。Python 的兼容性(C)较强,无论是跨平台还是对接多数据源都能支持。尤其是丰富的数据处理包让 Python 的适用范围极广。

Python 在结构化数据处理相比于 Java 等技术有相当的优势,但却难说很完善,尤其在处理有序分组等复杂计算时会很绕,Python 在敏捷性(A)上略有所欠缺。

不仅如此,Pandas 的性能(E)也往往达不到要求,尤其针对大数据量计算方面,这跟算法的实现效率有很大关系,敏捷语法可以很方便地实现高性能算法,反之就很困难。同样,在扩展性(S)方面,Python 也不尽如人意,本质上来讲作为编程语言的 Python 要拥有良好的扩展性需要投入大量资源开发完成,这点与 Java 是一样的。

Python 最大的问题是集成性(E),很难与现有应用集成在一起使用。虽然可以通过诸如 sidecar 模式进行服务间调用,但本质上与 DCM 要求与应用结合嵌入在一起(同一个进程)相去甚远。Python 的主要应用场景并非像 Java 一样做企业级应用开发,各有用途,勉强不来。归根到底,专业的事儿还需要专业的工具来做。

开源集算器 SPL 是专业的数据计算中间件,具备不依赖数据库的完备计算能力,同时开放的计算能力可以混合计算多样性数据,同时解释执行的 SPL 天然支持热部署,良好的集成性可以很方便嵌入应用中,让应用拥有强计算能力,充分发挥 DCM 的效力。

兼容性

SPL 采用 Java 开发,跨平台能力与 Java 一致,可以很好运行在各类操作系统、云平台下。而在多数据源支持方面,SPL 具备开放的计算能力,可以对接多种数据源,RDB、NoSQL、CSV、Excel、JSON/XML、Hadoop、RESTful、Webservice 都可以直接对接并进行混合计算,不需要入库,数据实时性和计算实时性都可以很好保障。

多源计算支持很好解决了原来数据库无法跨源计算、无法计算外部数据的问题,再加上 SPL 完备的计算能力和相对 SQL 更简洁的语法,对于应用来说就获得了与数据库相当(超过)的计算能力。

除了原生计算语法,SPL 还提供了 SQL 支持(相当 SQL92 标准),可以使用 SQL 查询文本、Excel、NoSQL 等非 RDB 数据源,这样就极大方便了熟悉 SQL 的应用开发人员。

DCM 只有在开放计算体系的支持下才能拥有足够强的兼容性,才能适应更多的应用场景。

热部署

SPL 采用解释执行机制,天然支持热部署。这样对于一些稳定性差经常需要新增、修改计算逻辑的业务(如报表、微服务)非常友好。

高性能

在性能方面,SPL 提供了诸多高性能算法与高性能存储机制。在前面提到的 DCM 消除中间表和 ETL 场景中,数据往往要落地成文件存储在数据库外,这时采用 SPL 的文件格式存储可以获得比文本等开放格式高很多的性能。

SPL 提供了两种存储类型:集文件和组表。集文件采用了压缩技术(占用空间更小读取更快),存储了数据类型(无需解析数据类型读取更快),支持可追加数据的倍增分段机制,利用分段策略很容易实现并行计算,保证计算性能。组表支持列式存储,在参与计算的列数(字段)较少时会有巨大优势。组表上还实现了 minmax 索引,同时支持倍增分段,这样不仅能享受到列存的优势,也更容易并行提升计算性能。

SPL 还支持各种高性能算法。比如常见的 TopN 运算,在 SPL 中 TopN 被理解为聚合运算,这样可以将高复杂度的排序转换成低复杂度的聚合运算,而且很还能扩展应用范围。

1=file(“data.ctx”).create.cursor
2=A1.groups(;top(10,amount))金额在前 10 名的订单3=A1.groups(area;top(10,amount))每个地区金额在前 10 名的订单

这里的语句中没有排序字样,也不会产生大排序的动作,在全集还是分组中计算 TopN 的语法基本一致,而且都会有较高的性能,类似的算法在 SPL 中还有很多。

SPL 也很容易实施并行计算,发挥多 CPU 的优势。SPL 有很多计算函数都提供并行机制,如文件读取、过滤、排序只要增加一个 @m 选项就可以自动实施并行计算,简单方便。同时也可以显示编写并行程序,通过多线程并行提升计算性能。

SPL 提供了原生的计算语法和简洁易用的 IDE 环境,在 IDE 中不仅可以很方便编码调试,过程计算的每步计算结果都可以实时查看,网格式编码代码天然整齐,通过格子名称引用中间计算结果无需定义变量,简单方便。

同时,基于 SPL 丰富的计算类库实施结构化数据计算更方便,分组汇总、循环、过滤、集合运算、有序计算等应有尽有。

SPL 尤其擅长复杂计算,原来 SQL 要嵌套很多层的计算使用 SPL 却可以很方便实现。比如根据股票记录计算某只股票最长连续上涨多少天?SPL 就比 SQL 简单很多。

上面 SQL 嵌套了 3 层,读起来都很绕就别提写了;下面的 SPL 完全按照自然思维、简单 3 行就能实现,高下立判。

良好的敏捷性不仅能提升开发效率,很多高性能算法通过 SPL 可以很方便实现。算法不仅要能想出来,还要能实现,最好实现还简单,SPL 提供了这种可能。

对于计算性能要求较高的场景,SPL 还可以部署单独的计算服务,同时支持多机分布式集群,支持负载均衡和容错机制,当计算资源达到上限时可以通过横向扩容增加算力,具备良好的扩展性。

在分布式计算中,用户可根据数据和计算任务的特点灵活定制数据分布及冗余方案,有效减少节点间数据传输量,以获得更高性能,实现可控数据分布。

SPL 采用无中心集群设计,集群没有永久的中心主控节点,允许程序员用代码控制参与计算的节点,从而有效避免单点失效。同时 SPL 会根据每个节点空闲程度(线程数量)决定是否分配任务,实现负担和资源的有效平衡。

在容错方面,SPL 提供内外存两种数据容错机制,外存冗余式容错和内存备胎式容错。支持计算容错,节点故障时自动将该节点计算任务迁移掉其他节点继续完成。

作为 DCM 与应用结合方面,SPL 提供了标准 jdbc/ODBC/RESTful 接口,应用可以像调用存储过程一样请求 SPL 计算结果。

逻辑上 SPL 作为 DCM 介于应用和数据源之间实施数据处理,对上提供计算服务,对下屏蔽多样性数据源差异,充分彰显了 DCM 的重要作用。

JDBC 调用 SPL 代码示例:

Class.forName("com.esproc.jdbc.InternalDriver");Connection conn =DriverManager.getConnection("jdbc:esproc:local://");CallableStatement st = conn.prepareCall("{call splscript(?, ?)}");st.setObject(1, 3000);st.setObject(2, 5000);ResultSet result=st.execute;

综合起来,从 DCM 的 6 个特性(CHEASE)来看,SPL 在各方面能力综合起来十分均衡,整体远优于其他技术,是 DCM 的理想选择。

SPL已开源免费,欢迎前往乾学院了解更多!

来源:走进科技生活

相关推荐