hadoop(十九)—Sqoop數(shù)據(jù)清洗

上節(jié)課學(xué)習(xí)了Hadoop集群測(cè)試,這節(jié)課我們一起學(xué)習(xí)一下Sqoop府框,Sqoop是專(zhuān)門(mén)用來(lái)遷移數(shù)據(jù)的吱窝,它可以把數(shù)據(jù)庫(kù)中的數(shù)據(jù)遷移到HDFS文件系統(tǒng),當(dāng)然也可以從HDFS文件系統(tǒng)導(dǎo)回到數(shù)據(jù)庫(kù)。

我來(lái)說(shuō)一下Sqoop的使用場(chǎng)景院峡,假如你們公司有個(gè)項(xiàng)目運(yùn)行好長(zhǎng)時(shí)間了兴使,積累了大量的數(shù)據(jù),現(xiàn)在想升級(jí)項(xiàng)目并換種數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ)原來(lái)的數(shù)據(jù)撕予,那么我們就需要先把數(shù)據(jù)都存放到另一個(gè)地方鲫惶,然后再用新數(shù)據(jù)庫(kù)的語(yǔ)句把這些數(shù)據(jù)插入到新的數(shù)據(jù)庫(kù)。在沒(méi)有Sqoop之前实抡,我們要做到這一點(diǎn)是很困難的欠母,但是現(xiàn)在有了Sqoop,事情就變的簡(jiǎn)單多了吆寨,Sqoop是運(yùn)行在Hadoop之上的一個(gè)工具赏淌,底層運(yùn)用了MapReduce的技術(shù),多臺(tái)設(shè)備并行執(zhí)行任務(wù)啄清,速度當(dāng)然大大提高六水,而且不用我們寫(xiě)這方面的代碼,它提供了非常強(qiáng)大的命令辣卒,我們只需要知道怎樣使用這些命令掷贾,再加上一些SQL語(yǔ)句就可以輕輕松松實(shí)現(xiàn)數(shù)據(jù)的遷移工作。

 接下來(lái)我們便正式開(kāi)始學(xué)習(xí)怎樣使用Sqoop荣茫。

第一步:環(huán)境準(zhǔn)備

1.1 從Sqoop官網(wǎng)下載安裝包并解壓到/itcast目錄

   大家可以參考:http://blog.csdn.net/u012453843/article/details/52951277這篇博客下載**sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz**

Sqoop的運(yùn)行需要Yarn和HDFS想帅,它只需要知道Yarn的管理者角色ResourceManager和HDFS的管理者角色NameNode在哪臺(tái)設(shè)備上就可以,我們?cè)诖罱旱臅r(shí)候每臺(tái)設(shè)備上都有相同的6個(gè)配置文件啡莉,因此我們把Sqoop放到任何一臺(tái)設(shè)備上都可以「圩迹現(xiàn)在itcast03上的進(jìn)程是最少的,我們便把Sqoop放到itcast03上吧咧欣。

我們使用工具把sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz上傳到Itcast03的root根目錄下浅缸,如下圖所示。

image

接著我們把sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz解壓到/itcast目錄下魄咕,執(zhí)行的命令如下衩椒。

[root@itcast03 ~]#tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /itcast/

解壓完之后我們到/itcast目錄下查看一下,發(fā)現(xiàn)已經(jīng)有sqoop的包了哮兰,如下所示烟具。

 [root@itcast03 ~]# cd /itcast/
 [root@itcast03 itcast]# ls **hadoop-2.2.0****sqoop-1.4.6.bin__hadoop-2.0.4-alpha**

[root@itcast03 itcast]#

sqoop-1.4.6.bin__hadoop-2.0.4-alpha這么長(zhǎng)的名字我們操作起來(lái)不方便,給它起個(gè)簡(jiǎn)單的名字sqoop-1.4.6奠蹬,如下所示朝聋。

[root@itcast03 itcast]#**mv sqoop-1.4.6.bin__hadoop-2.0.4-alpha/ sqoop-1.4.6**
[root@itcast03 itcast]# ls  
  hadoop-2.2.0  **sqoop-1.4.6**
[root@itcast03 itcast]#

那么,我們用不用配置Sqoop呢囤躁,如果你的環(huán)境已經(jīng)配置了NameNode和ResourceManager在哪臺(tái)設(shè)備上冀痕,那么我們不用配置任何內(nèi)容便可以使用Sqoop荔睹,現(xiàn)在我們的集群環(huán)境中core-site.xml和hdfs-site.xml兩個(gè)文件指定了NameNode在哪兩臺(tái)設(shè)備上,yarn-site.xml指定了ResourceManager在哪臺(tái)設(shè)備上言蛇,因此我們不用作任何配置了僻他。

那么問(wèn)題又來(lái)了,Sqoop是怎么知道我們集群的配置呢腊尚,其實(shí)Sqoop會(huì)自動(dòng)去查找這臺(tái)設(shè)備上HADOOP_HOME的位置吨拗,找到之后它會(huì)自動(dòng)讀取hadoop下面的配置文件,從而它也就知道了NameNode和ResourceManager的位置婿斥。

 [root@itcast03 itcast]#**echo $HADOOP_HOME **
    **/itcast/hadoop-2.2.0**
 [root@itcast03 itcast]#

1.2 安裝MySQL數(shù)據(jù)庫(kù)

   大家可以參考:http://blog.csdn.net/u012453843/article/details/52951422這篇博客來(lái)下載并配置使用Mysql

1.3 Hadoop集群

   大家可以參考:http://blog.csdn.net/u012453843/article/details/52829830這篇博客來(lái)搭建集群劝篷。

第二步:?jiǎn)?dòng)Sqoop

  2.1 經(jīng)過(guò)了第一步的準(zhǔn)備工作后,我們終于可以來(lái)啟動(dòng)Sqoop了民宿,啟動(dòng)之前我們先看看Sqooop的目錄娇妓,如下所示』钣ィ可以看到哈恰,在sqoop-1.4.6的bin目錄下有很多命令,我們最最常用的便是sqoop了志群,它基本上能滿(mǎn)足我們的所有要求了着绷。因?yàn)樗竺婵梢越雍芏鄥?shù),這些參數(shù)的功能非常強(qiáng)大锌云。

[root@itcast03 itcast]# ls
hadoop-2.2.0 sqoop-1.4.6
[root@itcast03 itcast]# cd sqoop-1.4.6/
[root@itcast03 sqoop-1.4.6]# ls
bin conf lib README.txt src
build.xml docs LICENSE.txt sqoop-1.4.6.jar testdata
CHANGELOG.txt ivy NOTICE.txt sqoop-patch-review.py
COMPILING.txt ivy.xml pom-old.xml sqoop-test-1.4.6.jar
[root@itcast03 sqoop-1.4.6]# cd bin
[root@itcast03 bin]# ls
configure-sqoop sqoop-export sqoop-list-tables
configure-sqoop.cmd sqoop-help sqoop-merge
sqoop sqoop-import sqoop-metastore
sqoop.cmd sqoop-import-all-tables sqoop-version
sqoop-codegen sqoop-import-mainframe start-metastore.sh
sqoop-create-hive-table sqoop-job stop-metastore.sh
sqoop-eval sqoop-list-databases
[root@itcast03 bin]#

  我們?cè)賮?lái)看看sqoop-1.4.6的conf目錄荠医,conf目錄下有個(gè)sqoop-site.xml文件,在這里面我們可以配置一些個(gè)性化的內(nèi)容宾抓,這里我們可以不做任何處理。

[root@itcast03 sqoop-1.4.6]# cd conf/
[root@itcast03 conf]# ls
oraoop-site-template.xml sqoop-env-template.cmd sqoop-env-template.sh sqoop-site-template.xml sqoop-site.xml
[root@itcast03 conf]#

 接下來(lái)我們便啟動(dòng)sqoop豫喧,我們還是先回到sqoop的bin目錄下石洗,然后使用命令**./sqooop**來(lái)啟動(dòng),啟動(dòng)的過(guò)程有很多警告紧显,這是因?yàn)槲覀冞€沒(méi)有安裝相關(guān)工具讲衫。我們不管它。

[root@itcast03 bin]# ./sqoop
Warning: /itcast/sqoop-1.4.6/bin/../../hbase does not exist! HBase imports will fail.
Please set $HBASE_HOME to the root of your HBase installation.
Warning: /itcast/sqoop-1.4.6/bin/../../hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Warning: /itcast/sqoop-1.4.6/bin/../../accumulo does not exist! Accumulo imports will fail.
Please set $ACCUMULO_HOME to the root of your Accumulo installation.
Warning: /itcast/sqoop-1.4.6/bin/../../zookeeper does not exist! Accumulo imports will fail.
Please set $ZOOKEEPER_HOME to the root of your Zookeeper installation.
Try 'sqoop help' for usage.
[root@itcast03 bin]#

第三步:把Sqoop目錄配置到環(huán)境變量(這步可以不配置孵班,只是所有命令需要到sqoop的bin目錄下去操作涉兽,比較麻煩)

由于我們是在itcast03上操作sqoop的,因此我們便在itcast03上配置它的環(huán)境變量篙程,使用的命令是vim /etc/profile枷畏,在最下方添加我們的SQOOP_HOME,如下紅色字體的內(nèi)容就是我們要添加的內(nèi)容虱饿。

export JAVA_HOME=/usr/java/jdk1.7.0_80
export HADOOP_HOME=/itcast/hadoop-2.2.0
export SQOOP_HOME=/itcast/sqoop-1.4.6
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$SQOOP_HOME/bin:$PATH

配置完環(huán)境變量之后別忘了使我們的環(huán)境變量生效拥诡,我們使用的命令是:source /etc/profile

第四步:導(dǎo)入

  4**.1 我們現(xiàn)在想把數(shù)據(jù)庫(kù)sqoop下的Student表中的數(shù)據(jù)遷移到HDFS触趴,我們先看看Student表中都有哪些數(shù)據(jù),可以看到有10條數(shù)據(jù)渴肉,我們就要把這10條數(shù)據(jù)上傳到HDFS冗懦。(****需要注意的是:Student表一定要有主鍵,否則會(huì)有問(wèn)題**)
image
     4.1.1  在開(kāi)始導(dǎo)入之前仇祭,我們需要先把jdbc的驅(qū)動(dòng)放到**/itcast/sqoop-1.4.6/lib**目錄下披蕉,驅(qū)動(dòng)包大家可以到官網(wǎng)下載也可以直接到:http://download.csdn.net/detail/u012453843/9667329這個(gè)網(wǎng)址下載**。**

[root@itcast03 ~]# ls
anaconda-ks.cfg Music
Desktop mysql-connector-java-5.1.40-bin.jar
Documents Pictures
Downloads Public
install.log sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
install.log.syslog Templates
jdk-7u80-linux-x64.gz Videos
[root@itcast03 ~]# cp mysql-connector-java-5.1.40-bin.jar /itcast/sqoop-1.4.6/lib
[root@itcast03 ~]#

   4.1.2 設(shè)置你的itcast03設(shè)備可以遠(yuǎn)程登錄到數(shù)據(jù)庫(kù)乌奇。

默認(rèn)情況下我們的itcast03是無(wú)法遠(yuǎn)程登錄到數(shù)據(jù)庫(kù)的没讲,直接進(jìn)行導(dǎo)入操作的話(huà)會(huì)報(bào)如下錯(cuò)誤:

    manager.SqlManager: **Error executing statement: java.sql.SQLException: null,  message from server: "Host 'itcast03' is not allowed to connect to this MySQL server"**
    java.sql.SQLException: null,  message from server: "Host 'itcast03' is not allowed to connect to this MySQL server"
            at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
            at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
            at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
            at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1040)
            at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253)
            at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2284)
            at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2083)
            at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:806)
            at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
            at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
            at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:410)
            at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:328)
            at java.sql.DriverManager.getConnection(DriverManager.java:571)
            at java.sql.DriverManager.getConnection(DriverManager.java:215)
            at org.apache.sqoop.manager.SqlManager.makeConnection(SqlManager.java:885)
            at org.apache.sqoop.manager.GenericJdbcManager.getConnection(GenericJdbcManager.java:52)
            at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:744)
            at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:767)
            at org.apache.sqoop.manager.SqlManager.getColumnInfoForRawQuery(SqlManager.java:270)
            at org.apache.sqoop.manager.SqlManager.getColumnTypesForRawQuery(SqlManager.java:241)
            at org.apache.sqoop.manager.SqlManager.getColumnTypes(SqlManager.java:227)
            at org.apache.sqoop.manager.ConnManager.getColumnTypes(ConnManager.java:295)
            at org.apache.sqoop.orm.ClassWriter.getColumnTypes(ClassWriter.java:1833)
            at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1645)
            at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:107)
            at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:478)
            at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:605)
            at org.apache.sqoop.Sqoop.run(Sqoop.java:143)
            at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
            at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:179)
            at org.apache.sqoop.Sqoop.runTool(Sqoop.java:218)
            at org.apache.sqoop.Sqoop.runTool(Sqoop.java:227)
            at org.apache.sqoop.Sqoop.main(Sqoop.java:236)
    16/10/29 02:21:06 ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: No columns to generate for ClassWriter
            at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1651)
            at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:107)
            at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:478)
            at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:605)
            at org.apache.sqoop.Sqoop.run(Sqoop.java:143)
            at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
            at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:179)
            at org.apache.sqoop.Sqoop.runTool(Sqoop.java:218)
            at org.apache.sqoop.Sqoop.runTool(Sqoop.java:227)
            at org.apache.sqoop.Sqoop.main(Sqoop.java:236)

解決方法如下:

mysql -u root -p
mysql>use mysql;
mysql>select host from user where user='root';
mysql>update user set host = '%' where user ='root';
mysql>flush privileges;
mysql>select host from user where user='root';
第一句是以權(quán)限用戶(hù)root登錄
第二句:選擇mysql庫(kù)
第三句:查看mysql庫(kù)中的user表的host值(即可進(jìn)行連接訪問(wèn)的主機(jī)/IP名稱(chēng))
第四句:修改host值(以通配符%的內(nèi)容增加主機(jī)/IP地址),當(dāng)然也可以直接增加IP地址
第五句:刷新MySQL的系統(tǒng)權(quán)限相關(guān)表
第六句:再重新查看user表時(shí)华弓,有修改食零。。
重起mysql服務(wù)即可完成寂屏。

 4.1.3 設(shè)置NameNode和DataNode時(shí)間同步贰谣,有可能NameNode和DataNode的時(shí)間是不同步的,這樣的話(huà)迁霎,在執(zhí)行導(dǎo)入操作的時(shí)候會(huì)報(bào)如下的錯(cuò)誤吱抚。

16/10/29 03:01:50 INFO mapreduce.Job: Job job_1477729967303_0001 failed with state FAILED due to: Application application_1477729967303_0001 failed 2 times due to Error launching appattempt_1477729967303_0001_000002. Got exception: org.apache.hadoop.yarn.exceptions.YarnException: Unauthorized request to start container.
This token is expired. current time is 1477736540684 found 1477735910751
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.apache.hadoop.yarn.api.records.impl.pb.SerializedExceptionPBImpl.instantiateException(SerializedExceptionPBImpl.java:152)
at org.apache.hadoop.yarn.api.records.impl.pb.SerializedExceptionPBImpl.deSerialize(SerializedExceptionPBImpl.java:106)
at org.apache.hadoop.yarn.server.resourcemanager.amlauncher.AMLauncher.launch(AMLauncher.java:122)
at org.apache.hadoop.yarn.server.resourcemanager.amlauncher.AMLauncher.run(AMLauncher.java:249)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
. Failing the application.

解決方法如下:

我們的集群有6臺(tái)設(shè)備,在每臺(tái)設(shè)備上使用以下兩條命令考廉。有個(gè)問(wèn)題是秘豹,在執(zhí)行第二條命令的時(shí)候,我在沒(méi)連網(wǎng)的情況下無(wú)法執(zhí)行昌粤,但是在連網(wǎng)的情況下執(zhí)行成功了<热啤!下面是我在itcast01上執(zhí)行的信息涮坐,注意要在其它設(shè)備上也執(zhí)行一下凄贩。

[root@itcast01 ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
cp: overwrite `/etc/localtime'? y
[root@itcast01 ~]# ntpdate pool.ntp.org
29 Oct 11:20:27 ntpdate[2800]: step time server 168.63.242.24 offset -28761.836642 sec
[root@itcast01 ~]#

 4.1.4 下面我們便開(kāi)始真正開(kāi)始我們的導(dǎo)入功能即將數(shù)據(jù)庫(kù)中的數(shù)據(jù)導(dǎo)入到HDFS系統(tǒng)。使用的命令如下紅色字體的內(nèi)容袱讹,我說(shuō)一下命令各項(xiàng)參數(shù)的意思疲扎。

首先./sqoop是我們操作sqoop最常用的命令也是功能最強(qiáng)大的命令。接著捷雕,import是導(dǎo)入的意思椒丧,接著,--connect jdbc:mysql://169.254.254.1:3306意思是以jdbc的方式連接數(shù)據(jù)庫(kù)救巷,169.254.254.1是我們的Windows的IP地址(該IP可以和集群連通)壶熏,3306是端口。接著浦译,sqoop是我們Student表所在的數(shù)據(jù)庫(kù)的名稱(chēng)。接著,--username root --password root 是指數(shù)據(jù)庫(kù)的用戶(hù)名和密碼监署。接著寇损,--table Student意思是我們要導(dǎo)的是Student表。

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --table Student

命令的執(zhí)行信息如下圖所示,看到紅色圈住的信息時(shí)說(shuō)明執(zhí)行成功了,這里大家發(fā)現(xiàn)了沒(méi)有,執(zhí)行過(guò)程中只有map甚带,reduce的進(jìn)度始終是0%,說(shuō)明導(dǎo)入功能根本就沒(méi)用到reduce的功能佳头,這個(gè)其實(shí)也好理解鹰贵,我們是要把數(shù)據(jù)庫(kù)中的數(shù)據(jù)導(dǎo)入到HDFS系統(tǒng),只需要多臺(tái)設(shè)備同時(shí)到數(shù)據(jù)庫(kù)中去讀取一條一條數(shù)據(jù)然后直接上傳到HDFS康嘉,根本就不需要進(jìn)行合并操作碉输。如果是要計(jì)算很多數(shù)的和的話(huà),就要用到reduce了亭珍,顯然我們的導(dǎo)入功能用不到reduce敷钾。

<main style="font-family: "WenQuanYi Micro Hei Mono", "WenQuanYi Micro Hei", "Microsoft Yahei Mono", "Microsoft Yahei", sans-serif, Simsun !important; float: left; width: 840px;">

<article style="font-family: "WenQuanYi Micro Hei Mono", "WenQuanYi Micro Hei", "Microsoft Yahei Mono", "Microsoft Yahei", sans-serif, Simsun !important; box-shadow: rgba(0, 0, 0, 0.0470588) 0px 2px 4px 0px; background-color: rgb(255, 255, 255); padding: 20px 0px;">

image
  4.1.5  執(zhí)行完了導(dǎo)入命令,我們到HDFS系統(tǒng)查看一下生成的結(jié)果肄梨。

  我們到狀態(tài)為active的namenode的HDFS界面阻荒,如下圖所示,可以看到itcast02現(xiàn)在是active狀態(tài)众羡,我們點(diǎn)擊"Browse the filesystem"侨赡。
image
  點(diǎn)擊上圖的"Browse the filesystem"鏈接之后我們會(huì)進(jìn)入到如下圖所示的界面,由于我們?cè)趯?dǎo)入的時(shí)候沒(méi)有指定要導(dǎo)入到HDFS的哪個(gè)目錄粱侣,因此系統(tǒng)會(huì)自動(dòng)幫我們存到一個(gè)地方羊壹,它自動(dòng)存的目錄在user文件夾下,如下圖所示齐婴,我們點(diǎn)擊"user"油猫。
image
  點(diǎn)擊上圖的"user"文件夾之后,我們會(huì)進(jìn)入到如下圖所示的界面尔店,由于我們是以root的身份進(jìn)行導(dǎo)入操作的眨攘,因此它自動(dòng)幫我們生成了一個(gè)root文件夾主慰,我們點(diǎn)擊它嚣州。
image
  點(diǎn)擊上圖的"root"文件夾之后,我們會(huì)進(jìn)入到如下圖所示的界面共螺,我們導(dǎo)的是數(shù)據(jù)庫(kù)中的Student表该肴,因此這里生成了一個(gè)叫Student的文件夾,我們點(diǎn)擊它藐不。
image
   點(diǎn)擊上圖的"Student"文件夾之后我們會(huì)鍵入到如下圖所示的界面匀哄,可以看到有4個(gè)結(jié)果文件秦效,也就是說(shuō)使用了4個(gè)mapper來(lái)參與導(dǎo)入操作了,我們還發(fā)現(xiàn)文件的名字中中間都是"m"涎嚼,“m”代表的意思是mapper生成的文件阱州,"r"代表的意思是reducer生成的文件。我們依次點(diǎn)開(kāi)這四個(gè)文件法梯,看看生成的結(jié)果是否正確苔货。
image
   我們先看part-m-00000文件的內(nèi)容,我們點(diǎn)擊上圖的"part-m-00000"鏈接立哑,會(huì)看到如下圖所示的內(nèi)容夜惭,可以看到有三條數(shù)據(jù)信息,列與列之間默認(rèn)是以","分隔的铛绰。
image
  接著我們?cè)賮?lái)看part-m-00001文件的內(nèi)容诈茧,如下圖所示,這個(gè)文件承接上個(gè)文件捂掰,存儲(chǔ)的是ID為4和5的兩條記錄敢会。
image
 接著我們?cè)賮?lái)看看part-m-00002文件的內(nèi)容,如下圖所示尘颓,這個(gè)文件承接上個(gè)文件走触,存儲(chǔ)的是ID為6和7的兩條記錄。
image
 接著我們?cè)賮?lái)看看最后一個(gè)文件part-m-00003文件的內(nèi)容疤苹,如下圖所示互广,該文件承接上個(gè)文件,可以看到有ID為8卧土、9惫皱、10的三條記錄。從而可以得出結(jié)論尤莺,我們剛才的導(dǎo)入操作完全沒(méi)問(wèn)題旅敷。
image

4.2 我們上面以最簡(jiǎn)單的方式導(dǎo)入了一下數(shù)據(jù),現(xiàn)在我們?cè)俣嗍褂脙蓚€(gè)參數(shù)來(lái)進(jìn)入導(dǎo)入操作颤霎,我們使用的命令如下媳谁,可以看到我們加了兩個(gè)參數(shù),--target-dir(指定要存放到服務(wù)器的哪個(gè)目錄下)和-m(指定要起的mapper的數(shù)量友酱,注意:m前面是一個(gè)"-"晴音,其它參數(shù)前面是兩個(gè)"--",由于用不到reducer合并數(shù)據(jù)缔杉,因此起幾個(gè)mapper就會(huì)生成幾個(gè)文件锤躁。)

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --table Student--target-dir /sqoop/td1 -m 2

 上面的命令執(zhí)行完之后,我們到服務(wù)器上查看一下生成的結(jié)果或详,我們先到服務(wù)器根目錄下系羞,如下圖所示郭计,可以看到確實(shí)生成了sqoop文件夾,我們點(diǎn)擊進(jìn)入

image

 點(diǎn)擊上圖的sqoop鏈接之后椒振,我們進(jìn)入到如下圖所示的界面昭伸,可以看到確實(shí)有我們剛才命名的td1文件夾,我們點(diǎn)擊進(jìn)入td1澎迎。
image
 點(diǎn)擊上圖的td1鏈接之后勋乾,我們會(huì)看到如下圖所示的界面,可以看到生成了兩個(gè)結(jié)果文件part-m-00000和part-m-00001嗡善,這符合我們?cè)O(shè)置的參數(shù)-m 2的要求辑莫,我們具體看看這兩個(gè)文件中的內(nèi)容。
image
 我們先看看part-m-00000文件中的內(nèi)容罩引,可以看到內(nèi)容是ID從1到5的Student表中的數(shù)據(jù)各吨。
image
 接著我們?cè)倏纯磒art-m-00001文件中的內(nèi)容,可以看到這里面的內(nèi)容是Student表ID從6到10的數(shù)據(jù)袁铐,也完全沒(méi)問(wèn)題=已选!剔桨!

image.png

4.3 我們接著來(lái)增加參數(shù)屉更,--fields-terminated-by '\t'意思是指定列與列的分隔符為制表符,--columns 'ID,Name,Age'意思是我們要導(dǎo)入的只有ID洒缀、Name和Age這三列瑰谜。如下所示

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --table Student --target-dir /sqoop/td2 -m 2--fields-terminated-by '\t' --columns 'ID,Name,Age'

已經(jīng)截的圖很多了,我就不挨個(gè)截圖了树绩,直接看生成的part-m-00001文件的內(nèi)容吧萨脑,如下圖所示,可以看到列與列之間確實(shí)是用\t來(lái)分隔了饺饭。

image

4.4 我們現(xiàn)在來(lái)玩一個(gè)更高級(jí)的渤早,我們使用where條件來(lái)篩選數(shù)據(jù)并導(dǎo)入符合條件的數(shù)據(jù),增加的參數(shù)是--where 'ID>=3 and ID<=8'瘫俊,顧名思義鹊杖,就是要把ID從3到8的數(shù)據(jù)導(dǎo)入到服務(wù)器。****

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --table Student --target-dir /sqoop/td3 -m 2 --fields-terminated-by '\t' --columns 'ID,Name,Age'--where 'ID>=3 and ID<=8'

** 命令執(zhí)行成功之后扛芽,我們來(lái)看看生成的兩個(gè)文件的內(nèi)容是否符合條件骂蓖,如下圖所示,發(fā)現(xiàn)完全符合我們的where條件胸哥。**

image

4.5 接下來(lái)我們玩更高級(jí)一點(diǎn)的涯竟,我們使用query語(yǔ)句來(lái)篩選我們的數(shù)據(jù)赡鲜,這意味著我們可以導(dǎo)入多張表的數(shù)據(jù)空厌,我們還是來(lái)個(gè)簡(jiǎn)單的庐船,命令如下。我們發(fā)現(xiàn)使用query語(yǔ)句的話(huà)嘲更,就不用指定table了筐钟,由于數(shù)量很少,現(xiàn)在我們指定mapper的數(shù)量為1赋朦。我們執(zhí)行下面的命令篓冲,該命令目前有個(gè)問(wèn)題。

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root--query 'select * from Student where ID>5'--target-dir /sqoop/td4-m 1 --fields-terminated-by '\t'

 執(zhí)行上面的命令會(huì)出現(xiàn)如下所示的錯(cuò)誤信息:**must contain '$CONDITIONS' in WHERE clause.**的意思是在我們的query的where條件當(dāng)中必須有**$CONDITIONS'這個(gè)條件宠哄,這個(gè)條件就相當(dāng)于一個(gè)占位符壹将,動(dòng)態(tài)接收傳過(guò)來(lái)的參數(shù),從而查詢(xún)出符合條件的結(jié)果毛嫉。**

16/10/29 18:09:46 ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: Query [select * from Student where ID>5]must contain '$CONDITIONS' in WHERE clause.
at org.apache.sqoop.manager.ConnManager.getColumnTypes(ConnManager.java:300)
at org.apache.sqoop.orm.ClassWriter.getColumnTypes(ClassWriter.java:1833)
at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1645)
at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:107)
at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:478)
at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:605)
at org.apache.sqoop.Sqoop.run(Sqoop.java:143)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:179)
at org.apache.sqoop.Sqoop.runTool(Sqoop.java:218)
at org.apache.sqoop.Sqoop.runTool(Sqoop.java:227)
at org.apache.sqoop.Sqoop.main(Sqoop.java:236)

我們?cè)谏厦娴拿钫Z(yǔ)句當(dāng)中加上**$CONDITIONS诽俯,如下所示。然后再執(zhí)行承粤,就可以執(zhí)行成功暴区。**

[root@itcast03 bin]#./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --query 'select * from Student where ID>5 and $CONDITIONS'--target-dir /sqoop/td4 -m 1 --fields-terminated-by '\t'

 **執(zhí)行成功后,我們看看結(jié)果文件辛臊,如下圖所示仙粱,發(fā)現(xiàn)確實(shí)導(dǎo)入的是ID從6到10的數(shù)據(jù)。**

image.png

假如我們要把-m 1改成-m 2的話(huà)彻舰,導(dǎo)入操作會(huì)失敗伐割,我們來(lái)看一下命令執(zhí)行及異常信息,如下所示刃唤。異常信息的意思是口猜,我們沒(méi)有指定mapper按什么規(guī)則來(lái)分割數(shù)據(jù)。即我這個(gè)mapper應(yīng)該讀取哪些數(shù)據(jù)透揣,一個(gè)mapper的時(shí)候沒(méi)有問(wèn)題是因?yàn)樗粋€(gè)mapper就讀取了所有數(shù)據(jù)济炎,現(xiàn)在mapper的數(shù)量是2了,那么我第一個(gè)mapper讀取多少數(shù)據(jù)辐真,第二個(gè)mapper就讀取第一個(gè)mapper剩下的數(shù)據(jù)须尚,現(xiàn)在兩個(gè)mapper缺少一個(gè)分割數(shù)據(jù)的條件,找一個(gè)唯一標(biāo)識(shí)的一列作為分割條件侍咱,這樣兩個(gè)mapper便可以迅速知道表中一共有多少條數(shù)據(jù)耐床,兩者分別需要讀取多少數(shù)據(jù)。

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --query 'select * from Student where ID>5 and $CONDITIONS' --target-dir /sqoop/td5-m 2 --fields-terminated-by '\t'
Please set $ZOOKEEPER_HOME to the root of your Zookeeper installation.
16/10/29 19:01:47 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6
16/10/29 19:01:47 WARN tool.BaseSqoopTool: Setting your password on the command-line is insecure. Consider using -P instead.
When importing query results in parallel, you must specify --split-by.
Try --help for usage instructions

** 知道了異常的原因楔脯,我們便加上分割數(shù)據(jù)的條件撩轰,我們使用的是Student表的ID字段。命令如下。**

[root@itcast03 bin]# ./sqoop import --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --query 'select * from Student where ID>5 and $CONDITIONS' --target-dir /sqoop/td5 -m 2 --fields-terminated-by '\t' --split-by Student.ID

執(zhí)行上面的命令堪嫂,導(dǎo)入操作便可以成功偎箫。如下圖所示。發(fā)現(xiàn)確實(shí)生成了兩個(gè)文件皆串,并且兩個(gè)文件中的內(nèi)容加起來(lái)剛好就是我們query中的條件ID>5淹办。這里我們?cè)僭敿?xì)說(shuō)說(shuō)$CONDITIONS'的作用,sqoop首先根據(jù)Student.ID將數(shù)據(jù)統(tǒng)計(jì)出來(lái)恶复,然后傳給$CONDITIONS'怜森,query語(yǔ)句就知道一共有多條數(shù)據(jù)了,假如第一個(gè)mapper讀取了2條數(shù)據(jù)谤牡,那么也會(huì)把這個(gè)2傳給$CONDITIONS副硅,這樣第二個(gè)mapper在讀取數(shù)據(jù)的時(shí)候便可以根據(jù)第一個(gè)mapper讀取的數(shù)量讀取剩下的內(nèi)容。

image

第五步:導(dǎo)出

 **我們把第四步最后導(dǎo)入的td5文件夾下兩個(gè)文件的數(shù)據(jù)導(dǎo)出到數(shù)據(jù)庫(kù)翅萤。**

** 5.1 我們新建一個(gè)table表想许,這個(gè)table表和我們的Student表結(jié)構(gòu)要一致,在mysql中有一個(gè)復(fù)制表的語(yǔ)句:create table student_copy like Student;這樣我們便可以得到一張表結(jié)構(gòu)和Student完全一樣的表断序,如下圖所示流纹。**

image

** 5.2 接下來(lái)我們便開(kāi)始將服務(wù)器上的數(shù)據(jù)導(dǎo)出到數(shù)據(jù)庫(kù)中,我們先來(lái)看一個(gè)錯(cuò)誤的命令违诗。**

[root@itcast03 bin]# ./sqoop export --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --export-dir /sqoop/td5 -m 1 --table student_copy

** 錯(cuò)誤信息如下:可以看到是數(shù)據(jù)轉(zhuǎn)換出現(xiàn)了異常漱凝。那么是什么原因?qū)е碌哪兀鋵?shí)是列與列的分隔符導(dǎo)致的诸迟,td5下的兩個(gè)文件中的數(shù)據(jù)是以"\t"來(lái)分隔的茸炒,而sqoop默認(rèn)是以","來(lái)分隔的,因此出現(xiàn)了問(wèn)題阵苇。**

Caused by: java.lang.RuntimeException: Can't parse input data: '6 baiyansong 45 88.0'
at student_copy.__loadFromFields(student_copy.java:335)
at student_copy.parse(student_copy.java:268)
at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:83)
... 10 more
Caused by: java.lang.NumberFormatException: For input string: "6 baiyansong 45 88.0"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at student_copy.__loadFromFields(student_copy.java:317)
... 12 more

知道了問(wèn)題壁公,我們對(duì)癥下藥,人為指定分隔符--fields-terminated-by '\t'绅项,命令如下所示紊册。這里說(shuō)明一點(diǎn)的是,--export-dir /sqoop/td5這個(gè)參數(shù)有些人可能會(huì)有疑惑,因?yàn)閠d5文件夾下除了part-m-00000和part-m-00001兩個(gè)結(jié)果文件外快耿,還有一個(gè)名為“SUCCESS”的文件囊陡,導(dǎo)出的時(shí)候會(huì)不會(huì)連這個(gè)文件的內(nèi)容都導(dǎo)出去了呢?其實(shí)不會(huì)的掀亥,我們指定到文件夾撞反,程序會(huì)去掃描這個(gè)文件夾下的所有文件,凡是不以""開(kāi)頭的文件都會(huì)被導(dǎo)出去搪花,SUCCESS文件是以“”開(kāi)頭的遏片,因此它不會(huì)被導(dǎo)出去嘹害,大家放心。

image

[root@itcast03 bin]#./sqoop export --connect jdbc:mysql://169.254.254.1:3306/sqoop --username root --password root --export-dir /sqoop/td5 -m 1 --table student_copy--fields-terminated-by '\t'

** 執(zhí)行成功后我們看看我們剛才復(fù)制的student_copy表中是否有了我們導(dǎo)出的數(shù)據(jù)吮便。發(fā)現(xiàn)確實(shí)導(dǎo)出到數(shù)據(jù)庫(kù)5條數(shù)據(jù)笔呀,這5條數(shù)據(jù)也就是td5下面兩個(gè)文件的內(nèi)容,說(shuō)明我們的導(dǎo)出功能也完全正常O呱馈!**

image

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惑折,一起剝皮案震驚了整個(gè)濱河市授账,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惨驶,老刑警劉巖白热,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異粗卜,居然都是意外死亡屋确,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)续扔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)攻臀,“玉大人,你說(shuō)我怎么就攤上這事纱昧∨傩ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵识脆,是天一觀的道長(zhǎng)设联。 經(jīng)常有香客問(wèn)我,道長(zhǎng)灼捂,這世上最難降的妖魔是什么离例? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮悉稠,結(jié)果婚禮上宫蛆,老公的妹妹穿的比我還像新娘。我一直安慰自己的猛,他們只是感情好洒扎,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著衰絮,像睡著了一般袍冷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上猫牡,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天胡诗,我揣著相機(jī)與錄音,去河邊找鬼。 笑死煌恢,一個(gè)胖子當(dāng)著我的面吹牛骇陈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瑰抵,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼你雌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了二汛?” 一聲冷哼從身側(cè)響起婿崭,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肴颊,沒(méi)想到半個(gè)月后氓栈,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡婿着,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年授瘦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竟宋。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡提完,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丘侠,到底是詐尸還是另有隱情氯葬,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布婉陷,位于F島的核電站帚称,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏秽澳。R本人自食惡果不足惜闯睹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望担神。 院中可真熱鬧楼吃,春花似錦、人聲如沸妄讯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)亥贸。三九已至躬窜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炕置,已是汗流浹背荣挨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工男韧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人默垄。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓此虑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親口锭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朦前,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1、運(yùn)行環(huán)境 主機(jī)IP 主機(jī)名 2鹃操、配置主機(jī)名(分別在五臺(tái)機(jī)器上執(zhí)行) hostname +主機(jī)名例如: h...
    獻(xiàn)給記性不好的自己閱讀 3,560評(píng)論 0 6
  • 上節(jié)課我們一起學(xué)習(xí)了怎樣搭建一個(gè)6臺(tái)設(shè)備的Hadoop集群韭寸,這節(jié)課我們一起來(lái)學(xué)習(xí)一下怎樣測(cè)試我們搭建的集群是否有問(wèn)...
    文子軒閱讀 959評(píng)論 0 1
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    Joyyx閱讀 8,328評(píng)論 0 16
  • 1/列出mysql數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)庫(kù)sqoop list-databases -connect jdbc:mys...
    時(shí)待吾閱讀 2,741評(píng)論 1 5
  • 2月12日,我的一天之陪著媽媽修打印機(jī)组民。 今天棒仍,我闖禍了悲靴,這是因?yàn)橐粓?chǎng)“蝴蝶效應(yīng)”臭胜,首先是我住在樓上的同學(xué)翟瀟宇來(lái)...
    Sernedipity閱讀 244評(píng)論 0 0