歡迎光臨
每天分享高質量文章

超越分散式事務

該文是Salesforce的軟體架構師Pat Helland於2016年12月發表的針對其在2007年CIDR(創新資料庫研究會議)上首次發表的同名文章的更新和縮寫版本。他曾經發表“不變性改變一切”。

 

業界談到分散式事務通常指兩段提交2PC事務(Spring/JEE中JTA等)或者Paxos與Raft,這些事務都有其明顯缺點和侷限性,Pat Helland在本文討論的是另外一種基於本地事務情況下的事務機制,它是基於物體和活動(Activity)的概念,其實類似DDD聚合根和領域事件的概念,這種工作流型別事務雖然需要程式員介入,依靠訊息系統實現,但可以實現接近無限擴充套件的大型系統。Pat文中提出了重要的觀點:“如果你不能使用分散式事務,那麼你就只能使用工作流。”

 

以下是Pat Helland的Life Beyond Distributed Transactions這篇著名文章的翻譯:

 

事務是非常強大的機制,我在它上面花費了我40年職業生涯中的大部分時間。1982年,我首先在Tandem NonStop系統上實現事務機制。這個系統有一個每年平均故障時間,包括跨地理位置的分散式的兩階段提交,為強一致性事務提供了極好的可用性。

 

新的創新,其中包括谷歌的Spanner,提供強一致性環境,在非常大的規模基礎上提供了卓越的可用性。構建一個以支援高度可用的分散式事務應用程式是卓越的創新和重大的挑戰。不幸的是,這個產品不能被廣泛使用。

 

在大多數分散式事務系統中,單個節點的失敗會導致事務提交失敗。這反過來導致應用程式被卡住。在這樣的系統中,系統越大,系統越可能停機。當一個飛機需要所有發動機都必須工作時才能飛行,增加發動機只會降低飛機的可用性。如果沒有特殊的機制來容忍中斷,那麼在數千個節點上執行分散式事務系統是不切實際的。當應用程式開發人員使用非高度可用的分散式事務構建系統時,解決方案很脆弱,必須丟棄。自然選擇就是放棄它(放棄兩段提交事務)…

 

相反,應用程式在沒有提供事務性保證前提下仍能滿足其業務需求。

 

本文探討併在拒絕傳統分散式事務的世界中實施大規模任務關鍵型應用程式時使用的一些實用方法。包括管理細粒度的應用程式資料,隨著應用程式的增長,這些應用程式資料可能會隨著時間的推移重新分割槽。包括一些設計樣式用來支援在這些可重新分割槽的資料之間傳送訊息。

 

這裡的標的是減少人們手工製作大型可擴充套件應用程式所面臨的挑戰。另外,透過觀察這些設計樣式,業界可以透過建立平臺來更輕鬆地開發可擴充套件的應用程式。最後,儘管本文的標的是同類性質可擴充套件的應用程式,但這些技術對於支援可伸縮的異構應用程式(如支援移動裝置)也非常有用。

 

標的

 

本文重點介紹如何在只有本地資料庫或本地事務系統時構建成功的可伸縮企業應用程式。可用性不是重點,主要瞄準規模和正確性。

 

1.可擴充套件應用程式的討論

 

大多數可擴充套件應用程式的設計者都瞭解業務需求。問題在於事務和可擴充套件系統互動的問題,只有概念和抽象卻沒有名稱,也沒有清晰的理解。本文的一個標的是啟動一個討論,以提高對這些概念的認識,為可擴充套件的程式帶來一套通用的術語和一致的方法。

 

2.考慮應用程式的幾乎無限縮放

 

文章提出了一個關於幾乎無限縮放的影響的非正式的思考實驗。也就是說可以允許客戶,可購買商品物體,訂單,發貨,生病患者,納稅人,銀行賬戶以及所有其他業務概念的數量隨著時間不斷顯著增長,這就是無限擴充套件的定義。通常情況下,每件事情都不會太大; 只是數量越來越多。如果CPU,DRAM,儲存或其他資源首先飽和,那並不重要。在某種程度上,需求的增加會導致在一臺機器上執行程式需要在大量的機器上執行。這個思想實驗使我們考慮數十或數十萬臺機器。

 

幾乎無限的縮放是一種鬆散的,不精確的,刻意的無定形的方式,它激發人們需要非常清楚何時何地可以知道某個機器上裝有什麼東西,以及如果無法確保它適合一臺機器,該怎麼辦。此外,您想要與資料和計算負載幾乎線性地縮放。當然,用一個大的日誌以N-log-N的速度進行縮放將會很好。

 

3.描述可擴充套件應用程式的一些常見樣式

 

幾乎無限的擴充套件對業務邏輯有什麼影響?我斷言縮放意味著在編寫程式時使用稱為物體的新抽象。一個物體一次只能在一臺機器上執行,而應用程式一次只能操縱一個物體。幾乎無限縮放的結果是,這種程式化的抽象必須暴露給業務邏輯的開發者。

 

透過命名和討論這個尚未命名的概念,我們也許可以商定一致的方案方法,並對構建可擴充套件系統所涉及的問題有一個一致的理解。

 

此外,物體的使用對用於連線它們的訊息傳遞樣式有影響。這導致了狀態機的建立,這些狀態機不一致性包括無辜的應用程式開發人員試圖為業務問題構建可伸縮解決方案時所產生的訊息傳遞不一致。

 

4.一些假設

 

考慮以下三個假設,假設這些基於經驗是真實的,這些假設是沒有道理的。。

 

(1)應用層面和規模不可知論

 

我們首先假設每個可伸縮應用程式至少有兩層:

程式碼高層 —> 感知規模的API —-> 程式碼下層

 

這些層在縮放的感知上有所不同。他們可能有其他的區別,但這些與這個討論無關。

 

該應用程式的下層理解是:更多的計算機被新增擴大系統規模。除了其他工作之外,它還管理上層程式碼到物理機器及其位置的對映。下層是可以識別的,因為它理解這個對映。我認為下層為上層提供了一個與尺度無關的程式設計抽象。有很多與規模無關的程式設計抽象的例子,包括MapReduce。

 

使用這種與規模無關的程式設計抽象,編寫應用程式程式碼的上層而不用擔心縮放問題。透過堅持與規模無關的程式設計抽象,您可以編寫應用程式程式碼,而不必擔心在部署日益增加的負載時發生的變化。

 

隨著時間的推移,這些應用程式的底層可能會演變成一個新的平臺或中介軟體,從而簡化了與規模無關的API的建立。

 

(2)事務範圍

 

在分散式系統上提供高度一致的事務的概念方面已經做了許多學術工作。這包括2PC(兩階段提交),1個 Paxos和最近的Raft。 經典2PC在一臺機器發生故障時會阻塞,除非事務協調員和參與者本身是容錯的,比如Tandem NonStop系統。Paxos和Raft不會因為節點故障而阻塞,但會像Tandem的系統一樣進行額外的協調工作。

 

這些演演算法可以被描述為在分散式系統上提供強一致的事務。他們的標的是允許任意原子更新傳播到許多機器上的資料。更新存在於跨越多臺機器的單個事務範圍中。

 

不幸的是,在許多情況下,這不是應用程式開發人員的選擇。應用程式可能需要跨越信任邊界,不同平臺以及不同的運營和部署區域。當你對分散式事務“說不”時會發生什麼?

 

即使在今天,在這篇論文寫了10年之後,真正的系統開發人員也很少嘗試在超過幾臺計算機上實現強大的一致性事務。相反,他們承擔多個獨立的事務範圍。每臺電腦都是一個獨立的範圍,內部有本地事務。

 

(3)大多數應用程式使用至少一次訊息

 

如果你是一個短暫的Unix風格的行程,TCP / IP是非常棒的,但考慮一個應用程式開發人員面臨的困境,他的工作是處理訊息並修改資料庫中相應的一些持久資料。該訊息已被消費但尚未確認。只有資料庫被更新後訊息才被確認。如果發生故障,則重新啟動並重新處理訊息。

 

這個困境來源於這樣的事實:除了透過應用動作之外,訊息傳遞不是直接耦合到持久資料的更新。雖然可以將訊息的消費與持久資料的更新結合起來,但這並不常見。兩者緊密耦合的喪失會導致失敗視窗的訊息被傳遞多次。為了防止丟訊息,訊息傳遞至少一次(banq註:Apache kafka在1.0之後提供了Stream的緊耦合更新,不同資料源需要不同Stream外掛)。

 

這種行為的後果是應用程式必須容忍訊息重試和無序傳遞。

 

一些意見分析

 

撰寫評論文章的好處是可以表達狂野的意見。這裡有一些這樣的文章。

 

(1)可擴充套件的應用程式使用唯一標識的物體

該意見認為,每個應用程式的上層程式碼必須處理一個稱為物體的資料集合。單個物體的大小沒有限制,除了必須在單個事務範圍內(即一臺機器)生存。

 

每個物體都有一個唯一的識別符號或鍵,物體鍵可以是任何形式,它必須唯一標識一個物體及其包含的資料。

 

對物體的陳述沒有任何限制。它可能被表示為SQL記錄,XML,JSON,檔案或其他任何東西。一種可能的表示形式是SQL記錄的集合,可能跨越許多表,其主鍵的物體鍵作為其字首。

 

物體表示不相交的資料集。每個資料只在一個物體中。

 

一個應用程式由許多物體組成。例如,訂單處理應用程式封裝了許多訂單,每個訂單都由一個唯一的訂單ID標識。要成為可擴充套件的訂單處理應用程式,來自一個訂單的資料必須與其他訂單的資料不相交(banq註:主鍵ID透過全域性分散式主鍵生成器唯一分配)。

 

(2)原子事務不能跨越物體

 

每臺計算機被假定為一個單獨的事務範圍。本文稍後介紹原子事務不能跨物體的論點。程式員必須始終確保每個事務中資料包含在的單個物體中(banq註:有些類似DDD的聚合根物體概念)。

 

從程式員的角度來看,唯一標識的物體就是事務範圍。這個概念對用於設計可縮放的應用程式具有強大的影響。需要探討的一個含義是,在設計幾乎無限的縮放比例時,可能不能保持事務一致。

 

(3)訊息被分配給物體

 

大多數訊息傳遞系統不考慮資料的分割槽,而是針對無狀態行程使用的佇列。標準做法是在訊息中包含一些資料,通知無狀態應用程式程式碼在哪裡獲取所需資料。這是物體的關鍵。物體的資料由應用程式從某個資料庫或其他持久儲存中獲取。

 

一些有趣的趨勢正在發生。首先,這組物體的大小正在變得比適合一臺計算機的大。每個單獨的物體通常適合一臺計算機,但是它們的集合不一樣。越來越多的無狀態應用程式正在路由以基於某種分割槽方案來獲取物體。

 

其次,抓取和分割槽方案正被分成應用程式的下層。這是故意與負責業務邏輯的上層隔離的。

 

該樣式透過使用物體鍵進行路由來有效地定位物體。無狀態的Unix風格的行程和應用程式的低層都只是為業務邏輯提供的與規模無關的API的實現的一部分。上層規模不可知的業務邏輯簡單地透過唯一標示將訊息定位到某個物體。

 

(4)物體管理每個合作伙伴狀態(活動)

 

與規模無關的訊息能夠在物體之間有效的傳遞。傳送物體以其持久狀態顯示,並由其物體鍵標識。它傳送一個訊息給另一個物體,並透過它的物體唯一鍵來識別它。物體接收者由與規模無關的上層業務邏輯和表示其狀態的持久資料組成。這是透過它的物體鍵來標識的。

 

回想一下這樣的假設:訊息至少被傳遞一次。接受者物體可能有些困擾,因為必須忽略的冗餘重覆訊息。在實踐中,訊息分為兩類:影響物體狀態的訊息和不影響狀態的訊息。不影響物體狀態的訊息很容易 – 它們是冪等的。改變狀態的訊息需要更多的關註(banq註:改變狀態的訊息一般稱為事件)。

 

為了確保冪等性(即保證重試訊息的處理是無害的),接收者物體通常被設計為記住訊息已經被處理。成功處理後,重覆的訊息通常會生成新的另一個響應以表示該訊息重覆。

 

接收到的訊息的物體建立了基於夥伴為基礎的狀態。每個狀態只能存在每個物體中,

 

術語“活動activity ”這個詞語適用於管理雙方關係,會對關係中每個夥伴狀態有影響的訊息。每個活動都是精確地生活在一個物體中,一個物體有一個為其夥伴物體準備的活動。(banq註:這個活動是一種業務活動,業務工作流)

 

除了管理訊息傳遞方式之外,還可以使用活動來管理鬆散耦合的協議。在一個原子事務不可能的世界裡,嘗試性的操作被用來進行談判以獲得共同的結果。這些都是在物體之間執行的,由活動管理。

 

建立工作流程以達成一致是充滿挑戰的,這些挑戰在其他地方都有詳細記錄。本文並沒有斷言活動解決了這些挑戰,而是為針對解決這些挑戰而儲存的狀態奠定了基礎。

 

幾乎無限的縮放規模要求竟然導致了出人意料的細粒度的工作流風格的解決方案。

 

參與者都是物體,每個物體使用有關其他物體的特定知識來管理其工作流程。在物體內維護的雙方知識被稱為活動。

 

活動的例子有時是微妙的。訂單應用程式將訊息傳送到發貨應用程式。它包括貨運ID和傳送訂單ID。訊息型別可用於激發運送應用程式中的狀態更改,以記錄指定的訂單已準備好出貨。通常情況下,實施者不會設計重試,直到出現錯誤。應用程式設計師偶爾也會考慮活動的計劃。

 

物體

 

本節更深入地研究物體的性質。

 

1.不相交的事務範圍

 

每個物體都被定義為一個擁有一個唯一標識的資料集合,這個標識只存在於一個事務範圍內。原子交易可能總是在一個物體內完成。(banq註:類似DDD中的聚合根物體)

 

2.唯一鍵的物體

 

應用程式上層的程式碼自然是圍繞具有唯一鍵的資料集合來設計的。客戶ID,社會安全號碼,產品SKU和其他唯一識別符號可以在應用程式中看到。它們被用作查詢應用程式資料的鍵。交易原子性的保證只能在由唯一標識的物體中。

 

3.重新分配和物體

 

之前提到的假設之一是新興的上層是規模不可知的,下層決定了隨著規模的變化,部署如何演變。隨著部署的演變,特定物體的位置可能會發生變化。應用程式的上層不能對物體的位置做出假設,因為這不會成比例。

 

物體可使用Hash雜湊或基於鍵範圍分配策略進行跨區分配。

 

比如key是ABC ABZ DEF FAW在A區伺服器 FXQ GHI JKL KZU LMN在B區伺服器,PAZ PJH TVA UTV ZZZ在C區伺服器。

 

4.原子事務和物體

 

在可擴充套件的系統中,您不能假設在這些不同物體之間實現更新修改的事務。每個物體都有一個唯一的標識,每個物體很容易放入一個事務範圍。回想一下這樣的前提:幾乎無限的縮放會導致物體的數量不可避免地增加,但是個體的大小仍然足夠小以適應事務範圍(即一臺計算機)。

 

你怎麼知道兩個獨立的物體保證在同一個事務範圍內,因而可以自行在自己事務中原子更新?只有當全域性只有一個唯一的key主鍵時,你能知道它真的是隻有一個物體!

 

如果Hash雜湊用於物體鍵的分割槽,則不知道具有不同鍵的兩個物體何時落在同一個伺服器內。如果鍵範圍分割槽用於物體鍵,大部分時間相鄰鍵值會駐留在同一臺機器上。偶爾會遇到不幸,而你的鄰居會在另一臺機器上。

 

一個簡單的測試案例,透過鍵範圍分割槽中的鄰居之間的計算原子性通常會成功。後來,當重新部署將物體移動到機器上時,潛在的錯誤就出現了。更新不再是原子的。你永遠不能指望在同一個地方居住的不同的物體鍵值(不要期望物體固定在哪個伺服器內被建立)。

 

簡而言之,應用程式的底層將確保每個物體鍵(及其物體)駐留在一臺機器上。不同的物體可能在任何地方。(banq註:DDD中倉儲工廠樣式就是負責一個個聚合根物體的建立)

 

規模不可知的程式設計抽象必須具有將物體作為原子性邊界的概念。理解物體,使用物體關鍵字以及明確承諾物體之間缺乏原子性是規模無關的程式設計必不可少的知識。

 

大規模的應用程式悄悄地在今天的行業中已經做到這一點; 只是沒有一個物體的概念的名稱。從上層應用程式的角度來看,它必須假定物體是代表一個事務的範圍。假設部署變化時會產生更多的中斷。

 

5.考慮候選索引

 

我們習慣於使用多個鍵或索引來處理資料。例如,有時一個客戶被社會安全號碼(有時是信用卡號碼,有時是街道地址)取用。假設進行大量的縮放,這些索引不能駐留在同一臺機器上,也不能駐留在單個大型叢集中。無法知道關於單個客戶的所有資料都駐留在單個事務範圍內。雖然物體本身駐留在單個事務範圍內。所面臨的挑戰是,用於建立這些候選索引的資訊副本必須被假定為與物體自身資訊駐留在不同的事務範圍中。

 

首先考慮確保候選索引駐留在相同的事務範圍內。當幾乎無限的縮放開始時,物體的集合被塗抹在巨大數量的機器之中。主索引和候選索引資訊必須位於相同的事務範圍內。確保這一點的唯一方法是使用主索引找到候選索引。這將把你帶到相同的事務範圍。如果您在沒有主索引的情況下啟動並且必須搜尋所有事務範圍,則每個候選索引查詢都必須在幾乎無限數量的範圍內檢查,因為它會使用候選鍵進行匹配查詢。這將最終成為站不住腳的。

 

唯一合乎邏輯的選擇是做兩步查詢。首先,查詢候選鍵。其次,使用物體鍵訪問物體。這與關係資料庫非常相似,因為它就是使用兩個步驟透過候選鍵訪問記錄的。但是幾乎無限縮放的前提意味著兩個指標(主要和候選)不能被認為是在相同的事務範圍內。

 

過去自動管理的候選索引現在必須由應用程式手動管理。透過非同步訊息傳遞的工作流風格更新是剩下的唯一選擇。當您從候選索引讀取資料時,您必須瞭解它可能與物體本身不同步。候選索引現在更難。這是一個巨大系統的殘酷世界中的生活事實。(banq註:索引是為查詢服務,可使用讀寫分離)

 

在物體之間傳遞的訊息

本節考慮使用訊息來連線獨立的物體。它檢查命名,事務和訊息,訊息傳遞語意以及重新分割槽物體的影響。

 

(1)訊息在物體之間進行通訊

 

如果您無法在同一事務中的兩個物體之間更新資料,則需要一種機制來更新不同事務中的資料。物體之間的連線是透過訊息。

 

(2)非同步傳送事務

 

由於訊息在物體之間傳遞,與傳送訊息的決定相關的資料在一個物體中,並且訊息的目的地在另一個物體中。根據一個物體的定義,這些物體不能被原子更新。訊息不能透過這些不同的物體自動傳送和接收。

 

如果應用程式開發人員在處理事務時傳送訊息,傳送訊息,然後事務中止,那將會非常複雜。這意味著你沒有任何措施記住發生的事情,但這些事情確實發生了。出於這個原因,訊息的事務排隊是必要的。

 

如果訊息在傳送事務提交之後才能在目的地被看到,則訊息對於傳送事務是非同步的。每個物體在一個事務中會進入一個新狀態。訊息是來自一次事務的刺激,併到達另外一個物體引起新的事務。

 

(3)命名訊息的目的地

 

考慮應用程式的規模無關部分的程式設計,因為一個物體想要傳送訊息給另一個物體。規模不可知的程式碼不知道標的物體的位置。物體主鍵就是關鍵。

 

物體鍵能夠實現應用程式的規模感知,將物體主鍵與物體的具體位置相關聯。

 

(4)重新分割槽和訊息傳遞

 

當應用程式與規模無關的部分傳送訊息時,較低階別的擴充套件感知部分搜尋標的並且傳遞訊息至少一次。

 

隨著系統規模的擴大,物體在移動。這通常被稱為重新分割槽。物體的位置以及因此訊息的目的地可能在不斷變化。有時訊息會追溯到舊的位置,只是為了找出討厭的物體已經傳送到別處什麼地方聊。現在,訊息將不得不這麼做。

 

隨著物體的移動,傳送者和目的地之間的先進先出佇列的清晰度偶爾中斷。訊息被重覆。稍後的訊息在較早的訊息之前到達 生活變得更加混亂。

 

由於這些原因,與規模無關的應用程式正在不斷演進到以支援所有應用程式對可見訊息的冪等處理。這也意味著在訊息傳遞中可進行重新排序。

 

2018-01-11 17:34

 

活動:應對雜亂的訊息

 

本節討論如何應對訊息重試和重新排序的挑戰。它將活動的概念介紹為管理與合作伙伴物體的關係所需的本地資訊。

 

1.重試和冪等性

 

由於任何訊息都可能被多次傳遞,因此應用程式需要一個處理重覆訊息的規則。儘管可以為消除重覆訊息構建低階支援,但在幾乎無限的擴充套件環境中,低階支援需要瞭解物體。當物體由於重新分割槽而移動時,必須知道哪些訊息已經傳送給物體。在實踐中,這種低階管理的知識很少發生; 訊息可能會被傳遞多次。

 

通常,應用程式的規模不可知(更高階別)部分必須實現機制來確保傳入訊息是冪等的。這對問題的本質並不重要。重覆的消除當然可以構建到應用程式的可感知尺度的部分。這還不可用。因此,這是很難做到的。

 

2.什麼是冪等

 

如果後續的處理執行沒有對物體進行實質性改變,則訊息的處理是冪等的。這是一個無定形的定義。

 

如果訊息沒有改變被呼叫的物體,但只是讀取資訊,則其處理是冪等的。即使寫入了描述讀取的日誌記錄,情況也是如此。日誌記錄對物體的行為沒有實質性的影響。

 

3.自然的冪等性

 

為了實現相同的標的,訊息不會造成實質性的副作用是至關重要的。一些訊息任何時候處理都不會引起實質性的工作。這些自然是冪等的。

 

只從一個物體讀取一些資料的訊息自然是冪等的。如果訊息的處理確實改變了物體,但沒有實質性的改變呢?那些也自然是冪等的。

 

現在變得更加困難。一些資訊所隱含的工作實際上引起了實質性的變化。這些訊息不是自然而然的冪等。應用程式必須包含機制來確保這些也是冪等的。這意味著要以某種方式記住資訊已經被處理,以便後續的嘗試不會有實質性的改變。

 

下一節將考慮處理不自然是冪等的訊息。

 

4.將訊息記為狀態

 

為了確保對那些不自然是冪等的訊息進行冪等處理,物體必須記住它們已被處理。這個知識是狀態。狀態在訊息處理時變化。(banq註:此時訊息可稱為事件)

 

另外,如果需要回覆,則必須傳回相同的回覆。畢竟,你不知道原始發件人是否收到回覆。

 

5.管理每個合作伙伴的狀態

 

為了跟蹤收到的關係和訊息,規模不可知的應用程式中的每個物體必須以某種方式記住關於其合作伙伴的狀態資訊。它必須以夥伴為基礎來捕捉這個狀態。讓我們把這個狀態命名為一個活動(banq註:類似事件)。參見圖6.每個物體如果與許多其他物體互動,可能會有許多活動。活動跟蹤與每個合作伙伴的互動。

 

每個物體都由一組活動組成,也許還有一些跨越活動的其他資料。

 

考慮處理由許多購買物品組成的訂單。為每個單獨專案的運輸保留庫存將是一個單獨的活動。倉庫將管理每個物料的訂單和物體。事務不能跨越這些物體。

 

在訂單物體內,每個庫存專案將分開管理。訊息傳遞協議必須分開管理。訂單物體中包含的每個庫存專案資料代表一個活動(訂單條目代表一個事件活動,類似賬本,每一行記錄發生的進出金額)。雖然它不是這樣命名的,但這種樣式經常存在於大型應用程式中。

 

在一個幾乎無限擴充套件的應用程式中,您需要非常清楚關係。你不能只是做一個查詢來弄清楚什麼是相關的。一切都必須透過雙方關係網路正式地結合在一起。編織是用物體鍵完成的。因為合作伙伴離我們有一段距離,所以當合作伙伴到達時,你必須正式把你對合作伙伴的狀態理解為新的知識。已知的關於遠方的本地資訊被稱為活動。(banq註:透過DDD有界背景關係定位聚合根物體,聚合根物體之間透過事件完成)

 

6.透過活動確保最多一次接受

 

處理不自然冪等的訊息需要確保每個訊息最多處理一次(即訊息的實質性影響最多隻發生一次)。要做到這一點,必須記住訊息的一些獨特特徵,以確保訊息不會被多次處理。

 

物體必須永久地記住從訊息接受切換相應狀態的處理不會產生實質性影響。

 

通常,一個物體使用其活動來逐個與其合作伙伴地實施這種狀態管理。這是非常重要的,因為有時一個物體支援許多不同的合作伙伴,每個合作伙伴都會傳遞一種與這種關係相關的訊息樣式 ,包含每個合作伙伴的狀態集合使其成為可能。

 

活動:應對沒有原子性

 

本節討論如何在無需分散式事務的情況下進行大幅擴充套件系統的決策。

 

管理分散式協議是艱苦的工作。在幾乎無限可擴充套件的環境中,不確定性的表示必須以圍繞每個夥伴關係的細粒度的方式進行。這些資料是使用活動的概念在物體內部管理的。

 

1.遠處的不確定性

 

分散式事務的缺乏意味著在試圖跨越不同物體做出決策時接受不確定性。不可避免地,分散式系統的決策需要一段時間來接受不確定性。當分散式事務可以被使用時,這種不確定性就體現在資料鎖上,並由事務管理器進行管理。

 

在不能依靠分散式事務的系統中,不確定性的管理必須在業務邏輯中實現。結果的不確定性是在業務語意中而不是在記錄鎖中。這簡直就是一種工作流程。這不是魔術。

 

如果你不能使用分散式事務,那麼你就只能使用工作流。

 

物體和訊息的概念提出,導致這樣一個結論:規模不可知的應用程式必須使用工作流程來管理不確定性。這需要跨多個物體達成協議。

 

考慮一下企業間常見的互動風格(辦公流程)。企業之間的合同包括時間承諾,取消條款,保留的資源,等等。業務功能的行為本身就包含了不確定性。雖然比使用分散式事務更複雜,但真實世界就是這麼工作的…(banq註:比如一個企業每個月定期向銀行匯款,這個過程是一個事務過程,通常透過流程規劃實現,如果第一次失敗了,從銀行接受失敗資料,然後重新再次報盤傳送,這種重試過程就是確保資料精確送達銀行的事務機制)

 

這隻是工作流程的一個論點。

 

2.活動與不確定性的管理

 

物體有時在與其他物體互動時接受不確定性。這種不確定性必須在逐個合作伙伴的基礎上進行管理,並且可以被視為在合作伙伴的活動狀態中具體化。

 

很多時候,不確定性是由關係來表示的。有必要跟蹤夥伴。活動跟蹤每個合作伙伴進入一個新的狀態。

 

如果訂單系統為某個商品保留了倉庫的庫存,則倉庫那邊系統在不知道這個商品已經被保留庫存情況下會為其重新分配庫存。這是可接受的不確定性。之後,倉庫會發現自己再次預留庫存是否有必要。這解決了不確定性。

 

倉庫庫存管理員必須保留每個訂單的關係資料。由於它連線物品和訂單,這些將按訂單條目組織。每個條目都儲存有關該條目未完成訂單的資訊。條目內的每項活動(每個訂單一項)管理訂單的不確定性。

 

3.執行暫時的業務操作

 

為了達成跨物體的協議,一個物體要求另一個物體接受不確定性。一個物體傳送另一個可能稍後取消的請求。這被稱為暫時性操作。在這一步的最後,一個物體同意遵守另一個的意願。(banq註:暫時性操作類似信用卡的預扣款請求,是一種嘗試性的、實驗性的、試探性的請求)。

 

4.暫時性操作,確認和取消

 

暫時性操作的基本要素是有權利能取消。如果請求物體決定不跟隨當前業務前進,則發出取消操作(banq註:如果被預扣款的信用卡沒有信用額度,則拒絕)。如果決定繼續,它會發出確認操作。

 

當一個物體同意進行暫時操作時,同意讓另一個物體決定其結果,它實際就接受不確定性,增加了混亂。隨著確認和取消的到來,不確定性下降,減少了混亂。隨著老問題的解決和新的問題的到來,隨著生活的不斷增加和不斷減少,這是正常的。

 

再次說明,這是一種工作流程,但它是以物體作為參與者的細粒度的工作流程。

 

5.不確定性和幾乎無限縮放

 

不確定性管理通常圍繞雙方協議進行。可能有多個雙方協議。這些作為連結和活動來跟蹤遠方的已知狀態,將它們組織在一起,形成一個細密的雙方協議網路,使用物體鍵作為連結和活動。

 

考慮購房和與託管公司的關係(banq註:中國是二手房資金託管中心)。買方與託管公司簽訂委託協議,賣方,抵押公司以及參與交易的所有其他各方也同意。

 

當你去簽署檔案買房子,你不知道交易的結果。但是你得接受,直到託管關閉,你一直是不確定的。控制決策的唯一方是託管公司。

 

這是一個集中的雙方關係,用來讓大量的當事方在不使用分散式事務的情況下達成一致。

 

在考慮近乎無限的規模時,考慮雙方關係是很有趣的。透過建立雙方的臨時/取消/確認(就像傳統的工作流程一樣),你可以看到實現分散式協議的基礎。正如在第三方託管公司,許多物體可能透過組合方式參與協議的完成。

 

因為這種關係是雙方的關係,一個簡單的活動概念就像是“我記得那個夥伴的東西”,成為管理龐大系統的基礎 – 即使資料儲存在物體中,而且你不知道物體在哪裡。你必須假設它很遠。不過,它可以按照與規模無關的方式進行程式設計。

 

現實世界中很多應用程式喜歡全域性性事務這樣的奢侈品。不幸的是,當系統出現故障時,我們大多數人並沒有意識到是我們自己引入脆弱性。

 

相反,試驗性工作的不確定性管理交給了應用程式的開發者手中。必須將其作為預留庫存、針對信用額度的預扣款以及其他應用程式特定的業務概念來處理。

 

結論

 

像往常一樣,計算機行業正在變化中。

 

今天,新的設計壓力正在被強加到只想解決業務問題的程式員身上。現實正在把他們帶入一個幾乎無限縮放的世界,並迫使他們陷入與現實生活無關的設計問題。今天是這樣,2007年這篇文章首次出版時就是這樣。

 

不幸的是,努力解決電子商務、供應鏈管理、財務和醫療應用程式等業務標的的程式員越來越需要思考如何在沒有分散式事務的情況下進行擴充套件。大多數開發人員根本無法訪問提供可擴充套件分散式事務的強大系統。

 

我們正處在一個可以看到構建這些應用程式的樣式的時刻,但是還沒有人能夠一致地應用這些樣式。本文認為,這些新生的樣式可以更為一致地應用於幾乎無限縮放設計的應用程式開發中。

 

本文介紹並命名了大量應用中出現的幾種樣式:

 

• 物體,是已命名(帶有鍵key)資料的集合,可以在物體內原子更新,但從不在物體間自動更新。

 

• 活動,由用於管理與單個合作伙伴物體之間的訊息關係的物體內狀態集合組成。

 

在物體內的活動中達成決策的工作流程。當看到幾乎無限的縮放規模時,你會意識到這是由工作流程的細粒度特性決定的。

 

許多應用程式已經悄悄地使用物體和活動這樣概念設計,只不過名稱不同而已。物體和活動這些名詞可能根本不是正式的,也沒有被一貫使用。如果使用不一致,則會發現錯誤並最終進行修補。透過討論並持續使用這些樣式,可以建立更好的大規模應用程式,並且作為一個行業,我們可以更接近於構建解決方案,使業務邏輯程式員能夠專註於業務問題而不是規模問題。

原文地址:https://blog.csdn.net/leonardc/article/details/80134418


.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com


 

    閱讀原文

    贊(0)

    分享創造快樂