Hadoop执行分布式Process
要把N个超级大表导入HBase,N是按月来分的,表:亿+的行数,100+的字段。测试过sqoop,JDBC,性能都不满意,对任务失败重做也很麻烦,HBase的批量导出还靠谱点,但这样导入HBase有几个麻烦的地方:
1.所以的表都是没主键的,HBase的rowkey就要了亲命了,只能在导出的时候用SQL拼个了。
2.HBase的importtsv只支持用符号分割的文本方式导入。
3.预先的region切分
以文本方式导出,sqluldr2是我用过最有效率的工具(感谢Fangxin Lou)。问题sqluldr2是底层工具,能不能相互结合提高性能呢?其实是可以的。
1.java API 里有个Process类,它可以去调用sqluldr2。
2.Hadoop的map-reduce可以让每个节点都去运行sqluldr2,然后转化成HBase格式进行put,参考Hbase的importtsv。
要注意的:
1.map的运行是依赖于input,比如你想要3map-task,但你的input在第一个task的时候就被读完了,那抱歉剩下的2个task 除了写日志什么都不会做(然后还会告诉你运行的相当成功...>_<)。
2.sqluldr2不导出重复数据,用SQL分割数据,可以先查下count,但map是不同机器的JVM运行的,我的解决办法是在 map-reduce 执行前,通过其他程序预先在HDFS写好分割文件,然后通过实现InputFormat,InputSplit每一行对应一个task。
3.使用合适的hadoop调度器保证map-task平均分摊到每个节点。
4.Process是用InputStream来交互的。
5.mapred.task.timeout,默认是10分钟,建议设置大点,mapred.map.tasks.speculative.execution最好设置为false。