Go 部落格
在 Heroku 上使用 Go
本週的部落格文章是由 Keith Rarick 和 Blake Mizerany 撰寫,他們是 Heroku 的系統工程師。用他們自己的話來說,他們「吃、喝、睡都是分散式系統。」他們在此討論他們使用 Go 的經驗。
建置分散式系統會遇到的重大問題,就是實體伺服器的協調。每部伺服器都需要知道系統整體的各種資訊。這項關鍵資料包含鎖定、組態資料等,且必須在資料儲存發生故障時維持一致且可用,因此我們需要一個有紮實一致性保證的資料儲存。我們針對此問題提出的解決方案是 Doozer,一個使用 Go 撰寫的全新、一致且高可用的資料儲存。
在 Doozer 的核心上是 Paxos,一個用在不可靠的伺服器網路上,用於解決共識的一系列協定。雖然 Paxos 對執行一個具有容錯能力的系統是必要的,但它以難於實作而聞名。儘管為了教學目的簡化過,但網路上可以找到的範例程式碼都依然複雜難懂,實際狀況的生產系統則惡名昭彰。
幸運的是,Go 的併發原語讓任務容易許多。Paxos 定義在獨立、併發的程序中,這些程序通過傳遞訊息來進行溝通。在 Doozer 中,這些程序以 goroutine 實作,它們的通訊以 channel 的操作。以垃圾收集器改善 malloc 和 free 的方式,我們發現 goroutine 和 channel 優於基於鎖的併發方式。這些工具讓我們避免複雜的管理工作,並專注於眼前的問題。我們仍然驚嘆於如此簡潔的程式碼行數,卻達到了執行複雜任務的能力。
Go 中的標準函式庫是 Doozer 的另一個大勝利。Go 團隊對於該放入哪些東西很務實。例如,我們很快發現有用的函式庫有 websocket。一旦我們的資料儲存可運作時,我們需要一種輕鬆的方式來內部檢視它並視覺化其活動。透過使用 websocket 函式庫,Keith 能夠在回家的火車上新增網路檢視器,且不需要外部依賴關係。這充分證明了 Go 如何將系統與應用程式程式設計結合得很好。
Go 的原始碼格式化程式 gofmt 為我們的工作流程帶來了一大項進步。我們從不爭論大括號該擺在哪裡、使用 tab 還是空格,或是我們是否應該對齊賦值。我們很乾脆地同意,一切都照 gofmt 預設輸出的結果。
部署 Doozer 令人滿意地簡單。Go 建立靜態連結的二進位檔,這表示 Doozer 沒有外部依賴關係;它是一個單一檔案,可以複製到任何機器上,並立即啟動以加入執行中的 Doozer 集群。
最後,Go 專注於簡潔性和正交性的基礎與我們對軟體工程的觀念一致。我們也像 Go 團隊對於 Doozer 中該放入哪些功能一樣務實。我們斟酌細節,我們選擇變更既有的功能,而非導入新功能。在這個意義上,Go 與 Doozer 非常契合。
我們已在腦海中計畫未來使用 Go 進行的專案。Doozer 只是更大系統的開端。
下一篇文章:Go 與 Google App Engine
上一篇文章:簡介 Gofix
部落格索引