當前位置:
首頁 > 科技 > 奧巴馬都去作客的美國版天涯論壇Reddit的代碼部署演變史

奧巴馬都去作客的美國版天涯論壇Reddit的代碼部署演變史

作者丨Neil Williams & Saurabh Sharma

譯者丨Vincent

我們經常在Reddit上面部署代碼。每位工程師都要寫代碼,進行檢查,檢查,並定期將其推廣到生產。 通常情況下每周發生200次,部署通常需要不到10分鐘。

這一體系已經演變了多年。讓我們來看看它發生了什麼改變(以及沒發生的)。

故事開始的地方:持續性和可重複部署(2007-2010)

目前這套系統是從push這個Perl腳本發展而來的。這個腳本誕生的時間與Reddit現在的歷史時間有很大不同。當時整個開發團隊小的可憐,用一間很小的會議室就可以裝滿了。甚至Reddit還沒有在AWS上。該站點運行在固定數量的伺服器上,需要手動添加額外的容量,並且由一個稱為r2的大型單片Python應用程序組成。

在這麼多年的發展過程中,還沒有變過的一件事就是請求在負載均衡器上進行分類,然後分配給不同的應用伺服器的特定「池」。比如,列表頁面和評價頁面是由單獨的伺服器池提供的。儘管給定任意的r2進程都可以處理任何類型的請求,但是單獨的池從流量的峰值再到其他的池,並且當它們有不同的依賴關係時,有可能就會處理失敗。

push工具有一套硬編碼的伺服器列表,並且是圍繞著整體的部署進程進行搭建的。它將遍歷所有應用程序伺服器,SSH到機器,運行預設的命令序列,以通過git更新伺服器上的代碼副本,然後重新啟動所有應用程序進程。本質上(也就是說經過大量的凈化,而不是真正的代碼):

部署是按照順序逐步進行的。它通過逐個伺服器進行工作。聽起來好像很簡單,但這其實是一種很好的思路:它允許使用canary式的部署形式。如果您僅部署到少量的伺服器,並注意到出現了一個新的異常,你應該就會知道代碼裡面可能有bug,你會終止部署(快捷鍵是Ctrl + C),並且在出現影響之前儘快回滾。因為這種部署很簡單,因此在生產環境中能很輕鬆的發現問題,並且在沒有產生影響之前也可以輕而易舉的對代碼進行回滾。這也意味著有必要一次就部署一下,以確保新的錯誤來自本次部署,而不是另一個,因此更容易知道什麼時候恢復以及恢復什麼。

這樣部署可以很好地確保部署一致性和可重複。它部署的很快,並且情況也很容易了解。

新員工的到來 (2011)

之後我們又招聘了一批新的員工,總工程師變成6位了,看起來似乎需要一間稍微大一點的會議室了。在這之後我們開始覺得需要有更好的合作開發的機制了,尤其是每個人在家裡工作的時候。於是我們便修改了一下push工具,當開始部署或者結束部署時,它會通過IRC的聊天機器人軟體通知到每個人。機器人軟體是在IRC裡面,也是由它去發送通知的。事實上,部署的形式看上去還是沒有改變,但是現在是系統代替了員工進行工作,並且也是由它去通知其他人你正在做什麼。

也就是從這時候開始,我們使用了通過聊天去通知部署這種工作流程。其實在這段期間我們使用了很多交流類的軟體去管理部署,但是由於我們使用的是第三方軟體IRC服務,我們沒辦法完全信任由產品控制的聊天室,因此它仍然是單向信息流。

隨著網站流量的增長,基礎設施的支持也顯得愈發重要。我們有時不得不推出一批新的應用伺服器並投入使用。這項工作還是非常的人工化,包括還需要去手工更新push裡面的主機列表。

當我們增加規模時,我們通常是通過一次性增加若干台伺服器,從而增加池的數量。其結果是通過順序的迭代伺服器列表,可以在同一池子中快速連續地訪問多個伺服器,而不是多樣化的組合進行訪問。

我們使用uWSGI來管理員工的工作進程,因此如果重啟它的話,會導致現有的進程被殺掉,並且啟動一批新的進程。新的進程需要花費部分時間來準備服務請求,這將會影響到服務請求池的數量。因此我們把速度限制到了只要安全部署到伺服器上面就可以了。

重複利用的部署工具 (2012)

我們對部署工具進行了一次徹頭徹尾的調整,現在用的是Python開發出來的,但是沒人知道為啥還是叫push。新版本在某些功能上做了一些改善。

首先,現在是從DNS去獲取所有的主機列表了,而不是在通過硬編碼的形式。這個調整就避免再出現那種更新主機列表的時候,忘記去更新部署工具了,這才是一個基本的服務發現系統。

為了解決需要按照順序進行重啟的問題,我們在重啟之前會打亂主機列表。因為這麼做會使得伺服器池變得混亂,這樣就可以以更快的速度回滾,因此部署也就變得更快。

最開始的時候,每次都是通過打亂順序去解決,但這麼做就增加了快速恢復代碼的難度,因為你不會每次都部署,第一台伺服器不可能每次都相同,因此我們又調整了這種機制,使用了seed技術,在恢復代碼時,它可以在第二次部署的時候重新使用。

另一個雖然小但是也很重要的調整點就是始終部署固定版本的代碼。這個工具的前一個版本會去更新指定主機上面的master,但是如果有人不小心提交了代碼而使得master改變了中期部署的方式,會怎麼樣呢?通過部署特定的git修訂而不是分支名稱,我們確保了每次部署的時候,無論在生產環境的哪個環節,都能獲取到相同的版本。

最後,新版本的工具區分了代碼(主要針對主機列表和SSHing)和正在運行的命令。它仍然與r2的需求有很大的偏差,但它有了排序的原始的API。這允許r2控制自己的部署步驟,對建立和發布流的更改更加容易。例如,以下可能是在單個伺服器上運行的功能。確切的命令是隱藏的,但是序列仍然是特定於r2的工作流程的。

fetch-names這一步是r2唯一重點關注的。

Autoscaler (2013)

於是我們決定使用雲端和autoscale(單獨博客文章的主題)。這可以幫我們節省一大筆錢,當網站處於沒有大量的訪問量時,自動增長可以滿足意料之外的需求。。

先前改為從DNS獲取主機列表的調整使得這是一個自然的過渡。主機列表的更改頻率比以前更塊,但與該工具沒有什麼不同。本來是生活的一部分,只不過現在變成了自動啟動autoscaler。

然而,autoscaling的確是引發了一些有趣的邊緣案例。就像沒有免費的午餐一樣。如果一台伺服器運行的同時,也發生了部署,那麼會產生什麼情況呢?我們必須確保每個新啟動的伺服器都登記過了,以獲取新的代碼,如果存在的話。伺服器如何中途部署呢?工具必須做得更智能,以檢測伺服器何時可以合理地移除,而不是在部署過程本身中出現問題的時候才進行提醒。

自然而然,由於各種各樣的原因,這次我們也把uWSG換成了Gunicorn。就部署而言,這並沒有帶來什麼不同。

所以革命還得繼續。

太多的伺服器(2014)

隨著時間的流逝,高峰的流量也需要越來越多的伺服器進行支撐。也就意味著每次部署所需要的時間也越來越長。最糟糕的情況下,正常的部署需要將近一個小時。這簡直糟透了。

我們重寫了部署工具來並行處理主機。新版本的名稱叫rollingpin。舊工具所花的大部分時間是消耗在了初始化連接ssh以及等待命令被執行完的時候,所以在一定的安全數量上進行並行的話是可以縮短時間的。部署的時間也立即被降到了5分鐘。

為了降低一次重啟多台伺服器帶來的影響,工具在打亂順序時也變得更明智了。它將以最大程度地將伺服器從每個池中分離出來,而不僅僅是盲目的打亂主機的順序。這樣做也是有意地減少對網站的影響。

新工具最重要的調整使部署工具和在每個伺服器上的工具之間API定義的更加清晰,並與r2的需求分離了。這最初是為了考慮開源而關注的,但最終在不久之後的確是非常有用。以下是部署示例,突出顯示的命令是遠程執行的API。

人員的增長(2015)

忽然就感覺到好像有很多人一下就使用r2了。這真是太偉大了,當然也意味著需要更多的部署。在同一個時間規則下,保持一個部署速度會變得越來越困難,因為每個工程師都需要在口頭上協調他們會在什麼順序上部署代碼。為了解決這個問題,我們又新加了一個功能,就是可以自動協調部署隊列。工程師將要求部署鎖定,並獲取或放入隊列。這有助於維持部署秩序,讓人們在等待的時候放鬆一下。

隨著團隊的發展,另一個重要的補充是在核心位置跟蹤部署。我們修改了部署工具以將指標發送給Graphite,因此很容易將部署與指標更改相關聯。

服務的增長 (2015年同樣的問題)

就像突然間,我們有第二個服務上線了。網站的新移動版本正在上線。這是一個完全不同的堆棧,並有自己的伺服器和構建過程。這是部署工具解耦API的第一個真正考驗。隨著對每個項目不同位置構建步驟的增加,它保持不變,並且我們能夠在相同的系統下管理這兩個服務。

25項服務(2016)

在接下來的一年中,我們看到了Reddit團隊的爆炸性增長。我們從這兩個服務發展到了二十幾個,從兩個團隊到十五個,我們的大部分服務都建立在Baseplate,後端服務框架,或類似於移動網路的節點應用也都是。基礎部分是所有部署的基礎,而且會上線越來越多,因為rollpin不在乎它的部署內容。這使得人們可以使用熟悉的工具輕鬆地開發新的服務。

安全網 (2017)

隨著伺服器數量的增加,這一塊也就變得越來越龐大,部署所需要的時間也越來越多。我們想要用高並行計數來進行部署,但是這樣做會導致應用伺服器帶出現大量的的重啟。於是,我們降低了規模,對於傳進來的請求也不能及時處理,其它的應用伺服器也出現了超載的情況。

Gunicorn的主進程使用了跟uWSGI相同的模型,也會一次重啟所有員工的工作進程。當新的工作進程啟動時,您無法滿足任何請求。我們整體的啟動時間為10-30秒,這意味著在此期間,我們將無法提供任何請求。為了解決這個問題,我們把Gunicorn的主進程換成了Stripe的工作經理Einhorn,同時保留了Gunicorn的HTTP stack和WSGI container。Einhorn是通過創建新的進程從而完成重啟的,等待它自己準備好,然後收穫老的進程,並重複,直到所有的升級。這種機制創建了一個安全網,並允許我們在部署期間可以響應請求。

新模式當然也帶來了新問題。就像前面提到的那樣,它需要30秒的時間完成進程的替代和啟動。這也就是說如果的你代碼裡面有bug,它不會立即顯示,您可以回滾多台伺服器。為了防止這種情況產生,我們引入了一種方法,可以阻止部署到另一台伺服器上,直到所有的進程都重新啟動才可以。很簡單,只需要調整einhorn的狀態,並且等到所有的機器都準備好就可以了。為了保證速度,我們增加了並發,這現在已經很安全了。

新的機制可以讓我們同時對多台伺服器進行部署,部署800台機器的時間降低到了7分鐘,儘管需要額外的等待。

回顧

部署的基礎部分是多年的逐步改進積累而來的,絕不是任何一次大的調整導致的。在當前系統和過去的任何時候,都可以看到歷史的陰影和每一次選擇的權衡。這樣一種演變的方法是有利弊的:在任何一個期間,都不需要花費太多的代價,但是我們最終可能會陷入絕境。重要的是要關注你的發展方向,這樣你就可以繼續朝著有用的方向前進。

未來

Reddit的基礎部分需要能夠跟得上團隊以及新事物的發展。公司的成長速度達到了Reddit歷史上的峰值,與以前相比,我們所從事的項目也越來越有趣。現在我們面臨的問題有兩部分:提高工程師自主權,同時維護生產基礎設施中的系統安全,以及為他們搭建更好的網路環境,讓他們更有信心進行部署。

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

蘋果終於入伙 WebRTC,新一代移動Web應用爆發路上還有哪些坑?
C+中命名空間的五大常見用法
十圖詳解TensorFlow數據讀取機制
資料庫壓縮技術的過去與未來,另又有公司的資料庫被工程師刪了
跳過肉眼?全面解讀Google最新發布的JPEG壓縮演算法Guetzli

TAG:CSDN |

您可能感興趣

Milken Institute被稱為美版達沃斯論壇 它是怎樣煉成的?
Cadenza Innovation獲世界經濟論壇表彰為技術先鋒
帕胖歸來!現為Oculus Subreddit論壇官方版主之一
全球IPv6論壇主席Latif Ladid致辭
OPPO 出席曼徹斯特 Distractions 高峰論壇,助力中國新銳藝術家走向國際
HCL Technologies在2019達沃斯世界經濟論壇上表彰人道主義領袖
「Hello Future」物聯網論壇與您相約利程坊
Join Us!SoMAx 跨境創新論壇
python論壇:python程序員學習交流的場所
丹麥納米衛星製造商GomSpace公司高管Tor-Arne Gr?nland先生確認出席中國商業航天產業國際論壇!
劉雯、辛芷蕾助陣Chloé2018春夏系列限時展覽、王源出席聯合國青年論壇,黃子韜成Saint Laurent亞太區眼鏡形象大使
第四屆華夏醫學婦產科論壇workshop開課啦,你想要的這裡都有
Art Amoy國際博覽會論壇預告——當代公共空間中藝術品的社會價值
國外論壇現iPhone新品真機圖 網友猜測:iPhone X SE?
BOE Mobile SBU副總經理魏星已確認出席論壇
華為音樂?DigiX Talk論壇精彩內容搶先看
中國—中東歐國家藝術合作論壇嘉賓:品三國文化,感受古蜀之美
區塊鏈如何影響時尚論壇How Tech Is Influenced Fashion Industry
這個論壇好special——吃貨篇
芝加哥論壇報-Should girls be good at everything?