如何使用python将数据从hadoop保存到数据库

时间:2012-11-08 10:21:50

标签: python xml database hadoop

我使用hadoop处理xml文件,所以我在python中编写了mapper文件,reducer文件。

假设需要处理的输入是 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默认创建的文本文件中,而是我想将数据保存到{{1}数据库

所以我在MYSQL文件中编写了一些python代码,将数据直接写入reducer.py数据库,并试图通过删除输出路径来运行上面的命令,如下所示

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 
  1. 我怀疑在处理文件后如何在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. ......................... ......................... 中保存数据?
  2. 我们可以在哪个文件(mapper.py/reducer.py?)中编写将数据写入数据库的代码
  3. 使用哪个命令运行hadoop将数据保存到数据库中,因为当我删除hadoop命令中的输出文件夹路径时,它显示错误。
  4. 有谁可以帮我解决上述问题.............

    被修改

    已按照

    进行处理
    1. 如上所述创建Databasemapper个文件,这些文件读取xml文件,并在reducer

      的某个文件夹中创建文本文件

      Ex:文本文件(使用hadoop命令处理xml文件的结果)所在的文件夹

      /家庭/本地/用户/ Hadoop的/ xml_processing / xml_output /部分-00000

    2. 此处xml文件大小为hadoop command,在使用hadoop处理后,创建的1.3 GB的大小为text file

      现在我想做的就是345 MB尽可能快。

      我用基本的python尝试了这个,但是正在使用一些reading the text file in the above path and saving data to the mysql database来处理文本文件并保存到mysql数据库。

      1. 现在如nichole所示,下载了sqoop并解压缩到如下所示的路径

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

      2. 并输入350 sec文件夹并输入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'
        

        上述sqoop命令是否对读取文本文件和保存到数据库的功能有用? ,因为我们必须从文本文件处理并插入到数据库!!!!

2 个答案:

答案 0 :(得分:3)

我在python中编写了所有的hadoop MR作业。我只想说你不需要使用python来移动数据。 使用Sqoop http://sqoop.apache.org/

Sqoop是一个开源工具,允许用户从关系数据库中提取数据到Hadoop中进行进一步处理。而且它的使用非常简单。您需要做的就是

  1. 下载并配置sqoop
  2. 创建您的mysql表架构
  3. 指定hadoop hdfs文件名,结果表名称和列分隔符。
  4. 阅读本文以获取更多信息:http://archive.cloudera.com/cdh/3/sqoop/SqoopUserGuide.html

    使用sqoop的

    优势是我们现在可以使用单行命令将我们的hdfs数据转换为任何类型的关系数据库(mysql,derby,hive等),反之亦然

    对于您的用例,请进行必要的更改:

    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

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

    注意

    1. 请根据需要更改mapper
    2. 我用过&#39;:&#39;作为mapper和sqoop命令中的列分隔符。根据需要进行更改。
    3. Sqoop教程:我个人关注Hadoop:The Definitive Guide(Oreilly)以及http://archive.cloudera.com/cdh/3/sqoop/SqoopUserGuide.html

答案 1 :(得分:1)

将数据写入数据库的最佳位置是OutputFormat。可以完成减速机级写入,但不是最好的事情。

如果您使用Java编写了mapper和reducer,那么您可以使用DBOutputFormat

因此,您可以编写一个自定义的OutputFormat,它可以满足reducer的数据输出格式(键,值),以便将数据接收到MySQL。

阅读Yahoo Developer Network上的this教程,了解如何编写自定义输出格式