天天看點

Uber:用司機手機做資料中心備份

Uber:用司機手機做資料中心備份

【編者的話】

uber是一家總部位于舊金山的風險投資的創業公司和交通網絡公司,以移動應用程式連結乘客和司機,提供租車及實時共乘的服務。在最近短短四年間,uber的業務量已經驚人地增長了38倍,在這背後起到支撐作用的是公司強大的系統架構。其中一項非常傑出的工作是他們在處理系統故障時,包括當出現資料中心故障的時候,通過将司機的手機作為一個外部分布式存儲系統,uber采用了一種非常出色的系統恢複方式。最近uber的工程師nikunj aggarwal 和joshua corbin在scale conference上做了一個題為“how uber uses your phone as a backup datacenter”的報告,對系統的工作方式做了一個生動的介紹。本文是一篇翻譯稿,原文題目為“uber goes unconventional: using driver phones as a backup datacenter”,已獲得作者授權。

【正文】

uber在處理資料中心失效轉移時,使用司機的手機作為一個外部的分布式存儲系統,以用于資料恢複。

這個系統具體是如何工作的呢?資料庫通過使用一個傳統的後端複制方案,實作資料中心之間的狀态同步。但uber并沒有這樣做,他們在司機的手機上存儲足夠的狀态,這樣,當資料中心發生失效轉移時,使用者的行程資料也不會在失效轉移中丢失。

為什麼選擇這種方式呢?事實上,傳統的方法更加簡單。我認為這是為了確定客戶始終有一個良好的客戶體驗,對于一個活動的行程來說,行程資訊的丢失會給使用者帶來一個槽糕的客戶體驗。

通過圍繞着手機建立自己的同步政策,雖然這有些複雜并需要大量的工作,但uber還是能夠儲存好行程資料,并且在資料中心出現故障時能為客戶提供一個滿意的客戶體驗。而讓客戶滿意應該是最重要的,尤其是在那些使用者轉換工具的成本接近零的市場中。

是以,我們的目标是,即使在資料中心失效轉移的過程中也不丢失任何行程資訊。使用傳統的資料庫複制政策,這幾乎是不可能的,其原因類似于網絡管理系統所一直采用的工作方式。

下面我對此進行詳細解釋。

在一個網絡中,裝置是分組錯誤、警報、發送和接收分組等狀态資訊的權威來源。網絡管理系統負責配置警報門檻值等配置資訊以及管理客戶資訊。複雜之處在于裝置和網絡管理系統并不總是處于連接配接狀态,是以它們工作互相獨立,并導緻它們之間不同步。這意味着在啟動、失效轉移以及通信重連時,為了確定正确性和一緻性,不得不通過一個複雜的調節将所有這些資訊在兩個方向上進行合并。

uber也有同樣的問題,隻是這些裝置是智能手機,而手機包含的權威狀态是行程資訊。是以在啟動、失效轉移和通信重連時,行程資訊必須保留,因為手機是行程資訊的權威來源。

即使是在連接配接斷開的時候,手機也準确地記錄了所有的行程資料。是以,你不需要進行從資料中心到手機的行程資料同步,因為這将消除掉手機上正确的資料。正确的資訊肯定來自于手機。

uber也從網絡管理系統中學習到了一項技術。他們定期對手機進行查詢,以測試資料中心中資訊的完整性。讓我們來看看他們是如何做到這一點的。

為什麼要使用手機來做資料中心備份

不久前,一個發生故障的資料中心丢失了客戶的行程資料。這個問題現在已經解決了。在一個資料中心出現故障時,客戶能夠在幾乎沒有明顯的停機時間的情況下繼續他們的行程。

狀态變化的轉換包括:行程的要求、提供給司機、行程的接受、挑選乘客,結束行程。隻要行程在持續,整個行程事務就在持續。

行程開始的時候,行程資料就開始在備份資料中心中被建立。uber似乎在每個城市都設計了一個資料中心。

資料中心發生故障的典型解決方案:從目前資料中心到備份資料中心複制資料。工作的效果主要取決于你使用的資料庫。缺點:

使用兩個資料中心使問題變得複雜。

資料中心之間的複制滞後。

資料中心之間一直需要一個高的帶寬,特别是當你的資料庫并沒有很好地支援資料中心複制,或者你沒有為優化增量調整業務模型的時候。

(一個好處在這裡并沒有被講到,可能對uber來說不重要,但對一些小的公司來說影響很大,即使用司機手機的計劃所需要補貼的帶寬成本沒有資料中心之間傳輸所需要的帶寬成本高。)

創意應用感覺解決方案:由于與司機的手機之間一直存在通信,是以隻需要将資料儲存在司機的手機裡。優點:

可以失效轉移到任何資料中心。

避免出現手機失效轉移到錯誤的資料中心的問題,出現這個問題将導緻所有行程資料丢失。

使用司機的手機進行資料中心的備份需要一個複制協定。

與資料中心通信時,所有的狀态轉換發生。例如,有一個開始行程或開始駕駛請求,這些狀态轉換過程是與手機交換狀态資料并獲得手機存儲資料的一個絕佳機會。

在資料中心失效轉移過程中,當手機ping新的資料中心時,行程資料被要求從手機上切換。停機時間非常小。(沒有處理任何關于資料中心如何映射的資訊)。

挑戰:

并非所有儲存的行程資訊都是司機可通路的。例如,一次行程有大量關于乘客的資訊,它們都不應該被暴露。

資料必須防篡改。是以,所有手機上的資料都是加密的。

需要讓複制協定盡量簡單,以友善推理和調試。

盡量減少額外的帶寬。使用基于手機的方法,通過調試哪些資料被串行以及哪些增量被保留,可以盡量減少移動網絡上的流量。

複制協定

一個簡單的key-value存儲模型,使用了get、set、delete和list等鍵值操作。

一個key隻能get一次,以防止出現意外覆寫和消息亂序的問題。

使用一次get規則,版本控制不得不進入key空間。更新一個存儲的行程是這樣的:set(“trip1, version2”,

“yyu”);delete(“trip1,

version1”)。它的優點是,如果在set和delete操作之間發生了故障,将有兩個值被存儲,不會出現什麼都沒有存儲的情況。

失效轉移僅僅是手機和新的資料中心之間合并鍵值的問題,具體通過将存儲的鍵值當成任意已知的正在進行的司機的行程,為任何丢失的資料發送一個或多個get操作。

確定系統是非阻塞的,同時提供最終的一緻性。即使在系統已關閉的情況下,系統中的任何後端應用程式應該能夠更新。應用程式更新應該付出的唯一代價是,它可能需要一段時間将資料存儲在手機上。

資料中心之間的資料可以移動,是以沒有必要擔心資料在什麼地方。需要有一種方法來調和司機與伺服器之間的資料。

當失效轉移到資料中心的時候,資料中心有一個活動的司機和行程的視圖,資料中心中沒有任何服務感覺到故障的發生。

轉移到原始資料中心的過程中,司機和行程資料有些過期,這會導緻一個糟糕的客戶體驗。

使其可測試。資料中心故障很少發生,是以它通常很難測試。他們希望能夠不斷地測試系統是否成功,是以當故障發生時他們能夠有信心進行失效轉移。

一個司機在發生更新或狀态變化時,例如,接上了一個乘客。當請求排程服務的時候,更新就開始了。

排程服務為行程更新行程模式。更新被發送到複制服務。

複制服務将請求進行排隊,并傳回success。

排程服務更新自己的資料存儲,并傳回success到移動用戶端。其他的資料也可能被傳回,例如,如果它是一個uber

pool行程,另一個乘客也可以被接上。

在背景,複制服務對資料進行加密并将它發送到消息傳遞服務。

消息傳遞服務為所有司機提供一個雙向通道。這個通道與司機用來進行服務通信的原始請求通道是分開的。這確定了正常的業務操作不受備份過程的影響。

消息傳遞服務将備份發送到手機。

這種設計的好處:

避免了應用程式出現複制延遲和失敗。複制服務立即傳回。并且應用程式隻需要做一個簡單的調用(同一個資料中心内),就可以實作資料的複制。

消息服務支援手機的任意查詢,而不會影響正常的業務操作。手機存儲可以被視為一個基本的key-value存儲。

第一種方法是手動運作失效轉移的腳本,從資料庫中清理舊的狀态。這種方法存在操作成本的硬傷,必須有人來進行操作。并且由于同一時間在多個城市同時進行失效轉移是可能的,這時腳本會變得過于複雜。

回想一下,key-value資料庫中的key包括一個行程id和一個版本号。版本号過去常常是一個遞增的數。這裡被更改為一個修改的矢量時鐘。在手機上使用矢量時鐘資料可以比作為伺服器上的資料。任何因果侵犯可以被檢測和解決。這解決了正在進行的行程的問題調和。

傳統上,完成的行程會從手機中删除,是以複制資料将不會無限增長。問題在于,當因為故障傳回到原始資料中心的時候,資料中心将有過時的資料,這可能會引起排程異常。解決方法是在行程完成時使用一個特殊的墓碑鍵值(tombstone

key)。該版本有一個标志,用來标記此行程已經完成。當複制服務看到标志時,它可以告訴排程服務,次行程已經完成。

存儲行程資料的開銷很大,因為它是一個巨大的加密的blob。已完成的行程需要少得多的存儲空間。一個星期内完成的所有行程的存儲空間僅僅相當于一個活動的行程的存儲空間。

失效轉移系統不斷進行測試,以确定失效轉移成功後,它還在正常地工作。

第一種方法是為單個城市手動地進行失效轉移。然後檢視恢複的成功率,并通過檢視日志進行問題調試。

高的操作成本。每周手動地執行此過程是行不通的。

糟糕的客戶體驗。對于沒有正确恢複的幾次行程,其收費必須重新調整。

低覆寫率。同一時間隻有少數幾個城市可以測試,因為有些問題僅僅在特定的幾個城市中存在。

不清楚一個備份資料中心能否處理負載。有一個主用和一個備用的資料中心。即使他們的配置相同,你又怎麼知道備份資料中心能處理這種“驚群”問題,即在失效轉移中會出現大量的請求。

為了解決這些問題,他們檢視了系統中他們想測試的關鍵概念。

確定排程服務中的所有變化實際上都存儲在手機上。例如,一名司機在接上一名乘客之後可能會失去連接配接,是以複制資料可能不會立即發送到手機上。需要確定資料最終在它的手機上。

确儲存儲的資料可用于複制。有很多問題可能影響資料的複制,例如,加密/解密問題。

確定備份資料中心能處理負載。

需要一個監視系統監視系統的健康狀态。

每隔一小時服務從排程服務中擷取一份所有活動的司機和行程的清單。對于所有司機來說,消息傳遞服務可用于擷取複制資料。

然後将資料進行比較,以檢視資料是否符合預期。這就産生了很多不錯的健康名額,如失敗比例。

按區域和應用程式版本分解名額對查明問題有很大的幫助。

需要一個陰影重建(shadow restoration)用于測試備份資料中心。

由監測服務收集的資料被發送到備份資料中心,用于陰影重建。

通過使用排程服務将一個來自于主用資料中心的快照與備份資料中心中活動的司機和行程的數量進行比較,成功率能夠被計算出來。

關于備份資料中心處理負載好壞的名額也被計算出來。

在備份資料中心的任何配置問題可以通過這種方法被捕獲到。

原文釋出時間為:2015-10-22

本文來自雲栖社群合作夥伴“大資料文摘”,了解相關資訊可以關注“bigdatadigest”微信公衆号