利用sqoop从数据源获取数据到hive的流程化
2015-05-11 18:35
309 查看
在流程化中,我不太清楚其他朋友是怎么做的,这里参考我司的数据仓库的调度逻辑将sqoop脚本放到shell里执行,最终结果能基本解决后期日常维护、代码重用的需求;注意这里只讨论从数据源获取数据到hive而不包括在hive中对数据的处理脚本,但是是值得参考的
目标
根据需要每天从业务库导入前一天的数据,在hive中生成一个日表,格式与数据源保持一致即可,比如今天2015年5月11日,那么我们将在凌晨从数据源中获取的2015年5月10日的数据;这里hive当做一个数据仓库来使用,先将数据原封不动的抽取过来,相当于三层结构中的ods层。
读取该文件的方法参考如下
在对应的脚本中加入此代码就可以获取到ip、connectURL等配置在datawarehouse中的值
在sqoop中可以使用类似语句就可以重复引用文件fdw.txt中的信息
这种情况,对于大量的数据来源库可能需要自己维护,十几二十可以用,但是更多的就可能有点乏力了,事实上不管有多少数据源都建议给予一个良好的命名规范,至少能要让使用者能够看命名就知道内容
在hive中的参数定义,可以直接使用shell中的参数(下面的判断代码块既是如此)
另一种参数使用方式是利用hiveconf,但这个不能通过hive -e这种方式去使用,只能在文件中去引用
格式如下
xxx.hql 内容如下,这里只为了说明参数的引用
完整的脚本将放在本文的最后面,这是一些简单的属性说明
这里提供一个hive中的建表语句
这里的保留字段是因为在之前的RDBMS中存在的,保留因为后续可能有需要export到RDBMS,这里根据各自需求可以自行建表
该表的意义是在每次sqoop之后往hive中写入一个记录,相关的脚本如下
首先在路径/home/9003547/sqooppath下建了一个sh文件,命名为
注:dual表是一个自建的表,相当于oracle中的dual,只有一列属性为string,并且值只有一个为”x”
这个表的存在只是为了在select一些自给的值的时候使用,只要注意里面只有一行数据就可以了
这个
现在贴出一个完整的使用脚本
以上就是完整的脚本说明
这个东西的调度方式可以采用linux自带的crontab,但是如果有条件最好还是弄一个可视化图形进行操作,包括作业的顺序、重跑等,在系统后台维护各个作业的依赖关系,这样对所有的作业维护才是最轻松的,具体的话这个设计到web或者客户端开发,需要更专业的同事实现
1、明细日志输出到文件
2、sqoop脚本错误结果获取存入库中,这样每天不但不用翻明细的日志文件,也可以直接在hive中select出来
3、如果可以将现在写在hive中的日志记录写入RDBMS,速度快一点也不需要在export回去,最直接的就是写入mysql,因为hive的元数据也存储在这里呀,现成的数据库可以使用。
目标
根据需要每天从业务库导入前一天的数据,在hive中生成一个日表,格式与数据源保持一致即可,比如今天2015年5月11日,那么我们将在凌晨从数据源中获取的2015年5月10日的数据;这里hive当做一个数据仓库来使用,先将数据原封不动的抽取过来,相当于三层结构中的ods层。
测试环境
数据源:MS sqlserver 2012 hadoop-2.5.0 hive-0.13 sqoop-1.4.5 对应的数据库为fengmingdw
1、数据源的配置文件
关于配置文件的存在是为了将所用相关的属性整合到同一个文件,每一个需要对应属性的脚本,只要到里面去读就可以了;在设计过程中这里提供了两种方法,方法一可以参考一下,建议直接方法二方法一,自定义配置文件
配置文件格式可以自选,包括诸如xml、ini等等,考虑到shell实现的困难,这里选取最简单的 形如xxx=aaaa ,这是linux中通用的配置文件方式
#文件命名为datawarehouse ip=192.168.73.12 #注意等号两边不要有空格 username=testUser passwd=123456 dbname=fdw connectURL="jdbc:sqlserver://`echo $ip`;DatabaseName=`echo $dbname`"
读取该文件的方法参考如下
function load_config() { filePath="/home/9003547/datasource.d/`echo $1`" #这是我存放的配置文件路径 echo $filePath if [ -f "$filePath" ]; then . $filePath fi } load_config datawarehouse #传入配置文件名称 echo $ip #读取的参数 echo $connectURL
在对应的脚本中加入此代码就可以获取到ip、connectURL等配置在datawarehouse中的值
方法二,options-file参数
sqoop中提供了一个选项 --options-file,允许sqoop去读取一段文件内的脚本 这里提供一个文件,路径为 /home/9003547/sqooppath/fdw.txt,该文件内容如下
import --connect jdbc:sqlserver://192.168.73.12:1433;DatabaseName=fdw --username testUser --password 123456
在sqoop中可以使用类似语句就可以重复引用文件fdw.txt中的信息
sqoop --options-file /home/9003547/sqooppath/fdw.txt \ --table myTestTable \ --xxxxxx #后面补充相应的参数
这种情况,对于大量的数据来源库可能需要自己维护,十几二十可以用,但是更多的就可能有点乏力了,事实上不管有多少数据源都建议给予一个良好的命名规范,至少能要让使用者能够看命名就知道内容
shell中的sqoop与hive脚本
在这里做简单的设置,包括传入一个日期参数作为表名、将hive中存在的表名给删除、sqoop抽取表数据日期参数的设置
因为是每天一个表存放数据,所以采取的方式是表名+日期,这里设置日期参数#定义时间,允许传入一个时间,如果未传递则默认当前日期的前一天 if [ -z $1 ] then d_date=`date +%Y%m%d --date="-1 day"` else d_date=$1 fi tableName=testTable_$d_date
shell中的hive
在hive中提供了临时访问hive终端的方式,即使用 【hive -e “语句块”】,也可以通过【hive -f 文件名】 去执行hive脚本文件在hive中的参数定义,可以直接使用shell中的参数(下面的判断代码块既是如此)
#判断hive中的表是否存在,存在就删掉,以支持重复抽取 hive -e "drop table if exists dino.$tableName" #指定了库名
另一种参数使用方式是利用hiveconf,但这个不能通过hive -e这种方式去使用,只能在文件中去引用
格式如下
hive -hiveconf variable1='aaa' -hiveconf variable2='bbb' -f xxx.hql
xxx.hql 内容如下,这里只为了说明参数的引用
select * from testTable where col1 betweeb '${hiveconf:variable1}' and '${hiveconf:variable2}'
shell中的sqoop
#sqoop 抽取数据,这里是全表抽取,即没有加where和column参数 sqoop --options-file /home/9003547/sqooppath/fengmingdw.txt \ --table $tableName \ --delete-target-dir --target-dir /user/hive/tmp/$tableName \ --hive-import --hive-table dino.$tableName \ --create-hive-table \ --hive-overwrite \ --null-non-string '\\N' \ --null-string '\\N' \ --fields-terminated-by '\t' \ --lines-terminated-by '\n' \ --m 1
完整的脚本将放在本文的最后面,这是一些简单的属性说明
1、target-dir 指的是hdfs上的目录,需要当前用户具有读写权限,否则会被拒绝 2、$tableName 是在shell中预先定义的表名,该表名由两部分组成 表名+日期,中间使用下划线分开 3、hive中的null值,在rdbms上的null值在hive中会直接转换成字符串“null”,如果不需要可以使用null-non-string和null-string两个参数将其替换掉,这里将其转换为hive中的空值,即‘\N’,记得转义 4、如果不是一张表,比如只要某些列并限定条,可以使用--columns "col1,col2" --where "col1>2 and col2<10"类似参数
sqoop结果的记录
在shell中,我们可以把运行的日志利用符号【>>】将结果指向到指定的文件中,但是如果脚本太多,那么把每一个脚本的记录都写入同一个hive表或者rdbms中的表是一个比较好的选择这里提供一个hive中的建表语句
create table dino.etl_table2 ( etl_name string comment 'sqoop的job名,可以用table_name替代' ,table_name string comment '表名,如果MyTestTabel_20150511则MyTestTable' ,etl_date string comment '取日期,如果MyTestTabel_20150511则20150511' ,start_time string comment 'sqoop脚本的开始时间' ,end_time string comment 'sqoop脚本的结束时间' ,etl_rows int comment '保留字段,抽取的数据行数,hive中不知道怎么获取' ,etl_hours int comment '保留字段,抽取的具体小时时间点' ) comment 'table for keeping etl audit record' row format delimited fields terminated by '\t' lines terminated by '\n' stored as textfile;
这里的保留字段是因为在之前的RDBMS中存在的,保留因为后续可能有需要export到RDBMS,这里根据各自需求可以自行建表
该表的意义是在每次sqoop之后往hive中写入一个记录,相关的脚本如下
首先在路径/home/9003547/sqooppath下建了一个sh文件,命名为
hive_etl_record.sh
if [ $# != 5 ];then echo 'must be provide 5 paras' echo $# exit 2 fi echo "传入的参数值为以下" for arg in "$@" do echo $arg done #参数赋值 table_name=$1 etl_date=$2 etl_status=$3 start_time=$4 etl_errors=$5 hive -e " insert into table dino.view_etl_audit select '$table_name'as etl_name ,'$table_name'as etl_table ,'$etl_date' as etl_date ,$etl_status as etl_status ,'$start_time' as start_time ,from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss')as end_time ,'$etl_errors'as etl_errors ,'\\N' as etl_rows ,'\\N'as etl_hour from dino.dual; "
注:dual表是一个自建的表,相当于oracle中的dual,只有一列属性为string,并且值只有一个为”x”
这个表的存在只是为了在select一些自给的值的时候使用,只要注意里面只有一行数据就可以了
这个
hive_etl_record.sh的存在是为了实现代码重用,在实际的sqoop中可以方便的直接传递参数。下面是使用这个文件的实际方法
#判断sqoop执行结果,紧跟在上面的sqoop语句之后 if [$? -ne 0];then etl_status=0 etl_error="errors" else etl_status=1 etl_error="\\N" fi #日志写入到hive中,参数顺序对应说明 #table_name=$1 #etl_date=$2 #etl_status=$3 #start_time=$4 #etl_errors=$5 ./home/9003547/sqooppath/hive_etl_record.sh "$table" "$d_date" "$etl_status" start_date" "$start_date" "$etl_errors"
完整的代码
在上述中,更多的是对零散代码的说明,已经贴出了option-file中的代码 fdw.txt hive_etl_record.sh的配置
现在贴出一个完整的使用脚本
#!/bin/bash . ~/.bashrc #这里要用户自己填写的,有两个地方,第一个是设置tableName的设置,第二个是sqoop语句要自己看表看需求来写 #使用说明 # 抽取指定的表名的数据 # 如果用户在执行该脚本的时候不传入日期参数则默认为当前日期的前一天进行 # 否则为用户指定的日期,格式为yyyyMMdd,如要抽取2015-05-10的数据,那么执行的方式应该是如下 # sh 脚本名 20150510 #声明获取的数据表名 table=ods_crm_rolegroup logfile=/home/9003547/sqooplog/$table.txt #日期 #得到业务日期,如果没有传入日期参数,则由系统直接赋值 if [ -z $1 ] then d_date=`date +%Y%m%d --date="-1 day"` else d_date=$1 fi echo $d_date >> $logfile d_date_format=`echo ${d_date} | awk '{print substr($d_date,1,4)"-"substr($0,5,2)"-"substr($0,7,2)}'` echo ${d_date_format} >> $logfile start_date=`date '+%Y-%m-%d %H:%M:%S'` echo ${start_date} >> $logfile tableName=$table"_"$d_date echo $tableName #判断表在hive中是否存在,存在就删除,这里hive中的库名为dino hive -e "drop table if exists dino.$tableName" #sqoop 抽取数据,这里全表抽取 sqoop --options-file /home/9003547/sqooppath/fdw.txt \ --table $tableName \ --delete-target-dir --target-dir /user/hive/tmp/$tableName \ --hive-import --hive-table dino.$tableName \ --hive-drop-import-delims --create-hive-table \ --hive-overwrite \ --null-non-string '\\N' \ --null-string '\\N' \ --fields-terminated-by '\t' \ --lines-terminated-by '\n' \ --m 1 #判断sqoop执行结果,etl_status为0表示失败,为1表示成功,由于这里无法获取到错误信息,只能以"errors"代替 if [ $? -ne 0 ];then etl_status=0 etl_error="errors" echo "执行失败" >> $logfile else etl_status=1 #etl_error="\\N" echo "执行成功" >> $logfile fi #日志写入到hive中,参数顺序对应说明 #table_name=$1 #etl_date=$2 #etl_status=$3 #start_time=$4 #etl_errors=$5 #write audit of etl's recored into hive's table sh /home/9003547/sqooppath/hive_etl_record.sh "$table" "$d_date" "$etl_status" "$start_date" "$etl_errors"
以上就是完整的脚本说明
这个东西的调度方式可以采用linux自带的crontab,但是如果有条件最好还是弄一个可视化图形进行操作,包括作业的顺序、重跑等,在系统后台维护各个作业的依赖关系,这样对所有的作业维护才是最轻松的,具体的话这个设计到web或者客户端开发,需要更专业的同事实现
可能的优化
这个脚本只是按照最简单的方式去处理,如果而已尝试着用python直接将sqoop语句写进去会更好,这样对日志输出又或者配置文件维护都会更方便一点,完善的地方包括但不限于以下内容1、明细日志输出到文件
2、sqoop脚本错误结果获取存入库中,这样每天不但不用翻明细的日志文件,也可以直接在hive中select出来
3、如果可以将现在写在hive中的日志记录写入RDBMS,速度快一点也不需要在export回去,最直接的就是写入mysql,因为hive的元数据也存储在这里呀,现成的数据库可以使用。
内容很简单,分享出来一起学习,如果有做改进,我会第一时间修改本文以提供最新的进展,如果看到的朋友有建议也请留言交流
相关文章推荐
- 利用Sqoop从MySQL数据源向Hive中导入数据
- 利用sqoop将hive数据导入导出数据到mysql
- 利用sqoop1将mysql数据导入至hive多分区
- Centos 利用sqoop从sqlserver导入数据到HDFS或Hive
- 利用sqoop从mysql向多分区hive表中导入数据
- 利用sqoop 将 hive/hdfs数据 导入 Oracle中
- 利用sqoop将hive数据导入导出数据到mysql
- 利用Sqoop把Oracle数据迁移到HDFS、Hive
- 利用sqoop 将 hive/hdfs数据 导入 Oracle中
- 利用sqoop将hive数据导入导出数据到mysql
- 利用sqoop将hive和MySQL数据互导入
- 利用sqoop导出hive数据到 oracle
- 利用sqoop将hive数据导入导出数据到mysql
- 利用sqoop将hive数据导入导出数据到mysql
- 利用sqoop将hive数据导入导出数据到mysql
- 利用sqoop将hive数据导入导出数据到mysql
- 利用sqoop从sqlserver导入数据到HDFS或Hive
- 利用sqoop将hive数据导入导出数据到mysql (转)
- 利用sqoop将hive和mysql数据互导简单实验
- 利用Sqoop将MySQL数据导入Hive中