spark 1.6.1
python 2.7.11
前言
整理了一下使用spark來進行日誌清洗及數據處理的套路,這裏以pyspark爲例
pyspark的啓動任務套路
對於使用spark作爲查詢清洗工具而言,啓動spark的套路主要使用sh文件進行終端帶參數啓動,啓動後開始調用sh傳遞處理參數,並且構造好sparkconf後傳遞提交(spark-submit) python文件,當然最主要的函數邏輯都是在python的文件中處理的。對於工程類而非工具類,就稍微複雜點,而且會顯得更規範點,以下爲一個例子的套路
對於參數輸入啓動的方法主要有兩種第一種是構造啓動的sh文件,第二種是構造啓動的python文件,啓動文件的作用就是在終端執行該文件,然後輸入參數,參數會被啓動文件捕獲並傳遞
方法一:start.sh
# start.sh
read -p "Please input info as (year/month/day) and split by space:" raw_info
year=$(echo $raw_info | awk -F'/' '{print $1}')
month=$(echo $raw_info | awk -F'/' '{print $2}')
day=$(echo $raw_info | awk -F'/' '{print $3}')
echo $year
echo $month
echo $day
# 進行spark任務的提交,這裏需要注意的是提交的時候需要設置隊列等
spark-submit --driver-memory 6G --queue 自己隊列的名字 --conf "spark.scheduler.executorTaskBlacklistTime=30000" deal.py $year $month $day
方法二:start.py
# start.py
info=raw_input("Please input info as (year/month/day/):") # raw_input make input as string
year=info.split("/")[0]
month=info.split("/")[1]
day=info.split("/")[2]
print "year={year},month={month},day={day}".format(year=year,month=month,day=day)
# 進行spark任務的提交,這裏需要注意的是提交的時候需要設置隊列等
spark-submit --driver-memory 6G --queue 自己隊列的名字 --conf "spark.scheduler.executorTaskBlacklistTime=30000" deal.py year month day
從腳本中獲取外界傳入的參數後,開始執行核心的邏輯操作,這裏以pyspark爲例,新建deal.py
#deal.py
#-*-coding:utf-8-*-
import sys
from pyspark import *
from pyspark.sql import *
import time
# 核心操作計算
def func_1():
funct...
def dealfunc(sc):
rdd=sc.textFile(hdfspath).map(func_1)... # 構建rdd方式可以從hdfs上把文件加載進來處理,之後進行各種Transformation操作,作爲清洗數據的第一步
# 方法一:如果清洗完後數據量不大,完全可以加載到內存中然後當做流來處理,但是數據量非常大,那請不要作死使用collect()
for data in rdd.collect():
func...
==================
# 方法二:直接進行多次map,filter,等各種操作,凡事都可以靠函數解決,一個不夠就寫兩個,函數傳遞進去的時候就當字符串流處理就可以了
data=rdd.map(func_1).filter(func_2).reduceByKey(func_3).map(func_4)...
# 如果需要把清洗好的數據上傳hdfs,
data.repartition(5).saveAsTextFile('/user/test/restore')
# 獲取上層傳遞進來的參數
year = sys.argv[1]
month = sys.argv[2]
day = sys.argv[3]
#在pysaprk中初始化spark
sparkconf = (SparkConf().setAppName("Wifi-God wants to see air quality").set("spark.akka.frameSize","2000"))
sc = (conf=sparkconf)
# 強烈建議使用try,finally來處理
try:
dealfunc(sc)
except Exceptions as ex:
print ex
finally:
sc.stop() # necessay
對於一般的任務,這樣差不多就可以結束了,然而對於日誌清洗和存儲來說,必不可少的是解壓和存儲過程,日誌的量非常多,所以即使存在hdfs上也是壓縮過的,比如文件格式是xxx.lzo樣式的,即使取cat,沒有解壓也將看不到任何有用的信息,這裏就要用到newAPIHadoopFile函數了,當然,textFile仍然可用
# 讀取
file = sc.newAPIHadoopFile(hadfspath, "com.hadoop.mapreduce.LzoTextInputFormat", "org.apache.hadoop.io.LongWritable", "org.apache.hadoop.io.Text")
# 用法見官方文檔
# 上傳至hdfs,使用saveAsTextFile
# repartition的作用是重新設定rdd分區數(關係到存入hdfs)
rdd_dealed.repartition(5).saveAsTextFile('/user/test/rdd_restore')
# 存在hdfs上rdd_restore文件夾中有幾個片段就是有幾個區
# $ hadoop fs -ls /user/test/rdd_restore
# Found 5 items
# -rw-r--r-- 3 owntest 0 2017-04-14 16:42 /user/test/rdd_restore/_SUCCESS
# drwxr-xr-x - owntest 0 2017-04-14 16:42 /user/test/rdd_restore/_temporary
# -rw-r--r-- 3 owntest 51 2017-04-14 16:42 /user/test/rdd_restore/part-00000
# -rw-r--r-- 3 owntest 150 2017-04-14 16:42 /user/rdd_restore/part-00001
# -rw-r--r-- 3 owntest 251 2017-04-14 16:42 /user/rdd_restore/part-00002
關於alias一些技巧,在終端各個目錄內都可直接啓動對應文件,工具化最方便的地方
#第一步,修改.bashrc文件,添加上以下信息,然後保存退出
$ vi ~/.bashrc
alias test='cd ~/user/test; sh start.sh' #這句話的意思是,當在終端輸入test的時候,執行的命令是先切換到user/test文件夾,然後,執行start.sh
#第二步,使配置生效,或者重新再啓動終端都可
$source ~/.bashrc
#第三步,啓動
$test
#這樣,使用別名的方法就可以再任何路徑下啓動自己對應的工具,值得注意的是,別名也不可用的太氾濫,不然不好管理