MongoDB資料建模小案例:物聯網時序資料庫建模
注:本案例來自MongoDB官方教程PPT,也是一個非常典型的CASE,故此翻譯,並結合當前MongoDB版本做了一些內容上的更新。
本案例非常適合與IoT場景的資料採集,結合MongoDB的Sharding能力,文件資料結構等優點,可以非常好的解決物聯網使用場景。
需求
案例背景是來自真實的業務,美國州際公路的流量統計。資料庫需要提供的能力:
- 儲存事件資料
- 提供分析查詢能力
-
理想的平衡點:
- 記憶體使用
- 寫入效能
- 讀取分析效能
- 可以部署在常見的硬體平臺上
幾種建模方式
每個事件用一個獨立的文件儲存
{
segId: "I80_mile23",
speed: 63,
ts: ISODate ("2013-10-16T22:07:38.000-0500")
}
- 非常“傳統”的設計思路,每個事件都會寫入一條同樣的資訊。多少的資訊,就有多少條資料,資料量增長非常快。
- 資料採集操作全部是Insert語句;
每分鐘的資訊用一個獨立的文件儲存(儲存平均值)
{
segId: "I80_mile23",
speed_num: 18,
speed_sum: 1134,
ts: ISODate("2013-10-16T22:07:00.000-0500")
}
- 對每分鐘的平均速度計算非常友好(speed_sum/speed_num);
- 資料採集操作基本是Update語句;
- 資料精度降為一分鐘;
每分鐘的資訊用一個獨立的文件儲存(秒級記錄)
{
segId: "I80_mile23",
speed: {0:63, 1:58, ... , 58:66, 59:64},
ts: ISODate("2013-10-16T22:07:00.000-0500")
}
- 每秒的資料都儲存在一個文件中;
- 資料採集操作基本是Update語句;
每小時的資訊用一個獨立的文件儲存(秒級記錄)
{
segId: "I80_mile23",
speed: {0:63, 1:58, ... , 3598:54, 3599:55},
ts: ISODate("2013-10-16T22:00:00.000-0500")
}
相比上面的方案更進一步,從分鐘到小時:
- 每小時的資料都儲存在一個文件中;
- 資料採集操作基本是Update語句;
- 更新最後一個時間點(第3599秒),需要3599次迭代(雖然是在同一個文件中)
進一步優化下:
{
segId: "I80_mile23",
speed: {
0: {0:47, ..., 59:45},
...,
59: {0:65, ... , 59:56}
}
ts: ISODate("2013-10-16T22:00:00.000-0500")
}
- 用了巢狀的手法把秒級別的資料儲存在小時資料裡;
- 資料採集操作基本是Update語句;
- 更新最後一個時間點(第3599秒),需要59+59次迭代;
巢狀結構正是MongoDB的魅力所在,稍動腦筋把一維拆成二維,大幅度減少了迭代次數;
每個事件用一個獨立的文件儲存VS每分鐘的資訊用一個獨立的文件儲存
從寫入上看:後者每次修改的資料量要小很多,並且在WiredTiger引擎下,同一個文件的修改一定時間視窗下是可以在記憶體中合併的;
從讀取上看:查詢一個小時的資料,前者需要返回3600個文件,而後者只需要返回60個文件,效率上的差異顯而易見;
從索引上看:同樣,因為穩定數量的大幅度減少,索引尺寸也是同比例降低的,並且segId,ts這樣的冗餘資料也會減少冗餘。容量的降低意味著記憶體命中率的上升,也就是效能的提高;
每小時的資訊用一個獨立的文件儲存VS每分鐘的資訊用一個獨立的文件儲存
從寫入上看:因為WiredTiger是每分鐘進行一次刷盤,所以每小時一個文件的方案,在這一個小時內要被反覆的load到PageCache中,再刷盤;所以,綜合來看後者相對更合理;
從讀取上看:前者的資料資訊量較大,正常的業務請求未必需要這麼多的資料,有很大一部分是浪費的;
從索引上看:前者的索引更小,記憶體利用率更高;
總結
那麼到底選擇哪個方案更合理呢?從理論分析上可以看出,不管是小時儲存,還是分鐘儲存,都是利用了MongoDB的資訊聚合的能力。
- 每小時的資訊用一個獨立的文件儲存:設計上較極端,優勢劣勢都很明顯;
- 每分鐘的資訊用一個獨立的文件儲存:設計上較平衡,不會與業務期望偏差較大;
落實到現實的業務上,哪種是最優的?最好的解決方案就是根據自己的業務情況進行效能測試,以上的分析只是“理論”基礎,給出“實踐”的方向,但千萬不可以此論斷。
VS InfluxDB
說到時序儲存需求,大家一定還會想到非常厲害的InfluxDB,InfluxDB針對時序資料做了很多特定的優化,但MongoDB採用聚合設計模式同樣也可以大幅度較少資料尺寸。根據最新的測試報告,讀取效能基本相當,壓縮能力上InfluxDB領先MongoDB。但MongoDB的優勢在於可以儲存更豐富的資訊,比如地理座標,文字描述等等其他屬性,業務場景上支援更廣泛。
另外,MongoDB的Sharding水平擴充套件能力,Aggragation功能,Spark Connector等等特性,對IoT來說,生態優勢明顯。
原文地址:https://yq.aliyun.com/articles/66477?spm=5176.100239.blogcont73664.27.h8eZaz