Whisper是一個固定大小的數據庫,在設計上相似於RRD(round-robin-database)。它能夠爲隨時間不斷變化的數值型數據提供快速,可靠的存儲。Whisper還能夠把高精度的指標數據轉換成低精度的指標數據以知足存儲長期的歷史數據的需求。好比說把按秒採集的指標轉換成按分鐘採集的指標,以減小數據量,進行長期存儲。python
Whisper使用大端雙精度浮點類型來存儲數據。每一個數據點包含一個時間戳和一個值。正則表達式
每一個whisper數據庫能夠包含一個或者多個針對不一樣數據的採集和存儲策略的定義。這些定義保存在graphite安裝路徑下的conf/ storage-schemas.conf配置文件裏面,以下圖所示:數據庫
上圖就定義了四個數據採集和存儲的策略,策略的定義語法以下:微信
[name]優化 pattern = regexspa retentions = timePerPoint:timeToStore, timePerPoint:timeToStore, ...設計 |
name:策略名稱,可隨意指定排序
pattern:用來匹配具體指標名的正則表達式。若是配置文件裏面定義了多個策略,那麼收到一個指標數據的時候,會從上到下使用每一個策略裏面的pattern對指標名稱進行正則表達式匹配,最早匹配到的策略將會被使用。ip
retentions:定義了數據採集精度和存儲時長。timePerPoint就是多長時間採集一個數據點,timeToStore就是採集的數據最長存儲多長時間。每一個retentions後面能夠定義多個timePerPoint:timeToStore對。每一個timePerPoint:timeToStore對按高精度短時長到低精度長時長進行排序。好比:ci
retentions = 15s:7d,1m:21d,15m:5y |
上面的retentions包含了三個timePerPoint:timeToStore對,分別是15秒採集一個數據點,保存7天的數據,1分鐘採集一個數據點,保存21天的數據和15分鐘採集一個數據點,保存5年的數據。
爲了能準確地從高精度數據轉換到低精度數據,兩個相鄰的timePerPoint:timeToStore對定義必須知足低精度定義能被高精度定義整除這個條件。好比上面的1m:21d就能被15s:7d整除,由於1分鐘能被15秒整除,而21天能夠被7天整除。相反,每180秒採集一次數據的定義就不能被每300秒採集一次數據的定義整除,由於300不能被180整除。
Whisper數據庫的最長存儲時間由最長的時長定義來決定。好比上面的例子,數據庫的最長存儲時長就是5年。
當retentions裏面包含多個timePerPoint:timeToStore對的時候,那麼whisper必須使用一個策略來進行高精度數據到低精度數據的聚合操做。默認的策略是取平均值。能夠使用的策略有一下幾種:
1:average 取平均值
2:sum 求和
3:last 取最後一個值
4:max 取最大值
5:min 取最小值
數據聚合的規則定義在graphite的安裝目錄下的conf/ storage-aggregation.conf配置文件裏面,以下圖所示:
上圖就定義了四個數據聚合規則,聚合規則定義的語法以下:
[name] pattern = <regex> xFilesFactor = <float between 0 and 1> aggregationMethod = <average|sum|last|max|min> |
name:規則的名稱,可隨意指定,但在這個配置文件裏面必須惟一
pattern:用來匹配具體指標名的正則表達式。若是配置文件裏面定義了多個聚合規則,那麼收到一個指標數據的時候,會從上到下使用每一個規則裏面的pattern對指標名稱進行正則表達式匹配,最早匹配到的規則將會被使用。
aggregationMethod:數據聚合策略(方法)
xFilesFactor:必須是一個0到1之間的浮點型數值。這個值規定了要把高精度的數據轉換成一個低精度的數據,高精度的數據必須有幾個。
以15s:7d,1m:21d這個定義爲例子,高精度的定義是15秒採集一個數據,而低精度的定義是1分鐘採集一個數據。那麼在高低精度數據轉換的時候,正常狀況下就是把4個數據點轉換成一個數據點。
可是實際可能存在這樣的狀況,就是1分鐘內的數據點沒有4個,只有一個,兩個,或者三個,就是有的時間點他沒有采集到數據。那麼xFilesFactor的意思就是在這種數據缺乏的狀況下,數據點數必須知足多少百分比,才能作數據聚合操做。若是定義成0.5,那麼就是說,至少要有2個點才能作數據聚合操做,若是定義成0.1,那就是說只要有1個點就能夠作數據聚合操做。
這個值定義成多少,還跟具體的數據聚合策略有關係。若是數據聚合策略是sum(求和),這種策略下就算沒有數據點,也是能夠作求和操做的,那麼xFilesFactor就能夠定義成0。若是數據聚合策略是min(求最小值),這種策略下,沒有數據點確定就無法取最小值,那麼xFilesFactor就能夠定義成0.1,就是說至少要有一個數據點,才能作聚合操做,等等。
以retentions = 15s:7d,1m:21d,15m:5y這個多精度定義爲例子,當數據寫入這個數據庫時,數據會被同時寫多份。數據會首先被寫入到最高精度的數據點中,而後當知足數據聚合條件後,再把多個高精度的數據聚合,寫到低精度的數據點中。
獲取數據的時候,會使用最符合當前時間段的精度的數據。
在磁盤使用率上,whiper能夠說是低效率的。表如今如下幾個方面:
1:每一個數據點不只存儲了值,還存儲了時間戳
2:數據庫文件生成時,就把全部的數據點都建立出來了。好比說1m:1d這個定義,在收到第一個數據點的時候,這個數據庫文件就被建立了,數據庫文件裏面總共1440個數據點。無論這些數據點有沒有收集到值,數據點都會提早建立好,若是沒有值,就是None。
可是這樣的數據文件是很小的,好比1m:1d這個定義生成的數據文件大小,才17K,以下所示:
能夠使用whisper-info.py +數據庫文件名,查看這個文件的一些信息,以下所示:
還能夠使用whisper-dump.py + 數據庫文件名查看裏面的數據點,以下所示:
對於不少應用來講,whiper已經夠快了。它比RRD慢的主要緣由是whisper是用python寫的,而RRD是用C寫的。但隨着對whisper的不斷地優化,實際上他們二者之間的速度差異已經很小了。
-----------------------------------------------------
歡迎關注個人微信公衆號 ^_^