如何週期性地統計近萬臺裝置的實時狀態?Redis時間序列儲存方案
文章目錄
場景:如何週期性地統計近萬臺裝置的實時狀態,包含裝置ID、壓力、溫度、溼度、時間戳
時間序列:與發生時間相關的一組資料,沒有嚴格的關係模型,記錄的資訊可以表示成鍵和值的關係。
讀寫特點
寫
- 要求插入速度快,所以選擇的資料結構插入的時候,複雜度要低,可以選String和hash
- String記錄小資料時,後設資料的記憶體開銷比較大
讀
多場景的讀
- 有對單調記錄的讀
- 對時間範圍內的資料的查詢
- 對時間範圍內的資料做聚合計算(均值、最大值、最小值、求和等)
Redis提供了儲存時間序列的以下兩種方案
基於Hash和Sorted Set實現(單鍵和範圍查詢)
Hash和Sort Set都是Redis內部成熟和效能穩定的資料型別,使用原因如下:
單鍵查詢
Hash滿足對單鍵的快速查詢,時間戳作為hash集合的key,裝置狀態值作為hash的value,不支援對資料的範圍查詢
範圍查詢
Sorted Sort滿足按時間戳範圍進行查詢,時間戳作為元素分數score,時間點上記錄的資料作為元素本身member,可以通過ZRANGEBYSCORE獲取某個範圍的資料
採用Sorted做聚合計算,需要把資料取回客戶端做,資料量大的時候,會導致大量資料在Redis例項和客戶端之間頻繁傳輸,阻塞網路。
原子性保障
同時使用兩種結構的時候,存資料的時候,就需要保證操作兩種結構的命令的原子性
Redis使用MULTI和EXEC命令保證執行這些命令時的原子性。
- MULTI 命令:表示一系列原子性操作的開始。收到這個命令後,Redis 就知道,接下來 再收到的命令需要放到一個內部佇列中,後續一起執行,保證原子性。
- EXEC 命令:表示一系列原子性操作的結束。一旦 Redis 收到了這個命令,就表示所有 要保證原子性的命令操作都已經傳送完成了。此時,Redis 開始執行剛才放到內部佇列 中的所有命令操作。
基於RedisTimeSeries實現(聚合計算)
通過RedisTimeSeries可以對時間序列的資料做聚合計算
場景模擬
場景:每3分鐘計算一次所有裝置各個指標的最大值
不使用方案
- 每個裝置每15s記錄一個指標值,1分鐘4個,3分鐘12個
- 假設要統計的指標值有33個,那麼單個裝置每3分鐘有33*12=396個資料
- 假設裝置總數1萬臺,每3分鐘有396*10000=396萬資料需要在客戶端和Redis例項之間傳輸
使用方案
- 在Redis上直接做聚合計算,單個裝置每3分鐘的12條記錄做一次聚合計算,也就是1個值
- 假設要統計的指標值有33個,那麼單個裝置每3分鐘有33個資料
- 假設裝置總數1萬臺,每3分鐘有33*10000=33萬資料需要在客戶端和Redis例項之間傳輸
使用方案RedisTimeSeries比不使用方案只是其十分之一的網路傳輸。
RedisTimeSeries 使用
RedisTimeSeries 是 Redis 的一個擴充套件模組,需要額外新增。專門面向時間序列資料提供了資料型別和訪問介面,並且支援在 Redis 例項上直接對資料進行按時間範圍的聚合計算。
TS.CREATE 建立一個時間序列資料集合
- 設定集合的key和過期時間
- 為資料集合設定標籤
// 建立key為device:temperature、資料有效期為 600s 的時間序列資料集合。
// 集合資料建立了 600s後,就會被自動刪除。
// 給集合設定了一個標籤屬性{device_id:1},表明資料集合中記錄的是屬於裝置ID號為1的資料。
TS.CREATE device:temperature RETENTION 600000 LABELS device_id 1
TS.ADD 插入資料
往時間序列集合中插入資料,包括時間戳和具體的數值
//往device:temperature 集合中插入了一條資料,記錄的是裝置在 2020 年 8 月 3 日 9 時 5 分的裝置溫度;
TS.ADD device:temperature 1596416700 25.1
TS.GET 讀取最新資料
使用 TS.GET 命令讀取資料集合中的最新一條資料。
TS.GET device:temperature
TS.MGET 按標籤過濾查詢資料集合
儲存多個裝置的時間序列資料時,我們通常會把不同裝置的資料儲存到不同集合中
使用 TS.MGET 命令,按照標籤查詢部分集合中的最新資料
假設用 4 個集合為 4 個裝置儲存時間序列資料,裝置的 ID 號是 1、 2、3、4建立資料集合時,把 device_id 設定為每個集合的標籤。
可以使用TS.MGET 命令,以及 FILTER (設定集合標籤的過濾條件),查詢 device_id 不等於 2 的所有其他裝置的資料集合,並返回各自集合中的最新的一條資料。
TS.MGET FILTER device_id!=2
TS.RANGE:支援需要聚合計算的範圍查詢
對時間序列資料進行聚合計算時,我們可以使用 TS.RANGE 命令指定要查詢的資料的時間範圍,同時用 AGGREGATION 引數指定要執行的聚合計算型別。
TS.RANGE device:temperature 1596416700 1596417120 AGGREGATION avg 180000
1) (integer) 1596416700
2) "25.6"
1) (integer) 1596416880
2) "25.8"
1) (integer) 1596417060
2) "26.1"
相關文章
- iNeuOS工業網際網路作業系統,釋出實時儲存方式:實時儲存、變化儲存、定時儲存,增加裝置振動狀態和電能狀態監測驅動,v3.6.2作業系統
- 不同時期資料如何儲存?浪潮資訊提供全生命週期管理方案
- 使用MongoDB儲存時間序列資料 - DACMongoDB
- redis 過期時間Redis
- 高頻時序資料的儲存與統計方案
- 如何正確的評估redis過期時間Redis
- MySQL 中儲存時間的最佳實踐MySql
- redis hset hmset過期時間Redis
- redis設定過期時間Redis
- 用Python預測「週期性時間序列」的正確姿勢Python
- 如何延長儲存伺服器上資料的儲存時間?伺服器
- 多級時序系統:機器週期,時鐘週期
- 即時聊天(IM)儲存方案
- 【時間序列分析】01. 時間序列·平穩序列
- Redis和DelayQueue設計具有過期時間的快取Redis快取
- localStorage設定儲存時間
- 解決MongoDB儲存時間時差的問題MongoDB
- 當裝置旋轉時android生命週期方法的呼叫順序Android
- Python 儲存字串時是如何節省空間的?Python字串
- React 狀態管理:狀態與生命週期React
- Redis乾貨|解鎖Redis 時間序列資料的應用Redis
- [20151226]統計資訊的儲存時間.txt
- 時間序列分析
- 時鐘週期,機器週期,指令週期
- 日期和時間的儲存與處理
- 將VAE用於時間序列:生成時間序列的合成資料
- 如何選擇移動儲存裝置
- docker - 生命週期和狀態Docker
- windows10系統如何關閉USB儲存裝置Windows
- Redis 過期時間與記憶體管理Redis記憶體
- JSP如何儲存使用者上次登入時間JS
- 【Flutter 知識集錦】從 restorationId 來說臨時狀態儲存FlutterREST
- Azure Blob儲存更改快取時間快取
- Activity Monitor log儲存時間調整
- vuex 閒置狀態重置方案Vue
- Redis Stack:基於Redis的搜尋、文件、圖形和時間序列功能Redis
- 時間序列分析基本思想及時間序列建模步驟
- 981-基於時間的鍵值儲存