Categories
程式開發

如何使用Redis TimeSeries和Grafana實現實時分析


本文要點

  • 時序數據管理對於組織中的數據分析至關重要,舉例來說,股票價格或CPU性能指標都是時序數據。
  • 像RedisTimeSeries這樣專門構建的數據庫解決了處理時序數據的需求,同時擺脫了關係型數據庫強加給我們的限制。
  • 其他專門為此構建的數據庫包括InfluxDB和Prometheus。
  • 通過將Grafana和RedisTimeSeries集成在一起,我們可以實時放大或縮小圖表。

時序數據可以廣義地定義為按照時間順序存儲的一系列數據,舉例來說,多年內的股票價格變動或過去幾個小時CPU性能指標都是時序數據。時序數據廣泛用於很多垂直行業,因為關係型、面向文檔的以及流式數據庫都不能滿足這種特殊類型的數據的需求。

時序數據的特點

時序數據庫有著獨特的特點(如下面列表所示),如果與其他數據庫一起管理的話,通常會是非常低效的:

  1. 高速的數據攝入:不管是IoT使用場景還是市場分析數據,我們都會有一個穩定的數據流,數據以很快的速度抵達,而且常常是爆發性的。對於大多數解決方案,一年中365天,24/7之內都有數據抵達。
  2. 數據不可變:一旦插入到數據庫之中,在過期或刪除之前,數據點不會進行任何修改。數據通常是帶有時間戳和多個數據點的日誌。
  3. 非結構化的標籤:時序數據通常是在一定的時間範圍內有很多源連續生成的。例如,在IoT使用場景中,每個傳感器都是時序數據的源。在這樣的場景中,序列中的每個數據點都以標籤的形式存儲源信息和其他傳感器測量數據。來自每個源的數據標籤可能並不符合相同的結構或順序。
  4. 數據的價值隨時間遞減:只有恰當時間範圍內的聚合匯總數據才會對未來產生價值。例如,在一年之後,大多數用戶都不需要毫秒範圍內存儲的每個數據點。只有按照分鐘、小時或每天聚合和匯總起來的數據才有意義。
  5. 查詢要根據時間間隔進行聚合:基於時序數據生成圖表能夠讓我們放大和縮小查詢。之所以能夠實現這一點是因為它們的數據是根據間隔聚合而成的。一般而言,時序數據查詢是聚合的。這與從數據庫檢索單條記錄是截然不同的。

在時序場景中使用傳統數據庫所面臨的問題

很多解決方案會依然在關係型數據庫中存儲時序數據。這種方式有很多缺點,這主要是因為關係型數據庫:

  • 是針對事務性使用場景設計的,並對此進行了優化。
  • 會帶來鎖和同步的開銷,對於不可變的時序數據來說,這是沒有必要的。這會導致數據攝入和查詢的性能都比要求更慢。企業最後只能投資額外的計算資源實現擴展。
  • 會對標籤強制定義嚴格的結構,不能存放非結構化的數據。
  • 需要定期的任務來清理舊數據。
  • 會用於多個使用場景。時序數據查詢的過量使用可能會影響其他的工作負載。

重新思考時序數據庫

專門的時序數據庫解決了處理時序數據的需求。它同時移除了關係型數據庫強加的限制。RedisTimeSeries是一個專門構建的用來收集、管理和交付大規模時序數據的方案。它提供瞭如下的功能:

  • 快速的數據攝入:作為一個內存數據庫,RedisTimeSeries可以在單個節點上每秒鐘攝入超過500000條記錄。根據我們的基準測試,在16個Redis分片(shard)的集群中,每秒可以攝入超過1150萬條記錄。
  • 高效的資源使用:借助RedisTimeSeries,我們可以通過縮減採樣(downsampling)的方法添加規則來壓縮數據。舉例來說,如果我們每天會收集超過10億個數據點,但是,我們可以按照每分鐘對這些數據進行聚合,從而實現縮減採樣,所以這樣可以把數據集縮減到24 * 60 = 1440個數據點。我們還可以設置數據保留策略,在不需要它們的時候將其設置為過期失效。

如何使用Redis TimeSeries和Grafana實現實時分析 1

圖1:使用時序數據庫縮減採樣和聚合

  • 簡單快速的查詢:RedisTimeSeries允許我們根據平均值、最小值、最大值、總和、計數、範圍、第一個和最後一個來聚合數據。我們可以以毫秒級的延遲每秒鐘運行超過100,000個聚合。我們還可以在特定的時間範圍內對標籤執行反向查找。

其他專門適用於時序數據的數據庫包括Influx DB和Prometheus。

典型的時序數據庫通常就是為了管理時序數據來構建的,所以它所面臨的一項挑戰就是在時序數據之上進行某些計算的使用場景。舉例來說,我們要在時序數據庫中捕獲實時視頻。如果我們要使用某種AI模型進行人臉識別,那麼必須要抽取時序數據、應用某種類型的數據轉換,然後再進行計算。對於實時使用場景來說,這種方式並不理想。多模型的數據庫還能夠管理其他的數據模型,這樣的數據庫解決了這些使用場景的問題,它們可以在恰當的位置操作多個數據模型。

RedisTimeSeries快速指南

開始學習RedisTimeSeries的最便捷方式就是將其作為數據源添加到Grafana儀錶盤中。在本文的下一節中,我將會展示如何加載樣例時序數據到RedisTimeSeries中,並在Grafana儀錶盤中瀏覽該數據。

我選擇比較蘋果公司(Apple Inc.,AAPL)和英特爾公司(Intel Inc.,INTC)過去19年間的股價表現,在這裡會使用Grafana面板上的圖表:

如何使用Redis TimeSeries和Grafana實現實時分析 2

圖2:使用RedisTimesSeries和Grafana對比蘋果和英特爾的股價

我的RedisTimeSeries搭建過程

我首先從GitHub下載了RedisTimeSeries的源碼,並在本地進行構建。隨後,我使用命令將“.so”文件導入到Redis中:

MODULE LOAD (path to)/redistimeseries.so

我也可以通過在redis.conf中插入以下命令來加載模塊:

loadmodule (path to)/redistimeseries.so

如果你更喜歡Docker的話,那麼可以嘗試執行如下的命令:

docker run -p 6379:6379 -it --rm redislabs/redistimeseries

Redis服務器啟動之後,我們可以通過運行“module list”命令檢查Redis是否已經成功加載模塊。如下所示,“timeseries”作為一個模塊列到了下面:

127.0.0.1:6379> module list1) 1) "name"   2) "timeseries"   3) "ver"   4) (integer) 200

示例數據集:過去19年的股票市場數據

我從Wall Street Journal網站下載了AAPL和INTC的每日股票價格。該文件以csv(逗號分隔值)的格式包含了從2000年到現在的價格信息。如下是AAPL的一些示例數據:

2006-01-03,10.34,10.68,10.32,10.68,201853036,AAPL2006-01-04,10.73,10.85,10.64,10.71,155225609,AAPL2006-01-05,10.69,10.7,10.54,10.63,112396081,AAPL2006-01-06,10.75,10.96,10.65,10.9,176139334,AAPL2006-01-09,10.96,11.03,10.82,10.86,168861224,AAPL2006-01-10,10.89,11.7,10.83,11.55,570088246,AAPL2006-01-11,11.98,12.11,11.8,11.99,373548882,AAPL2006-01-12,12.14,12.34,11.95,12.04,320201966,AAPL2006-01-13,12.14,12.29,12.09,12.23,194153393,AAPL2006-01-17,12.24,12.34,11.98,12.1,209215265,AAPL

接下來,我編寫了一個Python腳本將該數據導入到RedisTimeSeries中:

import sysimport csvimport timeimport redisif(len(sys.argv) > 1):   ticker = str(sys.argv(1))else:   ticker = 'test'file = ticker + '.csv'r = redis.Redis(host='localhost', port=6380, db=0)with open(file) as csv_file:   csv_reader = csv.reader(csv_file, delimiter=",")   r.execute_command("ts.create stock:"+ticker);   count = 0   for row in csv_reader:      time_tuple = time.strptime(row(0), '%Y-%m-%d')      time_epoch = time.mktime(time_tuple)*1000      r.execute_command("ts.add stock:"+ticker+" "+str(int(time_epoch))+" "+row(1))      count = count + 1   print(f'Imported {count} lines')

可以看到,我在這裡使用RedisTimeSeries的TS.CREATE命令來建立新的時序數據結構,並使用它的TS.ADD命令填充該數據結構。對於代碼為AAPL的股票,該程序創建了名為stock:aapl的數據結構。添加數據的樣例命令如下所示:

TS.ADD stock:aapl 1513324800000 173.04

接下來,我運行TS.RANGE命令來校驗數據。請注意,該查詢中所使用的時間戳是毫秒級別的。

127.0.0.1:6379> TS.RANGE stock:aapl 1513324800000 1514324800000 aggregation avg 11) 1) (integer) 1513324800000   2) "173.63"2) 1) (integer) 1513584000000   2) "174.88"3) 1) (integer) 1513670400000   2) "174.99000000000001"4) 1) (integer) 1513756800000   2) "174.87"5) 1) (integer) 1513843200000   2) "174.16999999999999"6) 1) (integer) 1513929600000   2) "174.68000000000001"7) 1) (integer) 1514275200000   2) "170.80000000000001"

在下一節中,我將會闡述如何使用Grafana來瀏覽和對比股票價格。

在Grafana中瀏覽RedisTimeSeries數據

在本節中,我將會介紹如何安裝Grafana,並使用SimpleJSON數據連接器從RedisTimeSeries中讀取數據。為了實現這一點,我開發了一個新的SimpleJSON數據源應用程序。它是一個中間層,是基於HTTP的Node.js應用,它會將SimpleJSON調用轉換為Redis調用,並將RedisTimeSeries數據轉換為JSON數據。

第一步:安裝Grafana

首先,我使用homebrew工具將Grafana安裝到我的Mac電腦上(如果你使用PC的話,請按照Grafana的使用說明安裝並搭建環境)。我運行如下的命令啟動Grafana:

$ brew install grafana$ brew services start grafana==> Successfully started `grafana` (label: homebrew.mxcl.grafana)

Grafana現在已經在3000端口運行了,因此我們可以使用http://localhost:3000登錄。

第二步:開發和運行SimpleJSON數據源應用

Grafana有一個內置的數據源連接器,名為SimpleJSON,它能夠連接至支持“/”、“/search”和“/query” HTTP服務器的任意應用程序。因為RedisTimeSeries目前還沒有自己的連接器,所以我開發了一個新的Node.js應用程序,它支持HTTP協議,並且支持SimpleJSON數據源應用所需要的查詢。你可以從GitHub上下載我的代碼,並在本地Node.js環境中運行它。

SimpleJSON數據源應用中的每個HTTP查詢都有特定的目的,針對每個HTTP查詢,我基於如下的設計原則開發了我的程序:

1. “/”:這是一個默認的請求,其響應是任意的消息。它用來測試連接(類似於ping測試)。

2. “/search”:該查詢應該返回持有時序數據的key列表。 (在其他數據庫中,這可能是表名的列表,而不是key的列表,但是,因為Redis是key-value存儲,所以我們返回的是key的列表,它們用來表示時間序列的特定類型。)

為了獲取key的列表,我使用了更安全的“SCAN”命令來替換“KEYS”。對於每個key,我會檢查它是不是“TSDB-TYPE”類型,這是我們用於時序key的內部名稱。程序維護了所有該類型key的一個數組,並以JSON格式返回這個數組。

3. “/query”:該查詢接收輸入參數,其中包含了key的列表、開始時間、結束時間和bucket時間。應用程序會基於傳入的命令以JSON格式返回時序數據。

另外,還有第四個HTTP請求,名為“/annotations”,但是對於示例應用程序來說,我們並不需要這個請求。

代碼就緒之後,我就可以運行node應用程序了。示例代碼在3333端口監控HTTP請求,所以我可以在瀏覽器中通過訪問http://localhost:3333對其進行測試。它將會返回:“I have a quest for you!”。

第三步:使用RedisTimeSeries連接Grafana

在所有的步驟中,這是最簡單的一步。在登錄Grafana之後,我添加了一個數據源,這是通過訪問Configuration > Data Sources並點擊“Add data source”實現的。

如何使用Redis TimeSeries和Grafana實現實時分析 3

我搜索SimpleJSON選項並選中它。

如何使用Redis TimeSeries和Grafana實現實時分析 4

這會打開一個配置界面,在這裡輸入URL,以便於連接至我的Node.js應用。

如何使用Redis TimeSeries和Grafana實現實時分析 5

數據源配置完成之後,我就可以添加新的面板到儀錶盤中。對於本例來說,我添加了一個具有兩項查詢的面板:對於每個股票的行情各有一個時序查詢。如圖所示,我的查詢所對應的下拉菜單中已經填充了時序key,即:stock:aapl and stock:intc。我選完時序key之後,該圖表將會立即填充上數據。在幕後,SimpleJSON連接器已經使用對應的查詢(“/search”和“/query”)調用了我們的應用程序。

如何使用Redis TimeSeries和Grafana實現實時分析 6

如何使用Redis TimeSeries和Grafana實現實時分析 7

這就是最終結果:Grafana面板能夠查詢RedisTimeSeries了。搭建RedisTimeSeries並將其連接至Grafana是非常簡單的。

總而言之,RedisTimeSeries結合了Redis和專門的時序數據庫的所有優點。它能夠以多種方式來幫助我們的業務,包括節省資源、支持更多的終端用戶,並且借助便捷的集成,能夠讓我們的應用更快地推向市場。通過集成Grafana與RedisTimeSeries,我們可以實時放大或縮小圖表。每秒鐘我們可以處理更多的查詢,從而能夠讓儀錶盤的面板上展示更多的數據點。基於此,我們能夠添加更多的面板,服務於更多的用戶。

作者簡介

Roshan Kumar是Redis Labs, Inc的高級產品經理。他在軟件開發和產品管理方面有著豐富的經驗。以前,Kumar曾在惠普(Hewlett-Packard)和多家成功的矽谷創業公司工作。他擁有美國加利福尼亞州聖克拉拉大學的計算機科學學士學位和MBA學位。

原文鏈接:

How to Use Redis TimeSeries with Grafana for Real-time Analytics