DataStage 中的Hash File

 
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。

    
对hashfile算法及存贮机制深入的了解,留在以后有时间继续。
  动态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使用脏读写隔离级别和顺序执行的方式,比依赖锁机制避免污染数据而并行执行几个进程的方式要好很多。
 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值