4

Hadoop を使用して xml ファイルを処理しているため、マッパー ファイル、リデューサー ファイルを Python で記述しました。

処理する必要がある入力がtest.xmlであるとします。

<report>
 <report-name name="ALL_TIME_KEYWORDS_PERFORMANCE_REPORT"/>
 <date-range date="All Time"/>
 <table>
  <columns>
   <column name="campaignID" display="Campaign ID"/>
   <column name="adGroupID" display="Ad group ID"/>
  </columns>
  <row campaignID="79057390" adGroupID="3451305670"/>
  <row campaignID="79057390" adGroupID="3451305670"/>
 </table>
</report>

mapper.pyファイル

import sys
import cStringIO
import xml.etree.ElementTree as xml

if __name__ == '__main__':
    buff = None
    intext = False
    for line in sys.stdin:
        line = line.strip()
        if line.find("<row") != -1:
        .............
        .............
        .............
        print '%s\t%s'%(campaignID,adGroupID )

reducer.pyファイル

import sys
if __name__ == '__main__':
    for line in sys.stdin:
        print line.strip()

次のコマンドでhadoopを実行しました

bin/hadoop jar contrib/streaming/hadoop-streaming-1.0.4.jar 
- file /path/to/mapper.py file -mapper /path/to/mapper.py file 
-file /path/to/reducer.py file -reducer /path/to/reducer.py file 
-input /path/to/input_file/test.xml 
-output /path/to/output_folder/to/store/file

上記のコマンドを実行すると、hadoop は出力パスに出力ファイルを作成しています。reducer.py必要なデータを含む、ファイルに記載されている形式で出力ファイルを正しく作成しています。

結局のところ、私がやろうとしているのは、上記のコマンドを実行したときに haddop によってデフォルトとして作成されたテキスト ファイルに出力データを保存したくないということです。代わりに、データをMYSQLデータベースに保存したいのです。

reducer.pyだから私はデータベースにデータを直接書き込むファイルにいくつかのpythonコードを書き、MYSQL以下のように出力パスを削除して上記のコマンドを実行しようとしました

bin/hadoop jar contrib/streaming/hadoop-streaming-1.0.4.jar 
- file /path/to/mapper.py file -mapper /path/to/mapper.py file 
-file /path/to/reducer.py file -reducer /path/to/reducer.py file 
-input /path/to/input_file/test.xml 

そして、私は以下のようなエラーが発生しています

12/11/08 15:20:49 ERROR streaming.StreamJob: Missing required option: output
Usage: $HADOOP_HOME/bin/hadoop jar \
          $HADOOP_HOME/hadoop-streaming.jar [options]
Options:
  -input    <path>     DFS input file(s) for the Map step
  -output   <path>     DFS output directory for the Reduce step
  -mapper   <cmd|JavaClassName>      The streaming command to run
  -combiner <cmd|JavaClassName> The streaming command to run
  -reducer  <cmd|JavaClassName>      The streaming command to run
  -file     <file>     File/dir to be shipped in the Job jar file
  -inputformat TextInputFormat(default)|SequenceFileAsTextInputFormat|JavaClassName Optional.
  -outputformat TextOutputFormat(default)|JavaClassName  Optional.
   .........................
   .........................
  1. 結局のところ、Databaseファイルを処理した後にデータを保存する方法は疑問です?
  2. データベースにデータを書き込むコードを記述できるファイル (mapper.py/reducer.py ?)
  3. Hadoopコマンドで出力フォルダーパスを削除すると、エラーが表示されるため、データをデータベースに保存するためにhadoopを実行するために使用されるコマンド。

誰でも上記の問題を解決するのを手伝ってもらえますか........

編集済み

処理済み

  1. 上記のように作成されmapperreducerファイルは、xml ファイルを読み取り、いくつかのフォルダーにテキスト ファイルを作成します。hadoop command

    例:テキストファイル(hadoopコマンドでxmlファイルを加工した結果)が入っているフォルダ

    /home/local/user/Hadoop/xml_processing/xml_output/part-00000

ここでxmlファイルのサイズは1.3 GBあり、hadoopで処理した後にtext file作成されるサイズは345 MB

今、私がやりたいことはreading the text file in the above path and saving data to the mysql database、できるだけ速くすることです。

基本的なpythonでこれを試しましたが、350 secテキストファイルを処理してmysqlデータベースに保存するためにいくつかを取っています。

  1. nichole が sqoop をダウンロードし、以下のようなパスで解凍したことで示されるようになりました

    /home/local/user/sqoop-1.4.2.bin__hadoop-0.20

binフォルダーに入力して入力する./sqoopと、以下のエラーが表示されました

sh-4.2$ ./sqoop
Warning: /usr/lib/hbase does not exist! HBase imports will fail.
Please set $HBASE_HOME to the root of your HBase installation.
Warning: $HADOOP_HOME is deprecated.

Try 'sqoop help' for usage.

また、私は以下を試しました

./sqoop export --connect jdbc:mysql://localhost/Xml_Data --username root --table PerformaceReport --export-dir /home/local/user/Hadoop/xml_processing/xml_output/part-00000 --input-fields-terminated-by '\t'

結果

Warning: /usr/lib/hbase does not exist! HBase imports will fail.
Please set $HBASE_HOME to the root of your HBase installation.
Warning: $HADOOP_HOME is deprecated.

12/11/27 11:54:57 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset.
12/11/27 11:54:57 INFO tool.CodeGenTool: Beginning code generation
12/11/27 11:54:57 ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.RuntimeException: Could not load db driver class: com.mysql.jdbc.Driver
java.lang.RuntimeException: Could not load db driver class: com.mysql.jdbc.Driver
    at org.apache.sqoop.manager.SqlManager.makeConnection(SqlManager.java:636)
    at org.apache.sqoop.manager.GenericJdbcManager.getConnection(GenericJdbcManager.java:52)
    at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:525)
    at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:548)
    at org.apache.sqoop.manager.SqlManager.getColumnTypesForRawQuery(SqlManager.java:191)
    at org.apache.sqoop.manager.SqlManager.getColumnTypes(SqlManager.java:175)
    at org.apache.sqoop.manager.ConnManager.getColumnTypes(ConnManager.java:262)
    at org.apache.sqoop.orm.ClassWriter.getColumnTypes(ClassWriter.java:1235)
    at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1060)
    at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:82)
    at org.apache.sqoop.tool.ExportTool.exportTable(ExportTool.java:64)
    at org.apache.sqoop.tool.ExportTool.run(ExportTool.java:97)
    at org.apache.sqoop.Sqoop.run(Sqoop.java:145)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65)
    at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:181)
    at org.apache.sqoop.Sqoop.runTool(Sqoop.java:220)
    at org.apache.sqoop.Sqoop.runTool(Sqoop.java:229)
    at org.apache.sqoop.Sqoop.main(Sqoop.java:238)
    at com.cloudera.sqoop.Sqoop.main(Sqoop.java:57)

上記の sqoop コマンドは、テキスト ファイルを読み取ってデータベースに保存する機能に役立つかどうか。、テキスト ファイルから処理してデータベースに挿入する必要があるためです !!!!

4

2 に答える 2

4

私はすべての Hadoop MR ジョブを Python でコーディングしています。データの移動に python を使用する必要はありません。Sqoop を使用する: http://sqoop.apache.org/

Sqoop は、ユーザーがリレーショナル データベースから Hadoop にデータを抽出してさらに処理できるようにするオープン ソース ツールです。使い方はとても簡単です。あなたがする必要があるのは、

  1. sqoop をダウンロードして構成する
  2. mysql テーブル スキーマを作成する
  3. Hadoop hdfs ファイル名、結果テーブル名、列区切り文字を指定します。

詳細については、こちらをお読みください: http://archive.cloudera.com/cdh/3/sqoop/SqoopUserGuide.html

sqoopを使用する利点は、hdfs データを任意のタイプのリレーショナル データベース (mysql、derby、hive など) に、またはその逆に 1 行のコマンドで変換できることです。

あなたのユースケースでは、必要な変更を行ってください:

mapper.py

#!/usr/bin/env python

import sys
for line in sys.stdin:
        line = line.strip()
        if line.find("<row") != -1 :
            words=line.split(' ')
            campaignID=words[1].split('"')[1]
            adGroupID=words[2].split('"')[1]
            print "%s:%s:"%(campaignID,adGroupID)

ストリーミング コマンド

bin/hadoop jar contrib/streaming/hadoop-streaming-1.0.4.jar - file /path/to/mapper.py file -mapper /path/to/mapper.py file -file /path/to/reducer.py file -reducer /path/to/reducer.py file -input /user/input -output /user/output

mysql

create database test;
use test;
create table testtable ( a varchar (100), b varchar(100) );

スクープ

./sqoop export --connect jdbc:mysql://localhost/test --username root --table testnow --export-dir /user/output --input-fields-terminated-by ':'

:

  1. 必要に応じてマッパーを変更してください
  2. マッパーと sqoop コマンドの両方で、列区切りとして「:」を使用しました。必要に応じて変更してください。
  3. Sqoop チュートリアル: 私は個人的に Hadoop:The Definitive Guide (Oreilly) とhttp://archive.cloudera.com/cdh/3/sqoop/SqoopUserGuide.htmlに従っています。
于 2012-11-12T11:46:28.570 に答える
1

データをデータベースに書き込むのに最適な場所は、OutputFormat です。Reducer レベルの書き込みは実行できますが、最善の方法ではありません。

Java でマッパーとリデューサーを作成していた場合は、DBOutputFormatを利用できたはずです。

したがって、リデューサーのデータ出力形式 (キー、値) を満たすカスタム OutputFormat を記述して、データを MySQL にシンクできます。

カスタム出力フォーマットの作成方法については、Yahoo Developer Network でこのチュートリアルをお読みください。

于 2012-11-08T11:46:48.247 に答える