Spotify如何從Apache kafka遷移到雲平臺的pub/sub系統

banq發表於2019-11-14

Spotify是一家提供資料資訊的公司,在這樣的公司中,事件傳遞是關鍵元件。包含有關使用者,他們採取的操作或數百個系統中的操作日誌的資料的每個事件都是有價值的資訊。沒有成功的事件傳遞系統,我們將無法深入瞭解使用者併為他們提供他們喜歡的個性化內容。

2015年,當Spotify決定將其基礎架構移至Google Cloud Platform(GCP)時,很明顯,我們需要在雲中重新設計Event Delivery。這篇文章是我們關於Spotify事件傳遞的部落格系列的下一部分。前三個可以在Spotify的事件交付中找到-通往雲之路(第一部分)(第二部分)(第三部分)。自從我們撰寫了最初的3篇部落格文章以來,我們已經在Cloud中執行了Event Delivery已有2.5年了,我們認為現在是該系列部落格中另外兩個部分的時候了。在本部分(IV)中,我們將討論已實現的目標以及從原始計劃中獲得的收益,正在採取的後續步驟以及如何通過向上移動雲中的堆疊來發展和簡化。在那2.5年中,很多事情發生了變化,我們有了新的要求。現在,我們正在開發下一代事件傳遞,我們將在本部落格系列的第V部分中進行介紹。

事件傳遞系統

我們花了將近一年的時間來設計,編寫,部署和擴充套件當前的Cloud Pub / Sub的事件交付系統完全投入生產。從一開始,該系統就應該僅在雲(GCP)中執行,而我們實現了這一目標。為了快速迭代,我們使生產和使用介面與舊系統相容。此設定使我們能夠並行執行兩個系統,以便比較所有交付的資料是否完整。這對於我們通過嚴格的稽核要求至關重要,這在當時是一個緊迫的問題。由於我們確保新的事件交付系統已準備就緒,可以滿足嚴格的IT稽核要求,因此首先將關鍵業務資料遷移到新系統是有意義的。

關鍵業務資料的示例包括EndSong事件(Spotify使用者結束收聽曲目時發出的事件),該事件用於向唱片公司和藝術家支付版權費,計算每日活動使用者(DAU),每月活動使用者(MAU);和UserCreate事件(指示新的Spotify使用者帳戶的事件)。

我們計劃進行務實且分階段的部署,但是並沒有按計劃進行。我們僅在一天之內就將新系統部署到了100%的流量中,並且令人驚訝地執行良好。

2017年2月,我們取消了現有的基於Kafka的系統,新系統已成功執行,此後每天交付數十億個事件。

自從我們將基於GCP的事件交付系統投入生產以來,Spotify的使用者基礎有了驚人的增長。在2016年至2018年之間,我們的MAU翻了一番以上,現在為232M MAU(截至2019年8月5日)。系統全面投入生產後,我們達到了150萬個事件/秒(e / s),僅比我們在設計階段所測試的最大值少了0.5M e / s(請參閱第二部分中的更多內容)。到2019年第一季度末,我們在全球峰值產量超過了8M e / s。有500多種不同的事件型別,每天總計有超過350 TB的事件(原始資料)流經我們的系統,這些事件來自我們的客戶和內部系統。

原則,策略和重大決策

這些數字令人印象深刻,那麼,讓我們構建如此可擴充套件的基礎架構的原則是什麼?讓我們分享一些。

1.每個事件型別的隔離

事件型別由生產者定義,它具有名稱,架構和後設資料。從基於Kafka的系統的運維困難中,我們瞭解到並非所有事件都是平等的,我們可以利用這一點對我們有利。事件型別具有優先順序,並且可能會根據下面列出的某些屬性而有所不同:

  • 業務影響事件型別–有些用於向唱片公司和藝術家支付版權費,有些用於計算公司關鍵指標。這些事件型別均受外部SLA的約束,以便及時交付並保證質量
  • 批量事件型別–每小時發出幾百次,有些每秒發出1M +次。
  • 大小事件型別–大小在幾位元組到幾十千位元組之間變化。

為了防止大量或嘈雜的事件破壞業務關鍵資料,我們選擇儘快隔離事件流。事件型別緊接在事件服務之後,事件服務是我們基礎結構的入口點。它負責解析和識別事件型別,並將其釋出到Cloud Pub / Sub(Pub / Sub)。

格式錯誤或無法識別的事件將被拒絕。最後,每個事件型別都有其自己的釋出/訂閱主題,提取,轉換,載入(ETL)過程以及最終儲存位置。

此設定使我們可以靈活地單獨交付每個事件型別。出於運維目的,事件型別按重要性進行區分:高,中和低,並且每個重要性級別都有單獨的優先順序和服務級別目標(SLO)。

這使我們能夠在事件發生期間確定工作和資源的優先順序,以便首先交付最關鍵的事件。我們還錯開警報,以免在不太重要的事件型別出現問題時在深夜醒來。我們最嚴格的SLO如下:

  • 高優先順序–幾個小時的SLO
  • 正常優先順序– 24小時SLO,為第二天會出現事件的選擇
  • 低優先順序– 72小時SLO,主要在內部使用,用於下一個工作日所需的事件

您可以在《網站可靠性工作手冊》(線上提供,第13章–資料處理管道,案例研究:Spotify)中與我們共同撰寫的一章中,從操作角度閱讀更多關於我們如何維護事件交付管道的資訊。

2.活著超過延遲

傳遞的事件按小時劃分;這意味著每個事件型別都有一個儲存事件的不可變的每小時時段。請參見圖3,每小時的時段由正方形表示,每種顏色表示給定的事件型別,例如,帶有T14標籤的深紅色正方形表示一個不可變的時段),其中包含即抵達到我們的系統13:00至14:00之間UTC(紅暗事件型別)的所有事件,由於每個事件型別前面提到的分離,我們選擇優先活著超過延遲。  換句話說,嘈雜的,破碎或受阻止的事件型別不會都塞系統的其餘部分。

您可以在可靠地將Cloud Pub / Sub流匯出到Cloud Storage中瞭解有關此概念的更多資訊,該部落格文章解釋了我們ETL的所有技術。

3.關注點分離和自動縮放

我們的系統包含將近15種不同的微服務,這些微服務部署在大約2500個VM上。這使我們能夠分別處理它們中的每一個,並在需要時進行替換。每個元件都被單獨監視,這使得除錯和發現瓶頸變得容易。當然,將變更引入如此具有業務關鍵意義的大型系統存在風險。為了使我們能夠自信地進行迭代,我們提供了端到端整合測試,暫存環境和Canary機器。這些服務中的一些是自動縮放的,這就是為什麼前面提到的VM數量有所不同的原因。具有數百臺機器的自動伸縮基礎架構的最大挑戰是其狀態始終在變化。這成為我們的痛點之一。有了我們現在已經達到的規模,使用Spotify的部署工具進行自動擴充套件會導致整個團隊的部署最多需要三個小時!這意味著儘管系統設計用於安全且快速的迭代,但是由於部署工具的侷限性,現在不幸的是我們的迭代週期很長。

您可以在下面閱讀有關我們配置的更多資訊自動擴充套件Pub / Sub使用者

4.管理服務

作為Spotify遷移到雲的一部分,該策略一直是將耗時的問題外包給Google和GCP,這些問題對於我們的業務而言並非核心。特別是,我們利用了託管訊息佇列,資料處理和儲存的優勢。我們系統的骨幹是Cloud Pub / Sub雲端儲存(GCS)是最終資料集和中間資料的主要儲存。ETL建立在Compute Engine(GCE)例項(每個事件型別為一個群集,使用區域託管例項組),CloudSQL(用於後設資料)和Dataproc(用於重複資料刪除)的基礎上。我們使用Dataflow作業對事件中的敏感資料進行加密。我們使用BigQuery 用於資料倉儲,此工具已成為資料工程師,資料科學家,分析師,產品經理以及大多數希望與事件資料進行互動的人的最愛。

我們通過所有這些託管服務實現穩定的途徑已經成功,但並非一帆風順。我們與Google建立了牢固的合作關係,並且瞭解了很多有關在雲中構建基礎架構的知識。使用託管服務時,需要考慮以下幾點:

  • Google支援工程師全天候提供服務,這非常有價值。
  • 工程師只需單擊幾下,便可以快速將其想法轉化為基礎架構專案。儘早構建概念可以減少以前嘗試新事物所需的時間,並且可以大大降低與失敗相關的風險。
  • 使用alpha或beta產品的價值。雲提供商需要新產品的早期採用者,並且通過及早提供反饋,您就可以吸引組織可能會從中受益甚至可以決定產品未來的功能請求。
  • 有時,事情開箱即用。由主要的雲提供商構建的解決方案是通用的,以便滿足各種不同的需求。您所做的工作很可能在某種程度上很特別。就我們而言,通常是我們的規模。我們成功地為許多託管服務構建了自己的擴充套件和庫。隨著時間的推移,這些擴充套件已經過時了,但是我們接受限制並建立擴充套件的意願是交付專案的主要部分。如果您遇到限制併為您的用例構建擴充套件,那麼它很有可能在整個社群中都很有價值,這是開源貢獻的絕佳機會(請參閱我們的GitHub個人資料)。

5. 測試新想法,快速失敗,更快恢復

在遷移到雲服務期間,由於可用的選項並非最合適,因此我們需要建立自定義解決方案。在嘗試根據我們的需求量身定製雲服務時,我將提供三個試驗和錯誤經驗的示例。

資料流是一個出色的資料處理框架,可以根據型別和處理時間實時對資料進行分割槽。這聽起來像是我們的ETL流程的理想選擇-這個想法失敗了。當我們試圖生產我們的概念證明時,我們遇到了問題。我們撰寫了有關此初始計劃的詳細資訊以及將Cloud Pub / Sub流可靠匯出到Cloud Storage中失敗的內容。

另一個例子是我們試用Pub / Sub的經驗。當我們開始採用該服務的早期採用者時,我們的計劃是使用官方Java客戶端庫-這也失敗了。他們要麼還沒有準備好,要麼就不能滿足我們的用例和規模要求。但是,我們仍然在Pub / Sub上出售,因此決定編寫自己的庫供釋出和使用。在改用Google的圖書館之前,我們已經在生產中成功使用了這些庫一年以上。

建立和維護定製解決方案可能很困難,並且軟體很快就會過時。使用推薦的客戶端或庫時不是這種情況,因為只要產品可用,雲提供商通常就必須提供更新。此外,自定義解決方案降低了客戶支援專家提供的價值,因為他們很難確定問題是在雲供應商的基礎架構內還是在您的磁帶庫內。

事件傳遞即服務

我們有數百個團隊擁有500多種不同的事件型別,這些團隊很可能是給定事件型別的生產者。但是,某些事件型別是通用的,並且在許多團隊之間共享,例如PageView。所有者可以完全控制其事件型別,但最重要的是,他們所需的更改不需要我們的參與。他們可以隨時定義並開始發出新的事件型別。所有者可以將不同型別的儲存(GCS或BQ)和分割槽策略(每小時或每天)應用於其事件型別定義。我們允許所有者以向後相容的方式來發展事件型別的模式(我們使用Apache Avro)。受此限制,消費者可以讀取長達10年的歷史記錄,並使用相同的程式碼來開發資料,而無需回填資料集。

所有這些自動化基礎架構均由集中式協調器管理,以獲取所需的雲資源。對於每種事件型別,它都會建立一個單獨的釋出/訂閱主題和訂閱,ETL叢集(並計劃ETL作業),分發其架構,向適當的SLO註冊它,並在所有不同的微服務和管道上配置監視。在正式棄用“事件型別”之後,該作曲者還負責所有清理工作。這種集中式服務是執行時元件,但是我們希望下一次迭代成為宣告性和靜態資源,例如配置檔案。

得到教訓

設計按比例縮放的系統時,一個好的方法是為系統提供容量模型。這將幫助您計算每種資源所需的配額,並隨著規模的增加而平穩執行。有趣的是,我們觀察到資料增長比服務流量快一個數量級。

大系統要花大錢

我們開始開發該系統的目的是減少摩擦,以便我們可以收集儘可能多的資料。兩年,研發翻了一番org以後,我們收集的資料超出了我們的使用範圍。花錢沒事,但浪費錢不對。具有數百萬使用者和數千個VM的系統將花費大量資金,無論它是在您自己的資料中心中執行還是外包給雲提供商。最初,有意識地決定從資料社群中提取資料生產成本,以不妨礙學習和創新。不利的一面是,它變得太容易浪費,有時浪費大量金錢。當前,我們正在努力在不受限制的創新和成本意識之間尋求平衡。間歇性和短期節省成本的衝刺一直是減少浪費的好方法,同時允許在新專案上不受限制地支出。

相關文章