使用MongoDB儲存時間序列資料 - DAC
瞭解如何使用Java + Spring示例在MongoDB中最佳化時序資料的儲存。
什麼是時間序列資料?
引用維基百科,“ 時間序列是按時間順序索引(或列出或繪製)的一系列資料點 ”。但這實際上是什麼意思?讓我們舉個例子。
考慮交通工程公司的情況。在特定的用例中,該公司需要收集橫穿特定路口的確切數量的汽車的資料,以便管理交通燈演算法。透過交叉路口的每輛汽車都將被報告回系統。這種事件就是我們所說的資料時間點。經過交叉路口的多輛汽車就是我們所說的資料“系列”。
時間序列資料可能以不規則的速率生成-在我們的示例中,它僅在汽車經過時才出現-或可以以固定的時間間隔捕獲-例如每秒的裝置測量值。
Mongo資料讀取
假設我們要每隔1秒收集一次裝置溫度。在典型的MongoDB文件中儲存該資訊看起來像這樣:
{ "_id" : ObjectId(), "temperature" : 90.50, "deviceId" : "1", "date" : ISODate("2019–11–10T00:00:01Z") }, { "_id" : ObjectId(), "temperature" : 92.50, "deviceId" : "1", "date" : ISODate("2019–11–10T00:00:02Z") } |
每分鐘產生60個文件,每小時產生3600個檔案,每天產生86400個文件,這還只是一臺裝置!這種方法有明顯的缺陷,並且對效能和磁碟使用率有重大影響。
必須有更好的解決方案…
Mongo時間序列,又稱基於大小的儲存桶
MongoDB允許我們建立一個文件來儲存多個連續的資料讀取。在我們裝置的溫度收集情況下,此類檔案要求:
- id —文件的ID(MongoDB的ObjectId)
- deviceId —查詢樣品時文件分組依據的元素
- bucketSize -檔案中的最大樣本量
- date—樣品的日期;我們可以將其儲存在此處以簡化聚合
- first —在儲存桶中讀取的最舊資料的時間戳
- last —儲存桶中讀取的最新資料的時間戳
- samples —資料容器
我們的最終時間序列檔案將類似於以下檔案:
{ _id: ObjectId(), deviceid: 1, date: ISODate("2019-11-10"), bucketSize: 4, first: 1573833152, last: 1573833155, samples : [ { val: 10, time: 1573833152}, { val: 15, time : 1573833153}, { val: 14, time: 1573833154}, { val: 20, time : 1573833155} ] } |
每個新的從裝置讀取得數值都將附加到這個文件,直到儲存桶大小達到1000個樣本的閾值(請參閱:bucketSize值)。upsert:true一旦達到閾值,將透過該子句建立一個新文件。
在upsert過程中,我們將sample物件推送至samples,first將其更新為最小值,last最大值,並bucketSize為每個新條目增加1。
Java和Spring中基於大小的儲存
好了,足夠多的理論,讓我們現在付諸實踐。我們將使用Spring的MongoTemplate將入站溫度讀取插入MongoDB。讓我們實現上面給出的示例。
我們的DeviceTemperature模型將如下所示:
@lombok.Data class DeviceTemperature { private Integer deviceId; private Integer temperature; private Long timestamp; private LocalDate date; } DeviceTemperature deviceTemperature = new DeviceTemperature(); deviceTemperature.setDeviceId(1); deviceTemperature.setTemperature(12); deviceTemperature.setTimestamp(1573833152L); deviceTemperature.setDate(LocalDate.parse(“2019–11–10”); |
建立好模型後,我們需要建立criteria和query:
Criteria criteria = Criteria.where("deviceId").is(deviceTemperature.getDeviceId()) .and("bucketSize").lt(1000) .and("date").is(deviceTemperature.getDate()); Query query = Query.query(criteria); |
上面的程式碼建立了一個查詢,其中包含用於上載特定MongoDB文件的條件。
現在建立一個update命令:
Integer deviceId = deviceTemperature.getDeviceId(); Update update = new Update() .push("samples", deviceTemperature) .inc("bucketSize", deviceId) .min("first", deviceTemperature.getTimestamp()) .max("last", deviceTemperature.getTimestamp()); |
最後呼叫mongoTemplate 實現upset資料:
mongoTemplate.upsert(query, update, DeviceTemperature.class) |
這就是使用Java和Spring以時間序列的方式儲存資料所需的一切。
相關文章
- 解決MongoDB儲存時間時差的問題MongoDB
- Python爬蟲之使用MongoDB儲存資料Python爬蟲MongoDB
- 如何延長儲存伺服器上資料的儲存時間?伺服器
- 將VAE用於時間序列:生成時間序列的合成資料
- 技術乾貨| MongoDB時間序列集合MongoDB
- MongoDB後設資料的儲存介紹MongoDB
- 服務端指南 資料儲存篇 | 聊聊 MongoDB 使用場景服務端MongoDB
- 時間序列資料的處理
- 爬蟲學習筆記(2)使用MongoDB儲存拉鉤資料爬蟲筆記MongoDB
- 資料庫儲存時間到底該用什麼型別?資料庫型別
- 什麼時候該使用NoSQL儲存資料庫?SQL資料庫
- 使用mongodb、Kafka儲存mqtt訊息MongoDBKafkaMQQT
- go 把時間儲存到 MongoDB , 時間是 time 型別MongoDB型別
- MongoDB文件儲存MongoDB
- SQL Server資料庫事務日誌儲存序列SQLServer資料庫
- localStorage設定儲存時間
- 使用InfluxDB時間序列資料功能構建可觀察性UX
- JavaScript使用localStorage儲存資料JavaScript
- 大資料時代的資料儲存,非關係型資料庫MongoDB大資料資料庫MongoDB
- 分散式文件儲存資料庫之MongoDB索引管理分散式資料庫MongoDB索引
- 分散式文件儲存資料庫之MongoDB副本集分散式資料庫MongoDB
- 人工智慧 (07) 時間序列資料分析人工智慧
- 讓時空大資料不再神祕——如何直連使用ArcGIS時空大資料儲存大資料
- 資料儲存的 timestamp 時間正確 但是 Laravel 取出來的時間慢的 8 小時Laravel
- 【時間序列分析】01. 時間序列·平穩序列
- Druid:實時分析資料儲存UI
- 分散式文件儲存資料庫之MongoDB分片叢集分散式資料庫MongoDB
- 分散式文件儲存資料庫之MongoDB訪問控制分散式資料庫MongoDB
- 使用Room持久庫儲存資料OOM
- 資料儲存--檔案儲存
- 從零寫一個時間序列資料庫資料庫
- 時間序列資料如何助力釀酒和BBQ?
- Spring Boot實戰系列(2)資料儲存之NoSQL資料庫MongoDBSpring BootSQL資料庫MongoDB
- JSP如何儲存使用者上次登入時間JS
- Laravel 5.6+ 使用 MongoDB 儲存框架日誌LaravelMongoDB框架
- 資料儲存
- postgresql資料定時轉存mongodb方案SQLMongoDB
- 線上mongodb 資料庫使用者到期時間修改的操作記錄MongoDB資料庫