五十度灰之石墨
互聯網產品通常有個特點:迭代的頻次較高。
而發布新特性或是系統升級總是伴隨著風險,比如:
- 新舊版本兼容的風險
- 用戶使用習慣突然改變而造成用戶流失的風險
- 系統不穩定的風險,因此採用灰度發布的方式
本文會通過5個案例來介紹灰度發布的一些策略,我們可以讓一部用戶繼續用A,一部分用戶開始用B,如果用戶對B沒有什麼反對意見,那麼逐步擴大範圍,把所有用戶都遷移到B上面來,這就是我們在本文中將會介紹的灰度發布。
灰度發布(又叫金絲雀部署)是指在黑與白之間,能夠平滑過渡的一種發布方式。灰度發布可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。
下面會舉例介紹幾種灰度發布的策略。
0.Cookie 篇
場景
某電商平台在周一時發布了一個大的改版,界面風格以及交互和原有的有很大不同。
問題
通過數據觀察發現,在發布了這個新的版本之後,用戶的轉化率相比之前降低了不少,此時已經對成交量造成了比較大的影響。
目前方案
此時的解決辦法只有全部回滾到原來的版本。
更優方案
那有沒有辦法能夠既發布了新的改版,但是又能把可能發生的風險降到最低呢?
石墨在使用的一種方案是使用 Cookie 來實現灰度。
根據維基百科對 Cookie 的解釋:
Cookie,中文名稱為「小型文本文件」或「小甜餅」,指某些網站為了辨別用戶身份而儲存在用戶本地終端(Client Side)上的數據(通常經過加密)。
本文中的用戶本地終端主要是指瀏覽器。
怎麼優化
石墨會使用什麼樣的方案來解決呢?當我們在發布產品時,新的版本不需要精確的灰度給某些特定用戶,那麼只是控制 Cookie 的比例即可讓部分用戶訪問到新的服務,而另一部分仍然使用原來的服務。
- 在用戶首次訪問時,會獲取到某個特定值的 Cookie ,例如 Cookie name 為 new_feature 的取值範圍從 1 到 100
- 如果我們控制的灰度比例是 50% 的用戶,那麼可以判斷 new_feature 值為 1 - 50 的用戶會看這個新的版本,而 Cookie 值 為 51 - 100 之間的用戶則依然訪問到了舊的版本。
- 如果發現了問題,可以回滾這一部分灰度的服務,待調整好之後再次灰度發布;如果發現灰度版本的表現比現有版本更好,可以提高灰度比例進一步觀察甚至到全量
在這樣的策略下,如果新的版本從數據上看體驗是更好的,那麼可以在下次發布時,將這一次的更新全量部署,若從發現存在一些缺陷或體驗不如原來的好,可以暫時回滾此次更新,避免更大的損失。這裡的 50% 並不是什麼標準,只是假設,通常灰度發布的比例會小的多,根據自己的產品影響程度決定。
1.用戶、用戶組篇
場景
我們現在又發布了一個新功能,優化了用戶中心的一些體驗,從上面的經驗來看,我們可以使用 Cookie 來進行灰度,這樣一部分用戶就可以看到這些新的版本了。
問題
但是很快我們就會發現有一個問題,有很多用戶其實並沒有經常發生購買行為,所以使用用戶中心的頻率較低,這樣我們在灰度發布這個新功能期間,就不能從數據上觀察出這個功能的體驗是否更好或更差。
目前方案
使用 Cookie 對系統進行隨機的進行灰度發布。
更優方案
石墨會怎麼處理這種場景呢?我們會選取特定的用戶或者用戶組進行灰度。
怎麼優化
- 我們找出購買頻率較高的用戶群,在這些用戶中選取一部分用戶,根據這些用戶ID或者用戶組ID進行灰度新功能
- 這些用戶訪問用戶中心時就會進入到新功能的界面,然後觀察這些活躍用戶和其他非灰度的活躍用戶比起來是使用頻次更高了,還是更低了或者是其他的數據指標來判斷那麼這樣得出的數據更能精確
- 再根據數據情況決定新的功能是否應該進一步擴大灰度範圍還是回滾或縮小灰度範圍。
- 將活躍用戶覆蓋後,再考慮非活躍用戶的灰度直至全量灰度。
2.後端服務篇
在我們產品發布時,有很多時候是用戶無法直接感知到功能明顯的改變,這種時候可能是在後端的服務調整,在用戶規模不大或者是活躍用戶不是非常多時,直接切換後端服務對用戶產生的影響會相對較小,但是如果用戶規模比較大或是訪問量較大的情況下,如果直接切換到新服務去,很有可能發生服務不穩定,導致服務崩潰而產生雪崩效應導致更多的服務不可用,這對於用戶是很難接受的,又或者是間接的導致轉化率下降,這對平台或者是商家也是無法接受的。
場景
戶在訪問某類商品列表時,系統會根據推薦演算法展示一些用戶喜歡會購買的商品。
問題
而原有的推薦演算法邏輯就在當前的業務系統中,隨著訪問量的增大,推薦演算法對業務服務的性能造成了影響並且轉化率也不夠理想,現在需要將推薦演算法獨立出來作為一個單獨的服務。新的演算法得出的結果可能更優有個風險就是相對舊的演算法消耗更多的CPU、內存資源。
目前方案
暫停服務,將原有的演算法直接遷移到新的演算法服務中,再啟動服務查看是否正常。
更優方案
這種情況下灰度發布可以在盡量保證系統的整體的穩定性的情況下,進行小範圍灰度,觀察新的服務效果更好,並且穩定性也過關,再逐步遷移。
怎麼優化
在石墨我們會這樣來處理:
- 針對某一分類 A 的商品開啟灰度,程序中發現是 A 分類則採用新的推薦演算法,而其他的分類 B、C、D 繼續使用原有的推薦演算法。
- 在灰度過程中觀察一下這個新的演算法運行過程中是不是穩定還有轉化率是否有所提升。如果這個服務比之前更優,那麼逐步將 B 分類也遷移到新的服務上來,C、D 分類保持原有邏輯。如果服務效果較差或是不太穩定,可將 A 分類暫時換回原有的邏輯。
- 逐步灰度直至全量完成。
這樣既保證了整體服務穩定性,也能及早的發現新服務的問題及時進行調整。
3.服務進程灰度
場景
有很多時候,我們會發現服務會遇到了一些性能問題,可能是我們在編碼時考慮的不夠全面,導致在極端場景下遇到性能問題。
問題
當我們嘗試使用一個優化的方案解決原有問題時,並不能完全確定還有沒有其他因素沒有考慮到,前面提到,每次的發布也是伴隨著一定的風險。
更優方案
所以我們這裡對一些會影響穩定性的更新時,依舊採用:
- 先將更新發布至部分服務節點
- 觀察灰度節點的情況
- 根據反饋擴大或縮小灰度
這種方式通常更多的偏向於通過運維手段來介入灰度的發布過程。
4.數據存儲篇
通常互聯網的產品都會經歷一個從無到有,從小到大的過程,數據量也會經歷從少到多的一個過程,相信大部分產品都是從一個資料庫開始的,首先是開發簡單,也便於維護,但當數據量到達一定數量級時,會有一定程度上影響其他表的性能,從而影響整個服務的性能,這時候會涉及到分庫,拆分獨立的服務了。那麼問題來了,怎麼才能平滑的將數據遷移到新的資料庫而且不影響原來的服務呢?
場景
商品詳情中通常會有評論這個模塊,最開始存儲在主庫的 MySQL 表中和其他的數據表在同一個資料庫,開始是沒有什麼問題的,因為數據並不多。
問題
後由於這個功能的數據量越來越大,已經對原有資料庫產生了一定影響,需要獨立為一個評論服務並且需要切換到 Mongodb 來存儲商品評論信息。
目前方案
暫停服務,將原有數據全部遷移至新服務及新的資料庫後,再啟動服務,查看是否正常
更優方案
這裡介紹石墨是怎樣應對這樣的場景的,在石墨我們會使用 數據遷移 + 雙寫 的策略來進行數據存儲類的數據遷移。
怎麼優化
- 需要先存儲時保持雙寫到 MySQL 和 Mongodb 中,此時業務查詢等操作依然還在 MySQL 中。
- 在這個過程中確認 Mongodb 數據寫入是否符合預期,如果不符合預期,先進行服務調整後可考慮捨棄這部分數據,重新開始雙寫。
- 確認新的存儲服務中數據是正常的,接下來開始遷移舊的數據到新的資料庫中。
- 當全部數據遷移完畢後,可以將業務查詢等操作的數據源按上一節的方法灰度到新的服務上去,觀察是否有問題,然後再逐步遷移。
總結
以上介紹了石墨在產品迭代時,是如何進行灰度發布的集中處理方案,目的是為了使產品迭代的風險降到最低,從而為用戶提供更好的產品體驗。我們來簡單總結一下。
- 使用「Cookie」讓部分小部分用戶體驗到新的產品功能,根據反饋逐步灰度至全量。
- 根據特定的「用戶ID」或「用戶組ID」進行產品新功能的灰度,根據反饋逐步灰度至全量。
- 對同一功能的某一部分進行後端服務的灰度,根據反饋逐步灰度至全量。
- 對服務進程進行灰度部署,根據反饋逐步灰度至全量。
- 使用先「雙寫」數據,然後「遷移」舊的數據,再進行「服務灰度」的方式,根據反饋逐步灰度至全量。
通過這幾點我們不難看出,灰度發布的要點就是「逐步灰度」,這樣我們可以及時發現、調整問題而保證整體的穩定性。
好啦 ~ 以上介紹了一些石墨進行灰度發布的方案 ~ 如果大家有一些其他的經驗,請大家不吝賜教 ~ 文中如有不對之處,還望斧正。
推薦閱讀: