[奥莱理] Apache Sqoop Cookbook-读书笔记

Apache Sqoop Cookbook 笔记

 

导入:

1 全表导入(mysql 2 hdfs)

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--tablecities

2 全表导入(mysql 2hdfs)指定到入文件夹

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--passwordsqoop \

--table cities \

--target-dir/etl/input/cities

或者

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--warehouse-dir/etl/input/

 指定的文件夹必须不能存在,sqoop会拒绝向已经存在的文件夹写入,以避免覆盖数据

3 部分表导入(mysql 2 hdfs)

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--where"country= 'USA'"

Where语句中也可以放方法,甚至自定义函数,但是sqoop是集群并行执行的,要小心权衡,避免在集群中对相关数据库做过多操作,导致负载高等问题;如果使用函数,函数应该尽量简单

4 保护密码

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--table cities \

-P

这个会命令sqoop从键盘输入中获取密码

sqoop import \

--connect jdbc:mysql://mysql.example.com/sqoop\

--username sqoop \

--table cities \

--password-filemy-sqoop-password

将密码保存在文件中

echo "my-secret-password">sqoop.password

hadoop dfs -put sqoop.password /user/$USER/sqoop.password

hadoopdfs -chown 400 /user/$USER/sqoop.password

rm sqoop.password

sqoopimport --password-file /user/$USER/sqoop.password...

创建密码文件,设置权限为400,其他用户无法操作和查看

5 用除了“逗号分隔”的方式(Avro、SequenceFile.)

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--as-sequencefile

或者

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--as-avrodatafile

 

6 压缩导入数据

sqoop import \

--connect jdbc:mysql://mysql.example.com/sqoop\

--username sqoop \

--table cities \

--compress

也可以指定压缩格式

sqoop import --compress \

--compression-codecorg.apache.hadoop.io.compress.BZip2Codec

 

7 更快的传输

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--table cities \

--direct

不是支持每一个服务器,mysql可以,其他不一定,必须在各个节点都安装了相关数据库的本地jar包

 

8 覆盖表的映射类型类型

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--usernamesqoop \

--table cities \

-map-column-javac1=Float,c2=String,c3=String ...

 

9 设置并行map数量

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--num-mappers10

 

10 覆盖null值

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--null-string 'NULLSTR' \

--null-non-string'NULLNON'

导入hbase这个配置好像无效

 

11 导入全部表

sqoopimport-all-tables \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--passwordsqoop

或者

导入全部表,但是除了….

sqoop import-all-tables \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--exclude-tablescities,countries

 

 

 

二增量导入:

1 只增量导入新数据

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table visits \

--incremental append \

--check-column id \

--last-value1

过去的数据不会被重新载入,即时修改过

 

2 增量导入易变数据

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--usernamesqoop \

--password sqoop \

--table visits \

--incremental lastmodified \

--check-column last_update_date \

--last-value"2013-05-2201:01:01"

 

3建立job(可自动实现每次导入最新)

sqoop job \

--createvisits \

-- \

import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table visits \

--incremental append \

--check-column id \

--last-value0

执行

sqoop job --execvisits

看都有哪些job

sqoop job –list

删除job

sqoop job--delete visits

查看job

sqoop job --showvisits

用job会自动

 

4 job的密码存储

可以直接在定义时写,也可以写到配置文件中

<configuration>

...

<property>

<name>sqoop.metastore.client.record.password</name>

<value>true</value>

</property>

</configuration>

 

5 在运行时增加(或重写)job参数

sqoop job --execvisits -- --verbose

如果是临时使用要特别小心,因为job无论你是采用哪种方式执行,都会把最后一行的信息存入元数据,这样有可能会丢失信息

 

6 机器间共享元数据

首先开启服务

sqoop metastore

然后执行时指定

sqoop job

--create visits \

--meta-connectjdbc:hsqldb:hsql://metastore.example.com:16000/sqoop \

-- \

import \

--table visits

...

 

配置

sqoop-site.xml

服务端口:sqoop.metastore.server.port

自动连接metastore:

<configuration>

...

<property>

<name>sqoop.metastore.client.autoconnect.url</name>

<value>jdbc:hsqldb:hsql://your-metastore:16000/sqoop</value>

</property>

</configuration>

 

三 从多个表自由导入(用query)

1 从两个表导入(有外键关联)

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--query 'SELECTnormcities.id, \

countries.country, \

normcities.city \

FROM normcities \

JOIN countries USING(country_id) \

WHERE $CONDITIONS' \

--split-by id \

--target-dircities

 

2 用自定义边界的query

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--query 'SELECTnormcities.id, \

countries.country, \

normcities.city \

FROM normcities \

JOIN countries USING(country_id) \

WHERE $CONDITIONS' \

--split-by id \

--target-dir cities \

--boundary-query"selectmin(id), max(id) from normcities"

 

3  给sqoop内部的mapreducejob起名

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--query 'SELECTnormcities.id, \

countries.country, \

normcities.city \

FROM normcities \

JOIN countries USING(country_id) \

WHERE $CONDITIONS' \

--split-by id \

--target-dir cities \

--mapreduce-job-namenormcities

 

4 从多表导入时有重复列

--query "SELECT\

cities.city AS first_city \

normcities.city AS second_city \

FROM cities \

LEFTJOIN normcities USING(id)"

 

四 导出

1 从hadoop环境导出到mysql数据库

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--export-dircities

 

2 批量导出

首先

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--export-dir cities \

--batch

定义每个语句的数量

sqoop export\

-Dsqoop.export.records.per.statement=10 \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--export-dircities

然后定义每个事物提交的数量

sqoop export\

-Dsqoop.export.statements.per.transaction=10 \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--export-dircities

 

3 保证事务性(或者全部转移成功或者都不转移)

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--staging-tablestaging_cities

用中间表

可以加下面这句来清空中间表

--clear-staging-table

 

4 更新已经存在的数据集

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--update-keyc2,c4

 

5 一次插入和更新

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--update-key id \

--update-modeallowinsert

 

6 使用存储过程

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--callpopulate_cities

 

7 导出的列少于目标表的列时

指定hdfs中存储的是哪些列

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--columnscountry,city

 

8 为null值设置不同的值

sqoop export\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--input-null-string '\\N'\

--input-null-non-string'\\N'

 

9 导出数据出错

读hadoop的日志

 

五 hadoop生态系统集成

1 和oozie整合,用oozie启动sqoop命令

<workflow-app name="sqoop-workflow" xmlns="uri:oozie:workflow:0.1">

...

<action name="sqoop-action">

<sqoop xmlns="uri:oozie:sqoop-action:0.2">

<job-tracker>foo:8021</job-tracker>

<name-node>bar:8020</name-node>

<command>import --table cities --connect ...</command>

</sqoop>

<ok to="next"/>

<error to="error"/>

</action>

...

</workflow-app>

 

为避免无法识别command里的空格,可以用如下方法

<arg>import</arg>

<arg>--table</arg>

<arg>cities</arg>

<arg>--username</arg>

<arg>sqoop</arg>

<arg>--password</arg>

<arg>sqoop</arg>

...

 

等待

 

2 oozie中的command指令无需转移

比如

sqoopimport --password "spEci@l\$" --connect'jdbc:x:/yyy;db=sqoop'

可直接写成

<command>sqoop import --password spEci@l$ --connectjdbc:x:/yyy;db=sqoop pass:

[<phrase role='keep-together'></command></phrase>]

 

3 oozie中配置属性参数

<workflow-app name="sqoop-workflow" xmlns="uri:oozie:workflow:0.1">

...

<action name="sqoop-action">

<sqoopxmlns="uri:oozie:sqoop-action:0.2">

<job-tracker>foo:8021</job-tracker>

<name-node>bar:8020</name-node>

<configuration>

<property>

<name>sqoop.export.statements.per.transaction</name>

<value>1</value>

</property>

</configuration>

<command>import --table cities --connect ...</command>

</sqoop>

<ok to="next"/>

<error to="error"/>

</action>

...

</workflow-app>

 

4 安装 oozie JDBC Driver

放到相关目录下,如需,查本书(Apache Sqoop Cookbook)

 

5 将数据直接导入hive

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hive-import

改变键的类型可以用如下

sqoop import \

...

--hive-import \

--map-column-hiveid=STRING,price=DECIMAL

可以用如下命令,会清空这个hive表,再导入

--hive-overwrite

 

6 导入分区的hive表

sqoop import \

--connect jdbc:mysql://mysql.example.com/sqoop\

--username sqoop \

--password sqoop \

--table cities \

--hive-import \

--hive-partition-key day \

--hive-partition-value"2013-05-22"

 

7 导入hive时去掉源数据中的在hive中是分隔符的字符

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hive-import \

--hive-drop-import-delims

会去掉\n, \t, 和 \01

 

或者将这些改成指定字符串:

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hive-import \

--hive-delims-replacement"SPECIAL"

 

8  导入hive时null值的处理

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hive-import \

--null-string '\\N'\

--null-non-string'\\N'

 

9 导入hbase

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hbase-table cities \

--column-familyworld

如果需要自动创建则添加

--create-hbasetable

 

10 将行健也存入列中(本来是不存的)

sqoop import \

-Dsqoop.hbase.add.row.key=true\

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hbase-table cities \

--column-familyworld

 

11 导入hbase时提高性能

提前建立hbase表,将分区设的比较大

hbase> create 'cities', 'world', {NUMREGIONS=>20, SPLITALGO=> 'HexString

Split'}

 

六 各种数据库专门的连接器

1postgreSQL中loolean值的重写

sqoop import \

--connectjdbc:postgresql://postgresql.example.com/database \

--username sqoop \

--password sqoop \

--direct \

--table table_with_booleans \

-- \

--boolean-true-string 1 \

--boolean-false-string 0

将true改成1,false改成0

这两个参数只有导入时有用,导出不生效

 

2 postgreSql 导入Custom Schema

sqoop import \

--connectjdbc:postgresql://postgresql.example.com/database \

--username sqoop \

--password sqoop \

--table cities \

-- \

--schema us

 

3 postgreSql pg_bulkload

 

4 连接mysql问题

 

5 直接从mysql导入到hive时null值的设置

 

sqoop import \

--connectjdbc:mysql://mysql.example.com/sqoop \

--username sqoop \

--password sqoop \

--table cities \

--hive-import \

--null-string '\\N'\

--null-non-string '\\N'

 

6 导到mysql时自动辨别更新或插入

--update-key

用来标识唯一列,用于判断是更新还是插入

 

7 oracle 导入时用户名密码区分大小写

sqoop import \

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table KATHLEEN.cities

 

8 导入oracle时 使用Synonyms

sqoop import \

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table CIT \

--driver oracle.jdbc.OracleDriver \

--connection-managerorg.apache.sqoop.manager.GenericJdbcManager

 

9 oracle时提高传输速度

用OraOop

 

10 用oraoop将oracle导入avro

sqoop import \

-Doraoop.timestamp.string=false\

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table cities \

--as-avrodatafile

 

sqoop import \

-Doraoop.timestamp.string=false\

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table cities \

--as-avrodatafile \

--map-column-java CREATED=String,UPDATED=String

 

11 为oracle选择适当的连接器

首选OraOop,不行再用内置连接器,不行再用the Generic JDBCConnector

Choose the OraOop connector:

sqoop import \

--connection-managercom.quest.oraoop.OraOopConnManager \

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table cities

 

Choose the built-in Oracle connector:

sqoop import \

--connection-managerorg.apache.sqoop.manager.OracleManager \

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table cities

 

And finally, choose the Generic JDBCConnector:

sqoop import \

--connection-managerorg.apache.sqoop.manager.GenericJdbcManager \

--driver oracle.jdbc.OracleDriver \

--connectjdbc:oracle:thin:@oracle.example.com:1521/ORACLE \

--username SQOOP \

--password sqoop \

--table cities

 

12 导出到Teradata

sqoop export\

-Dsqoop.export.records.per.statement=1 \

--connectjdbc:teradata://teradata.example.com/DATABASE=database\

--username sqoop \

--password sqoop \

--table cities\

--export-dir cities

 

13 导出到Teradata时使用ClouderaTeradata连接器

下载Cloudera Teradata Connector

 

14 导出到Teradata时使用长列名

sqoop import \

--connectjdbc:teradata://teradata.example.com/DATABASE=database\

--username sqoop \

--password sqoop \

--query "SELECTREALLY_LONG_COLUMN_NAME_30CHAR AS shorter_column_name \

FROM table"

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值