多活架構思考總結

爲什麼要做多活

多活架構主要是爲了提升系統的容災能力,提高系統的可用性,保障業務持續可用。比如單機房的網絡故障、地震火災等不可抗因素,都有可能造成整個機房癱瘓,對業務的可用性造成嚴重影響。多活架構還可以解決單機房容量問題,提高系統的擴展能力。

要不要做多活

隨着業務的高速發展,規模越來越大,技術上的投入也越來越高,每次故障造成的損失和影響更是會加速增長,初期故障損失和影響小於技術投入,隨着高速發展當故障造成的損失和影響高於技術上的投入時,就需要加大技術上的投入使用更加高可用的技術架構來避免故障,提高系統容災能力,來減少故障對業務造成的影響,提高系統的可用性,多活架構就是其中最重要的一種。

一般來說,容災能力的兩個關鍵技術指標是RTO和RPO:

  • RTO,Recovery Time Objective,恢復時間目標。表示能容忍的從故障發生到系統恢復正常運轉的時間,這個時間越短,容災要求越高。

  • RPO,Recovery Point Objective,數據恢復點目標。表示能容忍故障造成過去多長時間的數據丟失,RPO爲0表示不允許數據丟失。

多活架構方案

兩地三中心

主流的災備技術是兩地三中心,兩地三中心架構下,一般在同城距離較近的地方有兩個數據中心,用戶隨機訪問這兩個數據中心,兩個數據中心的數據會做同步複製,因爲要做同步複製,所以這兩個機房距離必須很近,網絡延時低,在異地還有一個數據中心,數據異步複製,正常情況下不對外服務,做冷備份。

這種架構下有明顯缺點:

  1. 冷備需要對全站做備份,故障發生時才能進行切換,這種情況下,冷備機房非故障時完全處於浪費狀態,資源利用率低,成本高。

  2. 發生故障時,因爲服務冷備,切流量過去後不能保證冷備服務能完全正常工作,整個功能是不是都正常,也不能確定切換過程到底要多久,而且因爲數據是異步複製,數據的丟失情況也難以預期,所以真的故障時也難以決策是否要切。

  3. 單機房資源瓶頸仍然無法解決。

所以實踐時往往會先退化爲同城多活,先保障具備機房級別容災能力。

同城多活

選擇同城做多活主要是因爲物理距離帶來的網絡延時問題,一般北京到上海的網絡延遲一般是30ms,一般一次業務請求,後臺系統會發生數十次甚至上百次系統調用,每次調用都有30ms的延遲情況下,響應時間無法滿足業務需求,同城(或距離很近)可以保障機房之間的網絡延時低、可控,各模塊之間的調用不會存在過大的網絡延時,公司內各系統模塊可以自行進行多活架構設計;數據複製也可以更容易做到強一致。

同城雙活在發展過程往往會經歷以下幾個階段:

  1. 兩個機房各承擔一部分流量,入口流量完全隨機,內部RPC調用也會隨機選擇一個機房進行調度,數據單點寫到主機房數據庫,然後同步到從機房數據庫,從機房數據只讀。

    • 優勢:

      1. 服務雙活,數據同城災備,機房級別容災。

      2. 突破了單機房容量瓶頸。

    • 問題:

      1. 跨機房調用頻繁(內部RPC,寫數據都會跨機房),雖然同城網絡延時低,但是積少成多,也是一筆很大的開銷。

      同城雙活1

  2. 兩個機房各承擔一部分流量,入口流量完全隨機,內部RPC調用閉環在同機房,相當於兩個機房鏡像部署了兩個獨立集羣,數據仍然是單點寫到主機房數據庫,然後同步到從機房數據庫,從機房數據只讀。

    • 優勢:

      1. 服務雙活,數據同城災備,機房級別容災。

      2. 突破了單機房容量瓶頸。

      3. 跨機房調用頻繁問題得到緩解。

      4. 流量可以在入口進行控制,可以靈活的進行流量調度,基於此還可以實現服務藍綠髮布,提高系統的故障應對能力,提高了系統穩定性。

    • 問題:

      1. 寫數據仍然會進行跨機房,跨機房問題沒有完全解決。

      同城雙活2

單元化異地多活

單元化是指應用層和數據層按照相同的分片維度進行流量劃分,把整個請求鏈路收斂在一組服務器中,從應用層到數據層組成一個封閉的單元。單元可以作爲一個相對獨立的整體來挪動,甚至可以把部分單元部署到異地去。單元化的核心思想就是單元內高內聚,單元間低耦合,跨單元調用無法避免,但應該儘量限定在少數的服務層調用,把整體耗時控制在可接受的範圍內,包括對直接用戶體驗和對整體吞吐量的影響。

單元化首先要考慮的問題是如何進行單元化分片,一般來說可以根據用戶的UID進行流量和數據的分片,比如可以使用UID的後兩位將流量和數據分成100個片,多個分片組成一個單元。使用UID分片時,比如轉賬操作,會同時操作兩個UID下的賬戶,這種情況不避免的需要進行跨單元調用,這時儘可能通過一定的設計將跨單元的操作進行異步化處理,避免延時問題對用戶體驗產生直接影響。還有一種情況像是淘寶這類的交易業務,還存在商家和商品等信息,如果使用買家UID進行分片,就意味着非買家維度的信息需要做一定的妥協,一般會將這些全量數據進行全局複製,複製到所有機房內,當買家對非買家維度數據訪問時,可以接受“最終一致”的就直接讀買家單元內非買家的非實時數據,不能接受“最終一致”的則需要跨單元訪問寫單元,比如交易減庫存,也就是數據集中寫寫單元,然後複製到所有單元,由每個單元進行本地讀,最終達到買家的所有操作在買家所在的單元內儘可能的讀寫封閉。

在實施過程中,可以先在同城多機房或同機房內多個邏輯機房中進行單元化改造,改造完成後再根據實際情況將單元挪動到異地,進行異地多活構建。這樣做可以防止單元化改造沒有徹底完成的情況下,走向異地會帶來嚴重的遠程網絡延時問題,進而導致服務超時,在同城的話即使沒有改造好,也能保證延時是可控的。

單元化

單元化架構的優勢:

  1. 異地多活,具備城市級故障容災能力。每個單元都分配有一定的真實流量進行業務處理,每個單元都是活的,流量可以靈活的在機房間進行切換調度。單個單元故障後,其他單元可以隨時接管故障單元的流量和數據。極大提高了服務可用性,保證了業務的連續性,減少故障發生的時候對於用戶的打擾、對於業務的中斷;即使無法切換流量也可以將故障減小到隻影響部分用戶,減小故障影響面。

  2. 解決單機房容量問題。核心服務可以分別部署在多個數據中心中,避免單個機房服務器遇到資源瓶頸,單個單元基本只需要使用(1+1)/N數量的機器資源(N代表單元數,加一是爲了在機房間流量切換時預留足夠資源)。

  3. 解決跨機房服務調用和數據庫讀寫問題,減少跨機房網絡延時。絕大部分的服務間調用和所有數據庫讀寫操作都在本單元內完成,只有少數場景產生跨機房調用,一般要保證單次用戶完整的請求鏈路上不超過2-3次跨機房處理。

  4. 解決DB連接數瓶頸問題。傳統關係型數據庫的連接數是有限的,因爲集羣中每個應用節點都會與所有數據庫節點保持連接,當應用數量達到一定規模,單臺數據庫連接數將會達到瓶頸,此時,應用也將因此無法再進行橫向擴容。而單元化架構下,每個單元內的應用節點都只會連接本單元內的數據庫,極大的節省了數據庫連接資源,提高了服務橫向擴展能力。

  5. 提供極高的服務擴展能力。單元化架構下,可以按單元來對服務進行橫向擴展,幾乎可以無限擴容。

  6. 藍綠髮布。流量可以在入口進行靈活的流量調度,基於此可以實現藍綠髮布,減小發布引起的故障影響面,將發佈引起的故障處理時間極大縮短。

多活的技術點

多活架構中除了整體架構方案,還有很多細節技術點,比如流量管控以及數據同步的具體方案

流量管控

流量管控主要涉及兩方面,外部調用的流量和內部調用的流量。

首先,需要有一個全局的流量管控中心,各個應用需要從流量管控中心同步分片規則,流量調整時也需要將規則迅速同步到分佈式系統中的各個需要的節點上,在一次請求的整個鏈路調用過程中,都需要包含分片數據,比如UID,然後計算本次請求需要調用哪個單元的服務。

還需要一個全局服務註冊中心,不同單元的註冊中心之間互相同步數據,最終所有服務消費者都知道每個單元的服務提供者有哪些,RPC框架就可以根據需要選擇調用目標。

外部調用的流量

外部調用的流量指用戶發起的流量,在調用時,一般會先經過DNS解析得到反向代理層ip地址,反向代理層處理請求,然後再請求到網關層,然後到服務層,最後是數據層。DNS解析得到反向代理層ip地址的時候,這個時候一般無法得知本次請求應該訪問哪個單元的反向代理層,所以請求有可能進入到不屬於該請求的單元,這時流量就已經進入了內部服務器,當反向代理層或網關層識別出請求所屬單元后,再將請求轉發到對應的單元時,這個時候就會產生一次額外的跨機房訪問。可以進行一定的優化,比如在PC端,如果知道用戶所屬單元,可以直接讓用戶訪問對應單元的域名;在移動端時,服務端可以將流量調度規則下發到端上或者端上定時從服務端拉取流量調度規則,端上再根據UID和流量調度規則計算出該用戶應該訪問的單元,然後直接訪問對應單元的ip或者對應單元的域名。反向代理層可以根據請求的cookie等標識,將請求轉發到對應的網關層。網關層基本一定可以根據請求信息識別出請求所屬的單元,然後調用請求所屬單元上的服務,並在cookie中添加單元標記。最後的數據層,作爲請求數據的最後一道防線,保證請求一定寫入到正確單元的數據庫中。

內部調用的流量

內部系統調用一般主要是指RPC調用,在RPC調用的全鏈路過程中,必須要帶上分片數據,比如UID,然後根據流量管控中心同步過來的分片規則,調用到指定的單元上。一些全局數據的修改,比如庫存扣減功能,需要在服務接口打標記,明確調度到特定的寫單元。

還有一些公司內部的組件,比如消息隊列和定時任務,也需要支持單元化的調度,儘量讓各自單元只處理各自單元的調用。

數據同步

數據是系統中最核心的部分,在多活架構中,爲了達到容災備份的效果,數據往往需要在多個數據中心之間進行同步,同步數據那就涉及到數據一致性的問題了,不同的業務場景下對數據一致性的要求是不同的,對應的具體同步方案也不同,有些業務場景可以接受同步數據時數據不一致導致的少量數據丟失,比如報價緩存類業務,這類業務在多活架構下遇到機房故障時往往可以快速恢復業務;有些業務則對同步數據時的數據一致性要求極高,比如資金類業務,交易類業務,如果無法做到數據的強一致,那麼在故障發生時就存在數據丟失的風險,這種情況下的這類業務即使在多活架構下遇到機房故障,是否進行機房容災切換還是等待機房故障恢復也是難以決策的,往往會因此不敢進行機房切換,真的切換也需要考慮好數據丟失帶來的各種風險和問題,並提前針對這種情況做好針對性的預案,所以這類業務往往會考慮使用一些強一致的數據同步手段保證數據一定不丟。

以下是一些常見的數據同步方案:

Mysql異步複製

MySQL異步複製是最常見的主從複製方案,指數據可以從一個MySQL數據庫主節點複製到一個或多個從節點。

MySQL主從複製的基本過程:

  1. Slave上面的IO線程連接上Master,並請求從指定日誌文件的指定位置(或者從最開始的日誌)之後的日誌內容。

  2. Master接收到來自Slave的IO線程的請求後,通過負責複製的IO線程根據請求信息讀取指定日誌指定位置之後的日誌信息,返回給Slave端的IO線程。返回信息中除了日誌所包含的信息之外,還包括本次返回的信息在Master端的Binary Log文件的名稱以及在Binary Log中的位置。

  3. Slave的IO線程接收到信息後,將接收到的日誌內容依次寫入到Slave端的Relay Log文件(mysql-relay-bin.xxxxxx)的最末端,並將讀取到的Master端的bin-log的文件名和位置記錄到master-info文件中,以便在下一次讀取的時候能夠清楚的告訴Master需要從哪個bin-log的哪個位置開始進行日誌同步。

  4. Slave 的 SQL 線程檢測到 Relay Log 中新增加了內容後,會馬上解析該 Log 文件中的內容成爲在 Master 端真實執行時候的那些可執行的 Query 語句,並在自身執行這些 Query。這樣,實際上就是在 Master 端和 Slave 端執行了同樣的 Query,所以兩端的數據是完全一樣的。

優點:

  1. 架構比較簡單,常見,運維起來也比較簡單。

  2. 性能高,由於是異步複製,主節點寫入時無需關注數據同步操作。

  3. 從庫可以提供一定的讀的能力,進行架構上的讀寫分離。

  4. 主庫宕機後,從庫仍保存有數據,防止數據大量丟失,若業務對主從同步產生的數據丟失可以接受,那麼可以將從庫升級爲主庫繼續提供服務。

缺點:

  1. 異步複製導致主從之間會產生延遲,數據一致性無法保證,主庫宕機後,數據可能丟失。RPO>0

  2. 網絡抖動時,主從複製延遲會加大,延遲導致的數據丟失情況會更加嚴重。

  3. 從庫只有一個sqlThread,複製性能不高,主庫寫壓力大時,主從複製延遲會加大,可以通過基於GTID的組提交併行復制技術提高主從複製的併發能力以提高複製速度,MySQL5.7的並行複製建立在組提交的基礎上,所有在主庫上能夠完成prepared的語句表示沒有數據衝突,就可以在slave節點並行複製。

Mysql半同步

半同步複製(Semi-synchronous Replication):相比異步複製,半同步複製犧牲了一定的性能,提升了主備之間數據的一致性(有一些情況還是會出現主備數據不一致)。

MySQL半同步複製的實現是建立在MySQL異步複製的基礎上的。MySQL支持兩種略有不同的半同步複製:AFTER_SYNC和AFTER_COMMIT。rpl_semi_sync_master_wait_point參數控制半同步模式下主庫返回給客戶端事務成功的時間點。

  • AFTER_COMMIT過程:

    1. 寫master binlog並commit
    2. 同步binlog到slave並commit
    3. slave返回acknowledgment給master
    4. master接收到slave acknowledgment
    5. master返回結果給client

      Master commit之後再將日誌複製到slave。所有已經複製到slave的事務在master上一定commit了。所有master上commit的事務不一定複製到slave,比如,master commit之後,還沒來得及將日誌複製到slave就宕機了,這時無法保證數據的一致性。

  • AFTER_SYNC過程:

    1. 寫master binglog
    2. 同步主binlog到slave
    3. slave返回acknowledgment給master
    4. master接收到acknowledgment並commit
    5. master返回結果給client

      日誌複製到slave之後,master再commit。所有在master上commit的事務都已經複製到了slave。所有已經複製到slave的事務在master不一定commit了,比如,master將日誌複製到slave之後,master在commit之前宕機了,那麼slave有可能比master執行了更多事物。

優點:

  1. 從庫可以提供一定的讀的能力,進行架構上的讀寫分離。

  2. AFTER_SYNC模式下,可以保證數據不丟,主庫宕機時從庫可以升級爲主庫繼續提供服務。

缺點:

  1. 開啓半同步複製時,Master在返回之前會等待Slave的響應或超時,當Slave超時時,半同步複製退化成異步複製。

  2. 當Master宕機時,數據一致性無法保證,依然存在從節點多執行或從節點少執行的情況,重啓時可能需要人工干預。

  3. 網絡質量要求高,每次事務處理都需要實時進行遠程數據同步,對性能有一定影響。

Mysql PXC(Percona XtraDB Cluster)

Percona XtraDB Cluster是MySQL高可用性和可擴展性的解決方案,Percona XtraDB Cluster提供的特性如下:

  1. 同步複製,事務要麼在所有節點提交或不提交。

  2. 多主複製,可以在任意節點進行寫操作。

  3. 在從服務器上並行應用事件,真正意義上的並行複製。

  4. 節點自動配置。

  5. 數據一致性,不再是異步複製。

PXC是基於引擎層的同步複製,而不是異步複製,所以數據一致性更高。同時,基於引擎層,是物理複製,而不是發日誌,所以沒有sql thread應用過程,所以幾乎沒有延遲。

工作原理

certificationcertification

PXC是基於認證的複製方式進行數據複製。首先客戶端先發起一個事務,當客戶端提交一個commit命令,在事務提交之前,所有對數據庫的操作都會被寫入write-set中,包括主鍵,然後數據庫會將這個write-set發給所有其他節點,write-set將在每個節點(包括生成write-set的節點)上使用主鍵進行認證嘗試。如果認證失敗,節點會丟棄這個write-set,同時集羣會回滾到之前的事務點;如果認證成功,commit正常提交,事務會應用到其他節點上。Galera Cluster基於認證的複製主要依賴於全局事務序號,複製期間,Galera Cluster會爲每一個事務分配一個全局事務序號。當某個事務到達commit階段時,節點會檢查待提交事務的序號與上一次成功提交事務的序號,檢查區間所有事務是否與新事務存在主鍵衝突,如果檢查到衝突,認證就會失敗。所有節點以相同的順序接受事務,所有節點對事務是否提交做一致性決定。事務提交成功之後,首先生成此事務的節點會通知應用程序事務已正確提交。

優點:

  1. 實現mysql數據庫集羣架構的高可用性和數據的強一致性,多活架構下,主庫宕機情況下可以保證數據0丟失,RPO=0。

  2. 物理複製改善了傳統意義上的主從複製延遲問題,性能高,基本上達到了實時同步。

缺點:

  1. 性能低,任何更新事務都需要全局驗證通過,纔會在每個節點庫上執行。集羣性能受限於性能最差的節點,也就是經常說的短板效應。

  2. 網絡質量要求高,異地多活場景下,需要跨機房進行數據實時同步,網絡抖動對性能和穩定性造成的影響嚴重。

  3. 沒有表級別的鎖定,執行DDL語句操作會把整個集羣鎖住,而且也kill不了(建議使用Osc操作,即pt-online-scheme-change)

MySQL Group Replication

MySQL官方推薦的一款高可用集羣方案MySQL Group Replication,簡稱:MGR(組複製)。它是官方推出的一種基於Paxos協議的狀態機複製,徹底解決了基於傳統的異步複製和半同步複製中數據一致性問題無法保證的情況。

工作原理

MGR通過分佈式一致性協議Paxos在Group中原子廣播事務產生的Binlog並在遠端節點進行回放的方式來達到數據複製目的的,由至少3個或更多個節點共同組成一個數據庫集羣,事務的提交必須經過半數以上節點同意方可提交,每個事務將按照通過Paxos的先後順序進行認證,通過認證後再寫入Relaylog,最後按順序進行並行回放。MGR允許部分節點故障,只要保證半數以上節點存活,就不影響對外提供數據庫服務,是一個真正可用的高可用數據庫集羣技術。

MGR

優點:

  1. 保證了數據的強一致性,允許有延遲,它在校驗完事務是否衝突後把當前事物廣播到各個節點並確定各個節點收到事務後即進入下一個事物的衝突檢測,此時每個節點只是拿到了所有事務的執行序列,保證了事務最終順序執行。多活架構下,主庫宕機情況下可以保證數據0丟失,RPO=0。

  2. 通過binlog實現節點同步。這一點對DBA很友好,意味着我們可以很輕易的找回熟悉的主從的感覺。

缺點:

  1. 性能低,需要至少半數以上節點同意後方可提交事物,相較PXC來說短板效應不明顯。

  2. 網絡質量要求高,異地多活場景下,需要跨機房進行數據實時同步,網絡抖動對性能和穩定性造成的影響嚴重,不過由於只需要保證半數以上節點同意,所以對部分節點的網絡抖動有一定容忍,提高了穩定性。

OceanBase

OceanBase利用Paxos協議在底層實現了多副本數據一致性,具有RPO=0、低RTO(通常在30s以下)、故障時自動切換的優勢。基於此,支付寶的會員ID系統採用“三地五中心”部署方式,建立了城市級故障自動容災能力。

優點:

  1. 保證數據強一致性,故障時數據零丟失。RPO=0。

  2. 基於Paxos協議,只要超過半數的節點存活,就可以在故障時自動切換。低RTO(通常在30s以下)。

  3. 性能高,OceanBase採用和傳統數據庫一樣的WAL(Write-Ahead Logging)方案,通過多數派先持久化事務日誌的方式,保證提交事務不丟失。基於LSM-Tree的架構,增刪改的數據其實都是在內存裏完成,將更新暫存在內存中,定期再將內存增量批量合併到持久化存儲上。

缺點:

  1. 一致性讀寫性能降低,非一致性讀性能不變。性能的降低主要是網絡延時導致的,因爲數據需要在多機房之間進行同步,三地五中心部署下,兩個距離較近的城市中各有兩個機房,較遠城市中有一個機房,一般只在距離較近的兩個城市中的四個機房進行寫操作,數據需要在本城市的另外一個機房,以及較近城市中的其中一個機房完成同步即可提交,所以對網絡抖動具備一定容忍能力,提高了穩定性。

其他數據同步方案

強一致:阿里的X-DB(強一致);Oracle Data Guard的最大保護模式;DB2 HADR中採用Sync模式;共享存儲。

非強一致:阿里雲的DTS;餓了嗎的DRC;otter。

自定義DB-Failover方案

在系統設計上,我們往往追求系統的高可用性,但是當真的遇到數據不一致的情況下,比如機房故障,往往爲了要保證數據一致性,選擇暫停業務,待數據達到一致後再啓動業務,因爲數據不一致性帶來的影響,往往恢復起來十分困難,即使有對賬、覈對等手段。爲了保證數據同步時的一致性問題,除了通過數據庫本身及相關組件提供的數據同步方案之外,還可以通過業務上的一定改造來達到這個目的。

  • 流水型業務數據的DB-Failover解決方案:

    流水型業務數據比如訂單數據,特點是同一用戶的每個訂單之間沒有強關聯性。

    業務正常狀態下,進行數據流水讀寫的時候,只有主庫提供服務,主庫和備庫之間進行正常的數據同步,在備用機房額外增加一組和主庫相同結構的Failover庫,Failover庫不進行數據同步,沒有任何歷史數據,只在故障期間使用;當故障發生時,將所有數據讀寫遷移至Failover庫,這樣保證了所有新的交易流水能夠正常處理,歷史交易由於數據一致性的問題將暫時不提供服務;當故障恢復後,將讀寫遷移回主庫,並將Failover庫上的數據同步回主庫,然後提供正常服務。基於此方案,在保證數據一致性的前提下提高了業務的可用性。

  • 賬戶型業務數據的DB-Failover解決方案:

    賬戶型業務數據比如用戶賬戶餘額,特點是屬於業務上的共享數據,每一筆交易都有可能與之關聯。

    業務正常狀態下,在更新賬戶的同時,通過事物消息將賬戶更新後的快照同步更新到另外一個機房的緩存中,同時額外增加一組和主庫相同結構的Failover庫,Failover庫不進行數據同步,沒有任何歷史數據,只在故障期間使用;當故障發生時,先從事物消息中間件中拉取所有預提交狀態的消息(因爲這部分消息無法確定事物最終是提交還是回滾狀態)或未消費完成消息,將這部分用戶作爲黑名單,後續故障期間的交易不對這部分用戶提供服務,然後將業務的讀寫遷移至Failover庫,在Failover庫上進行操作前,先從緩存中讀取賬戶快照,緩存中有快照則直接使用緩存中的快照,緩存中沒有則讀從庫獲取賬戶快照,緩存沒有說明該賬戶最近一段時間無操作或在黑名單中,先讀緩存再讀從庫是因爲緩存+黑名單的數據一定覆蓋了主從延遲丟失的數據,然後將得到的賬戶快照數據寫入Failover庫,該用戶賬戶就可以正常在Failover庫上進行賬戶業務操作了;待故障恢復後,再將Failover庫的數據同步回主庫。

  • 通用數據的DB-Failover解決方案

    業務正常狀態下,每次請求預先將操作日誌記錄到備機房,當故障發生時,任何操作前先查詢操作日誌庫,如果在故障發生前一段時間(取決於數據庫最大同步延遲)有過操作記錄,則不對該部分黑名單執行業務操作,只處理新增數據以及最近無操作的數據,操作直接在從庫執行,這個從庫將升級爲新的主庫,待故障恢復後,由dba將原主庫未同步的數據重新同步至新主庫,當同步追平後黑名單自然解除。核心思路即WAL(Write-Ahead Logging),故障時通過WAL中的數據對問題數據進行隔離。

各種自定義DB-Failover方案的核心思路就是通過業務層去發現可能存在狀態不一致的數據,並對其進行攔截,避免在髒數據上繼續進行操作,待故障恢復後,重新同步至一致性狀態。

文章來源:http://blogxin.cn/2019/03/02/multi-datacenter/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章