把不再变化的历史数据存储成轻量级的 esProc SPL 列存文件,可以利用 SPL 语言的强大计算能力,跑出远超传统数据库的查询性能。 esProc SPL 很轻,直接嵌入应用就可以运行,在实现数据外置提速的同时,也不会让整个系统架构变得很复杂:这里准备了一套使用 SPL 外置数据提速查询的实践方法:第一篇 - 常规过滤及分组汇总第二篇 乾学院有例子数据 csv 文件和建表 SQL,模拟某公司线下订单和电子商务的部分数据。需要在 MYSQL 数据库中建表,并导入 csv 数据。 例子表结构是这样的:事件表 events,电商网站用户的操作事件,一千万行,包括字段:订单表 orders,存储线下订单数据,一千万行:订单名细表 details,存储线下订单明细数据,三千万行:客户表 customer,存储线下客户数据,数据量较小:城市表 city,存储线下客户所在城市数据,数据量较小:州表 state,存储线下客户所在州数据,数据量较小:运货商表 shipper,存储线下运货商数据
但数据库无法保证存储的次序,很难实施这样的有序去重算法。esProc SPL 可以把数据导出后有序存储,实现这种高性能的有序去重计数。 数据外置时,要按照用户号有序存储,可以使用有序去重提高性能。 我们用 ETL 工具定义一个新的 Q2.etl 文件,重复前面的步骤,连接数据库 - 拖拽 events 表 - 编辑:这里按照客户号有序存储,可以使用有序去重提高性能。排序字段必须放在第一个。 SPL 代码 12:icount 是去重计数,加 @o 选项就是有序去重计数,也是只合并相邻且相同的值。 是否可以用有序去重来提速?
SPL可以让文件拥有计算能力,用它的轻量级列存文件存储不变的历史数据,较小的投入就能实现高速查询。SPL引擎非常轻,部署后占用存储空间仅几百M,单机就可以运行,无须集群。 SPL还能嵌入前端应用中,只需要几个jar包和配置文件,就可以在应用内提供强计算能力。 实现数据外置提速的同时,也不会让系统架构变得很复杂:轻量的SPL,计算能力却非常强大,在列式存储、数据压缩、多线程并行等方面都做了深度优化,能让条件过滤、分组汇总这些常规运算的性能大幅提升,完全不输于专业的 SPL常规计算与MYSQL对比(单位:秒)注:测试环境和方法参见 《如何用esProc将数据库表转储提速查询》SPL代码也很简单,比如大订单表的过滤和分组汇总:专业OLAP数据仓库利用列存压缩等技术能让常规运算中跑出较高性能 同时,SPL代码仍很简单:6月6日有现场讲解用SPL实现外置提速的免费培训:课程涉及的实例都是传统数据库很头疼的老大难问题,比如COUNT DISTINCT,外键JOIN,大主子表关联(包括EXISTS
SPL 代码 27:A1=now()2=file("employeeQ6.btx").import@b()3=A2. SPL 代码 29:采用对位序列的写法。A1=now()2=file("employeeQ6.btx").import@b()3=A2. SPL 代码 30:不使用对位序列。 SPL 代码 31:使用对位序列。A1=now()2=file("customerQ6.btx").import@b()3=A2. 是否可以用对位序列提速?
这一篇介绍主键关联的提速。主表订单表和子表明细表的关联就是主键关联。SQL 中,这种关联仍用 JOIN 实现,在两个表都很大的情况下,常常出现计算速度非常慢的现象。 如果预先将主子表都按照主键有序存储,就可以使用归并算法实现关联。这种算法只需要对两个表依次遍历,不必借助外存缓存,可以大幅降低计算量和 IO 量。 esProc SPL 支持有序归并算法,可以大幅提升主子表关联计算性能。先做数据准备,把历史数据从数据库导出为 CTX 文件。在 ETL 中定义 Q4.etl:修改两个表的名字,加上 Q4。 注意:两表要按照 order_id 连接,就按照这个字段有序存储。但不选中“用数据库排序”。生成 SPL 代码 18:A5和 A8 中用 #order_id 来声明 CTX 是对这个字段有序的。 是否可以用有序归并方法提速?
我们以订单表为例实现 esProc SPL 数据外置,提速常规过滤及分组汇总计算。我们使用 SPL 的 ETL 工具来生成脚本,实现数据的转储。 打开工具 - 数据连接:点击连接后,数据库的表可以拖拽到工作区:工具 - 数据目录,设置数据文件存储的目录。工具 - 生成 SPLX 代码:导出后,记得这次新建的 etl 保存成 Q1.etl 文件。 SPL 代码 2:导出的 SPL 代码,是从 MYSQL 数据库中导出数据,转储成集文件 BTX。 SPL 的分组会缺省将分组键和聚合值拼成结果集,不像 SQL 那样要在 SELECT 中把分组键再写一遍。SPL 的执行时间是 2.2 秒。BTX 是行式存储,还不能最大程度发挥 SPL 的性能。 需要注意的是,SPL 文件存储有其特定的适用场景。因为要导出数据,所以更适合计算不变的历史数据,其实这种场景就很多了。
SPL 重新定义了关联。关联不再和笛卡尔积有关,而是分成两种情况:外键关联和主键关联。SPL 用不同的函数来计算不同的关联,体现关联运算本质。 这样就可以利用不同关联的特征,采用不同的手段甚至不同的存储方式有效提速。关联的一种情况是外键关联。一个表的普通字段(外键)和另一个表的主键关联。比如订单表与客户表、运货商表都是外键关联。 下面,我们以订单表、客户表、城市表、州表和运货商表为例,介绍 esProc SPL 外置数据提速外键关联的方法。 SPL 代码 17:在前面代码 SPL 代码 16 基础上,改一下 A4 就可以了。执行时间是 0.3 秒。 是否可以用序号关联的方法来提速?
这样的计算本质上是在做主键关联,如果能预先将主子表都按照主键有序存储,也可以使用有序归并算法有效提速。esProc SPL 可以把主子表的 EXISTS 转化为有序归并,从而提升计算性能。 下面通过订单表和订单明细表的例子,介绍这种情况的外置提速方法。先完成数据准备,可以直接使用第四篇生成的 CTX 文件。例 5.1 对包含 7 号产品的订单,按照客户号分组统计订单个数。 d.order_id = o.order_id and d.product_id=7)group by o.customer_id;执行时间 41 秒SPL SPL 代码 25:A1=now()2=file("ordersQ4.ctx").open().cursor@m(order_id,order_date)3=file("detailsQ4.ctx"). 是否可以用有序归并方法提速?
0 准备篇背景多样性数据源混合计算是常态需求,同构或异构数据库之间、文件与数据库、NoSQL 与文件等,理论上任何数据存储之间都涉及数据混合计算和分析。 最常见的 RDB,文本、Excel、JSON 等本地文件,以及 HTTP 数据源等都属于原生连接器,内置在 SPL 核心体系中。 而其他多样性数据源,如 MongoDB、Kafka、ElasticSearch、云存储都属于外部连接器,不在 SPL 核心体系内,需要另外部署。 这里使用 SPL 做多源计算包括以下内容:目录实践 1:在 RDB 上跑 SQL学习 SPL 基本使用,如何与数据库交互,SPL 如何与应用集成实践 2:查询 csv/xls 等文件查询分析文件数据源, 学会分别使用 SPL 原生语法和 SQL 语法处理文件实践 3:查询 Restful/JSON 数据学会使用 SPL 处理多层数据实践 4:查询 MongoDB以 MongoDB 为例学习连接查询其它外部数据源实践
用 SPL 查文件也很简单,而且能处理各种文件格式。 计算用例查询目标基于 orders1.csv(有标题),统计 2024 年各类订单状态的订单金额SPL 语法编写脚本A1:读入 CSV,T() 函数会根据文件扩展名读出文件内容,返回成序表全部加载到内存 A1:加了 @b 选项代表处理无标题文件,读出后字段名会用 _1 _2 _3…来表示A2:就用 _3(第三列)来过滤 2024 年数据。后面的计算是类似的。 SQL 语法SPL 的原生语法可以完成各类计算,但有时对于熟悉 SQL 的人如果能用 SQL 查文件就好了。SPL 考虑到了这点,也提供了 SQL 语法。比如前面的计算,也能直接用 SQL 搞定。 目前 SPL 提供的 SQL 语法支持到 SQL92 程度,连 WITH 也可以使用,但是并不支持窗口函数,因为使用 SPL 原生语法可以处理各种复杂计算,所以支持到这种程度就够了。
多样性数据源混合计算是常态需求,同构或异构数据库之间、文件与数据库、NoSQL与文件等,理论上任何数据存储之间都涉及数据混合计算和分析。 SPL为多源计算设计了两种Connector,最常见的RDB,文本、Excel、JSON等本地文件,以及HTTP数据源等都属于原生Connector内置在SPL核心体系中;其他多样性数据源,如MongoDB 、Kafka、ElasticSearch、云存储属于外部Connector,不在SPL核心体系内,以“外部库”的形式提供,随需引入即可。 一句执行SQL并传递参数:处理CSV文件也简单,3句就能完成从读取到过滤再到汇总的计算:而且SPL还为熟悉SQL的小伙伴提供了SQL支持,可以用SQL查文件:SPL语法和SQL语法还能混用,可以应付任意复杂情况 我们已经将SPL做多源混合计算的各种情况做成了免费课程,6月20日线上直播~~乾学院通过本课程,您将快速掌握多源数据融合计算能力,轻松实现跨库/文件/API/NoSQL的混合计算,完成从轻量级方案设计到
轻量级的 esProc SPL 弥补这个空缺,用 SPL 这辆小轿车一样可以跑出高铁(MPP)的速度! 不需要分布式 作为开源计算引擎,SPL 是专门为结构化数据处理而设计。 SPL 设计了支持这些机制的高性能文件存储,不需要封闭的数据库管理系统,文件存储可以直接分布在任何的文件系统之上,表现更加开放。不仅性能高,SPL 即装即用,表现也更轻。 部分案例参考: SPL 提速天体聚类任务 2000 倍 开源 SPL 将银行手机账户查询的预先关联变成实时关联 开源 SPL 提速保险公司团保明细单查询 2000+ 倍 开源 SPL 提升银行自助分析从 前面我们提到 SPL 提供的高性能文件存储可以充分保障计算性能。但与数据库要将数据封闭在内部不同,SPL 并不绑定存储,这些数据文件在本地或异地都可以。 即使使用 SPL 提供的高性能文件,在整个系统中的表现与使用文本一样,都可以将其存放在本地或网络文件系统中,还可以直接使用 S3 等云上对象存储。
FastDFS是什么 FastDFS是使用c语言编写的开源高性能分布式文件系统 是由淘宝开发平台部资深架构师余庆开发,FastDFS孵化平台板块 他对文件进行管理,功能包括文件存储,文件同步,文件访问等 存储策略 为了支持大容量,存储节点采用分组的组织方式,存储系统由一个或多个组组成,组与组之间文件相互独立,所有组加起来就是存储系统的容量,一个组可以有一个或多个存储服务器组成,一个组下的存储服务器的文件都是相同的 ,storage将会分配一个存储目录,支持如下规则(在storage配置文件可以通过storage-path*,可以设置多个) 多个存储目录轮询 剩余空间最多优先 6.生成文件名 编码,转换为可以打印的字符串 7.选择两级目录 当选定存储目录之后,storage会为文件分配一个file id,每个存储目录下有两级256*256的子目录,storage会按文件名称进行两次hash, 路由到其中一个目录,然后将文件filedid为文件名存储在改子目录下 8.生成fileid 当文件存储到某个目录后,即认为文件存储成功,接下来就会为改文件生成一个文件id,文件id,有group,存储目录
函数定义与扩展SPL 支持的数据库类型和函数定义在发布包 esproc-bin.jar 中的字典文件 /com/scudata/dm/sql/function.xml 中。<? 另外,我们希望把 SQL 移植做到尽量透明,除了首次改写,以后再换数据库无需再更改代码重编译,只要维护配置文件即可。因此,我们把数据库类型维护在配置文件中。 比如,我们增加数据库类型配置文件 dbconfig.properties ,里面配置数据库类型,如 MYSQL。 A1 中判断 dbName 变量是否存在,如果不存在则在 B1 调用初始化脚本 initGlobalVars.splx:这个脚本读取配置文件中的数据源名称和数据库类型,用 ENV 函数放置在全局变量 dbType 其中,配置文件 dbconfig.properties 内容:database.type=MYSQLdatabase.name=MYDATASOURCEA2 进行 SQL 翻译,这个方法大家已经不陌生了
Rest 服务和数据格式访问http://192.168.2.52:8503/orders可以获得订单数据:Orders 采用多层 json 存储了订单产品等相关信息,结构如下:[ { "order_id quantity)>200). new(order_id,order_date,customer,order_details.sum(price*quantity):amount)JSON如果数据是以 json 文件的形式提供
我们用 SPL 连接 MongoDB 做计算。导入 MongoDB 数据。 外部库SPL 支持的多种数据源大概分两类,一类是像 RDB 有 JDBC 直接使用,或者文件等直接读取;另一类是像 MongoDB 等非关系数据源是在官方驱动上进行了简单封装,具体以“外部库”的形式提供 计算用例Orders 集合存储了订单相关信息,其结构和内容如下:{ "_id": { "$oid": "6826ade0cbc0428d8335b0bb" }, "order_id": "ORD1001 这里以 MongoDB 来举例说明 SPL 连接特殊数据源时的处理方式。其他数据源也是类似配置外部库,然后使用对应的原生语法访问即可。 比如读取 Kafka 数据:访问 Elasticsearch:访问 HDFS:SPL 这种 Native 接口 + 简单封装的方式简单方便,可以保留数据源的特点,充分利用其存储和计算能力,不需要先把数据做
NSUserDefaults简介 在Android和ios都提供了本地轻量级数据存储,底层实现都是基于key-value的方式。 比如说我们要存储 用户名(NSString):userName 密码(NSNumber):userPassword 用户信息(NSDictionary):userInfo 那么我们可以定义如下: NSString @"sex":@"male" }; BOOL isOn=YES; 接着我们使用NSUserDefaults开始对资料进行存储 forKey:@"info"]; [[NSUserDefaults standardUserDefaults] setBool:isOn forKey:@"isOn"]; //调用synchronize存储 initWithDictionary: [[NSUserDefaults standardUserDefaults]dictionaryRepresentation]]; NSUserDefaults只能存储一些简单的数据类型
交管系统(DB_Traffic)存储了车辆交通信息,其中违章记录表 traffic_violation 结构如下:公民信息系统(DB_CitizenEvent)存储了公民相关信息,其中公民事件表 citizen_event SPL 在做 JOIN 运算时会根据不同的关联情况选择不同的方法,简化编码的同时还能提升计算效率。 由于外键指向的维表记录是唯一的,switch 直接将关联字段 citizen_id 转换成 A2 中的记录(实际在内存中存储的是维表记录所在地址)。 再次强调,无论是跨库还是跨其他任何数据源,SPL 在处理时只要数据源能接入,后续计算都一样,因为 SPL 提供了统一的序表和游标数据对象。
相同结构的数据按照年份存储到不同数据库时,要进行数据统计就会涉及多库混合计算。 事实上,不管是数据库还是其他任何存储介质,相同结构数据合并都是类似的,只是读取数据这一步有所不同(不同数据源有不同的接口 / 函数)。 = ~(2).order_status运行后可以看到比对结果:大数据情况如果数据量比较大不能把数据全部读入内存,就需要使用 SPL 游标机制完成混合计算。 如果计算结果也比较大没法全内存,还可以将结果输出到文件。再改造一下上面的代码:在 C7-C10 的 fetch 中加入输出文件名。执行后就得到了这几个结果文件。 无论是跨库,还是跨其他数据源,SPL 就都能很容易完成了。
集算器SPL是个很好的选择,它内置了很多高性能算法(如二分法),也支持多线程并行,代码写起来也简单明了,还提供了友好的可视化调试机制,能有效提高开发效率,以及降低维护成本。 实际效果 相较于Python来说,SPL为本任务提速2000倍,二分法能够提速500倍,多线程并行又提速4倍(笔者笔记本电脑的CPU只有4核),总计提速2000倍,使用SPL完成500多万目标规模的聚类任务只需要数个小时 SPL的代码不仅性能优异,而且也并不复杂,关键计算代码只要23行。 C17格的select@b(...)函数是二分查找方法,也是本任务提速的关键。 SPL有足够的算法底层支持且允许高并发,代码能做到很简洁,还提供了友好的可视化调试机制,能有效提高开发效率,以及降低维护成本。