一文看懂Pinterest如何構(gòu)建時間序列數(shù)據(jù)庫系統(tǒng)Goku

來源: AI前線
作者:AI前線小組
時間:2021-01-06
16918
在Pinterest,開發(fā)人員依靠Statsboard來監(jiān)控系統(tǒng)并發(fā)現(xiàn)問題,因此,可靠有效的監(jiān)控系統(tǒng)對于開發(fā)速度來說非常重要。之前,Pinterest使用OpenTSDB來提取和提供指標數(shù)據(jù)。然而,隨著Pinterest的發(fā)展,服務器也從數(shù)百個增加到數(shù)千個,每秒產(chǎn)生數(shù)百萬個數(shù)據(jù)點,而且這個數(shù)字還在繼續(xù)增長。

10.jpg

在Pinterest,開發(fā)人員依靠Statsboard來監(jiān)控系統(tǒng)并發(fā)現(xiàn)問題,因此,可靠有效的監(jiān)控系統(tǒng)對于開發(fā)速度來說非常重要。之前,Pinterest使用OpenTSDB來提取和提供指標數(shù)據(jù)。然而,隨著Pinterest的發(fā)展,服務器也從數(shù)百個增加到數(shù)千個,每秒產(chǎn)生數(shù)百萬個數(shù)據(jù)點,而且這個數(shù)字還在繼續(xù)增長。

雖然OpenTSDB在功能上運行良好,但其性能隨著Pinterest的增長而降低,導致運營開銷(例如嚴重的GC問題和HBase經(jīng)常崩潰)。為了解決這個問題,Pinterest開發(fā)了自己的內(nèi)部時間序列數(shù)據(jù)庫——Goku,其中包含用C++編寫的OpenTSDB兼容API,以支持高效的數(shù)據(jù)提取和成本昂貴的時間序列查詢。

11.jpg

(使用Goku進行兩級分片)

時間序列數(shù)據(jù)模型

時間序列數(shù)據(jù)

Goku遵循OpenTSDB的時間序列數(shù)據(jù)模型。時間序列由一個鍵和一系列時間數(shù)字數(shù)據(jù)點組成。key=metric name+一組標記鍵值對。例如,“tc.proc.stat.cpu.total.infra-goku-a-prod{host=infra-goku-a-prod-001,cell_id=aws-us-east-1}”。數(shù)據(jù)點=鍵+值。值是時間戳和值對。例如,(1525724520,174706.61),(1525724580,173456.08)。

時間序列查詢

除了開始時間和結(jié)束時間之外,每個查詢都由以下部分或全部組成:度量標準名稱、過濾器、聚合器、降采樣器、速率選項。

1)度量名稱示例:“tc.proc.stat.cpu.total.infra-goku-a-prod”。

2)對標記值應用過濾器,以減少在查詢或組中拾取系列的次數(shù),并在各種標記上聚合。Goku支持的過濾器示例包括:完全匹配、通配符、Or、Not或Regex。

3)聚合器規(guī)定將多個時間序列合并為單個時間序列的數(shù)學方法。Goku支持的聚合器示例包括:Sum、Max/Min、Avg、Zimsum、Count、Dev。

4)降采樣器需要一個時間間隔和一個聚合器。聚合器用于計算指定時間間隔內(nèi)所有數(shù)據(jù)點的新數(shù)據(jù)點。

5)速率選項可選擇計算變化率。有關(guān)詳細信息,請參閱OpenTSDB數(shù)據(jù)模型(http://opentsdb.net/docs/build/html/user_guide/query/index.html)。

挑戰(zhàn)

Goku解決了OpenTSDB中的許多限制,包括:

1)不必要的掃描:Goku用倒排索引引擎取代了OpenTSDB的低效掃描。

2)數(shù)據(jù)大小:OpenTSDB中的數(shù)據(jù)點是20字節(jié)。Pinterest采用Gorilla壓縮來實現(xiàn)12倍壓縮。

3)單機聚合:OpenTSDB將數(shù)據(jù)讀取到一個服務器上并進行聚合,而Goku的新查詢引擎是將計算遷移到更接近存儲層的位置,該存儲層在葉節(jié)點上進行并行處理,然后在根節(jié)點上聚合部分結(jié)果。

4)序列化:OpenTSDB使用JSON,當有太多數(shù)據(jù)點要返回時,JSON會很慢;Goku使用thrift二進制代替。

架構(gòu)

存儲引擎

Goku在內(nèi)存存儲引擎中使用了Facebook Gorilla來存儲過去24小時內(nèi)的最新數(shù)據(jù)。

12.jpg

(存儲引擎簡介。請查看Gorilla論文(http://www.vldb.org/pvldb/vol8/p1816-teller.pdf)及其GitHub存儲庫(https://github.com/facebookarchive/beringei)來了解詳細信息)

如上所述,在存儲引擎中,時間序列被分成稱為BucketMap的不同分片。對于一個時間序列,也被分為可以調(diào)整時長的bucket(Pinterest內(nèi)部以每2小時為一個bucket)。在每個BucketMap中,每個時間序列都被分配一個唯一的ID并鏈接到一個BucketTimeSeries對象。BucketTimeSeries將最新的可修改緩沖區(qū)存儲區(qū)和存儲ID保存到BucketStorage中的不可變數(shù)據(jù)存儲區(qū)。在配置存儲bucket時間之后,BucketTimeSeries中的數(shù)據(jù)將被寫入BucketStorage,變?yōu)椴豢勺償?shù)據(jù)。

為了實現(xiàn)持久性,BucketData也會寫入磁盤。當Goku重新啟動時,它會將數(shù)據(jù)從磁盤讀入內(nèi)存。Pinterest使用NFS來存儲數(shù)據(jù),從而實現(xiàn)簡單的分片遷移。

分片和路由

我們使用兩層分片策略。首先,我們對度量名稱進行散列,以確定某一時間序列屬于哪個分片組。我們在度量名稱+標記鍵值集上進行散列,以確定時間序列在所在組中的哪個分片。此策略可確保數(shù)據(jù)在分片之間保持平衡。同時,由于每個查詢僅進入一個組,因此扇出保持較低水平,以減少網(wǎng)絡開銷和尾部延遲。另外,我們可以獨立地擴展每個分片組。

查詢引擎

倒排索引

Goku通過指定標記鍵和標記值來支持查詢。例如,如果我們想知道一個主機host1的CPU使用率,我們可以進行查詢cpu.usage{host=host1}。為了支持這種查詢,Pinterest實現(xiàn)了倒排索引。(在Pinterest內(nèi)部,它是從搜索項到位集的散列映射。)搜索項可以是像cpu.usage這樣的度量名稱,也可以是像host=host1這樣的標記鍵值對。使用這個倒排索引引擎,我們可以快速執(zhí)行AND、OR、NOT、WILDCARD和REGEX操作,與原始的基于OpenTSDB掃描的查詢相比,這也減少了許多不必要的查找。

聚合

從存儲引擎檢索數(shù)據(jù)后,開始進行聚合和構(gòu)建最終結(jié)果的步驟。

Pinterest最初嘗試了OpenTSDB的內(nèi)置查詢引擎。結(jié)果發(fā)現(xiàn),由于所有原始數(shù)據(jù)都需要在網(wǎng)絡上運行,性能會嚴重下降,而且這些短期對象也會導致很多GC。

因此,Pinterest在Goku中復制了OpenTSDB的聚合層,并盡可能地早地進行計算,以盡量減少線上的數(shù)據(jù)。

典型的查詢流程如下:

用Statsboard客戶端查詢(Pinterest的內(nèi)部度量監(jiān)控UI)任何代理goku實例

代理goku基于分片配置將查詢扇出到同一組內(nèi)的相關(guān)goku實例

每個goku讀取倒排索引以獲取相關(guān)的時間序列ID并獲取其數(shù)據(jù)

每個goku基于查詢聚合數(shù)據(jù),如聚合器、降采樣器等

代理goku在收集每個goku的結(jié)果并返回客戶端后進行第二輪聚合

13.jpg

性能

與之前使用的OpenTSDB/HBase解決方案相比,Goku在幾乎所有方面都表現(xiàn)更好。

14.jpg

另一個在使用Goku前后高基數(shù)查詢延遲對比圖,如下圖所示:

15.jpg

下一步

基于磁盤的長期數(shù)據(jù)存儲

Goku最終將支持超過一天時間數(shù)據(jù)的查詢。對于像一年這樣的時長查詢,Pinterest將不會過分強調(diào)一秒鐘內(nèi)發(fā)生的事情,而是關(guān)注整體趨勢。因此,Pinterest將進行降采樣和壓縮,把以小時計的bucket合并為更長期的時長,從而減小數(shù)據(jù)量并提高查詢性能。

16.jpg

(Goku階段#2——基于磁盤:數(shù)據(jù)包括索引數(shù)據(jù)和時間序列數(shù)據(jù))

復制

目前,Pinterest有兩個goku集群進行雙行寫入。此設置提高了可用性:當一個集群中存在問題時,可以輕松地將流量切換到另一個集群。但是,由于這兩個集群是獨立的,因此很難確保數(shù)據(jù)的一致性。例如,如果寫入一個集群成功而另一個未成功時,則數(shù)據(jù)寫入失敗,數(shù)據(jù)由此變得不一致。另一個缺點是故障轉(zhuǎn)移總是在集群層面發(fā)生。為此,Pinterest正在開發(fā)基于日志的集群內(nèi)復制,以支持主從分片。這將提高讀取可用性,保持數(shù)據(jù)一致性,并支持分片級的故障轉(zhuǎn)移。

分析用例

所有行業(yè)都需要廣泛的分析,Pinterest也不例外,例如面臨詢問實驗和廣告推廣效果等問題。目前,Pinterest主要采用離線作業(yè)和HBase進行分析,這意味著不會有實時數(shù)據(jù)產(chǎn)生,并避免大量不必要的預聚合。由于時間序列數(shù)據(jù)的性質(zhì),Goku可以很容易地適應它,不僅可以提供實時數(shù)據(jù),還可以提供按需聚合。

Pinterest表示將繼續(xù)探索Goku的用例,如果你對此類項目感興趣,請查看:https://careers.pinterest.com/careers/engineering。

原文鏈接:

https://medium.com/ Pinterest_Engineering/goku-building-a-scalable-and-high-performant-time-series-database-system-a8ff5758a181

立即登錄,閱讀全文
版權(quán)說明:
本文內(nèi)容來自于AI前線,本站不擁有所有權(quán),不承擔相關(guān)法律責任。文章內(nèi)容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權(quán),請聯(lián)系管理員(zzx@kchuhai.com)刪除!
優(yōu)質(zhì)服務商推薦
更多