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。

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