SPL 实践:跑批提速时的数据流程

跑批提速是SPL的一个主要优化场景,把跑批数据转储到SPL的高性能文件是优化过程中的重要环节。需要被转储的数据,通常包括两部分:历史冷数据和周期性增量数据(增删改)。下面介绍如何把历史与增量数据转储计算,以及周期性更新与定期重整。

一、历史数据转储

组表是SPL提供的高性能存储格式,其原理在于将数据事先排序并以压缩方式紧致存储,好处是占用空间更小,可利用有序进行快速定位。

TPC-HORDERS表为例,从数据库中将历史数据转储为组表文件,代码如下:


A

B

1

fork 4.()

=connect@l("oracle12c")

2


=B1.cursor@x("SELECT O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS,O_TOTALPRICE,O_ORDERDATE,O_ORDERPRIORITY,O_CLERK,O_SHIPPRIORITY,O_COMMENT FROM ORDERS WHERE MOD(O_ORDERKEY,4)="/(A1-1)/"ORDER BY 1")

3


=file("orders"/A1/".btx").export@b(B2)

4

=directory("orders?.btx")

5

=A4.(file(~).cursor@b()).merge(#1)

6

=file("hisdata.ctx").create(#o_orderkey,o_custkey,o_orderstatus,o_totalprice,o_orderdate,o_orderpriority,o_clerk,o_shippriority,o_comment)

7

>A6.append@i(A5)

8

=A4.(movefile(~))

执行后,生成按主键O_ORDERKEY 有序hisdata.ctx历史数据组表文件。

二、增量数据仅追加

2.1增量数据与历史数据整体有序

当增量数据的主键只在历史数据的主键最大值后,可以直接在历史数据后追加。

例如,历史数据组表hisdata.ctx主键O_ORDERKEY的最大值为6000000,增量数据newdata.csv的主键从6000001开始递增

O_ORDERKEY

O_CUSTKEY

O_ORDERSTATUS

1

36901

O

2

78002

O

32

130057

O

hisdata.ctx

O_ORDERKEY

O_CUSTKEY

O_ORDERSTATUS

6000001

666

O

6000011

54321

F

6000012

12345

O

newdata.csv

代码如下:


A

1

=file("newdata.csv").cursor@ct()

2

=file("hisdata.ctx").open().append@i(A1)

2.2增量数据与历史数据分别有序,但不整体有序

2.2.1数据较小的情况

历史数据不大,每次与原表归并即可。

例如,历史数据组表hisdata.ctx主键O_ORDERKEY的最大值为6000000,增量数据newdata.csv中有主键小于6000000

O_ORDERKEY

O_CUSTKEY

O_ORDERSTATUS

1

36901

O

2

78002

O

32

130057

O

hisdata.ctx

O_ORDERKEY

O_CUSTKEY

O_ORDERSTATUS

3

444

F

500

66666

O

6000012

12345

O

newdata.csv

代码如下:


A

1

=file("newdata.csv").cursor@ct()

2

=file("hisdata.ctx").reset(;A1)

2.2.2数据量较大

历史数据随时间增涨,每次与原表归并需要的时间变得越来越久。这时可以将数据组表文件分为两部分:历史数据组表hisdata.ctx和增量数据组表newdata.ctx,每次追加只对增量数据组表,一段时间后,再将增量数据与历史数据归并。例如,增量数据需要每天更新、每月重整:


A

B

1

if day(now())==1

=file("hisdata.ctx").reset(;file("newdata.ctx").open().cursor())

2


=file("newsdata.ctx").create@y(#o_orderkey,o_custkey,…)

3

=file("newdata.ctx").reset(;file("newdata.csv").cursor@ct())

读数据时,需要将增量数据组表与历史数据组表归并后使用,例如:

=[file("newdata.ctx").open().cursor(),file("hisdata.ctx").open().cursor()].merge(#1)

这里需要注意的是,游标序列中应按数据新旧顺序,即[增量数据,历史数据]

如果数据量更大,可能还会涉及分区存储成复组表,可以参考:复组表定期维护例程

三、增量数据涉及修改与删除

这种情况,数据量不会非常大,我们这里只介绍单个组表上更新的方法。数据量巨大需要多个组表的情况可以使用复组表,参考:复组表定期维护例程

3.1只增加修改没有删除

当增量数据还涉及修改时,历史数据需要按主键更新。

例如,历史数据组表hisdata.ctx主键O_ORDERKEY的最大值为6000000,另有增量数据newdata.csv

O_ORDERKEY

O_CUSTKEY

O_ORDERSTATUS

1

36901

O

2

78002

O

32

130057

O

hisdata.ctx

O_ORDERKEY

O_CUSTKEY

O_ORDERSTATUS

1

1111

F

999

9999

O

6000012

12345

O

newdata.csv

代码如下:


A

1

=file("newdata.csv").cursor@ct()

2

=file("hisdata.ctx").reset@w(;A1)

3.2还有删除的情况

历史数据还是上面的一样,不同的是,增量数据newdata.csv在主键O_ORDERKEY后有状态列STATUS,记录状态分为4种:B(主键变更)、D(删除)、A(更新)、I(插入),BI必定成对出现,例如:

O_ORDERKEY

STATUS

O_CUSTKEY

O_ORDERSTATUS

1

B

36901

O

6000001

I

36902

F

2

A

123314

F

6000001

A

36902

O

33

D

136777

O

6000002

I

88888

O

6000002

A

88888

F

这种情况,需要在最初设计组表时,维字段后加个删除标识列(字段名随意,这里用DEL),其值为false代表记录有效,true代表记录作废,默认设为false。历史组表hisdata.ctx如下:

C_CUSTKEY

DEL

C_NAME

C_ADDRESS

1

false

36901

O

2

false

78002

O

32

false

130057

O

33

false

66958

F

34

false

61001

O

需要注意,在有删除标识的组表,建立时,需要用加上create@d参数,将维后的第一列作为删除标识列。

增量数据newdata.csv按状态描述,不难转为以下形式:

C_CUSTKEY

DEL

C_NAME

C_ADDRESS

1

true

36901

O

2

false

123314

F

33

true

136777

O

6000001

false

36902

O

6000002

false

88888

F

代码如下:


A

1

=file("newdata.csv").cursor@ct()

2

=file("hisdata.ctx").reset@w(;A1)

带有删除标识列的组表,归并后,删除标识列为true的记录将从组表中删除。读组表时,可以在cursor中不将删除标识列读出,例如:=file("hisdata.ctx").open().cursor(o_orderkey,o_custkey,o_orderstatus,…)