hadoop streaming multi-input 输入任意时间段

最近项目中需要一个时间段的数据作为输入到 Mapreduce 处理,比如时间段20190410 - 20190510 这样一个月的数据。以下是我的解决办法,可能有更好的方式,欢迎大家留言。
首先回顾一下 hadoop streaming 的通配符:

通配符 名称 匹配
* 星号 匹配0或者多个字符
问号 匹配单一字符
[ab] 字符类别 匹配{a,b} 中的一个字符
[ ^ab ] 非字符类别 匹配不是{a,b} 中的一个字符
[a-b] 字符范围 匹配一个在{a,b} 范围内的包括ab, a<=b
[ ^a-b ] 非字符范围 匹配一个不在{a,b} 范围内的包括ab, a<=b
{ a, b } 或选择 匹配包含a或b 的一个语句
\c 转义字符 匹配元字符c

在看一下 常见的 hadoop streaming 的执行脚本

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper myPythonScript_mapper.py \
    -reducer myPythonScript_reducer.py \
    -file myPythonScript_mapper.py \
    -file myPythonScript_reducer.py

这里的input 就是需要定义的输入,但是只通过上面的通配符(正则表达式不支持)我们没有办法实现输入这样一个时间的数据。
通过研究发现 -input myInputDirs 这个参数可以输入多个路径,也就是可以

-input myInputDirs_1,myInputDirs_2,myInputDirs_3,...

之间通过"," 连接不能有空格。所以抛弃原来的通配符,我们需要将所有的路径拼接然后左右 -input 的参数。
现在有另一个问题了,20190410-20180510 中间跨了一个月,虽然可以写代码确认现在是哪个月,有多少天,但是对于一个shell 执行脚本,显然太复杂了。
这个时候就要借用时间戳(Unix timestamp )来解决这个问题。一天的时间就是86400秒
脚本运行命令如下:

./get_data.sh 20190410 20190510

时间输入的格式也可以是 2019-04-10, 可以识别的时间格式挺多的,我没有深入研究。 如果只是当天也不需要详细到时分秒,默认是2019-04-10 00:00:00。
下面就是./get_data.sh 的内容

#!/bin/sh
hadoop_home=/data/home/hadoop
start_time=$1
end_time=$2
if [ ! -n "$1"] || [ ! -n "$2" ]; then
	echo "Please input para !"
else
	start_timestamp=$( date -d "$start_time" +%s)
	end_timestamp=$( date -d "$end_time" +%s)
	input=/data_of_hive_path/$start_time/part-*
	for((i=$start_timestamp+86400; i <= $end_timestamp; i+=86400))
	do 
		cur_time=$(date -d "@$i" +%Y%m%d)
		str=/data_of_hive_path/$cur_time/part-*
		input=$input','$str
	done
fi
echo $input

这样就可以获取了我们想要的input。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章