均一好省-如何降低系統平台費用

這一篇主要是寫給後端工程師,並且是對於降低系統平台費用有興趣的人看的,如果是對前端、資料有興趣的,請期待我們其他工程師的文章。

隨著平台使用者越來越多、流量越來越大,Google Cloud Platform 的花費越來越高,降低平台費用成為工程師滿重要的一件事情。我們評估了一些可能的方向,短期來說,可以就 API、Backend Code 做優化,長期來說可以考慮調整系統架構,或是尋找更便宜的解決方案,而這一篇是針對短期方案做說明,也記錄我們最近三個月所做的努力。

系統費用分析

降低費用的第一步,我們要先知道我們到底把錢花在哪邊,在 GCP 的 Billing Page 有列各個 GCP 服務的花費,我們統計了一下各項花費,可以得到以下這張圖,Datastore Read、Frontend Instance Hours 這兩項佔了大宗,其實這個滿直觀的,因為均一本來就是架在 GAE 上,把錢花在資料讀取、以及開機器處理 request 這兩件事情上是相當容易理解。因此,我們可以把省錢這個 project 的目標先訂在

  1. 降低 Datastore Read
  2. 降低 Frontend Instance Hours

因為影響 Frontend Instance Hours 的因素滿多的,比較難掌握,而 Datastore Read 則比較直接,只要網站少 fetch 一個 entity,就直接省下一筆錢,所以這篇文章會聚焦於減少 Datastore Read。

為了降低 Datastore read,我們做了一個假設,我們只要知道使用者最常到訪哪個頁面,或者最常發出哪些 API,我們只要優化相關的頁面、API 的 Datastore Read,就可以降低費用了。因此,我們統計了 10 天內常用的 API 執行次數。

統計各個 API 的執行次數

根據統計,執行次數前 10 名的 API,就佔了全部執行次數的 6 成以上,所以只要優化前 10 名的 API,應該就可以降低不少費用,於是,我們開始仔細研究這些 API。不過,我們仔細看完之後,發現能優化的空間不多。

回到我們一開始的假設,執行次數高是不是就代表值得優化呢?其實不然,因為雖然有些 API 的執行次數很高,但是實際 Datastore Read 的次數卻很少,所以再怎麼優化這些 API ,也很難降低費用。我們少考慮了各個 API 的 Datastore Read 次數這項重要因子。

統計各個 API 的 Datastore Read 次數

要在 GAE 上計算各個 API 的 Datastore Read 不會太難,因為有一個叫做 AppStats 的工具,可以讓我們很方便的統計 Datastore Read,如下圖,他不僅告訴我們 Datastore Read,還有其他有用的資訊可以看,像是 server 在 Timeline 中實際到底做了什麼事情。我們開始用 AppStats 統計前 30 名的 API,看看到底是哪些 API 讀了很多資料出來。

統計完各個 API Datastore Read 後,我們現在又離事實更接近了一步,我們發現,有些 API 雖然排名前 10 名,但是他的 Datastore Read 非常低,所以可以先不要選擇他們來進行優化。相對的,我們也發現有些項目的 API 在10名以外 ,但它的 Datastore Read 卻異常地高,每次都會讀取上千筆資料出來,因此這是很值得優化的 API。將這支 API 優化後,大概可以下降 GCP 花費的 5%,不過這只是剛好遇到前人沒寫好後台的情況,不是天天都會發生。

我們期待的是找到 Datastore Read 總量多的項目,然後透過 Cache 、CDN 優化,來降低 Read 次數。在這過程中,也發現了一些 API 是符合上述條件的,像是抓習題的 API,因為習題不會天天改變,所以很適合我們用 Cache 策略降低 Datastore Read,而降低 Datastore Read 的同時也會縮短 Response Time,屬於一舉兩得的優化。

備份的 Datastore Read

但是事情是不是如我們想像的那麼順利呢?當然不是啦!我們將前面 30 名的 API 統計完之後,發現這跟帳單上的 Total Datastore Read 還有一大截距離,就算我們把不必要的 Datastore Read 拿掉,並且用 Cache、CDN 優化之後,也省不超過 10%,一定還有什麼漏算的!

我們後來熊熊發現,除了 API 之外,還有一個 Datastore Read 的大宗:備份,我們的備份大概佔了至少 50% 的 Datastore Read,如果按照現在使用者的成長速度,Backup 會越來越多,最終變成基金會費用的絆腳石。過去覺得沒有必要刪除 Datastore,因為覺得保留使用者資料很重要,可以給使用者看他們的學習歷程,還可以拿來訓練 Model,讓我們的推薦越來越精準,但是意識到 Backup 這麼貴,我們一定要想辦法開始刪除 Datastore 的資料。

這時候,我突然理解 Datstore Delete 這個操作的必要性,Datastore Delete 這個操作雖然需要費用,但是他能幫我們省下很多備份的 Datastore Read 花費。

後記

我們的省錢專案還在進行中,我們還在與他奮戰。接下來我們要在不改變使用者服務的情況下,嘗試把資料放到比較便宜的地方,像是 Cloud SQL、Cloud Storage 或是 BigQuery 等等,祝我們好運。