一、sqoop提交任务后,转换成map作业,数据最终是写入到磁盘,然后load到hive表里,因为是load操作无mr计算,hive表存储必须是textfile格式。 至于启多少个map就是根据参数 -m 5 --split-by id 这个操作
二、hive建表默认是列分割是\t 行分割是\n sqoop抽数据写入磁盘,默认的列分割是\001 行分割是\n
所以你抽数据写表就是3种方式 1.sqoop写数据,load到hive表的时候自动建表,表的列行分割就是 \001 \n 2.hive提前建表以\001 \n分割列行,sqoop抽数据的时候就可以省略那两个参数 3.第三种就是hive建表自定义分隔符 比如 \t \n 你写sqoop的时候就需要指定–fields-terminated-by ‘\t’ --lines-terminated-by ‘\n’ 参数
三、sqoop抽数据经常发生的错误 1、数据列错位,数据行数变多 比如数据列分割是逗号分割的,现在Mysql里面有两个字段 id name Mysql表数据如果是 id=1 name=张三 这条数据写入到磁盘就是 1,张三 最后能正常的load到hive的两个字段里。 如果mysql里面字段值出现脏数据等情况,例如: 字段值是 id=1 name=张,三 写入磁盘就是 1,张,三 hive就是会读取成3个字段,最终到hive的两个字段里就是id=1,name=张。 如果表有3个、甚至多个字段,因为张三有逗号,导致后面字段全部错位。
四、数据行数变多就是比如某个字段的数据,它是很多的文本,不是一行数据,而是多行,比如有2个字段, id=1 describe=“yn: xxsdasodsds sdijsdij”
这样的形式,注释有3行,这个数写入到磁盘后就是 1,yn: xxsdasodsds sdijsdij 变成了3行,load到hive里面就成了3行数据 id=1,describe=yn: id=xxsdasodsds,describe=null id=sdijsdij,describe=null
五、sqoop有两个指令: 一个指令–hive-drop-import-delims 这个是去除\r \n \001的 把字段文本数据都去掉,然后就不会出现字段错位,行数变多
六、然后如果你接入的数据字段都是varchar,自然OK,这个指令都没问题 如果遇到oracle一些特殊字段,Oracle中的Bit,Blob,Clob,LongText这些字段类型,当这种字段类型的字段数据出现上面问题的时候,你用那个指令的时候就没用,还得加个命令:–map-column-java column=String 把特殊字段类型,map分析的时候,把字段类型转为string,然后再结合那个–hive-drop-import-delims,就可以去除特殊字段的\t \r \n这些 map任务会自动把varchar转换为string去处理,oracle特殊字段它不会识别,这个命令大概就是类似于java的类型强转.
六、还有两个点就是: 1.hive建表的列分隔符一定要跟sqoop的分隔符对应,数据抽完后select * 检查下,有时候不注意就是没对应上,导致一行数据全部写到第一个字段,后面字段都为null 2.–split-by id 根据字段切分,启动多个map的命令,这个切割字段最好是int类型,尽量别用varchar,varchar有时候也能用,比如某个字段是年月日,但是是varchar类型,你也可以用。 除了这两个字段其他都别用,尤其date类型 因为split-by本质上是加where条件 wher date = ‘’ 如果用date类型,会报字段类型不匹配 一般用int的id,如果没有,数据量贼大,自己加一个自增id字段,用完再删了。 另外:oracle表有个隐藏字段rownum,这是一个自增字段,sqoop抽数的时候,只要抽取oracle的数据,都可以用–split-by rownum切割
|