天天看点

海量数据迁移之分区并行切分

在海量的数据迁移中,如果某个表特别大,可以考虑对表中的分区进行切分,比如某个表有100g,还有100个分区,那么可以考虑针对这100个分区,那么可以考虑把这100个分区看成100个表进行并行抽取,如果某个分区数据比较多,可能生成5个dump,那么着100个分区,就可能生成105个分区以上。

那么如果有100多个表,那么可能分区都算进来就可能有上千个。如何对这上千个dump进行最快的加载呢。

可以考虑基于分区的并行切分,里面可能还涉及一些算法的知识。

目前生成了如下的数据报告,我们需要基于这个报告来对如下的表/分区进行切分。

REEMENT这个表不是分区表,所以在分区信息的地方填写了默认值'x',在数据加载的时候会进行过滤。

MEMO这个表比较大,对于分区partition(P0_A1000_E3),生成的dunp序号为21,22,23,总共有3个dump。在数据加载的时候就可以先加载21号dump,然后22号dump,23号dump

MEMO partition(P0_A1000_E3) 3 21..23

MEMO partition(P0_A1000_E2) 3 18..20

MEMO partition(P0_A1000_E1) 3 15..17

USR_GRP_MEMBERS x 2 1..3

REEMENT x 2 1..3

MEMO partition(PMAXVALUE_AMAXVALUE_EMAXVALUE) 1 699..700

MEMO partition(P9_A3000_E5) 2 697..698

MEMO partition(P9_A3000_E4) 2 695..696

MEMO partition(P9_A3000_E3) 2 693..694

MEMO partition(P9_A3000_E2) 2 691..692

MEMO partition(P9_A3000_E1) 2 689..690

MEMO partition(P9_A3000_E0) 2 687..688

MEMO partition(P9_A2000_E5) 2 685..686

MEMO partition(P9_A2000_E4) 2 683..684

MEMO partition(P9_A2000_E3) 2 681..682

MEMO partition(P9_A2000_E2) 2 679..680

MEMO partition(P9_A2000_E1) 2 677..678

MEMO partition(P9_A1000_E0) 2 657..658

我们现在就需要基于第三列的信息,对表、分区表进行切分。使得启用的多个并行进程能够最大程度的达到平衡。

我们可以使用如下的脚本来进行表、分区的并行切分。

比如我们考虑启用6个并行的进程,生成的日志类似下面的形式。可以看到切分还是很均匀的。

move INVOICE partition(A11_B6)  to par6_

move INVOICE partition(A11_B4)  to par1_

move INVOICE partition(A11_B2)  to par2_

move INVOICE partition(A11_B10)  to par3_

move INVOICE partition(A10_B8)  to par4_

move INVOICE partition(A10_B6)  to par5_

move INVOICE partition(A10_B4)  to par6_

move INVOICE partition(A10_B2)  to par1_

move INVOICE partition(A10_B10)  to par2_

move RESOURCE partition(A9)  to par3_

move RESOURCE partition(A8)  to par4_

move RESOURCE partition(A7)  to par5_

move RESOURCE partition(A6)  to par6_

move RESOURCE partition(A5)  to par1_

move RESOURCE partition(A4)  to par2_

move RESOURCE partition(A3)  to par3_

move RESOURCE partition(A2)  to par4_

move RESOURCE partition(A1)  to par5_

move RESOURCE partition(A0)  to par6_

213

214

脚本如下:

par_file_name=$1

sort -rn -k3 $par_file_name > ${par_file_name}_tmp

mv  ${par_file_name}_tmp  ${par_file_name}

par_no=$2

obj_length=`cat ${par_file_name}|wc -l `

echo $obj_length

for i in {1..$par_no}

do

sed -n ''$i'p' ${par_file_name}> par${i}_${par_file_name}

export par${i}_sum=`cat par${i}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'`

done

function getMin

{

param_no=$#

for i in {1..$param_no}

min_sum=$par1_

min_par=par1_

for i in {2..$param_no};

j=`expr $i - 1`

tmp_cur_par=par${i}_

if [ $min_sum -le $tmp_cur_sum  ]

then

 min_sum=$min_sum

 min_par=$min_par

else

 min_sum=$tmp_cur_sum

 min_par=$tmp_cur_par

fi

echo  $min_par

}

function getSumList

for k in {1..$par_no}

#export par${k}_sum=`cat par${k}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'`

#echo $par_list

tmp_sum=`cat par${k}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'`

echo $tmp_sum

#tmp_par_list=${tmp_par_list} "" $tmp_sum

#echo $tmp_par_list

j=`expr $par_no + 1`

for i in {$j..${obj_length}}

tmp_obj=`sed -n ''$i'p' ${par_file_name}`

par_list=`getSumList`

tmp_par=`getMin  $par_list`

echo 'move '`sed -n ''$i'p' ${par_file_name}|awk '{print $1 " " $2}'` ' to '$tmp_par

echo $tmp_obj >> ${tmp_par}${par_file_name}

tmp_par=0

cat par${i}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'

继续阅读