2つのバッグ間の最小中心を計算しようとしているPigプログラムがあります。それが機能するためには、バッグを単一のデータセットにグループ化する必要があることがわかりました。全体の操作には時間がかかります。UDF内のディスクからバッグの1つを開くか、COGROUPを使用せずに別の関係をUDFに渡すことができるようにしたい......
コード:
# **** Load files for iteration ****
register myudfs.jar;
wordcounts = LOAD 'input/wordcounts.txt' USING PigStorage('\t') AS (PatentNumber:chararray, word:chararray, frequency:double);
centerassignments = load 'input/centerassignments/part-*' USING PigStorage('\t') AS (PatentNumber: chararray, oldCenter: chararray, newCenter: chararray);
kcenters = LOAD 'input/kcenters/part-*' USING PigStorage('\t') AS (CenterID:chararray, word:chararray, frequency:double);
kcentersa1 = CROSS centerassignments, kcenters;
kcentersa = FOREACH kcentersa1 GENERATE centerassignments::PatentNumber as PatentNumber, kcenters::CenterID as CenterID, kcenters::word as word, kcenters::frequency as frequency;
#***** Assign to nearest k-mean *******
assignpre1 = COGROUP wordcounts by PatentNumber, kcentersa by PatentNumber;
assignwork2 = FOREACH assignpre1 GENERATE group as PatentNumber, myudfs.kmeans(wordcounts, kcentersa) as CenterID;
基本的に私の問題は、特許ごとにサブリレーション(ワードカウント、kcenters)を渡す必要があるということです。これを行うために、クロスを実行してから、PatentNumberによるCOGROUPを実行して、セットのPatentNumber、{wordcounts}、{kcenters}を取得します。UDF内から関係を渡す方法やセンターを開く方法を見つけられれば、PatentNumberで単語数をグループ化し、myudfs.kmeans(wordcount)を実行できます。これは、CROSS/COGROUPがなくてもはるかに高速です。
これは費用のかかる操作です。現在、これには約20分かかり、CPU/RAMに影響を与えているようです。CROSSがないともっと効率がいいのではないかと思っていました。速くなるかどうかわからないので、実験してみたいと思います。
とにかく、Pig内からLoading関数を呼び出すには、evalfuncから取得しないPigContextオブジェクトが必要なようです。また、hadoopファイルシステムを使用するには、いくつかの初期オブジェクトも必要ですが、取得方法がわかりません。だから私の質問は、PIG UDF内からhadoopファイルシステムからファイルを開くにはどうすればよいですか?また、デバッグのためにmain経由でUDFを実行します。したがって、デバッグモードのときに通常のファイルシステムからロードする必要があります。
もう1つのより良いアイデアは、CROSS/COGROUPを必要とせずにリレーションをUDFに渡す方法があるかどうかです。これは、特にリレーションがメモリ内にある場合に理想的です。つまり、kcentersを使用したCROSS / COGROUPを必要とせずに、myudfs.kmeans(wordcounts、kcenters)を実行できます。
ただし、基本的な考え方は、IOをRAM/CPUサイクルと交換することです。
とにかく、どんな助けでも大いに感謝されるでしょう、PIG UDFは、UDFマニュアルでさえ、最も単純なものを超えてあまりよく文書化されていません。