本文介紹了 Shopify 構建彈性平臺的方法。這篇文章不僅讀起來有意思,而且你可以把它運用到實踐中,構建自有的彈性平臺。Shopify面臨的擴展挑戰電商解決方案提供商 Shopify 每個月的獨立訪問用戶大約有 3 億。注意,這些用戶訪問并不是均勻分布的。
其中一個最大的挑戰是“閃購”,即最流行的那些網店在特定時間內的銷售活動。
例如, Kanye West 開賣新款鞋子。加上 Kim Kardashian ,他們在 Twitter 上有 5,000 萬粉絲。
有些客戶還在超級碗上打廣告。因此, Shopify 根本無法預期屆時有多大的訪問流量。想想這種情況:在 3 點, 200,000 訪客一涌而入,參與幾小時后就會結束的特賣活動。
Shopify 該如何擴展,以應對突然增加的訪問?即使擴展后不能很好地應對某一場特賣,那么怎么確保這場特賣不會影響其它網店呢?在下一節,我們首先介紹 Shopify 的應用架構,然后以此為背景,深入地討論上述問題。Shopify 應用架構去年, Shopify 全面采用 Docker ,但是仍然采用單體的應用架構。 Simon 告訴我,之所以這么做,是因為轉向微服務架構的代價不低。當然,由于全面采用 Docker ,如果他們將來決定轉向微服務架構,也比較容易。
總之, Shopify 的架構大致是這樣的:應用請求首先發送到 Nginx ,然后再轉發到服務器應用集群,每個服務器應用是一個運行 Rails 應用的 Docker 容器。
在數據層,他們用到了:MemcachedRedisElasticSearchMySQLKafkaZooKeeper大部分軟件運行自有的硬件上,少部分運行在 AWS 上。
為了減少成本, Shopify 運營了一個多租戶平臺,即不同的網店可能運行在同一臺服務器上——例如, shopA.com 和 shopB.com 運行在一臺服務器上。
雖然全面轉向 Docker 并非一帆風順,但是最終獲得了下列好處:
只需大約 5 分鐘,就能運行完數十萬行 Ruby 代碼的持續集成(沒用 Docker 之前需要 15 分鐘),部署到橫跨 3 個數據中心的 300-400 臺服務器上只需 3 分鐘(以前需要 15 分鐘)。多么令人印象深刻的成效。如何處理流量激增平臺最好自己就能處理訪問的激增。不過,這還沒完全實現,在每次大型售賣之前,他們運行一系列的性能檢測。
以上面的 Kanye West 為例,他們提前花了兩周的時間,把平臺的關鍵部分組合在一起,進行廣泛的被動負載測試和性能優化。
為了運行不同的測試,他們用到了彈性矩陣:
摘自 Simon 的大會報告
在某項服務失效時,彈性矩陣有助于搞清楚系統出了什么問題。
假設 Redis 服務不可用了。從彈性矩陣可以看出, Redis 是買單服務的一部分。這時候,是不是要整個網站下線,進入維護狀態呢?當然不,可以讓每個用戶登出網站,仍然允許他們在沒有客戶賬戶的情況下繼續買單。然后,一旦 Redis 服務恢復了,將電子郵件地址與客戶賬戶關聯,據此補上此前缺少的信息。
依次下線每一個服務(像網店前端、管理面板、API等等),看看此時系統的運行情況——這是否影響到系統的其它部分?盡量去掉服務之間的依賴,整個應用的彈性會因此顯著地增加。這好比一條拉鏈,最弱的那一環決定了應用的健壯程度。
Shopify 開源了與之相關的兩個工具: Toxiproxy 和 Semian 。
Toxiproxy 能夠控制系統的延遲。
Semian 用于檢驗系統是否存在單點失效。
更多細節,請看 Simon 的大會報告(https://speakerdeck.com/sirupsen/dockercon-2015-resilient-routing-and-discovery),非常有意思的一個報告。
在彈性平臺之上,由于 Shopify 擁有自己的硬件,它能夠做到超額配置。對他們而言,這種解決方案很便宜,但是還是比在云上運行花費高。請仔細比較相應的代價和收益,確定這種方案是否適合你的需求。
數據存儲的擴展是另外一個巨大的挑戰。由于 Shopify 處理的是金融交易,他們的數據庫必須保持同步。解決方案是什么呢? 兩年前 Shopify 就開始實施 MySQL 分片了。他們非常激進,力求經過一段時間后把數據庫切分成更多更小的切片。
Simon 隨即說道,數據庫的擴展尤其是切片是相當難的。不到最后,別采用數據庫切片,盡可能地利用緩存。采用切片后的一個好處是有助于事故的隔離。如果在某個切片中某個客戶的數據發生災難,也只會影響整個平臺的一小部分。
說到對彈性的測試, Simon 強調說有了彈性平臺和自動災后恢復機制,大部分數據庫擴展問題都已經被解決了。接下來,他們準備提高哪些方面?接下來, Shopify 團隊正在審視應用之間的隔離問題。另外一個主要問題是如何讓網店同時運行在位于不同大洲的多個數據中心上。這不僅非常有利于保證數據本地性,也能避免意外事件的影響。
我訪問 Jeremy Edberg 時,他說過 Netflix 也投入很多資源研究如何避免意外事件的影響。
除此之外,他們也在研究如何實現一天內的多次災后恢復。在訪談 Simon 的頁面,你能了解到他們如何在整個數據中心進行災后恢復測試。
目前,如果要實現整個數據中心的災后恢復,就不得不臨時關閉買單服務。他們正在尋找相關的解決方案。