集群组表

10.1服务器 中,介绍了如何使用分机实现集群计算,组表可以通过分机访问,作为集群组表使用。首先,需要把组表文件上传到服务器,在集算器安装目录的esProc\bin路径下,运行datastore.exe,打开数据存储管理器,将组表文件上传到分机中指定的分区:

在这里先将文件上传到各个分机的0分区中,每个分机的文件分区的磁盘路径可以在服务器配置中设置,0分区默认的存储位置是D:/0。此时即可通过访问分机读取组表文件:

 

A

1

[192.168.10.229:8281]

2

=file@0("employees.ctx",A1)

3

=A2.create()

4

=A3.cursor().fetch()

5

=A3.cursor()

6

=A5.groups(Dept;count(~):Count)

A2中,使用函数file(fn,h) 从服务器列表h中读取组表文件fn,打开集群文件。这个例子中仅使用了单个分机上的组表文件,由于文件存储在0分区,在file函数中添加了@0选项,A2中得到结果如下:

A3中用T.create() 打开组表的基表,此时的组表称为集群组表,集群组表的实表称为集群实表。在集群组表中,可以用T.attach(T') 函数取出附表T'。集群表是只读的,在计算时和本地组表是相同的,根据集群文件的不同,集群表相应称为分布表复写表A4中用T'.cursor()由集群组表的基表T'生成游标,并从游标中取得数据如下:

在分机中,可以查看窗口信息如下:

在使用集群组表时,分机中只有主进程参与提供文件服务,会在访问集群文件时输出信息。

集群组表生成的游标也可以执行cs.join()cs.groupx()cs.groups() 等各类计算。如A6中用cs.groups() 得到分组聚合的结果如下:

 

与组表类似,使用集群组表时,也可以使用集群内表,在内存中使用集群表:

 

A

1

[192.168.10.229:8281]

2

=file@n("D:/file/dw/employees.ctx",A1)

3

=A2.create().attach(etable)

4

=A3.memory(;right(Name,6)=="Garcia")

5

=A4.dup()

6

=A5(4)

A2中打开集群文件时,添加了@n选项,此时的文件并不是从分机对应的分区中查找的,而是直接根据文件名获取。与生成本地组表的内表类似,在A4中用memory() 函数生成集群内表,A4中可以查看到集群内表的结果如下:

集群内表并不能直接作为序表使用,可以用T.dup() 函数,将集群内表T转换为本地内表,如A5中结果如下:

A5中即为普通内表了。普通的内表T也可以用T.dup(h) 函数转换为集群内表。

 

实际上,在上面的分区示意图中可以看到,在另一台分机192.168.10.245:8281上,也同样在0区存储了employees.ctx,此时,也可以同时使用两台分机执行查询,如:

 

A

1

[192.168.10.245:8281, 192.168.10.229:8281]

2

=file@0("employees.ctx", A1)

3

=A2.create()

4

=A3.cursor@z()

5

=A4.fetch()

和前面的使用不同的是,A2中打开集群文件时使用了多个分机。而在A4中生成游标时,添加了@z选项,此时读取相同的组表文件时,将会在分机间拆分处理,但游标的使用和单分机时是相同的。A5中得到结果如下:

在上面的例子中,如果集群文件由各个分机上相同的文件构成,称为复写文件,各个分机上的文件必须完全相同。如果集群文件由多个分机上不同的文件构成,称为分布文件,这种情况下,各个分机上的文件名称必须是相同的。下面我们来看在集群中如何使用分布文件,为此需要先构建分布文件,它们会存储着同一个表中的不同数据,如:

 

A

B

1

=file("D:/file/dw/employees.ctx")

=file("D:/file/dw/orders.ctx")

2

=A1.create()

=B1.create()

3

=A2.attach(stable)

=B2.attach(otable)

4

=A3.cursor(EID,Name, OCount).fetch()

=B3.cursor(Date,EID,Amount).sortx(Date,EID).fetch()

5

=file("D:/file/dw/1/salespart.ctx")

=file("D:/file/dw/1/orderpart.ctx")

6

=A5.create(#EID, Name, OCount)

=B5.create(#Date,#EID,Amount)

7

>A6.append(A4.cursor(1:2))

>B6.append(B4.cursor(1:2))

8

=file("D:/file/dw/2/salespart.ctx")

=file("D:/file/dw/2/orderpart.ctx")

9

=A8.create(#EID, Name, OCount)

=B8.create(#Date,#EID,Amount)

10

>A9.append(A4.cursor(2:2))

>B9.append(B4.cursor(2:2))

A4中从组表employees.ctx的实表stable中获取销售员数据如下:

B4中,从组表orders.ctx的实表otable中取得订单数据,这里的数据是先按Date排序,再按EID排序,数据如下:

A5~A10的代码中,将销售员数据拆分,存入了两个同样命名为salespart.ctx的组表文件,这两个文件置于不同目录中,准备将它们用作分布文件。

B7~B16的代码中,将订单数据拆分,存入了不同路径中两个文件名同为orderpart.ctx的组表中。

这次在同一台电脑启动两个分机A(192.168.10.229:8281)B (192.168.10.229:8291),使用Data Store工具将这些文件分别上传到分机中。其中分机A存储目录D:/file/dw/1中的前一半数据,分区1中存储salespart.ctx,分区0中存储orderpart.ctx;分机B存储目录D:/file/dw/2中的后一半数据,分区2中存储salespart.ctx,分区0中存储orderpart.ctx

此时来看如何使用分布式集群组表:

 

A

B

C

1

192.168.10.229:8281

192.168.10.229:8291

[192.168.10.229:8281, 192.168.10.229:8291]

2

=file@0("orderpart.ctx", A1)

=file@0("orderpart.ctx", B1)

=file@0z("orderpart.ctx", C1)

3

=A2.create()

=B2.create()

=C2.create()

4

=A3.cursor().fetch()

=B3.cursor().fetch()

=C3.cursor().fetch()

5

 

 

 

6

=file@z("salespart.ctx", A1)

=file("D:/file/dw/2/salespart.ctx")

=file@z("salespart.ctx", C1)

7

=A6.create()

=B6.create()

=C6.create()

8

=A7.cursor().fetch()

=B7.cursor().fetch()

=C7.cursor().fetch()

在两个分机上,orderpart.ctx都存储在0分区上,在A2B2中使用file@0(fn, h) 函数,指明集群文件所在的分机,即可打开对应分机中0分区中的文件。在A3B3中取出对应的集群实表,在A4B4中结果如下:

可以看到两个分机上存储文件的不同,分机A上只存储了前一半订单记录,分机B上只存储了后一半订单记录。两个部分的数据是相邻的。

C2中使用file@0z(fn, h) 函数打开分布集群文件,@0z选项表示由分机列表h中所有分机0区的文件构成分布文件。C3中打开集群实表后,C4中取出数据如下:

可以看到,集群表中能够获得各个分机文件中的数据。

 

对于存储在其它分区中的文件,就只能使用file@z(fn, h) 函数打开了,但是使用选项时,对文件存储的分区是有要求的,在分机列表h中,分布式文件必须存储在第一台分机的1区,第2台分机的2区,……因此,在A6中只指定了1台分机时,会打开分机1区中的文件,A8中返回实表中数据如下:

对于分机B中的文件salespart.ctx,由于它存储在分区2中,因此不能单独读取这个文件。B6中打开了本地的组表文件,在B8中取出实表中数据如下:

可以看到,分机A中只存储了前24852条数据,而分机B则存储的是后面的销售员数据,两个部分的数据是相邻的。

C6中,由不同分机不同分区上的分布文件构成集群文件,在C8中取出实表中数据如下:

从集群组表中,取出的就是全部的数据了。

 

从上面的两个分布表salespart.ctxorderpart.ctx中的数据可以发现,它们在不同分机上存储的数据是不匹配的,如分机A中,salespart.ctx中存储了前一半销售员的信息,而orderpart.ctx中存储的是前一半订单的数据。这样,如果需要将两个分布表中的数据关联起来计算,需要用cs.sortx(…;x) cs.groupx(…;x) 与集群游标x同分布处理,如:

 

A

B

1

[192.168.10.229:8281, 192.168.10.229:8291]

 

2

=file@z("salespart.ctx", A1)

=file@0z("orderpart.ctx", A1)

3

=A2.create()

=B2.create()

4

=A3.cursor()

=B3.cursor()

5

=B4.sortx(EID; A4)

=joinx(A4:s,EID;A5:o,EID)

6

=B5.new(s.EID:EID,s.Name:Name,o.Date:Date,o.Amount:Amount)

=A6.fetch()

A4B4中分别用salespart.ctxorderpart.ctx构成分布表的集群游标,在A5中,将B4中测试数据的排序,将排序的结果按照用户数据来同分布处理,生成与用户数据同分布的游标。在B5中,用join函数将两个同分布的游标连接,并在A6中生成需要整理的结果。B6中取出数据如下:

可以发现,不同分步的集群组表,能够正确匹配,返回所需要的计算结果了。