對于operation部門而言,實時性很重要:
目前時間點,全球有多少量車在運作?有多少量車在空駛?
最近10分鐘内,有多少uberx(類似于滴滴中的商務專車)在sf出現,熱點地區在哪裡?
每個區域的平均行駛時間、以及其他名額分别是多少?
作者給出了一個示意圖,我們可以解讀下:
右側是一個灣區的地圖,通過蜂窩狀六邊形把坐标劃分若幹區域,紅色就代表車的密集程度
左側是該區域在過去n分鐘内各項名額的變化情況,例如平均的形式距離,接單率,平均客單價等
通過篩選時間段、名額(metric)等,可以全方面了解營運狀況

這個圖表讓我相當了之前用treemap來監控叢集使用率的場景,如出一轍。
左側通過heatmap顯示各個機架上的不同時間段上metric變化情況
右側則是各名額在時間段上分布的場景
隻不過在機器運維的portal上顯示的是,隻不過我們面對的是叢集,uber面對的是車與地圖:)
例子:
有多少個司機在最近10分鐘内取消了3次接單以上?
如果發現後,會通過聊天軟體與司機對話
在什麼位置供大于求,什麼位置求大于供:
黃色的點代表需求
藍色的店代表供應
地理位置函數,一般用得比較多的是geohash,通過切分空間的方法把二維坐标,轉化成一維的數字。兩個區間的比較查詢,就演變成一個一維的比較函數。
uber的做法正好相反,将坐标轉化成一個特定的區域,通過六邊形的辦法來逼近真實的位置。使用六邊形有這樣幾個好處:
友善檢索、查詢、渲染
容易找到周圍相鄰的鄰居
每個區域大小相同,形狀相同
時間、空間、車輛狀态、地理位置等組合會非常大
時間代表某一個時刻
空間在時間點上車的位置(例如la,sf)
汽車的類型
狀态(運作中,接單中,已接單出發地中等)
為了減少空間的規模:在地理位置、時間兩個次元做了“取整”處理。通過六邊形區域取整了地裡位置,通過分鐘級采樣減少了其他狀态,一天的資料量為
原始的資料為:
車的種類、狀态非常多、是以查詢場景是面向多元資料的。
需要支援heatmap,top k, histogram,count,avg,sum,percentage等計算函數
巨大資料量:
每秒百萬級事件産生
每個事件中有20+field
多種資料源
司機端事件
乘客端事件
分為5個部分:
日志、事件資料來源架構 - kafka
資料清洗與處理,前置處理 - samza
存儲系統 - elastic search
資料讀取,後置處理 - 自己開發的架構
查詢與建構與查詢 - 自己建構
應用層 - web
這個slides裡面沒有提到uber架構,google上找了一些相關的材料,整體架構如下:
資料來源有:
rider app
driver app
api/service(服務端)
dispatch (gps 運作資料)
mapping & logistic
日志、事件采集上在kafka層包了restful api,提供java、python、go、nodejs的sdk:
主要有:
transformation(坐标轉化):gps坐标是二維的,為了能夠根據城市和地域查詢,轉化成更離散化的資料:zipcode、hexagon(六邊形坐标)、城市等。 (lat, long) -> (zipcode, hexagon, s2)
pre-aggregation:将一分鐘資料歸并成1分鐘取整
join multiple stream:例如driver status、rider status進行合并
sessionization:将乘客的狀态進行串聯
以上是一個etl任務,每隔10分鐘執行一次,既從kafka中獲得資料判斷有問題的司機清單
通過這樣的架構,支援營運人員能夠在es中清晰、索引的資料,獲得實時分析能力:
同時由于在es上層包裝query機制,也支援稍微複雜一些的離線查詢。es存儲本身不是很好的離線方式,但對于離線查詢頻率不多的場景,也是夠用的:
最終使用了lamdba架構,資料分别走一遍實時,離線。看起來比較浪費,但有幾個考慮:
spark + s3 for batch processing
會有補資料的需求,通過實時計算并不一定能滿足,比如通過eventtime進行計算,并非kafka中到服務端的時間
不同的存儲解決不同目的
samza的問題:
不能動态擴充
部署較為不便
對于資料營運團隊而言,重要的是實時性、另外就是大規模、準實時muti-dimension olap能力,特别是面對大量資料的場景下,如何在分鐘級延時中獲得篩選的資料與需求。這也是elk這樣技術方案受歡迎的原因。
對于地理位置類服務,資料預處理比較重要,例如根據ip獲得省市範圍,營運商等。根據gps經緯度獲得國家,城市,郵政編碼等資訊。根據位址資訊獲得坐标等。這些坐标轉換有2類做法,在寫入前通過flume等插件計算,帶來的問題是規模、并發不是很理想。第二種處理方法就是通過kafka這樣管道讀取,在下遊進行計算與消費。在日志落到存儲系統前,适當的清晰與join是必要的。
沒有一種存儲引擎是萬能,需要根據自己的需求來定制。es提供的索引、列存儲等能力還是非常适合對于事件類資料的存儲與查詢。目前最現實的做法還是資料收集一份,同時投遞到多個系統中。
資料在寫入存儲前需要清洗,否則事後會帶來非常大的代價。