共计 1786 个字符,预计需要花费 5 分钟才能阅读完成。
Sqoop 本身的容错依赖于 Hadoop,这里我们 focus 在 Sqoop 传输任务失败的处理,确切的说,focus 在 Sqoop 如何解决传输任务失败引发的数据一致性问题
对于一个传输任务,将数据从 A 传输到 B,如果这个传输任务失败,A 和 B 的状态,都应该和传输开始之前是一致的。
Sqoop 将一个传输作业生成一个 mapreduce job,一个 job 有多个并行执行传输作业的 mapreduce task 在和外部数据库做数据传输,然后,有很多原因可以导致个别 task fail,eg:
1. 违反数据库约束
2. 数据库连接丢失
3. 由于分隔符等原因,传输的列数和表的列数不一致
4. Hadoop 机器硬件问题
任何一个 task 由于上述问题 fail,会导致整个传输 job fail,而这可能会导致数据出现一致性问题!
一个传输任务,由多个 task 并行执行,每个 task 本身是一个 transaction,当这个 task fail,这个 transaction 会 roll back,但其他的 transaction 不会 roll back,这就会导致非常严重的脏数据问题,数据部分导入,部分缺失,怎么办???
对于 Sqoop Import 任务,由于 Hadoop CleanUp Task 的存在,这个问题不存在
Sqoop Export任务则提供了一个“中间表”的解决办法
先将数据写入到中间表,写入中间表成功,在一个 transaction 中将中间表的数据写入目标表
–staging-table <staging-table-name> 中间表
–clear-staging-table 任务开始前,清空中间表
eg:
./sqoop export –connect jdbc:mysql://127.0.0.1/test –table employee –staging-table employee_tmp –clear-staging-table -username root -password 123456 –export-dir hdfs://localhost:9000/user/hive/warehouse/employee
传输过程中数据暂存在 employee_tmp 中,最终 employee_tmp 的数据将被 move 到 employee
中间表的思路不错,但带来一个问题,如果要导入一份数据到数据库,需要建一个“伴身表”
如果传输工具需要通用化,这个建“伴身表”的操作就需要集成到整个传输工具中,而“建表”工作外放,DBA 会是一个很大的阻力
总结:
对于一个传输工具 / 平台,传输任务失败不可怕,可怕的地方在于“脏数据”如何处理,3 种思路:
1. 临时表:使用临时表缓存数据,然后在一个 transaction 中将临时表的数据 move 到目的表
2. 自定义回滚:通过用户自定义的语句 / 方法,在任务失败后,执行清数据操作
3. 传输任务的幂等性:如果一个任务失败了,产生了脏数据,解决问题后,再跑一次任务,能够最终正确,例如 hive 写入使用 INSERT OVERWRITE
相关阅读:
通过 Sqoop 实现 Mysql / Oracle 与 HDFS / Hbase 互导数据 http://www.linuxidc.com/Linux/2013-06/85817.htm
[Hadoop] Sqoop 安装过程详解 http://www.linuxidc.com/Linux/2013-05/84082.htm
用 Sqoop 进行 MySQL 和 HDFS 系统间的数据互导 http://www.linuxidc.com/Linux/2013-04/83447.htm
Hadoop Oozie 学习笔记 Oozie 不支持 Sqoop 问题解决 http://www.linuxidc.com/Linux/2012-08/67027.htm
Hadoop 生态系统搭建(hadoop hive hbase zookeeper oozie Sqoop)http://www.linuxidc.com/Linux/2012-03/55721.htm
Hadoop 学习全程记录——使用 Sqoop 将 MySQL 中数据导入到 Hive 中 http://www.linuxidc.com/Linux/2012-01/51993.htm
更多 Hadoop 相关信息见Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13