sqoop同步mysql到hive

思路:因为业务数据量较大,只需同步2018-01-01 00:00:00之后的数据。历史数据用全量同步,之后使用增量同步

一、全量同步

Sqoop脚本: sync_month.sh

#!/bin/bash

#数据库配置信息
mysql_ip='10.10.10.10:3306'
mysql_database='dataBaseName'
mysql_connect="jdbc:mysql://${mysql_ip}/${mysql_database}"
mysql_username='userName'
mysql_pwd='password'

table_name='tableName'
#需要通过hadoop fs -ls /user/hive/warehouse/ 看库是否已经存在,若不存在则先创建数据库
target_dir='/user/hive/warehouse/sync.db'
ch_column='ucid'
sp_column='account'

echo "####################### start table $table_name #############################"

start='2018-01-01 00:00:00'
end='2021-07-18 00:00:00'
tmp_date=$(date -d "$start 1 month" +'%Y-%m-%d %H:%M:%S')

t1=`date -d "$tmp_date" +%s`
t2=`date -d "$end" +%s`

while [ $t1 -le $t2 ]
do
echo "$start------------$tmp_date"
. $HOME/.bash_profile;
$SQOOP_HOME/bin/sqoop import \
"-Dorg.apache.sqoop.splitter.allow_text_splitter=true" \
--connect ${mysql_connect} \
--username ${mysql_username} \
--password ${mysql_pwd} \
--split-by ${sp_column} \
--m 1 \
--query "SELECT * FROM $table_name WHERE create_date >= \"$start\" AND create_date < \"$tmp_date\" AND \$CONDITIONS" \
--target-dir /user/hive/warehouse/accupasscn_sync.db/${table_name} \
--hive-table accupasscn_sync.${table_name} \
--hive-import \
--incremental append \
--check-column ${ch_column} \
--direct \
--null-string '\\N' \
--null-non-string '\\N' \
--hive-delims-replacement '\0D' \
--fields-terminated-by '\001'
start=$tmp_date
tmp_date=$(date -d "$tmp_date 1 month" +'%Y-%m-%d %H:%M:%S')
t1=`date -d "$tmp_date" +%s`
done

echo "####################### end table $table_name #############################"

直接放在服务器上执行,并记录执行日志:

nohup ./sync_month.sh > ./logs/sync_month.log 2>&1 &

二、增量同步

对新增、更新的数据 ,采用增量方式来同步到hive,使用crontab 来定时执行sqoop job

准备添加sqoop job脚本:sync_job.sh

#数据库配置信息
mysql_ip='10.10.10.10:3306'
mysql_database='dataBaseName'
mysql_connect="jdbc:mysql://${mysql_ip}/${mysql_database}"
mysql_username='userName'
mysql_pwd='password'

hive_database='sync'
last_time="2021-07-18 00:00:00"

#sqoop导入数据
echo "################################### start ###########################################"

table_name='tableName'
mg_key='account'
target_dir="/user/hive/warehouse/${hive_database}.db/${table_name}"
job_name="${table_name}_job"

. $HOME/.bash_profile;
$SQOOP_HOME/bin/sqoop job \
--create "$job_name" \
-- import \
--connect "$mysql_connect" \
--username "$mysql_username" \
--password-file /input/sqoop/pwd/mysql.pwd \
--query "SELECT * FROM $table_name WHERE \$CONDITIONS" \
--target-dir "$target_dir" \
--split-by "$mg_key" \
--incremental lastmodified \
--merge-key "$mg_key" \
--check-column update_date \
--last-value "$last_time" \
--m 1 \
--null-string '\\N' \
--null-non-string '\\N' \
--input-null-non-string '\\N' \
--hive-delims-replacement '\0D' \
--fields-terminated-by '\001'

echo "################################### ${job_name} had created ###########################################"

服务器上直接执行脚本。
通过sqoop命令来查看sqoop 的任务

${SQOOP_HOME} :sqoop安装路径
${SQOOP_HOME}/bin/sqoop job --list 查看所有任务列表
${SQOOP_HOME}/bin/sqoop job --show job_name 查看任务
${SQOOP_HOME}/bin/sqoop job --delete job_name 删除任务

需要注意的是 ,连接数据库的密码 ,通过--password的方式配置不行。需要通过--password-file后面跟文件路径来配置。sqoop在创建job时,规定密码文件必须存放在HDFS上,并且权限必须设置成为是400。

  • echo -n "hadoop" > mysql.pwd
  • hadoop fs -mkdir -p /input/sqoop/pwd/
  • hadoop fs -put mysql.pwd /input/sqoop/pwd/
  • hadoop fs -chmod 400 /input/sqoop/pwd/mysql.pwd //将密码设置成为仅读权限

在sqoop/conf配置目录下的sqoop-site.xml中添加如下配置:


    sqoop.metastore.client.record.password
    true
    If true, allow saved passwords in the metastore.
    

配置crontab 来定时执行sqoop job

0,30 * * * * /home/hadoop/sqoop/bin/sqoop job --exec job_name1>>/home/hadoop/mysql_sync/logs/job_name.log 2>&1

执行/sbin/service crond reload来刷新配置

需要注意的是sqoop命令中, 最好使用绝对路径来代替全局变量,因为cornd执行的时候,不会考虑你所配置的全局变量 。因为sqoop 是基于java的 ,所以需要使用到jdk环境变量 ,在crontab的最上面配上jdk的安装路径 JAVA_HOME=/usr/java/latest (通过profile文件可以查看服务器的jdk安装路径,可以直接copy过来)

验证的时候 ,可以通过${SQOOP_HOME}/bin/sqoop job --show job_name 来查看任务执行的last value 看上次执行的时间 ,可以看日志 ,来确定任务有没有成功执行。

你可能感兴趣的:(sqoop同步mysql到hive)