阿裡雲自研pb級nosql資料庫tablestore近期釋出了新功能stream,也就是增量通道,可以讓使用者實時的擷取資料庫中的增删改操作。很多使用tablestore的使用者會定期把資料導入各類計算平台做資料的離線分析,以前的做法是使用datax或者使用tablestore的sdk定期拉取資料。之前我們隻能采用全量拉取的辦法,定期的全量拉取勢必會帶來很多不必要的開銷,并且也失去了新增資料實時處理的可能。那有了stream增量通道後,之前的這些痛點都會被迎刃而解。
stream功能和其他表格存儲的很多功能一樣,是使用者表的一個屬性。使用者在建立表的時候可以指定是否開啟stream功能。使用者也可以通過updatetable操作在後續需要使用stream的時候開啟。當使用者開啟stream後,使用者的修改記錄在生命周期内(周期長短由使用者開啟stream的時候指定,目前預設最大是一天,如有更長周期需要可以在官網提工單)會被一直保留。
除了表操作以外,stream的api具體有以下:
在這裡,我們假設你使用如下的表結構存儲你的海量軌迹資料,
主鍵順序
名稱
類型
值
備注
1
partition_key
string
md5(user_id)前四位
為了負載均衡
2
user_id
string/int
使用者id
可以是字元串也可以是長整型數字
3
task_id
此次軌迹圖的id
可以使字元串也可以是長整型數字
4
timestamp
int
時間戳
使用長整型,64位,足夠儲存毫秒級别的時間戳
假如你有原始資料如下:
在表格存儲中存儲的是(11列);
part_key
longitude
latitude
brand
speed
wind_speed
temperature
distance
04fc
1495246210
120.1516525097
30.2583277934
bmw
25
20
8000
當使用者的位置不斷發生變化,我們會産生一系列類似上面的軌迹資料,例如我們的粒度可以是10秒一個軌迹點。這樣在一段時間内,我們可以積累海量的軌迹資料。那對于業務方,往往要做一些營運分析。
分析話題1:統計過去10分鐘内是否有一個區域有駕駛熱點,會帶來交通擁堵。發現潛在擁堵點後,提前做一些車流疏散。
分析話題2:又或者我們希望在晚飯時間點,統計一下來某個商圈吃飯的客戶都是從哪些地方開車過來的,日後可以在輻射區域内做一些精準推廣。
這類問題的共同點是需要在這張軌迹表中擷取一個時間段内新寫入的資料,針對我們的表結構設計,如果沒有增量通道的時候,我們能做的就是拿到所有的使用者id和taskid進行時間段内的getrange讀,這樣如果同時的軌迹使用者較多,會帶來大量的getrange并發通路,而且我們還需要一張額外的表記錄使用者和軌迹id的關系。如果我們修改表結構,把時間作為第一主鍵,又會帶來嚴重的資料寫入尾部熱點,資料分布不均勻等問題。
那麼我們的架構就由以前的
加上大量的range讀變為了下圖的基于增量擷取:
當你使用我們的stream api讀取增量資料的時候上面的資料會以下面的形式傳回,我們以go sdk為例傳回如下格式的stream record。
我們可以發現,表格的一次操作對應stream的一條記錄,記錄中會涵蓋這次操作的類型,操作的主鍵以及修改列的内容。有了這些資料我們可以友善做以下事情:
将資料做清洗寫入另一張tablestore表
将資料寫入流計算平台,做實時計算分析
将資料寫入maxcompute做進行分析
下面羅列下我們目前有如下幾種方式可以讀區表格存儲的增量資料:
datax 離線讀取stream資料到odps,具體使用參考[datax 通路tablestore增量]()
stream對接fc,通過fc觸發資料處理邏輯。 [即将釋出,敬請期待]()
下面我們就用外賣訂單系統為例再說明下stream如何可以友善我們簡化,高效的實作我們的應用。
現在外賣行業非常火熱,幾家大廠都在角逐這個領域。而外賣也确實給我們的日常生活帶來的很多便利,那如何基于表格存儲打造一款高效的外賣應用呢,下面我們來詳細介紹下。
很多外賣會在不同時間有明顯的波峰波谷,例如食品外賣,三餐點和宵夜時間點會有明顯的波峰。那麼表格存儲這類海量高性能彈性計費的資料庫産品就非常适合。除此之外,外賣系統還要基于一個區域内所有使用者的下單情況做一個做優化的配送,實作效率最優,那麼這樣的系統我們如何設計表結構呢。
order_id
訂單id
配送員id
delivery_id
配送序列
使用長整型,基于表格存儲主鍵自增列
設計好表結構後,我們看下具體如何存儲:
訂單表原始資料是:
配送表原始資料是:
merchant_id
commodity
price
address
payment_type
status
01f3
10005
黑暗料理
2烤肉,1咖啡
51
西湖區xxx路xx号
alipay
等待配送
1495249230
配送中
part_key:第一個主鍵,分區建,主要是為了負載均衡,保證資料可以均勻分布在所有機器上,提高并發度和性能。如果業務主鍵user_id可以保證均勻分布,那麼可以不需要這個主鍵。
user_id:第二個主鍵,使用者id,可以是字元串也可以是數字,唯一辨別一個使用者。
timestamp:第三個主鍵,時間戳,表示某一個時刻,機關可以是秒或者毫秒,用來表示使用者訂單的時間戳。在這裡放置時間,是因為系統往往需要查詢某個使用者一段時間内的所有訂單資訊。
order_id:第四個主鍵,訂單号。
至此,上述四個主鍵可以唯一确定某一個使用者在某一個時間點下的一個訂單。
user_id:第二個主鍵,配送員id,可以是字元串也可以是數字,唯一辨別一個使用者。
delivery_id:第三個主鍵,配送号,注意不是使用者的訂單号,這一列使用自增列,配送員的用戶端可以根據這個id拉去更新的配送資訊。
至此,上述三個主鍵可以擷取一個配送訂單的詳細資訊。
merchant_id :商家id
commodity:商品内容。
price:訂單價格。
address: 配送位址
payment_type:使用者支付類型。
status:訂單的狀态。
order_id :訂單id
由于表格存儲的分區鍵可以在資料通路增加時進行分裂,當我們有百萬使用者同時在高峰期下單時我們可以分裂出較多的分區輕松應對每秒數十萬甚至數百萬的新增訂單。有了這樣的一個訂單存儲系統後,如何銜接我們的派單系統呢,這時候我們就可以使用增量功能,把近期的訂單資訊導入排單系統進行線路優化計算。前面我們也提到了外賣訂單的伸縮特性,是以我們推薦使用函數計算進行訂單的派送計算,我們表格存儲stream對接函數計算的功能也即将上線,屆時我們是需要一些配置就可以打通表格存儲和函數計算這兩款全托管完全彈性計費的存儲,計算産品。讓我們的外賣訂單飛的再快一點吧。