LoginSignup
0
0

More than 5 years have passed since last update.

Pig on Tez on CDHでGPLライブラリを追加

Posted at

こんにちは。

前回の記事(下記)に引き続き、Pig on Tez on CDHのお試しです。
http://qiita.com/kimutansk/items/8a91baf476fff4232634

Pig on Tez on CDHでGPLライブラリを追加してみる理由

Pigを使う際、前提となるライブラリや設定の追加が必要になるケースがあるためです。

Pig UDFの場合はPig Script中で明示的にロードを行うため、
HDFS上にファイルをアップしておけば、Tez上で動作させても問題なく可能でしょう。

ただ、特定のファイルを扱うためにクラスが設定して指定されてロードされるケース、
例えばLzoなんかをどうやって設定すればいいのかについては疑問が残ります。

ですので、実際にやってみよう、という形です。

必要環境/パッケージのインストール

前提とする環境として、Lzoを含むGPLEXTRAのParcelを導入しておく必要があります。

Cloudera Managerのトップメニューから「Parcel」>「設定」を選択し、下記のリポジトリを追加します。
https://archive.cloudera.com/gplextras5/parcels/{latest_supported}

下記キャプチャのように追加される形になりますね。
ParcelSetting.JPG

追加した上で「新しいPercel のチェック」を実行すると、「GPLEXTRAS」が一覧に出てきますので、
それを「ダウンロード」>「配布」>「アクティブ化」と実行して有効化しておきます。

パッケージに対する設定実施

パッケージがインストールできたので、次は設定です。
該当のクラスタで「HDFS」>「設定」を選択し、下記のように設定項目に値を追加します。

  • 設定項目:io.compression.codecs
  • 追加内容:com.hadoop.compression.lzo.LzoCodec
  • 追加内容:com.hadoop.compression.lzo.LzopCodec

HDFSSetting.JPG

追加したら必要なサービスを再起動しておきます。

すると、下記のファイル中の設定に反映されていることがわかります。
- /etc/hadoop/conf/core-site.xml

読み込み用ディレクトリ/ファイルの作成

実際に読み込むためのファイルとして、前回使用した data_noheader.csv を圧縮して使用します。
下記コマンドを実行し、圧縮ファイルを作成します。

$ sudo yum install -y lzop
$ lzop data_noheader.csv

作成されたファイル( data_noheader.csv.lzo )をHDFSの /user/pub/example-lzo 配下にアップしておきます。

Pigスクリプトの実行>失敗

Pigスクリプトを下記のように修正し、実行します。

test-lzo-count.pig
loadresult = LOAD '/user/pub/example-lzo';
limitedresult = LIMIT loadresult 10;
logs_count = FOREACH (GROUP loadresult ALL) GENERATE COUNT(loadresult);
DUMP logs_count
DUMP limitedresult;
/opt/pig/bin/pig -x tez -f test-lzo-count.pig

実行すると、案の定というか、下記のエラーが発生して実行は失敗します。

/opt/pig/bin/pig -x tez -f test-lzo-count.pig
2016-04-24 18:44:47,043 [PigTezLauncher-0] INFO  org.apache.pig.backend.hadoop.executionengine.tez.TezJob - DAG Status: status=FAILED, progress=TotalTasks: 2 Succeeded: 0 Running: 0 Failed: 1 Killed: 1 FailedTaskAttempts: 4, diagnostics=Vertex failed, vertexName=scope-10, vertexId=vertex_1461490474710_0001_1_00, diagnostics=[Task failed, taskId=task_1461490474710_0001_1_00_000000, diagnostics=[TaskAttempt 0 failed, info=[Error: exceptionThrown=java.lang.IllegalArgumentException: Compression codec com.hadoop.compression.lzo.LzoCodec not found.
        at org.apache.hadoop.io.compress.CompressionCodecFactory.getCodecClasses(CompressionCodecFactory.java:135)
        at org.apache.hadoop.io.compress.CompressionCodecFactory.<init>(CompressionCodecFactory.java:175)
        at org.apache.hadoop.mapreduce.lib.input.LineRecordReader.initialize(LineRecordReader.java:87)
        at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigRecordReader.initialize(PigRecordReader.java:181)
        at org.apache.tez.mapreduce.lib.MRReaderMapReduce.setupNewRecordReader(MRReaderMapReduce.java:152)
        at org.apache.tez.mapreduce.lib.MRReaderMapReduce.setSplit(MRReaderMapReduce.java:85)
        at org.apache.tez.mapreduce.input.MRInput.initFromEventInternal(MRInput.java:614)
        at org.apache.tez.mapreduce.input.MRInput.processSplitEvent(MRInput.java:566)
        at org.apache.tez.mapreduce.input.MRInput.handleEvents(MRInput.java:530)
        at org.apache.tez.runtime.LogicalIOProcessorRuntimeTask.handleEvent(LogicalIOProcessorRuntimeTask.java:631)
        at org.apache.tez.runtime.LogicalIOProcessorRuntimeTask.access$600(LogicalIOProcessorRuntimeTask.java:98)
        at org.apache.tez.runtime.LogicalIOProcessorRuntimeTask$1.runInternal(LogicalIOProcessorRuntimeTask.java:694)
        at org.apache.tez.common.RunnableWithNdc.run(RunnableWithNdc.java:35)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: Class com.hadoop.compression.lzo.LzoCodec not found
        at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1980)
        at org.apache.hadoop.io.compress.CompressionCodecFactory.getCodecClasses(CompressionCodecFactory.java:128)
        ... 13 more
(省略)
]], Vertex did not succeed due to OWN_TASK_FAILURE, failedTasks:1 killedTasks:0, Vertex vertex_1461490474710_0001_1_00 [scope-10] killed/failed due to:null]
Vertex killed, vertexName=scope-11, vertexId=vertex_1461490474710_0001_1_01, diagnostics=[Vertex received Kill while in RUNNING state., Vertex did not succeed due to OTHER_VERTEX_FAILURE, failedTasks:0 killedTasks:1, Vertex vertex_1461490474710_0001_1_01 [scope-11] killed/failed due to:null]
DAG did not succeed due to VERTEX_FAILURE. failedVertices:1 killedVertices:1, counters=Counters: 4
        org.apache.tez.common.counters.DAGCounter
                NUM_FAILED_TASKS=4
                TOTAL_LAUNCHED_TASKS=4
                AM_CPU_MILLISECONDS=1730
                AM_GC_TIME_MILLIS=56

PigTezLauncherの段階でHadoopの設定ファイルを読み込んだ際にこけているようですね。
かつ、TezのYARNコンテナでも同種のエラーは発生するでしょうから、下記の対応が必要になりそうです。

  • Pig起動プロセスのクラスパスにLzoライブラリを追加
  • TezのYARNコンテナのクラスパスにLzoライブラリを追加

Pig on TezにLzoライブラリの設定を追加

  • Pig起動プロセスのクラスパスにLzoライブラリを追加

これはPigの起動スクリプトの頭に追加しても、
Tezのライブラリディレクトリにシンボリックリンクをはってもどちらでもいいのですが、
Pigの起動スクリプトに追加したのは完全にTezの設定ですので、Tezを使うのは確定だろう、
ということで後者で実施します。

$ ln -s /opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/hadoop-lzo.jar /opt/tez-lib/hadoop-lzo.jar
  • TezのYARNコンテナのクラスパスにLzoライブラリを追加

/opt/tez-conf/tez-site.xml に下記の設定を追加します。

tez-site.xml
  <property>
      <name>tez.cluster.additional.classpath.prefix</name>
      <value>/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/hadoop-lzo.jar</value>
  </property>

Pigスクリプトの再実行

再度hdfsユーザでPigスクリプトを実行してみます。すると・・・

hdfsユーザでの実行
/opt/pig/bin/pig -x tez -f test-lzo-count.pig
(省略)
2016-04-24 20:03:40,460 [main] INFO  org.apache.pig.tools.pigstats.tez.TezPigScriptStats - Script Statistics:

       HadoopVersion: 2.6.0-cdh5.7.0
          PigVersion: 0.15.0
          TezVersion: 0.7.0
              UserId: hdfs
            FileName: /tmp/test-lzo-count.pig
           StartedAt: 2016-04-24 20:03:28
          FinishedAt: 2016-04-24 20:03:40
            Features: GROUP_BY

Success!

DAG PigLatin:test-lzo-count.pig-0_scope-0:
       ApplicationId: job_1461490474710_0014
  TotalLaunchedTasks: 2
       FileBytesRead: 99
    FileBytesWritten: 67
       HdfsBytesRead: 61480
    HdfsBytesWritten: 7

Input(s):
Successfully read 1744 records (61480 bytes) from: "/user/pub/example-lzo"

Output(s):
Successfully stored 1 records (7 bytes) in: "hdfs://hadoophost01:8020/tmp/temp-1823417929/tmp552056591"
(1744)
(1871-01-01,4.44,0.26,0.4,12.46,5.32,84.52,4.95,7.61,,,,,,,)
(1871-02-01,4.5,0.26,0.4,12.84,5.32,83.12,4.8,7.39,,,,,,,)
(1871-03-01,4.61,0.26,0.4,13.03,5.33,83.91,4.73,7.28,,,,,,,)
(1871-04-01,4.74,0.26,0.4,12.56,5.33,89.54,4.91,7.56,,,,,,,)
(1871-05-01,4.86,0.26,0.4,12.27,5.33,93.95,5.03,7.73,,,,,,,)
(1871-06-01,4.82,0.26,0.4,12.08,5.34,94.64,5.11,7.85,,,,,,,)
(1871-07-01,4.73,0.26,0.4,12.08,5.34,92.87,5.11,7.85,,,,,,,)
(1871-08-01,4.79,0.26,0.4,11.89,5.34,95.56,5.19,7.98,,,,,,,)
(1871-09-01,4.84,0.26,0.4,12.18,5.35,94.29,5.07,7.79,,,,,,,)
(1871-10-01,4.59,0.26,0.4,12.37,5.35,88.04,4.99,7.67,,,,,,,)

実行に成功しました。
前回と比べると、読込ファイルサイズが下記のように変わっているので、確かに圧縮したファイルを読み込んだことがわかります。

前回結果
Successfully read 1744 records (116662 bytes) from: "/user/pub/example-data"
今回結果
Successfully read 1744 records (61480 bytes) from: "/user/pub/example-lzo"

が、しかし・・・?

ただ、ここで上手く行ったと思って別のユーザ(今回はビルド用ユーザのbuild)で実行してみると、
何故か読込に失敗する事象が発生しました。

buildユーザでの実行>失敗
/opt/pig/bin/pig -x tez -f test-lzo-count.pig
2016-04-24 20:13:44,815 [main] INFO  org.apache.pig.tools.pigstats.tez.TezPigScriptStats - Script Statistics:

       HadoopVersion: 2.6.0-cdh5.7.0
          PigVersion: 0.15.0
          TezVersion: 0.7.0
              UserId: build
            FileName: test-lzo-count.pig
           StartedAt: 2016-04-24 20:13:26
          FinishedAt: 2016-04-24 20:13:44
            Features: GROUP_BY

Failed!

DAG PigLatin:test-lzo-count.pig-0_scope-0:
       ApplicationId: job_1461490474710_0015
  TotalLaunchedTasks: 4
       FileBytesRead: 0
    FileBytesWritten: 0
       HdfsBytesRead: 0
    HdfsBytesWritten: 0

Input(s):
Failed to read data from "/user/pub/example-lzo"

Output(s):
Failed to produce result in "hdfs://hadoophost01:8020/tmp/temp-1843801261/tmp-1479312519"

2016-04-24 20:13:44,912 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1066: Unable to open iterator for alias logs_count. Backend error : Vertex failed, vertexName=scope-10, vertexId=vertex_1461490474710_0015_1_00, diagnostics=[Task failed, taskId=task_1461490474710_0015_1_00_000000, diagnostics=[TaskAttempt 0 failed, info=[Error: exceptionThrown=java.lang.IllegalArgumentException: Compression codec com.hadoop.compression.lzo.LzoCodec not found.

違いはどこにある?

どこに違いがあるのかざっと追ってみると、下記の2つの時点で差分があることがわかりました。

  • 1. YARNコンテナ起動時の環境変数設定(YARNの一時ファイル)
    • buildユーザで実行した側は tez.cluster.additional.classpath.prefix の設定がない
  • 2. Pigから呼び出されたTezClient中の処理(リモートデバッグ)
    • buildユーザで実行した側は tez.cluster.additional.classpath.prefix の設定がない

つまりはHadoopコマンド > Pig > Tezとなる中で設定が欠落しているのですが、
ざっとデバッグした時点では結論は見えずという状況。

ですので、Pigが読み込んでHadoopの設定に含めているファイルの pig.properties に設定を追記して試してみました。

$ echo "tez.cluster.additional.classpath.prefix=/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/hadoop-lzo.jar" >> /opt/pig/conf/pig.properties

再度実行

すると・・・?

buildユーザでの実行>成功
/opt/pig/bin/pig -x tez -f test-lzo-count.pig
2016-04-24 22:16:17,439 [main] INFO  org.apache.pig.tools.pigstats.tez.TezPigScriptStats - Script Statistics:

       HadoopVersion: 2.6.0-cdh5.7.0
          PigVersion: 0.15.0
          TezVersion: 0.7.0
              UserId: build
            FileName: test-lzo-count.pig
           StartedAt: 2016-04-24 22:16:06
          FinishedAt: 2016-04-24 22:16:17
            Features: GROUP_BY

Success!

DAG PigLatin:test-lzo-count.pig-0_scope-0:
       ApplicationId: job_1461490474710_0025
  TotalLaunchedTasks: 2
       FileBytesRead: 99
    FileBytesWritten: 67
       HdfsBytesRead: 61480
    HdfsBytesWritten: 7

Input(s):
Successfully read 1744 records (61480 bytes) from: "/user/pub/example-lzo"

Output(s):
Successfully stored 1 records (7 bytes) in: "hdfs://hadoophost01:8020/tmp/temp-1901693688/tmp-778527532"

(1744)
(1871-01-01,4.44,0.26,0.4,12.46,5.32,84.52,4.95,7.61,,,,,,,)
(1871-02-01,4.5,0.26,0.4,12.84,5.32,83.12,4.8,7.39,,,,,,,)
(1871-03-01,4.61,0.26,0.4,13.03,5.33,83.91,4.73,7.28,,,,,,,)
(1871-04-01,4.74,0.26,0.4,12.56,5.33,89.54,4.91,7.56,,,,,,,)
(1871-05-01,4.86,0.26,0.4,12.27,5.33,93.95,5.03,7.73,,,,,,,)
(1871-06-01,4.82,0.26,0.4,12.08,5.34,94.64,5.11,7.85,,,,,,,)
(1871-07-01,4.73,0.26,0.4,12.08,5.34,92.87,5.11,7.85,,,,,,,)
(1871-08-01,4.79,0.26,0.4,11.89,5.34,95.56,5.19,7.98,,,,,,,)
(1871-09-01,4.84,0.26,0.4,12.18,5.35,94.29,5.07,7.79,,,,,,,)
(1871-10-01,4.59,0.26,0.4,12.37,5.35,88.04,4.99,7.67,,,,,,,)

pig.properties に設定した分はbuildユーザでも問題なく読み込むことがわかりました。
差分が発生する原因はわかりませんが、とりあえず解消はできた、という形になりますね。
クラスパスからHadoop設定オブジェクトを生成するときの挙動の差のようですが、
これは気長に追ってみることにします・・・

まとめ

  • Pig on TezにLzoを追加する場合は下記の対応が必要
    • Pig on Tez起動時のクラスパスにLzoライブラリを含める
    • Tez動作時の追加クラスパス( tez-site.xml )にLzoライブラリを含める
      • ただし、一部のユーザでは tez-site.xml に含めても動作しない(原因が現状不明)
      • 上記の場合、 pig.properties に記述すれば動作する。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0