顧客コールのデータを保持するハイブテーブルがあります。 簡略化のため、2つの列があり、最初の列は顧客IDを保持し、2番目の列は呼び出しのタイムスタンプ(UNIXのタイムスタンプ)を保持します。それが返すハイブクエリを作成することが可能です各顧客のために、ハイブクエリでのHadoopの連続レコードの相違の計算
Customer1 timestamp11
Customer1 timestamp12
Customer1 timestamp13
Customer2 timestamp21
Customer3 timestamp31
Customer3 timestamp32
...
:
SELECT * FROM mytable SORT BY customer_id, call_time;
結果は次のとおりです。
私は、各顧客のすべてのコールを見つけるために、このテーブルを照会することができます2回目の呼び出しから、2回の連続した呼び出しの時間間隔を開始しますか?上記の例の場合 そのクエリが返す必要があります:
Customer1 timestamp12-timestamp11
Customer1 timestamp13-timestamp12
Customer3 timestamp32-timestamp31
...
を私はsql solutionからソリューションを適応しようとしましたが、私はハイブの制限がこだわっている:it accepts subqueries only in FROMとjoins must contain only equalities。
ありがとうございます。
EDIT1:
public class DeltaComputerUDF extends UDF {
private String previousCustomerId;
private long previousCallTime;
public String evaluate(String customerId, LongWritable callTime) {
long callTimeValue = callTime.get();
String timeDifference = null;
if (customerId.equals(previousCustomerId)) {
timeDifference = new Long(callTimeValue - previousCallTime).toString();
}
previousCustomerId = customerId;
previousCallTime = callTimeValue;
return timeDifference;
}}
と名 "デルタ" とそれを使用します。
私はハイブUDF関数を使用しようとしました。
しかし、(ログと結果から)MAP時に使用されているようです。 2つの問題はここから生じ:
まず:表のデータは、この機能を使用する前に、顧客IDとタイムスタンプでソートする必要があります。クエリ:
SELECT customer_id, call_time, delta(customer_id, call_time) FROM mytable DISTRIBUTE BY customer_id SORT BY customer_id, call_time;
ソート部分は、私の機能が使用されてから長い間、REDUCE時に実行されるため、機能しません。
関数を使用する前にテーブルデータを並べ替えることができますが、これはオーバーヘッドであるため避けたいと思っています。
セカンド:分散Hadoopの構成の場合には、データが利用可能なジョブトラッカー間で分割される。したがって、この機能の複数のインスタンスが各マッパーに1つずつ存在すると考えられます。したがって、同じ顧客データを2つのマッパーの間で分割することは可能です。この場合、私は顧客の電話を紛失しますが、それは受け入れられません。
この問題の解決方法はわかりません。 DISTRIBUTE BYは、特定の値を持つすべてのデータが同じレデューサーに送信されることを保証します(したがって、SORTが期待通りに機能することを保証します)。
次は、libjackがreduceスクリプトを使用することを提案します。他のハイブクエリの間にこの "計算"が必要なので、Balaswamy vaddemanの示唆するように、別のツールに移る前にハイブのすべてのものを試してみたい。
EDIT2:
私は、カスタムスクリプトソリューションを検討し始めました。
ストリーミングは通常、同等のUDFまたは のInputFormatオブジェクトをコーディングするよりも効率が低い。しかし、プログラミングハイブブックの章14(この章では、カスタムスクリプトを提示)の最初のページに、私は、次の段落を発見しました。それを渡すためにデータをシリアライズおよびデシリアライズし、パイプから を外すことは比較的非効率的です。統合された方法で プログラム全体をデバッグすることも難しくなります。ただし、高速プロトタイピング と、Javaで書かれていない既存のコードを活用するのに便利です。 Javaコードを作成したくないユーザーHive の場合は、非常に効果的な アプローチになります。
したがって、カスタムスクリプトは効率の点で最適なソリューションではないことが明らかでした。
しかし、私はUDFの機能をどのように保つべきですが、分散型Hadoop構成では正常に動作することを確認する必要がありますか?この質問に対する答えは、Language Manual UDF wikiページのUDF Internalsセクションにあります。私は私のクエリを記述する場合:
SELECT customer_id, call_time, delta(customer_id, call_time) FROM (SELECT customer_id, call_time FROM mytable DISTRIBUTE BY customer_id SORT BY customer_id, call_time) t;
は、それは時間を短縮し、通話のために、同じ顧客からのすべてのレコードが同じ減速によって処理されていることを保証する構築物によりBYおよびSORT、DISTRIBUTEで実行されます。
上記のUDFとこのクエリの構成は私の問題を解決します。
(リンクを追加しないため申し訳ありませんが、私は十分評判ポイントを持っていないので、私はそれを行うことは許されないよ)
これは[この質問]と非常に似ていると思います(http://stackoverflow.com/questions/14028796/reduce-a-set-of-rows-in-hive-to-another-set-ofrows )私はハイブでカスタムマップ/リダクションを使って答えました。適切なreduceスクリプトを用意するだけで済みます。 – libjack
ハイブでこれを行う方法はわかりませんが、カスケーディングするapiがあります。カスケードのバッファと呼ばれるものがあります.http://docs.cascading.org/cascading/2.0/userguide/html/ch05s05.html –