スタンドアローンは、データ処理を行うためのスクリプトを実行しますが、入力データが大きすぎる、メモリ集約型のシステムのプロセスは、しばしば殺され、そのデータ集計を行うためにハイブに検討します。UDAFは、書き留めあなたは回り道を避けるために役立つことを期待して、ピットに乗っての経験を作成する方法を研究するこの機会を取ります!ああ。。。江Ziをオン。
多くの場合、その後、UDAF何地獄、UDFに耳を傾けますか?UDFは〜建てハイブ数、合計、最大、最小、平均などなど、友人などの重合性機能です。しかし、組み込み関数は、実際に私たちの複雑な統計のニーズを満たすことができない、私たちは、達成するための方法を所有する必要があります。
一般的な、簡単な方法は、パフォーマンス上の問題を抱えていると言われている簡単なを達成するための2つの方法が、ありますが、我々はそれを見て - 一般的な実装を
達成ジェネリックUDAFは、2つの部分があります。
- 解きます
- エバリュエータ
たぶん、2つの抽象クラスに対応する商品:
輸入org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver; 輸入 org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator。
レゾルバとオペレータのオーバーロードをチェックするために使用される主なパラメータは、我々は、入力パラメータに応じて適切な評価者を選択することができます
評価者は、ここで静的内部クラスの形でメインロジック、実装されています
!#Javaの パブリック クラス GenericUDAFHistogramNumeric 拡張AbstractGenericUDAFResolver { 静的 最終ログインLogFactory.getLog LOG =(GenericUDAFHistogramNumeric。クラス.getName()); @Override 公共 GenericUDAFEvaluator getEvaluator(GenericUDAFParameterInfo情報)がスローSemanticException { // パラメータのチェックが 返す 新しい新しい; GenericUDAFHistogramNumericEvaluatorを() } / ** *この静的インナークラスは、自分自身への論理的な場所を書き込むことが必要な場合は、クラス名を変更することがあり、これが書かれた公式文書のバーグラフの例である * / パブリック 静的 クラス GenericUDAFHistogramNumericEvaluator延びGenericUDAFEvaluator { // UDAFロジック } }
私たちは、この例では、機能を導入すべきである:histogram_numeric機能でハイブは、ヒストグラムを行うには、例えば、私たちは年齢に30バレルをしたいヒストグラムを構築し、従業員の中から選択histogram_numeric(年齢、30)です。
ここでは例を見ていき
!#のJava / ** *このパラメータの方法は、新しいバージョンに変更されている、である直接のTypeInfo []パラメータ * / 公共 GenericUDAFEvaluator getEvaluator(GenericUDAFParameterInfo情報)がスローSemanticException { のTypeInfo []パラメータ = info.getParameters(); IF(パラメータ。 !長= 2 ){ スロー 新しい新 UDFArgumentTypeException(parameters.lengthを- 1。 、 「正確に二つの引数を指定してください」。); } // いない元の型(基本型)は例外場合、最初のパラメータの種類を確認 IF(パラメータを[ 0] .getCategory()!= ObjectInspector.Category.PRIMITIVE){ スロー 新新UDFArgumentTypeExceptionは(0 、 「のみプリミティブ型引数が受け入れられるが、」 +パラメータ[0] .getTypeName()+「パラメータ1として渡されました」)。 } スイッチ(((PrimitiveTypeInfo)パラメータ[0 ])getPrimitiveCategory()){ ケースBYTE: ケースSHORT: ケースINT: ケースLONG: ケースFLOAT: ケースDOUBLE: 破ります。 ケースSTRING: ケースBOOLEAN: デフォルト: スロー 新しい UDFArgumentTypeExceptionを(0、 「唯一の数値型の引数を受け入れている。しかし、」 +パラメータ[0] .getTypeName()+「合格1.パラメータとしてWAS」); } // 2番目のパラメータのタイプ、バーのバケット番号を確認し、ここで必要と想定されます整数 IF([1] .getCategory()!=パラメータ{ObjectInspector.Category.PRIMITIVE) スロー 新しい新しい UDFArgumentTypeException(。1は、 "唯一のプリミティブ型引数が受け入れられている。しかし、" +パラメータは、[1] .getTypeName()+「渡されました2.パラメータAS " ); } // それが整数でない場合、例外 IF([1((PrimitiveTypeInfo)パラメータ。])getPrimitiveCategory() =!PrimitiveObjectInspector.PrimitiveCategory.INT){ スロー 新しい(1 UDFArgumentTypeExceptionを、 "のみ整数の引数をパラメータ2として受け入れられているが、" +パラメータ[1] .getTypeName()+ "の代わりに渡されました。" )。 } // 返回对应的处理类 返す 新しい)(GenericUDAFHistogramNumericEvaluatorを。 }
その後、我々は評価を見ます
#!Javaの パブリック 静的 クラス GenericUDAFHistogramNumericEvaluatorは拡張GenericUDAFEvaluator { // PARTIAL1とCOMPLETEの場合:元のデータのためのObjectInspectors、这俩货是用来做类型转换的 プライベートPrimitiveObjectInspector inputOIを。 プライベートPrimitiveObjectInspector nbinsOI。 // PARTIAL2とFINALの場合:一部の集計のためObjectInspectors(ダブルスのリスト) 民間StandardListObjectInspectorのLOI。 @Override 公共 ObjectInspectorのINIT(モードm、ObjectInspector []パラメータ)スローHiveException { スーパー.INIT(M、パラメータ)。 // 戻り型がここに入り } @Override パブリックオブジェクトterminatePartial(AggregationBuffer AGG)はスローHiveExceptionは{ // ここで、戻り値が行く } @Override パブリックオブジェクト(AggregationBuffer AGG)を終了スローHiveException { // 最終的な戻り値はここに } @Override 公共 ボイド(AggregationBuffer AGGを、部分オブジェクト)マージスローHiveException { } @Override 公共 ボイド反復(AggregationBuffer AGG、オブジェクト[]パラメータ)スローHiveExceptionは{ } // 集約バッファ定義および操作方法 静的 クラス StdAggが実装AggregationBuffer { }。 @Override 公共 AggregationBuffer getNewAggregationBuffer()スローHiveException { } @Override 公共 ボイドリセット(AggregationBuffer AGG)がスローHiveExceptionを{ } }
我々は最初のいくつかのことを理解する必要があり、このクラスを理解し、HadoopのMapReduceの学生は、コンバイン、MapReduceのジョブがマップを分割することを知っている三つの段階を減らす必要があります書いて、マップのステージは、各建物のキーと値の関数に入力データに適用されますその後の重合のために、マッパーステージが重合のローカル側で行われ、重合中間パスの結果、機能を削減し、入力機能が同じである減らす組み合わせ、マッパー端を減らすと呼ばれています。このプロセスを理解した後、我々は基本的にこれらの段階に対応する、いくつかの方法の評価を見てください。
方法 |
効果 |
その中に |
初期化関数 |
getNewAggregationBuffer |
これは、仮重合の結果を記録し、キャッシュオブジェクトを生成するために使用されます |
反復 |
1つのデータ処理によって一つは、結果をキャッシュに格納されます。 |
terminatePartial |
このアプローチは、mapフェーズが完了したことを永続ストレージのキャッシュ内のデータを意味します。ここで返されるデータ型はカスタム型を使用していない、Javaの基本タイプ、パッケージの基本型だけでなく、HadoopのWritables、リスト、および地図の配列をサポートしています |
マージ |
受信terminatePartialによって返された結果は、部分的な重合の結果を組み合わせます |
終了 |
このような平均値を計算するように、最終的な結果は、ここで最後に評価を達成することができる返します |
ハイブに、列挙クラスにモードの異なる段階を表すために
/ ** *モード。 *官方的注释写的挺详细了^ _ ^ * / パブリック 静的 列挙モード{ / ** * PARTIAL1:元のデータから部分集計データに:反復()と * terminatePartial()と呼ぶことにします。 * / PARTIAL1、 / ** * PARTIAL2:一部の集計データに部分的集計データから: *マージ()とterminatePartial()が呼び出されます。 * / PARTIAL2、 / ** * FINAL:フル凝集部分集合から:マージ()と *と呼ばれます()終了。 * / FINAL、 / ** * COMPLETE:元のデータから直接完全凝集:反復()と *終了()と呼ぶことにします。 * / COMPLETE }。
ああ。。。瓶の外袋を作るために書いた後、一時的な機能のいずれかを使用して作成します
瓶hiveUDF.jarを追加します。 「com.test.xxxx」として一時的に機能test_udfを作成します。
XXXによって表2のgroupyからtest_udf(A、B)を選択します。
さて、最初の書き込みは、私は、Javaとするとき、ほとんどのデータ型を記述し、それは後にHadoopの内蔵タイプ見に行く、変換誤差の様々な種類を生産〜あなたを助けるために願っています〜