摘要:2017年,ofo向市場投入了一千多萬輛單車,這些單車的投放、運營和調度須要大量數據的支持。本文將從ofo選擇MaxCompute的理由以及數據完整性、任務調度、Proxy服務三個方面的實戰應用,分享ofo 在MaxCompute的大數據開發之路。python
演講嘉賓簡介:龍利民,ofo大數據,大數據副總監。正則表達式
PPT材料下載地址:https://yq.aliyun.com/downloa...sql
視頻地址:https://edu.aliyun.com/lesson...shell
產品地址:https://www.aliyun.com/produc...數據庫
本次分享主要包括如下內容:安全
1、ofo爲何選擇MaxCompute 服務器
2、實戰應用併發
1、 ofo爲何選擇MaxCompute框架
首先,回顧一下2016年。當時,ofo的數據分析師還在使用Excel+MySQL這樣原始的方式來製做報表。在這樣的背景下,要求一名研發人員利用兩週的時間開發出數據平臺。less
那麼,如何完成這個任務呢?首先,分析一個數據平臺主要包括哪些部分。其中,首要問題是集羣(大數據下僅利用MySQL常常出現查掛的狀況)。有了集羣以後,須要進行數據的裝載,這就涉及到ETL。對外界來講,他們更關心的是數據自己,所以還須要BI平臺,這部分也是須要大量投入的。有了BI平臺以後,就能夠在平臺上製做報表,且涉及到報表的調度。
其中,最首要的問題仍是集羣,是自建集羣仍是使用雲服務?在進行這一選擇時,主要從如下六個維度進行考量。
· 存儲:事實上,存儲也決定了性能。阿里雲中就使用了ORC,它是一種列式存儲。而MaxCompute使用的也是列式存儲。
· 計算:計算性能的要求就是減小耗時。好比,一句SQL語句執行二三十分鐘,這樣的計算性能顯然是不可接受的。
· 費用:費用這一因素一般是不須要考慮的。對於通常小公司而言,MaxCompute按量後付費是最好的選擇。
· 穩定性:穩定性須要長期使用才能得以體現,所以這裏不作過度強調。
· UDF:共享單車的特性決定了在計算中涉及大量「點」的計算。這裏必須用到UDF函數,所以,若是不支持UDF,則不歸入選擇範圍。
· 文檔:MaxCompute的文檔寫的很是的詳細。
綜合了多方面的因素,咱們最終選擇了MaxCompute。那麼,在使用了一年半後,其結果怎麼樣呢?下面簡單介紹幾個事例。
· 實錘一:某同事在ofo工做一年寫的SQL,超過前5年的總和;
· 實錘二:對比自建EMR集羣和MaxCompute:集羣成本 2 vs 1,運維成本 6 vs 1;
· 實錘三:新孵化項目,業務運轉良好的前提下,日費用不到50元。
2、 實戰應用
上面介紹的是選擇MaxCompute的緣由,下面介紹一些在使用過程當中的經驗。
1. 數據完整性:數據不許的問題是數據分析師最擔憂的問題。但更使人擔憂的是,看到數據時沒法得知它到底準不許!形成這個問題的一個重要緣由就是數據不完整。好比,昨天共產生了100萬條數據,但只上傳了99萬條。所以,必定要保證數據的完整性。
· 數據完整性的定義:程序計算的時候確保T+1天的數據是完整的,非割裂的,即原子的;
· 不注重數據完整性的作法:經過時間來約定計算,數據間的計算依賴也是基於時間;
不注重數據完整性的後果:很難發現數據的錯誤,須要人力來排查問題;若是不在邏輯上解決掉,會重複出現。
指望中的數據完整性只存在兩種狀況,要麼有數據,且必定是對的,要麼就沒有數據。
在實際應用中,如何解決數據完整性的問題呢?解決方案主要包括如下幾點。
· 用命令的 tunnel upload上傳數據,不用SDK;(利用tunnel upload上傳數據時,對文件來講,它是具備原子性的,不會存在文件只上傳了一半的狀況。而SDK是行級上傳的。)
· 維護數據標記。(當數據被上傳到MaxCompute以後要對數據進行標記,好比當天的數據是否傳完,後續的計算也會基於這一標記進行,不會對未ready的數據進行計算。)
作到這幾點後,在實際應用中起到了很是顯著的效果:沒有出現一塊兒,由於數據不完整致使的數據不許的狀況。
在程序上保證了數據完整性後,還要思考另外一個問題:自發查詢的數據完整性如何解決。好比在HUE中查詢時,用戶不知道數據是不是完整的。關於解決方案,這裏先埋個伏筆,後面會進行詳細介紹。
2. 任務調度:天天有近千張報表須要調度計算,報表間的關係會存在相互依賴的問題。如何有效的協做,是任務調度須要解決的問題。
任務調度主要分爲下面三種。
中間表、寬表:咱們將最原始的數據表稱爲原表,好比天天產生的訂單表、優惠券表等。但在實際查詢中須要將這些表進行關聯。好比,想要查詢某個訂單中的優惠券信息,若是不創建寬表則每次查詢都須要寫join語句。
計算報表:計算後用於統計的表。
結果寬表:計算報表會存入數據庫,這樣就會致使數據庫中存在很是大量的表。創建結果寬表以便於分析師找到想要分析的指標。
下圖展現了對任務調度的指望。
第一,併發,多機多進程,以減小進程掛掉服務器掛掉帶來的影響。
第二,協做,要求能創建依賴關係。好比先計算完某張表後再計算依賴它的表。
第三,可監控,當出現故障時能及時報警。
第四,可擴展性,在任務調度中寫的語句不只是SQL,也有多是python腳本或shell等。第五,資源隔離,在資源調度中要注意,不能讓大的SQL把資源所有佔用,一旦資源被所有佔用,整個計算都會卡住。
下面介紹在實際應用中使用的任務調度技術框架。數據庫中存儲了天天要計算的任務,生產者從數據庫中取數據,並覈實數據完整性和依賴關係,覈實狀態是否爲ready,覈實完成後進入隊列,狀態變爲waiting,消費者從隊列中獲取數據並將狀態改成running,最後將狀態寫回數據庫。在這一過程當中,每一個任務都須要將其心跳的狀態同步到數據庫中,好比某個生產者掛掉以後,若是沒有心跳機制,那麼它獲取的任務將有可能永遠在waiting狀態。
任務調度資源優化和隔離
MaxCompute主要包括兩種使用方式:預付費和後付費。預付費,有一個單獨的資源池,其中的資源可以使用但有上限,而且已經提早付費。後付費,有一個共享的資源池,你們須要搶佔資源。
在實際應用中包括如下規則:
· 大任務使用後付費
· 優先級高任務使用預付費
· 優先把預付費填滿
· 預付費隊列滿了,使用後付費
3. Proxy服務
下圖展現了Proxy endpoint能夠解決的問題。
· 解決重複執行:好比兩我的重複執行了同樣的SQL語句,且數據沒有更新。那麼第二次執行的時候,會直接返回上一次的結果。這樣,第二次查詢的過程不會佔用MaxCompute的資源。這樣,就能夠減小執行耗時,提高體驗。同時,下降資源開銷,節約成本。
· 安全控制:再也不對外暴露key,構建業務自由帳號,不一樣的人會擁有不一樣的帳號。同時,構建內網的IP白名單。MaxCompute的白名單是針對外網的,而在內網中也會有不少臺機器,若是全部內網機器都擁有訪問權限,也是不安全的。
· 方便統計:SQL開銷統計到人,而且也能夠方便地按部分來計費。
那麼,在實際應用中應該如何作呢?整體來說分爲下圖兩種方案。
方案一:代理轉發。收到數據後轉發到MaxCompute而後再經過response返回。
方案二:服務端在調用SDK。利用MaxCompute SDK,每次得到請求後,解析請求中的參數,再返回給SDK。
因爲方案二的工做量較大,咱們選擇了方案一,它具備如下優勢。
· 開發工做量小
· Pyodps升級也不影響
· 對於潛在的API接口具備兼容性
· 只實現咱們自由帳號體系
· ip白名單控制
下圖展現了其核心代碼。
下面簡單介紹其中的部分代碼。
對全部url進行規則判斷,正則表達式中寫的越多就會越優先命中。
主要是用於解決SQL代碼重複執行的問題。
主要解決命令行的問題。MaxCompute主要分爲兩個入口,一個是SDK,另外一個是命令行。SDK是比較易於實現的。而命令行中會本身生成taskname,每一次請求都會check其taskname。
另外,構建安全控制時,必定要有本身的簽名。不能使用客戶端上傳的簽名,咱們只能使用客戶端上傳的SSID的前綴。
上面的代碼中實現了整體的流程,但具體實現過程當中還存在一些問題。
難點1:如何確保優化後結果和實際執行結果一致?
· 從SQL中提取表信息和分區信息
· 在必定延時內,獲取表數據的更新信息
解決方案:
· 構建SQL語法樹,提取出表,目前還沒解決分區
· 另起新進程,捕獲表和分區的最後一次修改時間
難點2:命令行返回的適配,爲何呢?
· task name 由客戶端生成,例如:console_query_task_152696399361
· taskstatus和instanceprogress都會去校對服務端返回的信息中的task name, 一旦和客戶端的task name不一致,會出現:FAILED: task status unknown
解決方案:客戶端會從server的全部task name中查找到和本身同樣的task name。
· 保存歷史全部請求的task name
· 返回全部的task name
經過Proxy服務,取得了不錯的效果:
· 提高了體驗,具體例子:第一次sql執行耗時的70秒,再次執行不僅須要0.9秒;
· 減低了費用,總體費用減低了一半;
· 提高了安全的可控性,不暴露sercret_key給同事;
· 每一個業務分配1個帳號,能方便統計費用;
· 解決了前面提到的數據完整性問題。
目前,ofo使用的ODPS Proxy,任務調度和數據處理核心代碼都已經開源。
文章做者:隱林
本文爲雲棲社區原創內容,未經容許不得轉載。