Spotify的監測框架(上)
【編者的話】 Spotify 是全球最大的正版流媒體音樂服務平臺。Spotify提供的服務需要一個巨大的基礎設施平臺作為支撐,而監測這個平臺的運行顯得至關重要。Spotify實驗室的 John-John Tedro 近日對Spotify的監測進行了一個簡單的介紹。作為該系列文章兩個部分的 第一篇 ,本文主要介紹了Spotify的監控的歷史,當前面臨的挑戰,以及Spotify又是如何解決這些挑戰的。
Spotify的運行監測一開始是作為兩個系統的組合,即Zabbix和sitemon,其中sitemon是一個 支持RRD 的土生土長的圖形系統,它采用 Munin 用來進行數據收集。 Zabbix的所有權屬于我們的SRE團隊,而sitemon由我們的后端基礎架構團隊負責運行。當時,我們的團隊很小,身邊的很多問題常常都是由自己親手解決。我們采取了這種方案的原因更多的是因為我們選擇這個問題。
從2013年年底起,我們開始把更多的注意力放在 自助服務和分布式運行監測 上。我們想停止監測單個主機,并開始將服務作為一個整體考慮。Zabbix并不適合,因為它主要關注單個主機。唯一可以操作它的是SRE團隊的成員。隨著整個基礎設施變得越來越龐大,我們的系統在強大的負載壓力下開始產生裂痕。
我們也在試圖盡力將目前的工作做一些改進:基于內存的sitemon方案僅僅能在當前負載壓力下保存大約1個月的指標數據,從而我們的首席架構師 提出了一種新的替代方案。在這種方案下,雖然我們還有一些喘息的空間,但我們估計我們最多只能持續一年。出于這樣的體驗,Spotify組建了一個新的團 隊:Hero。他們的目標是改進Spotify的監測,并為未來做好準備。不惜一切代價。下面是他們采取的主要做法。
報警作為一種服務
報警是我們需要攻克的第一個問題。
我們考慮進一步發展Zabbix。它使用 觸發器表達式 來檢查報警條件。我們在系統中觀測到大量位衰減,許多正在運行的觸發器很難理解、已經損壞或無效。這就引出了我們為下一代警報系統所提出的其中一個要求: 它必須使得對觸發器的測試變得簡單,以使其容易理解。Zabbix的可擴展性也是一個問題。在接下來兩年中,我們不相信我們的系統可以在我們預期的規模上 運行。
在參加 Monitorama EU 時,我們偶然發現了 Riemann 。一個分布式監測系統解決方案。Riemann并沒有提供不確定情況下的可擴展性,但對于無狀態規則的偏愛很容易地讓它可以對負載進行劃分和分配。我們為一個服務中的每個主機配對至少兩個實例,這些實例運行了相同的規則集。
我們在Riemann之上建立了一個庫,稱為 Lyceum 。這使我們能夠建立一個git倉庫,倉庫內部,每一個方格可以將它們的規則放入一個隔離的命名空間中。使用這個配置,我們的工程師可以定義可重復的集成測 試。它使得任何人可以打開repo,并可以在產品中直接部署這些變更。我們的立場發生了改變,如果測試通過,我們便知道它的工作原理。這被證明是非常成功 的。Clojure是一門遠遠比觸發器表達式更易于理解的語言,基于git的審查過程更適合我們的開發方法。
制圖
在這個方面,我們折騰了好幾次。我們初始的堆棧是基于Munin的,其中的插件對應著收集到的所有東西。一些指標是標準的,但最重要的那些是服務指標。
切換到基于push的方式來降低我們選用工程師的門檻,是值得期待的。使用Munin的經歷告訴我們,復雜的定義指標的過程會延緩最后指標的采 納。基于Pull的方法需要配置讀出什么,以及從哪里讀出。而用Push的方法,你會忘記在最近的API中的樣本,最好使用一個共同的協議。考慮一個短暫 的任務,其中可能沒有足夠的時間被收集器發現。但對于Push來說,這并不是問題,因為是任務本身控制了度量的發送。
如果您想了解更多, sFlow 和 Alan Giles 針對這個問題進行了更深入的分析。
我們最初的實驗中,部署了一個基于 collected 和 Graphite 的通用解決方案來積累經驗。分析性能測試的結果,我們感覺對這種垂直的可擴展性并不滿意,我們不想只有一個Graphite節點。
whisper 寫入模式涉及到 跨眾多文件的隨機搜尋和寫入 。文件搜索過程中的向下采樣,存在一個很高的成本。
分片和再平衡Graphite存在的困難也經常讓人望而卻步。其中的一些可能最近通過使用后端支持的Cyanite已經得到了解決。但對我們來說,Graphite仍然遭受了一個重大的理論障礙:分層命名。
數據層次
Graphite中一個典型的時間序列按照類似下面這種方式命名:
確切的形式分情況不同,但是這可以被視為一個固定的層次結構。在一些情況下這種方式工作得很好,因為它們本質上就是層次結構。但是,如果我們想在 一個特定的網站選擇所有服務器。我們有兩個選擇:我們希望服務器名稱在不同的基礎架構中保持一致,并執行通配符匹配;或者為了解決這個問題,我們可以對命 名層次結構進行重新洗牌:
這種類型的重構是很難的。
沒有正確的答案。一個團隊可能要求將網站作為篩選的主要手段,也可能希望將角色作為篩選的主要手段。這兩個要求具有相同的優點。因此,弱點也都在于命名方案。
標簽
在解決這個問題中有一個完全不同的方式,即考慮將一個時間序列的標志符由一組標簽組成。
看看我們前面的例子,我們將現有層次結構映射到一組標簽。
通過一個過濾系統,其能夠讓工程師將內部組件相互連接的一大片時間序列進行拆分。提高了互操作性。
這樣一來,這就沒有了我們必須嚴格遵守的層次結構。按照慣例,他們可能是結構的一部分(“網站”和“主機”總是存在),但它們既沒有被要求,也不是嚴格有序的。
Atlas 、 Prometheus 、 OpenTSDB 、 InfluxDB 和 KairosDB 都是使用標簽的數據庫。 Atlas和Prometheus被認真考慮過,但在時間上并不可用。我們最終并沒有選擇OpenTSDB,因為在使用HBase時的糟糕的運行體驗。 InfluxDB不成熟,因為它缺乏自助服務的功能,而這正是我們需要推出的。KairosDB似乎像最好的選擇,所以我們進行了廣泛的試驗。但發現它在 性能和穩定性上存在問題,我們試圖做一些努力,但均告失敗。我們認為該項目由于缺乏社區的參與,并沒有朝著我們期待的方向前進。
受KairosDB的啟發,我們開始了一個新的項目。我們針對這個項目做了一些小的實踐,并取得了可喜的成果,所以我們堅持下來了,并給它取了一個名字;Heroic。
請繼續關注下一篇文章,我會介紹Heroic,即我們的可擴展的時間序列數據庫。