手工搭建 Spark 數據分析平台
我們的 應用 在線上也已經運行了快一年了,時常想分析一下過去積累的數據,比如用戶的類型,訪問路徑,轉化漏斗等等。 相對比較好做的也就是一點簡單的記錄在mysql中的數據。
對於用戶運營同事想要的基於uv的留存率等數據,之前的做法:
- 手動備份線上nginx log到一個地方
- 解壓日誌 (10g+)
- awk提取需要的信息(1g+)
- sort && unique得到基於日期和ip的訪問日誌 (200M)
- 同步到內網
- 寫個ruby腳本,解析uv, 計算留存率等,得到一個csv
- 發給運營同事
所以,每個月初,出上月月報的時候,挺痛苦的,幫各個角色出各種數據。
窮極思變
累的久了,自然想改變一下。於是自動同步線上日誌(rsync),自動解壓,解析,去重,生成uv. 每個月需要報表的時候,手動去執行一下腳本就可以了。
接著我們又想去計算轉化漏斗,計算每個平台訪問頻率高的頁面,計算演出訪問的關聯性。腳本已經跑不動了。
又一次變化
sparkcomes to the resuce.
spark 的好處
自動的任務分解
我理解,其實和functional programming里的概念很類似。haskell也可以在編譯時指定開啟多線程,就能自動分解任務。 基於的前提都是理解操作間的關聯與影響。知道哪些操作是可以先分解再合併的。於是,寫的時候當做單線程去寫,執行的時候幫你優化。
自動的中間結果緩存
同樣是為了效率的優化,對於撰寫腳本計算的人屏蔽了這一層優化的考慮,降低負擔.
可以直接本地執行,榨乾機器的CPU
任務示例
比如想知道點了一個演出之後,又點了另一個演出的比例。
# visitsframe為nginx日誌解析之後的dataframe# normalVisits為過濾了爬蟲的訪問之後的normalVisits = (visitsFrame.filter(visitsFrame[res] == True) .filter(ua not like "%pider%") .filter(ua != "Googlebot"))#relatedVisits 就是當前訪問為某個演出頁且refer也是某個演出頁的記錄,按天聚合後的數量relatedVistis = normalVisits.filter("host = www.piaoniu.com and url like /activity/% and refer like %www.piaoniu.com/activity/%").groupBy(day).count()
在寫這段腳本的時候,不關心如何計算,怎麼樣分解任務, 只負責描述清楚要達成的目標。 而spark負責很快的執行完。
當前的使用方式
- 安裝sparkdocker安裝jupyter/all-spark-notebook
- 數據同步 通過crontab的形式,將線上日誌導入到內網伺服器的制定位置
- 分析腳本開發 之前安裝的docker image, 8888埠會啟動一個ipython的server, 通過該埠使用 ipython 連接到 spark 的 shell, 通過python 來開發分析腳本
- 結果分析
- 直接在ipython的notebook中使用pandas看生成的圖片, 比如這樣的代碼和這樣的曲線
normalVisits.groupby(day).agg(func.countDistinct(ip)).toPandas().set_index(day).plot()
- 保存結果到csv後導入回mysql做報表展示
於是,生活又一次幸福了很多。
推薦閱讀:
※Spark Streaming:大規模流式數據處理的新貴
※在Spark集群中,集群的節點個數、RDD分區個數、?cpu內核個數三者與並行度的關係??
※Spark比Hadoop的優勢有這麼大嗎?
※MapReduce過程中,如果Map之後每個Key對應Value的數量不平衡會不會影響效率?
※Spark SQL到底支持什麼SQL語句?
TAG:Spark |