DataStage 中的Hash File

近期遇到些使用hash file的问题,遂整理些自己搜集的东西,有些是翻译的,有些是自己写的,有些english资料不忍篡改,遂保留其原汁原味。

首先,What Exactly Are Hash Fils?

 

Group -physical division
Record -contains data
Key -identifies record
     DataStage 中的hash file 无论是静态("static" Types 2 - 18)还是动态("dynamic" Type 30)都被分为许多group存储数据。group是存贮文件数据的物理单元,每个Group大小相同,存贮零条或者多条数据。对于静态Hash file,group的大小由指定分区决定,是512bytes的倍数。举例说明:指定4个分区,则group以2,048bytes来创建;对于动态hash file,group的大小由GROUP.SIZE参数来决定,以2,048 bytes为单元,GROUP.SIZE允许的值只有1和2,所以动态hashfile中的group大小只能是2 ,048或者4,096bytes。

     Record是数据存贮的的逻辑单元,它可以被逻辑地描述为一组fields或者被物理地描述为record header、key value和数据分区。每个record都有一个通过hash 算法产生的Key Value以确定此record所在的group
 
     文件的group的数目在静态hash file中称为modulo/modulus,在动态Hash File中称为current modulus。在没有外界干涉的情况下,静态hash file中的group的数目保持常量,而动态hash file中的group数目受动态地存贮数据量的大小而改变,这是静态hash和动态hash的首要的区别。我们统计file中的group从1数起,而DataStage Hash File是按照group的起始地址来引用group的。每个hash file都有一个header,groups从文件开始偏移header的大小的位置开始。我们可以通过LIST.READU这样的命令得到group的地址(十六进制给出)。DataStage Hash File工具uvfixfilefilepeek可以以十进制或十六进制计算地址。
 
     当group创建后(CREATE.FILE),group存在的文件section称为 primary group buffer。Primary group buffers 紧挨着file header连续排列,这样文件的对比只需要文件header和primary group buffer,这样大大提高记录读取的速度。但世界并不完美,有时候分配给group的记录不能被放入primary group buffer,这样group处于"溢出"(overflow)的状态,第二个group buffer进行分配,并且daisy-chained to primary group buffer,分配原则如下:
•  静态文件中紧接最后一个primary group
•  动态文件中,在 OVER.30 中(primary group buffers在DATA.30 部分中)

     静态和动态hash file之间唯一真正的区别在于primary buffers 存在于DATA.30 文件中,而溢出group和oversized record buffer存在于OVER.30文件中,由于DATA.30的大小随时间改变而改变,这是必须的。
有溢出(Overflow)说明文件没有调整到最优,可能是由于group太少,或者没有选择最适合的hash算法,或者只是因为key values/structuress不能用hash算法充分操作。ANALYZE.FILE是一个调试Hashfile的工具,可以报告"badly overflowed"的情况,意味着即使在一个Secondary group buffer中仍然没有足够的空间来存贮所有分配给这个group的数据。"badly overflowed" group是多于一个secondary group buffer。

     经验显示约90%的broken file在group buffer的连接上断开。DataStage hash file在group buffer的连接很脆弱,这是因为:
•由于group 被锁住直到整个group处理进或出memory,这样性能很受影响。
•如果secondary group buffer距离它连接的之前的buffer很远的距离,磁盘查询的延时将增加。在这些延时中,文件系统容易受到外部事件的伤害,例如停电。在动态文件中memory中的header信息会同物理文件一起丢失。所以如果溢出(overflow)越少,处理文件的风险就越小。办法就是减少溢出。

     在group中,增加记录,从group的开始处占据空间。记录是用向前和向后指针"daisy chained"的,没有group自己的存贮界定,如group header或者trailer。Free Space作为一个有"free space"的header的""record"存在,可以有对于一个的free space存在于group中,例如一个record从文件中删除,它实际通过有它的frees pace被标志为删除。每个record都把从文件开始的偏移量作为它的地址,例如group在0x2000地址,那么group中的第一个record的地址就是0x2000。

 

  动态hash file的魅力在于它可以随需求动态增长,自动加倍文件大小,重新分配数据,把溢出文件(OVER)中的数据移入数据文件(DATA)中。由于Hash file其特有的存贮机制,需要注意DataStage设计中其使用和误用的地方。

   要想在hash file中查找一条记录,需要知道其key值。数据都是连续字符存贮,字段分隔符是@AM(系统变量),每个字段都按照数据本来的数据排列,这样看来hash file几乎同sequential file一样,字段由其所在的位置定位而非字段名字。 实际上,由于数据是以文本字符串形式存贮,你只需要知道key和字段长度位置即可。在hash file中不要使用受限的ASCII字符,这些字符可能会被作为内部数据分隔符。此外,由于每条记录都是一条文本字符串存贮的,所以hash file中的每条记录都允许有自己的结构, hash file成为非一致结构的自由格式文件。

 

 Hash file在DataStage中以下主要用法

 

通过primary key的 非大量的lookup DataStage® 可以将Hash lookup放入cache内存(Lookup不是Join)。 Lookup使用hey值在hash file中指定查询的row. 如果使用ODBC/OCI stages来做lookup,由于缺少memory cache的能力 performance会差。此外,许多job都作ODBC/OCI Lookup,数据库查询将会饱和。 阶段性的关联性文件 也就是转换job为另外一个job准备的关联数据。通过hash file很容易完成。

 

 

 

非固定不变的中间结果文件. Hash files奇妙的存贮机制是它用于关联lookup的原因。如果数据不需要关联lookup,由于写入sequential file的appending方式,sequential file是最好的选择。Hash file需要检测可用空间,然后决定写入数据文件还是溢出文件。

 

 在DataStage设计中误用的地方:

 

1,存贮固定不变的生产数据在ETL工具中。Hash file 是应该用于丢出数据或者随意使用的中间结果暂存的文件,而非需要可以从被破坏的状态下恢复或者备份的文件。

 

2,把绝大多数row从未被关联到的Hash file Preload到内存中。如果处理的数据量不能超过关联的数据量,Preloading到内存既浪费时间由浪费内存。

 

3,每条记录可能只被Lookup一次的Hash file Preloading到内存。

 

4,使用SQL接口(UV/ODBC,UV/SQL命令)访问hash file。Hash file没有第二个索引支持任何关系型数据库的查询。虽然其内部的engine可以支持这类的操作,我们知道DataStage的大部分东西都是以HashFile存放的,你可以用UVSQL访问他们,但是别试图在你的ETL工具中建造起一个数据库,这也违背了ETL工具将数据展现为图形界面开发处理的初衷。也许这方面的操作,很多人没有遇到,或者不知道如何使用,在后面会有相关的介绍,比如我最近遇到hash file中数据删除问题,就采用了这样的方式。当然我不会总是用UVSQL访问DataStage的数据库和hash file(那样也太累太蠢了)。

 

 

继续hash File可能使用不当的地方。

 

5,企图欺骗Hash File,改变hashfile的元数据,使用一组不同的字段(即使这些字段都在hashfile的表定义中)找到某条记录。这种方式是关系型数据的优势,但不是用于hash file。DataStage 会读取hashfile中记录的全部内容(全部表定义字段)到内存中,所以必须要使用完整的元数据来定义hashfile,不能像操作RDB一样不同的job stage使用不同的表定义来获取记录。

6,多个job并行往同一个hashfile中入数据。尤其是选择Allowing stage write cache的时候,需要及其小心DataStage处理并行的方式。多实例的Job如果使用write cache 的方式写hash file会将数据放入缓冲区(buffer),会造成清洗缓冲点(flush point)的争用,这样就会当实例数增加到一定的数据,运行效率开始下降的分界点。例如,可能由于磁盘的拥堵和争用,4个实例运行的时间可能会比8个实例运行的时间短。对于不同server配置,分界点也会不同,需要测试去找到较好的实例数目。

7,同样,一个job中同时读写同一个hash file,不要选择"Allowing Stage Write Cache"属性。

8,为了帮助DataStage可以以交易模式(transactional mode)使用,在hashfile中加入了行锁机制。但是这个属性最好不要在ETL中使用,它会导致性能极度丧失。DataStage对hash file使用脏读写隔离级别和顺序执行的方式,比依赖锁机制避免污染数据而并行执行几个进程的方式要好很多。

 

此外,我们可以用Hash File玩些小把戏,得到些额外的收获。找点时间填东西了

 

sorry, coming soon...

1,我们都知道可以利用hash去除重复记录,对于键值一样的多条记录只保留最后一条写入的记录。其实这个类似table的update操作,也可以利用此功能进行hash中的数据更新。利用这个功能时候,容易犯错误的是,有时候键值看似一样的数据存在两条或者多条,这是由于hash file对于传入的字段字段中存在空字符串。这也做lookup时应该注意的问题。

2,DataStage中hash设置有两种方式:Use account name/use directory path

Use account name中如果不选account name,系统都会指向此hash目前所在的 account name(Project name),这样如果移植到别的项目时候,hash 会指向移植的项目,hash 文件会建立在此项目的默认目录下,同时写入VOC。如果要删除此hash file,只删除其物理文件不行,需要用TCL command,如在Adminitrator中:DELETE.FILE hashfilename;清空的话用 CLEAR.FILE hashfilename;

如果选择user diretory path,可以在选定的路径下,直接删除路径下的物理文件和路径就可以删除hash 文件了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值