配置環境
環境配置這裏就不再多講,只研究執行效率的對比
- spark
- hadoop
執行模式
假設一個查詢host出數量的sql是這樣:
select host,count(distinct c.mobile) as mobile_num from xml.my_goods d
right join ( select b.xmsec as mobile from(
select mobile_id from xll.xf_shenzhen where dt = '2018-08-31') a
left join zww.nami b on a.mobile_id = b.mobile_id
where b.money is not null ) c on upper(d.mobile) = upper(c.mobile)
where dt >= '20180827' and c.mobile is not null
group by host
hive模式
直接把上面的sql放到hue的hive工作臺中執行即可
pyspark模式
共三個文件:
- run.sh:執行文件,內容是一個執行py腳本的命令
spark2-submit --master local[*] spark_test.py
- spark_test.py:pyspark腳本,作用是執行sql,並把結果保存到hive上
import datetime
import sql_conf as xml
from pyspark import SparkConf,SparkContext
from pyspark.sql import HiveContext
filename='/user/liuxunming/spark_result_'+datetime.datetime.now().strftime('%Y%m%d%H%M%S')
conf = SparkConf()
conf.setAppName('url rate')
sc = SparkContext(conf=conf)
hc = HiveContext(sc)
url_table = hc.sql(xml.first_sql).repartition(1).write.csv(filename)
sc.stop()
- sql_conf.py:sql配置文件,裏面可以配置n條sql語句,要注意的是每條sql前後必須用三個單引號,這是規定的格式。
first_sql='''select host,count(distinct c.mobile) as mobile_num from xml.my_goods d
right join ( select b.xmsec as mobile from(
select mobile_id from xll.xf_shenzhen where dt = '2018-08-31') a
left join zww.nami b on a.mobile_id = b.mobile_id
where b.money is not null ) c on upper(d.mobile) = upper(c.mobile)
where dt >= '20180827' and c.mobile is not null
group by host'''
secend_sql='''select name from liuxunming.catch_product'''
最後直接執行run.sh腳本即可
./run.sh
最終結果
hive模式
直接在hue平臺hive界面上輸入sql,執行耗時20min22s
pyspark模式
可以看到執行耗時爲4min,是普通的hive模式耗時的五分之一
錯誤解決
錯誤一:字節編碼
SyntaxError: Non-ASCII character '\xe8' in file /home/liuxunming/url_rate/sql_conf.py on line 14, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
在sql_conf.py第一行加上配置
另外sql傳參中有中文的時候需要添加一個編碼的頭
# -*- coding: utf-8 -*-
錯誤二:傳遞參數
string.format
關鍵字模式
‘select * from run where dt <= {today} and dt >{yesterday}’.format(today='20180901',yesterday='20180831')
上面這種方式可能有問題,使用下面這種位置模式
‘select * from run where dt <= {0} and dt >{1}’.format('20180901','20180831')
事實證明這樣傳參也不行
最後的解決辦法就是在sql傳參的花括號前後添加單引號
'{}'
後續
傳參以後,可以把參數設置成每天的日期,然後把結果直接保存到hive表中,然後再通過sqoop把hive數據導入到mysql中,最後再調用linux的crontab定時器,就能實現一個自動化