自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

構(gòu)建Uber大型支付系統(tǒng)時學(xué)到的分布式體系結(jié)構(gòu)概念

開發(fā) 前端 分布式
在本文中,我總結(jié)了一些我認(rèn)為在構(gòu)建大規(guī)模,高可用分布式系統(tǒng)(為 Uber 提供底層支持的支付系統(tǒng))時必須學(xué)習(xí)和應(yīng)用的概念。

[[243320]]

兩年前我作為一名擁有后臺開發(fā)經(jīng)驗的移動端軟件工程師入職 Uber,并負(fù)責(zé) APP 端支付功能的開發(fā)以及重構(gòu)。后來我進(jìn)入了工程師管理團(tuán)隊,并獨(dú)立帶領(lǐng)一個團(tuán)隊。由于我的團(tuán)隊負(fù)責(zé)很多后端支付相關(guān)的系統(tǒng),因此我有更多的機(jī)會接觸整個支付系統(tǒng)的后端知識。

來 Uber 工作之前,我?guī)缀鯖]有分布式系統(tǒng)的工作經(jīng)驗。我的背景是一個傳統(tǒng)的計算機(jī)科學(xué)學(xué)位和十年的全棧軟件開發(fā)。然而,雖然我能夠畫架構(gòu)圖并討論折中方案,但我對分布式的相關(guān)概念(一致性,可用性或者冪等性)了解的并不多。

在本文中,我總結(jié)了一些我認(rèn)為在構(gòu)建大規(guī)模,高可用分布式系統(tǒng)(為 Uber 提供底層支持的支付系統(tǒng))時必須學(xué)習(xí)和應(yīng)用的概念。這是一個每秒負(fù)載高達(dá)數(shù)千個請求的系統(tǒng),其中關(guān)鍵的支付功能必須能夠正確的工作,即使整個系統(tǒng)的某些部分出現(xiàn)故障。本文會是一個完整的清單嗎?應(yīng)該不會。但如果我早點(diǎn)知道這些概念的話,我的工作和生活會輕松很多。因此,就讓我們開始來了解諸如 SLA,一致性,數(shù)據(jù)持久化,消息持久化,冪等性以及其他一些我在工作中需要學(xué)習(xí)的東西吧。

SLA

對大型系統(tǒng)來說,每天需要處理百萬級別的事件,因此必可避免的會出現(xiàn)問題。在深入設(shè)計一個系統(tǒng)前,我發(fā)現(xiàn)最重要的事情是確定什么是一個健康的系統(tǒng)。系統(tǒng)的健康度應(yīng)該是可衡量的,常用的方法是 SLA:服務(wù)等級協(xié)議(Service Level Agreements)。我見過的一些最常見的 SLA 有:

  1. 可用性:服務(wù)正常運(yùn)行時間的百分比。雖然擁有一個 100% 可用的系統(tǒng)的想法很誘人,但實現(xiàn)這個目標(biāo)是非常困難的,而且費(fèi)用高昂。即使像 VISA 信用卡網(wǎng)絡(luò),Gmail 或者互聯(lián)網(wǎng)提供商這樣的大型和關(guān)鍵系統(tǒng)也達(dá)不到 100% 的可用性,多年來,它們也會停機(jī)幾秒鐘,幾分鐘或者幾小時。對于許多系統(tǒng)來說,四個九的可用性(99.99%,即大約每年有 50 分鐘的停機(jī)時間)就被認(rèn)為是高可用的,通常為了達(dá)到這個水平就要花費(fèi)不少的工作。
  2. 準(zhǔn)確性:表示在系統(tǒng)中是否允許某些數(shù)據(jù)不準(zhǔn)確或者丟失?如果是,可接受的百分比是多少?對于我從事的支付系統(tǒng),準(zhǔn)確性要求是 100%,這意味著不允許丟失任何數(shù)據(jù)。
  3. 負(fù)載能力:系統(tǒng)預(yù)期能夠支持多少負(fù)載?這通常以每秒請求數(shù)來表示。
  4. 延遲率:系統(tǒng)應(yīng)該在多長時間內(nèi)做出響應(yīng)?95% 的請求和 99% 的請求的響應(yīng)時間是多少?系統(tǒng)通常有大量的噪聲請求,因此,P95 和 P99 的響應(yīng)時間對現(xiàn)實系統(tǒng)而言更加實用。

構(gòu)建大型支付系統(tǒng)時 SLA 為什么很重要呢?我們建立一個新系統(tǒng),并用來取代現(xiàn)有的系統(tǒng)。為了確保我們構(gòu)建了正確的系統(tǒng),需要保證新系統(tǒng)比舊系統(tǒng)更好。這時我們就可以使用 SLA 來定義期望值??捎眯允亲罡咭笾?。一旦確定了可用性目標(biāo),我們就需要在設(shè)計架構(gòu)時為了滿足這一目標(biāo)作出折中的選擇。

水平擴(kuò)展和垂直擴(kuò)展

假設(shè)使用新系統(tǒng)的業(yè)務(wù)不斷增長,負(fù)載會隨著不斷增加。在某個時間點(diǎn),現(xiàn)有的配置將無法支持更多的負(fù)載,需要增加更多的系統(tǒng)容量。這時有兩種最常用的擴(kuò)展策略:水平擴(kuò)展和垂直擴(kuò)展。

水平擴(kuò)展指的是向系統(tǒng)中增加更多的機(jī)器/節(jié)點(diǎn),以增加系統(tǒng)總體容量。水平擴(kuò)展是最流行的分布式系統(tǒng)擴(kuò)容方法,尤其是向集群中添加(虛擬)機(jī)器通常簡單到只需要在網(wǎng)頁上點(diǎn)擊一下按鈕。

垂直擴(kuò)展基本上就是通過購買配置更強(qiáng)大的機(jī)器來實現(xiàn)的,無非是給(虛擬)機(jī)器增加更多的處理器內(nèi)核,更多的內(nèi)存等。對于分布式系統(tǒng)而言,垂直擴(kuò)展通常不那么流行,因為它比水平擴(kuò)展費(fèi)用更高。然而,一些重要的站點(diǎn),例如 StackOverflow,已經(jīng)成功的實現(xiàn)垂直擴(kuò)展以滿足系統(tǒng)需求。

為什么構(gòu)建大規(guī)模的支付系統(tǒng)時,系統(tǒng)擴(kuò)展策略至關(guān)重要呢?我們很早就決定建立一個可水平擴(kuò)展的系統(tǒng)。雖然在某些情況下垂直擴(kuò)展是可能的,但由于我們的支付系統(tǒng)已經(jīng)處于預(yù)估的負(fù)載,我們對單臺昂貴的大型機(jī)在今天這種情況下能否支撐它持悲觀態(tài)度,更不用說將來了。我們團(tuán)隊中也有工程師曾經(jīng)在大型支付供應(yīng)商工作過,他們曾試圖在當(dāng)時能夠買到的大型機(jī)上進(jìn)行系統(tǒng)的垂直擴(kuò)展,但以失敗告終。

一致性

任何系統(tǒng)的可用性都是很重要的。分布式系統(tǒng)通常建立在具有較低可用性的機(jī)器上。假設(shè)我們的目標(biāo)是建立一個有 99.999% 可用性的系統(tǒng)(大約每年 5 分鐘時間不可用)。我們使用的機(jī)器/節(jié)點(diǎn)有平均 99.9% 的可用性(大約每年 8 小時時間不可用)。一個簡單的達(dá)到我們目標(biāo)可用性的方法是把一批機(jī)器/節(jié)點(diǎn)添加到一個集群中。即使集群中一些節(jié)點(diǎn)出現(xiàn)故障,也有其他的節(jié)點(diǎn)可用,系統(tǒng)總體的可用性將比單個節(jié)點(diǎn)的可用性更高。

一致性在高可用系統(tǒng)中是一個關(guān)鍵問題。如果集群中所有節(jié)點(diǎn)同時看到并返回相同的數(shù)據(jù),則系統(tǒng)是一致的?;氐街暗哪P停覀兺ㄟ^添加一組節(jié)點(diǎn)來獲得更高的可用性,這時確保系統(tǒng)保持一致性并不是一件微不足道的事情。為了確保每個節(jié)點(diǎn)具有相同的數(shù)據(jù),它們需要互相發(fā)送消息,以保持之間的數(shù)據(jù)同步。但是發(fā)送到對方的消息可能無法到達(dá),它們可能丟失,或者有些節(jié)點(diǎn)可能不可用。

一致性是我花費(fèi)了大量時間去理解的一個概念。有幾種一致性模型,在分布式系統(tǒng)中最常用的是強(qiáng)一致性,弱一致性和最終一致性這三種。Hackernoon 網(wǎng)站上這篇最終一致性和強(qiáng)一致性的對比文章對這些模型之間的權(quán)衡給出了很好的實用的概述。通常一致性越弱,系統(tǒng)可能越快,但它也更有可能不會返回最新的數(shù)據(jù)集。

為什么構(gòu)建一個大型支付系統(tǒng)時一致性很重要呢?系統(tǒng)中的數(shù)據(jù)需要保持一致,但到底多一致呢?對于系統(tǒng)中某些部分,只有強(qiáng)一致性的數(shù)據(jù)才行。例如知道用戶付款操作是否已經(jīng)開始是需要以強(qiáng)一致性的方式存儲下來的。對于其他不是關(guān)鍵業(yè)務(wù)的部分來說,最終一致性被認(rèn)為是合理的權(quán)衡。一個好的例子是列出最近交易這個功能,這種可以以最終一致性方式實現(xiàn)(也就是說,最近一次交易可能只會在一段時間后才在集群中某些節(jié)點(diǎn)中顯示出來,作為回報,查詢操作將以較低的延遲或者耗費(fèi)較少資源的方式返回)。

數(shù)據(jù)持久化

持久化意味著一旦數(shù)據(jù)成功添加到數(shù)據(jù)存儲中,那么將來它將是一直可用的。即使系統(tǒng)中某些節(jié)點(diǎn)離線,崩潰或者數(shù)據(jù)損壞,也不影響數(shù)據(jù)的可用性。

不同的分布式數(shù)據(jù)庫具有不同的持久化。 有些支持機(jī)器/節(jié)點(diǎn)級別的持久化,有些在群集級別支持此功能,有些則不支持該功能。 某種形式的復(fù)制通常用于增加持久化: 如果數(shù)據(jù)存儲在多個節(jié)點(diǎn)上,如果一個或多個節(jié)點(diǎn)發(fā)生故障,數(shù)據(jù)仍然是可用的。這是一篇關(guān)于為什么在分布式系統(tǒng)中實現(xiàn)數(shù)據(jù)持久化是具有挑戰(zhàn)性的好文章。

構(gòu)建大型支付系統(tǒng)時學(xué)到的分布式體系結(jié)構(gòu)概念

為什么構(gòu)建大型支付系統(tǒng)時數(shù)據(jù)持久化很重要呢?對于系統(tǒng)的大部分功能來說,是不允許數(shù)據(jù)丟失的,因為數(shù)據(jù)是非常關(guān)鍵的,例如支付功能。我們構(gòu)建的分布式數(shù)據(jù)存儲需要支持集群級別的數(shù)據(jù)持久化:這樣即使集群中有實例崩潰,已完成的交易依然會被持久化。目前大多數(shù)分布式數(shù)據(jù)存儲服務(wù),如 Cassandra,MongoDB,HDFS 或 Dynamodb 都支持不同級別的數(shù)據(jù)持久化,并且都可以通過配置提供集群級別的持久化。

消息持久化

分布式系統(tǒng)中的節(jié)點(diǎn)負(fù)責(zé)執(zhí)行計算,存儲數(shù)據(jù)和相互間發(fā)送消息。消息發(fā)送的一個關(guān)鍵特性是消息的可靠性。對于業(yè)務(wù)關(guān)鍵性系統(tǒng),通常要求消息零丟失。

對于分布式系統(tǒng),消息傳遞通常由某些分布式消息服務(wù)完成,例如 RabbitMQ,Kafka 等。這些消息服務(wù)可以支持(或者通過配置支持)不同級別的消息傳遞可靠性。

消息持久化意味著當(dāng)正在處理消息的節(jié)點(diǎn)發(fā)送某些故障時,消息仍將在故障解決后繼續(xù)進(jìn)行處理。消息持久化通常用于消息隊列級別。對于持久化的消息隊列,如果隊列(或節(jié)點(diǎn))在消息發(fā)送后脫機(jī)了,它將在重新聯(lián)機(jī)后仍然能夠收到消息。關(guān)于這個主題的更多信息可以看下這篇文章。

構(gòu)建大型支付系統(tǒng)時學(xué)到的分布式體系結(jié)構(gòu)概念

為什么構(gòu)建大型支付系統(tǒng)時消息持久化至關(guān)重要呢?因為我們系統(tǒng)存在不能丟失的消息,例如消費(fèi)者為他們的乘車付款的消息。這意味著我們使用的消息系統(tǒng)必須是無損的:每條消息都必須傳遞一次。但是構(gòu)建一個每條消息只傳遞一次的系統(tǒng),和構(gòu)建一個每條消息至少傳遞一次的系統(tǒng),這兩者復(fù)雜度是不同的。我們決定實現(xiàn)一個消息至少傳遞一次的持久化消息系統(tǒng),并選擇一個消息總線,并將在此基礎(chǔ)上構(gòu)建它(我們最終選擇了 Kafka,為此案例配置了消息無損的集群)。

冪等性

分布式系統(tǒng)往往存在出錯的可能性,例如連接中斷或請求超時等??蛻舳送ǔ卦囘@些請求。冪等系統(tǒng)能夠確保無論特定請求執(zhí)行多少次,該請求的實際執(zhí)行只發(fā)生一次。一個很好的例子就是付款,如果客戶端發(fā)出付款的請求,請求成功但客戶端超時了,客戶端可能會重試相同的請求。對于冪等系統(tǒng),付費(fèi)的人不會被兩次扣款,對于非冪等系統(tǒng),則會發(fā)生兩次扣款操作。

設(shè)計冪等的分布式系統(tǒng)需要某種分布式鎖定策略。這是一些早期分布式系統(tǒng)概念發(fā)揮作用的地方。假設(shè)我們打算通過樂觀鎖來實現(xiàn)冪等性,以避免并發(fā)更新。為了獲得樂觀鎖,系統(tǒng)必須是強(qiáng)一致性的,這樣在操作時,我們可以使用某種版本控制來檢查是否已經(jīng)有另外一個操作正在進(jìn)行。

根據(jù)系統(tǒng)的約束和操作類型,有多種方法可以實現(xiàn)冪等性。設(shè)計冪等方法是一個很好的挑戰(zhàn),Ben Nadel 在文章中介紹了他使用的不同策略,包括分布式鎖或者數(shù)據(jù)庫約束。當(dāng)設(shè)計分布式系統(tǒng)時,冪等性可能是最容易被忽視的部分之一。我就遇到過這樣的場景,我的團(tuán)隊因為沒有確保某些關(guān)鍵操作的正確冪等性而飽受煎熬。

為什么構(gòu)建大型支付系統(tǒng)時冪等性很重要呢?最重要的是:避免雙重收費(fèi)或雙重退款。 鑒于我們的消息系統(tǒng)至少有一次無損傳遞,我們需要假設(shè)所有消息可能多次傳遞,但系統(tǒng)需要確保冪等性。 我們選擇通過版本控制和樂觀鎖來處理這個問題,讓實現(xiàn)冪等行為的系統(tǒng)使用強(qiáng)一致性存儲作為其數(shù)據(jù)源。

分片和 Quorom

分布式系統(tǒng)通常必須比單個節(jié)點(diǎn)存儲更多的數(shù)據(jù)。那么如何在一定數(shù)量的機(jī)器上存儲大量數(shù)據(jù)呢?最常見的技術(shù)是使用分片。數(shù)據(jù)通過某種類型的散列算法進(jìn)行水平分區(qū),并分配給某個分區(qū)。雖然很多分布式數(shù)據(jù)庫在底層已經(jīng)實現(xiàn)了分片,但分片是一個值得進(jìn)一步了解的有趣的領(lǐng)域,尤其是關(guān)于重新分片。Foursquare 的系統(tǒng)在 2010 年有 17 小時的停機(jī)時間,就是因為遇到了一個分片邊緣案例,關(guān)于根本原因有一個很好的剖析。

許多分布式系統(tǒng)具有跨多個節(jié)點(diǎn)復(fù)制的數(shù)據(jù)或者計算。為了確保以一致的方式執(zhí)行這些操作,定義了基于投票的方法,其中一定數(shù)量的節(jié)點(diǎn)需要獲得相同的結(jié)果,以使操作成功,這稱為 Quorum。

為什么在構(gòu)建 Uber 的支付系統(tǒng)時,quorum 和 分片很重要呢?這兩個都是非常常用的基本概念。我在研究如何配置 Cassandra 副本時遇到了這個概念。Cassandra(以及其他分布式系統(tǒng))使用 quorum 和 本地 quorum 來確保集群之間的一致性。作為一個有趣的副作用,在我們的一些會議上,當(dāng)有足夠的人在房間里時,有人會問:“我們可以開始嗎?我們有法定人數(shù)(quorum)嗎?”

Actor 模型

描述編程實踐的常用詞匯,如變量,接口,調(diào)用方法等,都假設(shè)在單機(jī)系統(tǒng)上。在討論分布式系統(tǒng)時,我們需要使用一套不同的方法。描述這些系統(tǒng)的常用方法是遵循 actor 模型,它從通信的角度考慮代碼。這種模型很流行,因為它與我們想到的心理模型相匹配,例如,描述人們在組織中的溝通方式。另一個描述分布式系統(tǒng)的流行方式是 CSP:通信順序流程。

Actor 模型基于 actors 之間相互發(fā)送消息,并對它們作出響應(yīng)。每個 actor 可以做一組有限的事情:創(chuàng)建其他 actor,向其他 actor 發(fā)送消息或者決定如何處理下一條消息。通過一些簡單的規(guī)則,可以很好的描述復(fù)雜的分布式系統(tǒng),在 actor 崩潰后,這些系統(tǒng)也可以自我修復(fù)。簡單的總結(jié),我推薦 Brian Storti 寫的十分鐘了解 actor 模型一文。很多編程語言都實現(xiàn)了 actor 函數(shù)庫或者框架。例如在 Uber,我們在一些系統(tǒng)中使用 Akka 工具包。

為什么構(gòu)建大型分布式系統(tǒng)時 actor 模型很重要呢?我們有很多工程師在一起開發(fā)系統(tǒng),其中很多人有分布式的經(jīng)驗。我們決定遵循一個標(biāo)準(zhǔn)的分布式模型,而不是我們自己提出一個分布式模型概念,從而可能導(dǎo)致重新發(fā)明輪子。

響應(yīng)式架構(gòu)

在構(gòu)建大型分布式系統(tǒng)時,目標(biāo)通常是彈性可擴(kuò)展??赡苓@是一個支付系統(tǒng),或者是另外一個高負(fù)載系統(tǒng),但這樣做的模式可能是類似的。業(yè)內(nèi)人士一直在發(fā)現(xiàn)和分享這些情況下能夠良好運(yùn)行的最佳實踐,而其中響應(yīng)式架構(gòu)在這個領(lǐng)域是一種流行且廣泛應(yīng)用的模式。

開始使用響應(yīng)式架構(gòu)前,我建議您閱讀 Reactive Manifesto 并觀看有關(guān)該主題的 12 分鐘視頻。

為什么構(gòu)建大型支付系統(tǒng)時,響應(yīng)式架構(gòu)很重要呢?Akka,我們用于構(gòu)建大部分新支付系統(tǒng)的工具包,就深受響應(yīng)式架構(gòu)的影響。我們在開發(fā)這個系統(tǒng)的很多工程師也熟悉響應(yīng)式的最佳實踐。遵循響應(yīng)式原則:建立一個響應(yīng)的,彈性的且基于消息驅(qū)動的系統(tǒng),因此這對我們來說非常自然的。我發(fā)現(xiàn)它的好處在于擁有一個可信賴的模型,并檢查進(jìn)度是否處于正確的軌道上,我將繼續(xù)使用這個模型來構(gòu)建以后的系統(tǒng)。

總結(jié)

我很幸運(yùn)的參與了對 Uber 的支付系統(tǒng)這樣一個高可擴(kuò)展,分布式且關(guān)鍵的系統(tǒng)的重建。通過在這種環(huán)境中工作,我學(xué)到了很多以前沒有使用過的分布式概念。通過本文的總結(jié),希望能夠有助于其他人開始或者繼續(xù)對分布式系統(tǒng)的學(xué)習(xí)。

本文重點(diǎn)關(guān)注這些系統(tǒng)的設(shè)計和架構(gòu),關(guān)于在高負(fù)載系統(tǒng)之間構(gòu)建,部署和遷移以及可靠的操作它們,還有很多東西要說。但所有這些都是另一篇文章的主題了。

譯者簡介:顧浩鑫,《Android 高級進(jìn)階》 和 《Android 高級進(jìn)階(源碼剖析篇)》作者。

責(zé)任編輯:未麗燕 來源: ASCE1885
相關(guān)推薦

2023-04-17 08:21:42

2018-12-14 10:06:22

緩存分布式系統(tǒng)

2019-08-05 07:58:01

分布式架構(gòu)系統(tǒng)

2014-07-23 09:33:52

2010-04-01 16:54:06

Oracle體系結(jié)構(gòu)

2009-12-21 14:37:14

2010-02-25 14:46:31

2012-02-23 09:59:05

Hadoop分布式應(yīng)用

2022-05-11 13:55:18

高可用性分布式彈性

2023-01-06 16:42:28

2009-06-12 21:39:48

Java虛擬機(jī)體系結(jié)構(gòu)Java虛擬機(jī)

2009-06-26 15:58:28

EJB

2023-05-12 08:23:03

分布式系統(tǒng)網(wǎng)絡(luò)

2009-01-18 16:50:31

數(shù)據(jù)倉庫數(shù)據(jù)倉庫概念模型數(shù)據(jù)挖掘

2010-04-08 10:17:37

Oracle體系結(jié)構(gòu)

2022-02-22 10:29:24

分布式架構(gòu)高可用

2011-05-19 09:18:48

分布式數(shù)據(jù)庫

2023-02-11 00:04:17

分布式系統(tǒng)安全

2023-05-29 14:07:00

Zuul網(wǎng)關(guān)系統(tǒng)

2017-05-08 11:53:21

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號