[英]parallel query to spark with sqlcontext
我們正在嘗試在EMR中運行ETL。 S3中有大約2000億個事件,即gzip json行。 它們總共約有30個文件。 我正在使用pyspark。
這是代碼,
def value_to_list(columns):
def value_map(values):
data = []
for val in values:
d = val.asDict()
data.append([d[column] for column in columns])
return data
return value_map
def main():
sc = SparkContext()
sql_context = SQLContenxt(sc)
all_events = SQLContenxt(sc).read.json("s3n://...", schema=StructType(fields), timestampFormat="yyyy-MM-dd HH:mm:ss")
all_events.registerTempTable('allevents')
for event_type in event_types:
process_event(sc, event_type, "allevents")
def process_event(sparkcontext, etype, tablename):
query = "select app_id, source, type, {time_cols}, count(*) as total " \
"from {table} where type = '{event_type}' " \
"group by app_id, source, type, {time_cols}"
time_cols_spec = [('hour', 'day', 'month', 'year'),
('day', 'month', 'year'),
('month', 'year'),
('year')]
for time_cols in time_cols_spec:
final_query = query.format(time_cols=", ".join(time_cols),
table=tablename,
event_type=etype)
dataframe = sql_context.sql(final_query)
dataframe.rdd.groupBy(lambda r: r['app_id'])\
.mapValues(value_to_list(['source'] + time_cols))\
.saveAsTextFile("s3n://...")
因此,我們大約有30種類型的事件,對於每個事件,我將按小時,日,月和年的4種組合進行匯總。 因此,每個查詢4個。 我們總共有大約2000M個事件。
我正在繼續運行
m3.2xlarge
問題是,最后的保存要花很長時間。 上次我查詢時花了14個小時進行了2次組合和一個事件:(
我知道我不會並行進行。 循環是順序的。 並且有2個循環。 但是我希望rdd,groupBy
和mapValues
能夠並行運行。 當我看到事件時間軸時,我看到它的saveAsTextFile
占用了99%的時間。 可能是因為火花延遲執行。
我需要使此過程並行且快速。 我怎樣才能做到這一點?
您可以應用4種主要的優化方法:
您正在對未針對查詢進行優化的純json文件執行聚合。 將它們重寫為鑲木地板,按事件類型重新分區並存儲在S3上-它們將占用更少的空間,並且您的應用程序將獲得不錯的速度提升。
增加並行度。 在這種功能強大的VM上不需要驅動程序(主機),而是生成一個較小的實例(例如m3.medium
),並使用所有3個大型實例供工作者使用。
用Dataframe替換RDD API調用: .rdd.groupBy().mapValues()
可以替換為.groupBy(dataframe.app_id).agg(collect_list())
然后進行一些映射。
您可以對(小時,日,月,年)數據集的原始數據執行查詢,然后使用此聚合對給定事件進行所有剩余查詢的查詢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.