美文网首页
Sqoop实践

Sqoop实践

作者: 忘净空 | 来源:发表于2017-07-06 10:37 被阅读172次

    Crontab定时Sqoop脚本问题


    问题描述:如果上图我们的任务定时2小时一次,正常情况下任务在2小时可以执行完成,但是出现未知异常任务执行超过了2小时,所以第二个任务没有在第一个任务执行完后执行,这样可能导致执行错误。

    解决方法

    使用flock命令给脚本加锁
    • 命令格式:

        flock [-sxon] [-w timeout] lockfile [-c] command...
        flock [-sxun] [-w timeout] fd
      
    • 常用选项:
      -s, --shared :获得一个共享的锁。
      -x, --exclusive :获得一个独占的锁。
      -u, --unlock :移除一个锁,通常是不需要的,脚本执行完后会自动丢弃锁。
      -n, --nonblock :如果没有立即获得锁直接失败而不是等待。
      -w, --timeout :如果没有立即获得锁就等待指定的时间。
      -o, --close :在运行命令前关闭文件的描述符。用于如果命令产生子进程时会不受锁的管控。
      -c, --command :在shell中运行一个单独的命令。
      -h, --help :显示帮助。
      -V, --version :显示版本。

    • 测试

      //编写test.sh 脚本
      vim test.sh 
      echo "测试~~~~~~~~~~~~:"" `date '+%Y-%m-%d %H:%M:%S'`" >> test.log
      sleep 70
      
      //赋予可执行权限
      chmod 777 test.sh 
      
      //定时设置(1分钟执行一次)
      crontab -e
      */1 * * * * /usr/bin/flock -xn /home/hadoop/test.lock -c '/home/hadoop/test.sh'
      
      //观察日志
      //加锁的日志,10:30:01这个执行点没有执行
      测试~~~~~~~~~~~~: 2017-07-06 10:29:01
      测试~~~~~~~~~~~~: 2017-07-06 10:31:01
      
      //没有加锁的日志(每分钟一次)
      测试~~~~~~~~~~~~: 2017-07-06 10:33:01
      测试~~~~~~~~~~~~: 2017-07-06 10:34:01
      
      

    Crontab定时执行脚本和手动执行脚本结果不一致

    问题描述:因为CDH5.7.6的Sqoop1.4.6的bug导致使用--incremental lastmodified增量导入数据保存,所以安装了官网的Sqoop1.4.6,因为CDH中已经安装了Sqoop,所以我使用软连接来处理sqoop命令的冲突,官网的sqoop用sqoop1来替代,但是发现Crontab定时执行脚本和手动执行脚本结果不一致,表现在无法创建Sqoop job

    解决方法

    在脚本头添加 source /etc/profile(配置完环境变量后我也执行过source /etc/profile,但是不知为啥还要在脚本中执行一次)
    
    
    //创建软连接,配置环境变量
    Sqoop的安装位置:/opt/sqoop
    //创建软连接
    ln -s /opt/sqoop/bin/sqoop /opt/sqoop/bin/sqoop1
    //配置环境变量
    export PATH=$PATH:/opt/sqoop/bin/sqoop1
    //使环境变量生效
    source /etc/profile
    

    Sqoop每次执行需要输入数据库密码

    解决方法

    修改sqoop安装目录conf下的sqoop-site.xml文件,添加下面配置项(其实配置项存在,只要去掉注释就行)

      <property>
        <name>sqoop.metastore.client.record.password</name>
        <value>true</value>
        <description>If true, allow saved passwords in the metastore.
        </description>
      </property>
    

    Sqoop Job如何中如何避免明文输入密码

    • 首先我们使用hadoop credential create [alias_name] -provider [hdfs_location]命令(该命令在hadoop 2.6.0之后才有)在keystore中创建密码以及密码别名

      hadoop credential create mysql.pwd.alias -provider jceks://hdfs/user/password/mysql.pwd.jceks
      
    • 在Enter alias password后面输入我们数据库的密码。执行完后,程序在hdfs的/user/password/下创建了一个mysql.pwd.jceks文件,而且mysql.pwd.alias就是我们的密码别名。我们可以使用mysql.pwd.alias来代替我们真实的数据库密码。在执行sqoop命令时,我们可以使用--password-alias参数,参数的值就是我们刚才自己指定的密码别名

      sqoop list-databases -Dhadoop.security.credential.provider.path=jceks://hdfs/user/password/mysql.pwd.jceks --connect jdbc:mysql://hadoop01 --username root --password-alias mysql.pwd.alias
      

    sqoop提供数据库密码的4种方式

    MySQL到Hive数据类转换

    Hive表结构中的数据类型与MySQL对应列有如下关系

    MySQL(bigint) --> Hive(bigint) 
    MySQL(tinyint) --> Hive(tinyint) 
    MySQL(int) --> Hive(int) 
    MySQL(double) --> Hive(double) 
    MySQL(bit) --> Hive(boolean) 
    MySQL(varchar) --> Hive(string) 
    MySQL(decimal) --> Hive(double) 
    MySQL(date/timestamp) --> Hive(string)
    

    可以看出MySQL的decimal类型变成了Hive中的double类型。此时需要在导入时通过--map-column-hive 作出映射关系指定,如下所示:

    sqoop import --connect jdbc:mysql://hadoop01/test --username root --password 123 --query "SELECT * FROM xi WHERE date>='2015-09-16' AND date<='2015-10-01' AND $CONDITIONS" --split-by date --hive-import -m 5 --map-column-hive cost="DECIMAL",date="DATE" --delete-target-dir -m 1 --hive-table student

    Sqoop增量导入数据数据重复问题

    问题描述:线上使用Sqoop增量抽取MySQL数据到Hive,但是发现40W条完全一样的数据,通过时间排查那个时间端集群很不稳地,最终查找资料得到原因。

    原因

    Map Task 执行失败, 那么该 Map 任务会转移到另外一个节点执行重新运行,这时候之前导入的数据又要重新导入一份,造成数据重复导入。 因为 Map Task 没有回滚策略,一旦运行失败,已经导入数据库中的数据就无法恢复。

    相关文章

      网友评论

          本文标题:Sqoop实践

          本文链接:https://www.haomeiwen.com/subject/rwjqfxtx.html