HIVE SQLで発生したファイルの数とパラメータの調整

3679 ワード

発生背景:sqoopがoracleデータをhiveテーブルに抽出した場合、固定パーティション(--hive-partition-key萝hiveパーティションフィールドにしか書き込みできません。 --hive-partition-valueパーティション値)。まずデータをインクリメンタルテーブルに抽出して、インクリメンタルテーブルからパーティションテーブルに動的に書き込みます。
set hive.exec.dynamic.partition.mode = true;  --       ,   ture。
set hive.exec.dynamic.partition.mode = nonstrict;  --      ,   :strict,               ;nonstrict                      。       nonstrict。
set hive.exec.max.dynamic.partitions.pernode =10;  --     MR    ,             ,   :100。
set hive.exec.max.dynamic.partitions =1000;  --     MR    ,               ,   :1000。
set hive.exec.max.created.files = 100000;  --  MR Job          HDFS  ,   :100000。
set hive.error.on.empty.partition = false;  --        ,      ,   :false。
 
Hiveファイルが大量の小さいファイルを生成する理由:
一つはファイルそのものの原因です。小さいファイルが多いこととファイルのサイズ。
第二に、ダイナミックパーティションを使用すると、大量のパーティションが発生する可能性があります。
三つ目はReduceの数が多く、Hive SQL出力ファイルの数はReduceの個数と同じです。
小文書による影響:
ファイルの数と大きさはMapperのタスクの数を決定します。小さいファイルが多いほど、Mapperのタスクが多くなり、各MapperはJVMを起動して実行しますので、これらのタスクの初期化と実行には多くのリソースがかかり、パフォーマンスに深刻な影響を与えます。
NameNodeでは、各ファイルは約150バイトで、小さいファイルが多く、NameNodeの性能に深刻な影響を与えます。
小さいファイルの問題を解決します。
ダイナミックパーティションの数が予測できないなら、使わないほうがいいです。もし使うなら、distributed byパーティションフィールドを使ったほうがいいです。そうすると、フィールドをhash操作して、同じパーティションを同じReduceに処理します。
Reduce数量を減らす;
いくつかのパラメータで調整します。
制御Mapperの数:
Mapperの数を決定する要因は、ファイルの個数を入力し、ファイルのサイズ、クラスタが設定するファイルブロックサイズを入力することです。
例えば、入力ディレクトリの下に800 Mのファイルがあります。hadoopはファイルを7つのファイルに分けます。
例えば、入力ディレクトリの下には5つのファイルがあります。それぞれ15 M、20 M、50 M、100 M、150 Mであれば、hadoopは6つのファイル(15 M、20 M、50 M、100 M、128 M、22 M)に分けて、6つのMapperを生成します。
下記のパラメータを設定することにより、Mapが実行前に小さいファイルをマージすることで、Mapperの数を減らすことができます。
set mapred.max.split.size=100000000;   --     map          ,   B
set mapred.min.split.size.per.node=100000000;   --                
set mapred.min.split.size.per.rack=100000000;   --                
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;  ---  map               ,          
  
Mapperの全体原則を制御する:
大きなデータ量は適切なmap数を利用し、個々のmapは適切なデータ量を処理しなければならない。
map占用資源は小さいファイルを合併したいですが、mapが不足しています。大きなファイルを小さいファイルに分解します。
コントロールのReduceの数:
Reduceの個数はタスクの実行効率に大きく影響します。
  • Hive自己確定reduce数
  • Reduceの個数を指定しない場合、HiveはReduce個数を推測し、次の二つのパラメータで決定します。
    1、hive.exc.reducers.bytes.per.reducer(各reduceタスクで処理されるデータ量は、デフォルトは1000^3=1 G) 
    2、hive.exc.reducers.max(各タスクの最大reduce数は、デフォルトは999)
    Reduceの個数N=min(パラメータ2、合計データ量/パラメータ1を入力)は、例えば、Reduceの入力(mapの出力)の合計サイズが1 Gを超えない場合、一つのReduceタスクのみとなる。
  • 手動調整reduce数
  • Hive公式サイト:
    In order to change the average load for a reducer (in bytes): set hive.exec.reducers.bytes.per.reducer=
    In order to limit the maximum number of reducers: set hive.exec.reducers.max=
    In order to set a constant number of reducers: set mapreduce.job.reduces=
    
    Notes:ダイナミックパーティションピット
    ダイナミックパーティションを使用する場合、既知のデータがnつのパーティションに分割され、SQLが実行されているときにm個のMapperが作成されると、このSQLはm*n個のファイルを生成します。この値が設定された作成ファイルの総数(hive.exc.max.reated.files)より大きい場合、デフォルトは100000個で異常が発生します。
    ダイナミックパーティション数が不明な場合は、distribute byパーティションフィールドを使用して、パーティションフィールドの内容と同じデータを同じreduceに置くことができます。もちろん、distribute byを使用することもできます。 rand()は、データをメモに従ってreduceに割り当て、これにより、各reduceが処理するデータをほぼ同じにすることができる。
  • はmapと同じで、起動と初期化は時間と資源を消費し、どれだけのreduceがあればどれだけのファイル
  • が生成されますか?
  • 以下の場合は、一つのreduce:
  • だけです。
  • group byのまとめがなく、select dt、count(1)from test where dt='2019-12-12'group by dt;select count(1)from test where dt='2019-12-12'と書く。
  • order byを使いました。
  • はデカルト積があります。
  • Reduceの全体原則を制御する:
    大データ量を適切なreduce数に利用させる。
    単一のreduceタスクに適切なデータ量を処理させる。