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

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

10.jpg

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

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

11.jpg

(使用Goku進(jìn)行兩級(jí)分片)

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

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

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

時(shí)間序列查詢

除了開(kāi)始時(shí)間和結(jié)束時(shí)間之外,每個(gè)查詢都由以下部分或全部組成:度量標(biāo)準(zhǔn)名稱、過(guò)濾器、聚合器、降采樣器、速率選項(xiàng)。

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

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

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

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

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

挑戰(zhàn)

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

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

2)數(shù)據(jù)大?。篛penTSDB中的數(shù)據(jù)點(diǎn)是20字節(jié)。Pinterest采用Gorilla壓縮來(lái)實(shí)現(xiàn)12倍壓縮。

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

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

架構(gòu)

存儲(chǔ)引擎

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

12.jpg

(存儲(chǔ)引擎簡(jiǎn)介。請(qǐng)查看Gorilla論文(http://www.vldb.org/pvldb/vol8/p1816-teller.pdf)及其GitHub存儲(chǔ)庫(kù)(https://github.com/facebookarchive/beringei)來(lái)了解詳細(xì)信息)

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

為了實(shí)現(xiàn)持久性,BucketData也會(huì)寫(xiě)入磁盤(pán)。當(dāng)Goku重新啟動(dòng)時(shí),它會(huì)將數(shù)據(jù)從磁盤(pán)讀入內(nèi)存。Pinterest使用NFS來(lái)存儲(chǔ)數(shù)據(jù),從而實(shí)現(xiàn)簡(jiǎn)單的分片遷移。

分片和路由

我們使用兩層分片策略。首先,我們對(duì)度量名稱進(jìn)行散列,以確定某一時(shí)間序列屬于哪個(gè)分片組。我們?cè)诙攘棵Q+標(biāo)記鍵值集上進(jìn)行散列,以確定時(shí)間序列在所在組中的哪個(gè)分片。此策略可確保數(shù)據(jù)在分片之間保持平衡。同時(shí),由于每個(gè)查詢僅進(jìn)入一個(gè)組,因此扇出保持較低水平,以減少網(wǎng)絡(luò)開(kāi)銷(xiāo)和尾部延遲。另外,我們可以獨(dú)立地?cái)U(kuò)展每個(gè)分片組。

查詢引擎

倒排索引

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

聚合

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

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

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

典型的查詢流程如下:

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

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

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

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

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

13.jpg

性能

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

14.jpg

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

15.jpg

下一步

基于磁盤(pán)的長(zhǎng)期數(shù)據(jù)存儲(chǔ)

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

16.jpg

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

復(fù)制

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

分析用例

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

Pinterest表示將繼續(xù)探索Goku的用例,如果你對(duì)此類(lèi)項(xiàng)目感興趣,請(qǐng)查看: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)說(shuō)明:
本文內(nèi)容來(lái)自于AI前線,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
個(gè)人VIP
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪
投稿采訪
出海管家
出海管家