0

パラメータ入力に基づいてログ ファイルをロードする際に問題が発生し、誰かがガイダンスを提供できるかどうか疑問に思っていました。問題のログは Omniture ログで、年、月、日 (例: /year=2013/month=02/day=14) に基づいてサブディレクトリに保存され、ファイル名に日付スタンプが付いています。毎日、複数のログが存在する可能性があり、それぞれ数百 MB です。

現在、月と年をスクリプト パラメーターとして指定して、1 か月全体のログを処理する Pig スクリプトがあります (例: /year=$year/month=$month/day=*)。それはうまく機能し、私たちはそれにとても満足しています. つまり、以前の LOAD パス glob は機能しません (週は月や年をラップできます)。これを解決するために、開始日を取得し、1 週間分のログに必要なグロブを吐き出す Python UDF があります。

>>> log_path_regex(2013, 1, 28)
'{year=2013/month=01/day=28,year=2013/month=01/day=29,year=2013/month=01/day=30,year=2013/month=01/day=31,year=2013/month=02/day=01,year=2013/month=02/day=02,year=2013/month=02/day=03}'

このグロブは、適切なパスに挿入されます。

> %declare omniture_log_path 's3://foo/bar/$week_path/*.tsv.gz';
> data = LOAD '$omniture_log_path' USING OmnitureTextLoader(); // See http://github.com/msukmanowsky/OmnitureTextLoader

残念ながら、$year、$month、および $day スクリプト パラメータに基づいて $week_path を設定する方法は、一生わかりません。私は %declare を使用しようとしましたが、うなり声は不平を言い、そのロギングは言いますが、決してしません:

> %declare week_path util.log_path_regex(year, month, day);
2013-02-14 16:54:02,648 [main] INFO  org.apache.pig.Main - Apache Pig version 0.10.1 (r1426677) compiled Dec 28 2012, 16:46:13
2013-02-1416:54:02,648 [main] INFO  org.apache.pig.Main - Logging error messages to: /tmp/pig_1360878842643.log % ls  /tmp/pig_1360878842643.log
ls: cannot access /tmp/pig_1360878842643.log: No such file or directory

パラメータの前にドル記号を付けたり、前に付けたパラメータを引用符で囲んだりすると、同じエラーが発生します。

define を使用しようとすると (静的 Java 関数でしか機能しないと思われます)、次の結果が得られます。

> define week_path util.log_path_regex(year, month, day);
2013-02-14 17:00:42,392 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: <file script.pig, line 11, column 37>  mismatched input 'year' expecting RIGHT_PAREN

%declare と同様に、パラメーターの前にドル記号を付けたり、前に付けたパラメーターを引用符で囲んだりすると、同じエラーが発生します。

私は周りを検索しましたが、解決策は思いつきませんでした。私はおそらく間違ったものを探しています。シェル コマンドの呼び出しは機能する可能性がありますが、スクリプトの展開が複雑になるため困難であり、マウントされたディレクトリではなく S3 からログを取得していることを考えると実行できない可能性があります。同様に、生成されたグロブを単一のパラメーターとして渡すと、インスタンス化された MapReduce クラスターでの自動化されたジョブが複雑になる可能性があります。

また、グロブを使用する以外に、Pig に適した LOAD を制限する方法がある可能性もあります。とはいえ、問題の原因と思われるUDFを使用する必要があります。

これは、私のLOADステートメントにPig内に構築された動的パスグロブを含めたいということです。Pig はそう簡単にはいかないようです。

UDF を静的 Java メソッドに変換する必要はありますか? それとも、同じ問題に遭遇しますか? (これが機能する可能性が低い場合は、これを実行することを躊躇します。これは 8 行の Python 関数であり、容易にデプロイでき、同等の Java コードよりもはるかに保守しやすいです。)

カスタム LoadFunc が答えですか? その場合、おそらく /year= /month= /day=* を指定し、Pig に 2 つの日付の間にある日付スタンプのすべてのファイル名をテストするように強制する必要があります。これは大規模なハッキングであり、リソースの無駄遣いのようです。

何か案は?

4

1 に答える 1

2

この質問をPigユーザーリストに投稿しました。私の理解では、DAGを構築する前に、Pigは最初にスクリプトを前処理して、パラメーター、インポート、およびマクロを置き換えます。これにより、既存の変数に基づいて新しい変数を作成することがやや不可能になり、パスグロブを作成するためのUDFを作成できなかったことが説明されます。

既存のパラメーターに基づいて新しい変数を作成する必要があるPig開発者の場合は、別のスクリプトを使用してそれらの変数を作成し、パラメーターとしてPigスクリプトに渡すか、これらの新しい変数を使用する必要がある場所を調べて、ニーズに基づいて、別の構成でそれらを構築します。

私の場合、私はしぶしぶ、CheolsooParkによって説明されているカスタムを作成するLoadFuncことを選択しました。これLoadFuncにより、コンストラクターでレポートの期間の開始日、月、年が受け入れられ、そのpathGlob期間のパスに一致する属性が作成されます。次にpathGlob、の場所に挿入されsetLocation()ます。例えば。

/**
 * Limit data to a week starting at given day. If day is 0, month is assumed.
 */
public WeeklyOrMonthlyTextLoader(String year, String month, String day) {
    super();
    pathGlob = getPathGlob(
        Integer.parseInt(year),
        Integer.parseInt(month),
        Integer.parseInt(day)
    );
}

/**
 * Replace DATE_PATH in location with glob required for reading in this
 * month or week of data. This assumes the following directory structure:
 *
 * <code>/year=&gt;year&lt;/month=&gt;month&lt;/day=&gt;day&lt;/*</code>
 */
@Override
public void setLocation(String location, Job job) throws IOException {
    location = location.replace(GLOB_PLACEHOLDER, pathGlob);
    super.setLocation(location, job);
}

これは、次のようにPigスクリプトから呼び出されます。

DEFINE TextLoader com.foo.WeeklyOrMonthlyTextLoader('$year', '$month', '$day');

Stringコンストラクターは、ではなく、を受け入れることに注意してくださいint。これは、Pigのパラメーターが文字列であり、Pigスクリプト内で他のタイプにキャストまたは変換できないためです(MRタスクで使用される場合を除く)。

カスタムの作成はLoadFuncラッパースクリプトに比べてやり過ぎに思えるかもしれませんが、スクリプトを操作する前にアナリストにセットアップタスクを実行させないように、ソリューションを純粋なPigにしたかったのです。また、スケジュールされたジョブのAmazon MapReduceクラスターを作成するときに、さまざまな期間にストックPigスクリプトを簡単に使用したいと思いました。

于 2013-02-22T17:02:38.840 に答える