[英]Storing time-series data, relational or non?
我正在創建一個系統,使用SNMP以(可能)5分鍾的間隔輪詢設備以獲取有關各種指標的數據,例如CPU利用率,磁盤利用率,溫度等。 最終目標是以時間序列圖的形式為系統用戶提供可視化。
我曾經看過使用RRDTool,但拒絕了它,因為無限期地存儲捕獲的數據對我的項目很重要,我希望更高級別和更靈活地訪問捕獲的數據。 所以我的問題是:
什么是更好的關系數據庫(如MySQL或PostgreSQL)或非關系數據庫或NoSQL數據庫(如MongoDB或Redis)在查詢數據以進行圖形處理時的性能。
給定關系數據庫,我將使用data_instances
表,其中將存儲為所有設備測量的每個度量捕獲的每個數據實例,並包含以下字段:
字段: id
fk_to_device
fk_to_metric
metric_value
timestamp
當我想在特定設備上繪制特定指標的圖形時,我必須查詢此單個表, 過濾掉其他設備,以及為此設備分析的其他指標:
SELECT metric_value, timestamp FROM data_instances
WHERE fk_to_device=1 AND fk_to_metric=2
此表中的行數為:
d * m_d * f * t
其中d
是設備的數量, m_d
是為所有設備記錄的累計度量數 , f
是輪詢數據的頻率 , t
是系統收集數據的總時間 。
對於一年中每5分鍾記錄3個設備的10個度量標准的用戶,我們將有不到500萬條記錄。
如果沒有fk_to_device
和fk_to_metric
掃描的索引,這個不斷擴展的表將花費太多時間。 因此,索引上述字段以及timestamp
(用於創建具有本地化時段的圖表)是必需的。
MongoDB具有集合的概念,與表不同,這些可以在沒有設置的情況下以編程方式創建。 有了這些,我可以為每個設備划分數據存儲,甚至為每個設備記錄每個指標。
我沒有使用NoSQL的經驗,也不知道它們是否提供任何查詢性能增強功能,例如索引,但前一段提出在數據存儲在NoSQL下的結構中進行大多數傳統的關系查詢工作。
具有正確索引的關系解決方案是否會在一年內減少爬行? 或者NoSQL方法的基於集合的結構(與我存儲的數據的心理模型相匹配)是否提供了明顯的好處?
絕對是關系。 無限的靈活性和擴展。
兩個更正,包括概念和應用,然后是提升。
它不是“過濾掉不需要的數據”; 它只選擇所需的數據。 是的,當然,如果你有一個索引來支持WHERE子句中標識的列,它非常快,並且查詢不依賴於表的大小(從160億行表中抓取1,000行是瞬時的) 。
你的桌子有一個嚴重的障礙。 根據您的描述,實際的PK是(Device,Metric,DateTime)。 (請不要將其稱為TimeStamp,這意味着其他內容,但這是一個小問題。) 行的唯一性通過以下方式標識:
(Device, Metric, DateTime)
Id
列什么都不做,它完全是冗余的。
Id
列永遠不是Key(必須通過其他方式阻止在Relational數據庫中禁止的重復行)。 Id
列需要一個額外的索引,這顯然會阻礙INSERT/DELETE
的速度,並且會增加使用的磁盤空間。
你可以擺脫它。 請。
既然你已經消除了障礙,你可能沒有認出它,但你的桌子是第六范式。 速度非常快,只有一個PK指數。 為了理解,閱讀這個答案從什么是第六范式? 向前走。
(我只有一個索引,而不是三個;在非SQL上你可能需要三個索引)。
我有完全相同的表(當然沒有Id
“鍵”)。 我有一個額外的列Server
。 我遠程支持多個客戶。
(Server, Device, Metric, DateTime)
該表可用於使用完全相同的SQL代碼(是的,切換單元格)來透視數據(即,頂部的Devices
和側面的Metrics
,或者旋轉)。 我使用該表為客戶建立無限種類的圖形和圖表,以提高其服務器性能。
還有一件事
最后但並非最不重要的是,SQL是IEC / ISO / ANSI標准。 免費軟件實際上是非SQL的; 如果他們不提供標准,則使用術語SQL是欺詐性的。 他們可能提供“額外”,但他們缺乏基礎知識。
發現以上答案非常有趣。 嘗試在此處添加更多注意事項。
1)數據老化
時間序列管理通常需要創建老化策略。 典型場景(例如監視服務器CPU)需要存儲:
1秒的原始樣品短期(例如24小時)
中期(例如1周)的5分鍾細節聚合樣本
1小時的細節(例如長達1年)
雖然關系模型可以肯定(我公司為一些擁有數萬個數據系列的大客戶實施大規模集中式數據庫)來適當地管理它,但新一代數據存儲增加了有趣的功能,有待探索:
自動數據清除(請參閱Redis的EXPIRE命令)
多維聚合(例如map-reduce job a-la-Splunk)
2)實時收集
更重要的是,一些非關系數據存儲本質上是分布式的,並且允許更高效的實時(或接近實時)數據收集,這可能是RDBMS的一個問題,因為熱點的創建(在插入時管理索引)一張桌子)。 RDBMS空間中的這個問題通常被解決,恢復到批量導入過程(我們過去以這種方式管理),而no-sql技術已成功進行大規模實時收集和聚合(例如,參見Splunk,在之前的回復中提到過) 。
您的表在單個表中有數據。 所以關系與非關系不是問題。 基本上你需要閱讀大量的順序數據。 現在,如果你有足夠的RAM存儲一年的數據,那么就像使用Redis / MongoDB等。
大多數NoSQL數據庫會將您的數據存儲在磁盤上的相同位置並以壓縮形式存儲,以避免多個磁盤訪問。
NoSQL以與設備ID和度量標識創建索引相同的方式,但以自己的方式。 使用數據庫即使你這樣做,索引和數據可能在不同的地方,並且會有很多磁盤IO。
像Splunk這樣的工具使用NoSQL后端來存儲時間序列數據,然后使用map reduce來創建聚合(這可能是您以后想要的)。 所以在我看來使用NoSQL是一個選項,因為人們已經嘗試過類似的用例。 但是,一百萬行會使數據庫爬行(可能沒有,具有合適的硬件和正確的配置)。
創建一個文件,將其命名為1_2.data。 想法? 你得到什么:
=>按時間戳查詢的速度非常快,因為您可以使用二進制搜索在文件中找到正確的位置進行讀取。
如果你喜歡它甚至更優化開始考慮分割你的文件;
或者使用來自http://kx.com的 kdb +因為他們為你做了這一切:)以列為導向可以幫到你。
有一個基於雲的面向列的解決方案出現,所以你可能想看看: http : //timeseries.guru
如果您正在尋找GPL包,那么RRDTool是一個很好的選擇。 它是存儲,提取和繪制時間序列數據的好工具。 您的用例看起來與時間序列數據完全相同。
我認為這類問題的答案應該主要圍繞數據庫利用存儲的方式。 一些數據庫服務器使用RAM和磁盤,一些使用RAM(可選擇磁盤用於持久性)等。最常見的SQL數據庫解決方案使用內存+磁盤存儲並將數據寫入基於行的布局(每個插入的原始數據都寫在同一個物理位置)。 對於時間序列存儲,在大多數情況下,工作負載類似於:大量插入的相對較低的間隔,而讀取是基於列的(在大多數情況下,您希望從特定列讀取一系列數據,表示度量)
我發現Columnar數據庫(google it,你會發現MonetDB,InfoBright,parAccel等)在時間序列方面做得非常好。
至於你的問題,我認為這個問題有點無效(因為所有使用故障術語NoSQL-IMO的討論):你可以使用一方面可以說SQL的數據庫服務器,讓你的生活變得輕松,因為每個人都知道很多SQL多年來,這種語言一遍又一遍地完善數據查詢; 但仍以柱狀方式使用RAM,CPU緩存和磁盤,使您的解決方案最適合時間序列
5百萬行對於今天的暴雨數據來說並不算什么。 預計數據將在幾個月內出現在TB或PB中。 此時,RDBMS無法擴展到任務,我們需要NoSql數據庫的線性可伸縮性。 用於存儲數據的柱狀分區將實現性能,添加更多列和更少行的概念以提高性能。 利用在HBASE或MapR_DB等基礎上完成的Open TSDB工作。
我經常面臨類似的要求,並且最近開始使用Zabbix收集和存儲此類數據。 Zabbix有自己的圖形功能,但是很容易從Zabbix的數據庫中提取數據並隨意處理它。 如果你還沒有檢查過Zabbix,你可能會覺得值得花時間去做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.