掌握這些Java開發熱門前沿知識,小米Java校招面試題

mb60ed825746281 2021-09-19 05:33:09 阅读数:150

掌握 java 前沿 小米 java

背景知識

CAP定理

CAP定理,又被叫作布魯爾定理。對於設計分布式系統來說(不僅僅是分布式事務)的架構師來說,CAP就是你的入門理論。

? C (一致性):對某個指定的客戶端來說,讀操作能返回最新的寫操作。對於數據分布在不同節點上的數據上來說,如果在某個節點更新了數據,那麼在其他節點如果都能讀取到這個最新的數據,那麼就稱為强一致,如果有某個節點沒有讀取到,那就是分布式不一致。

? A (可用性):非故障的節點在合理的時間內返回合理的響應(不是錯誤和超時的響應)。可用性的兩個關鍵一個是合理的時間,一個是合理的響應。合理的時間指的是請求不能無限被阻塞,應該在合理的時間給出返回。合理的響應指的是系統應該明確返回結果並且結果是正確的,這裏的正確指的是比如應該返回50,而不是返回40。

? P (分區容錯性):當出現網絡分區後,系統能够繼續工作。打個比方,這裏個集群有多臺機器,有臺機器網絡出現了問題,但是這個集群仍然可以正常工作。

BASE理論

BASE 理論指的是基本可用 Basically Available,軟狀態 Soft State,最終一致性 Eventual Consistency,核心思想是即便無法做到强一致性,但應該采用適合的方式保證最終一致性,是對CAP中AP的一個擴展。

BASE,Basically Available Soft State Eventual Consistency 的簡寫:

BA:Basically Available 基本可用,分布式系統在出現故障的時候,允許損失部分可用性,即保證核心可用。

S:Soft State 軟狀態,允許系統存在中間狀態,而該中間狀態不會影響系統整體可用性。

E:Consistency 最終一致性,系統中的所有數據副本經過一定時間後,最終能够達到一致的狀態。

BASE 理論本質上是對 CAP 理論的延伸,是對 CAP 中 AP 方案的一個補充。

柔性事務

不同於 ACID 的剛性事務,在分布式場景下基於 BASE 理論,就出現了柔性事務的概念。要想通過柔性事務來達到最終的一致性,就需要依賴於一些特性,這些特性在具體的方案中不一定都要滿足,因為不同的方案要求不一樣;但是都不滿足的話,是不可能做柔性事務的。

幂等操作

在編程中一個幂等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。幂等函數,或幂等方法,是指可以使用相同參數重複執行,並能獲得相同結果的函數。這些函數不會影響系統狀態,也不用擔心重複執行會對系統造成改變。例如,支付流程中第三方支付系統告知系統中某個訂單支付成功,接收該支付回調接口在網絡正常的情况下無論操作多少次都應該返回成功。

為什麼需要分布式事務

隨著業務的發展及服務的SOA化,一些大的操作往往由不同的小操作組成,而這些小的操作分布在不同的服務器上,分布式事務需要保證這些小操作要麼全部成功,要麼全部失敗。從本質上來說,分布式事務是為了保證不同數據庫的數據一致性。可能應用分布式事務的場景有:

  1. 數據庫分庫分錶

當數據庫單錶數據達到千萬級別,就要考慮分庫分錶,那麼就會從原來的一個數據庫變成多個數據庫。例如如果一個操作即操作了01庫,又操作了02庫,而且又要保證數據的一致性,那麼就要用到分布式事務。

  1. 應用SOA化

所謂的SOA化,就是業務的服務化。例如電商平臺下單操作就會產生調用庫存服務扣减庫存和訂單服務更新訂單數據,那麼就會設計到訂單數據庫和庫存數據庫,為了保證數據的一致性,就需要用到分布式事務。

兩套協議、四類常見方案

兩套協議是指兩階段提交協議2PC和三階段提交協議3PC

四類常見方案這裏我們介紹以下分布式事務解决方案:Tcc、可靠消息最終一致性、最大努力通知、Saga

兩套協議

兩階段提交協議2PC

兩階段提交(2PC) 是 Oracle Tuxedo 系統提出的 XA 分布式事務協議的其中一種實現方式。

XA協議中有兩個重要角色:事務協調者事務參與者

漫話圖解

2PC協議有兩個階段:Propose和Commit. 在無failure情况下的2PC協議流程的畫風是這樣的:

? Propose階段:

? coordinator: “昨夜驗人有驚喜, 今天都投票出六娃”

? voter1/voter2/voter3: “好的女王大人!”

? Commit階段

? coordinator: “投六娃”

? voter1/voter2/voter3: “投了女王大人!” (畫外音: 六娃撲街)

掌握這些Java開發熱門前沿知識,小米Java校招面試題_Java

圖1: 2PC, coordinator提議通過, voter{1,2,3}達成新的共識

如果有至少一個voter (比如voter3)在Propose階段投了反對票, 那麼propose通過失敗. coordinator就會在Commit(or abort)階段跟所有voter說, 放弃這個propose.

掌握這些Java開發熱門前沿知識,小米Java校招面試題_後端_02

圖2: 2PC, coordinator提議沒有通過, voter{1,2,3}保持舊有的共識

具體流程

分布式事務中2PC的具體流程是這樣的:

第一階段

? 順利的情况

  1. 事務協調者的節點會首先向所有的參與者節點發送 Prepare(預備) 請求。

  2. 在接到 Prepare(預備) 請求之後,每一個參與者節點會各自執行與事務有關的數據更新,寫入Undo Log和Redo Log。

  3. 參與者執行成功,暫時不提交事務,向事務協調節點返回done(完成)消息。

  4. 進入第二階段

? 出錯時

在XA的第一階段,如果某個事務參與者反饋失敗消息,說明該節點的本地事務執行不成功,必須回滾。

  1. 事務協調者的節點會首先向所有的參與者節點發送 Prepare(預備) 請求。

  2. 在接到 Prepare(預備) 請求之後,每一個參與者節點會各自執行與事務有關的數據更新,寫入Undo Log和Redo Log。

  3. 參與者執行失敗,返回失敗消息。

  4. 協調者中斷事務

中斷事務

任何一個參與者向協調者反饋了 No 響應,或者在等待超時之後,協調者尚無法接收到所有參與者的反饋響應,那麼就會中斷事物。

  1. 發送回滾請求。協調者向所有參與者節點發出 Rollback 請求。

  2. 事物回滾。參與者收到Rollback請求之後,會利用其在階段一種記錄的 Undo 信息來執行事務回滾操作,並在完成回滾之後釋放在整個事物執行期間占用的資源。

  3. 反饋事物回滾結果。參與者在完成事物回滾之後,向協調者發送 Ack 消息。

  4. 中斷事務

第二階段

在XA分布式事務的第二階段,如果事務協調節點在之前所收到都是正向返回,那麼它將會向所有事務參與者發出Commit請求。

接到Commit請求之後,事務參與者節點會各自進行本地的事務提交,並釋放鎖資源。當本地事務完成提交後,將會向事務協調者返回“完成”消息。

當事務協調者接收到所有事務參與者的“完成”反饋,整個分布式事務完成。

優缺點

優點

2PC是强一致(要打個問號)協議:

  1. 預備、提交兩個階段保證了事務是原子的

  2. 2PC是允許讀-寫隔離的,這意味著某個字段的變更在事務協調者提交之前是不可見的。

缺點

  1. 同步阻塞:當參與事務者存在占用公共資源的情况,其中一個占用了資源,其他事務參與者就只能阻塞等待資源釋放,處於阻塞狀態。

  2. 單點故障:一旦事務管理器出現故障,整個系統不可用

  3. 數據不一致:在階段二,如果事務管理器只發送了部分 commit 消息,此時網絡發生异常,那麼只有部分參與者接收到 commit 消息,也就是說只有部分參與者提交了事務,使得系統數據不一致。

  4. 不確定性:當協事務管理器發送 commit 之後,並且此時只有一個參與者收到了 commit,那麼當該參與者與事務管理器同時宕機之後,重新選舉的事務管理器無法確定該條消息是否提交成功。

三階段提交協議3PC

漫話圖解

簡單的說來, 3PC就是把2PC的Commit階段拆成了PreCommit和Commit兩個階段. 通過進入增加的這一個PreCommit階段, voter可以得到Propose階段的投票結果, 但不會commit; 而通過進入Commit階段, voter可以盤出其他每個voter也都打算commit了, 從而可以放心的commit.

換言之, 3PC在2PC的Commit階段裏增加了一個barrier(即相當於告訴其他所有voter, 我收到了Propose的結果啦). 在這個barrier之前coordinator掉線的話, 其他voter可以得出結論不是每個voter都收到Propose Phase的結果, 從而放弃或選出新的coordinator; 在這個barrier之後coordinator掉線的話, 每個voter會放心的commit, 因為他們知道其他voter也都做同樣的計劃.

掌握這些Java開發熱門前沿知識,小米Java校招面試題_程序員_03

圖3: 3PC, coordinator提議通過, voter{1,2,3}達成新的共識

具體流程

階段一 CanCommit

  1. 事務詢問:Coordinator 向各參與者發送 CanCommit 的請求,詢問是否可以執行事務提交操作,並開始等待各參與者的響應;

  2. 參與者向 Coordinator 反饋詢問的響應:參與者收到 CanCommit 請求後,正常情况下,如果自身認為可以順利執行事務,那麼會反饋 Yes 響應,並進入預備狀態,否則反饋 No。

階段二 PreCommit

執行事務預提交:如果 Coordinator 接收到各參與者反饋都是Yes,那麼執行事務預提交:

  1. 發送預提交請求:Coordinator 向各參與者發送 preCommit 請求,並進入 prepared 階段;

  2. 事務預提交:參與者接收到 preCommit 請求後,會執行事務操作,並將 Undo 和 Redo 信息記錄到事務日記中;

  3. 各參與者向 Coordinator 反饋事務執行的響應:如果各參與者都成功執行了事務操作,那麼反饋給協調者 ACK 響應,同時等待最終指令,提交 commit 或者終止 abort,結束流程;

中斷事務:如果任何一個參與者向 Coordinator 反饋了 No 響應,或者在等待超時後,Coordinator 無法接收到所有參與者的反饋,那麼就會中斷事務。

  1. 發送中斷請求:Coordinator 向所有參與者發送 abort 請求;

  2. 中斷事務:無論是收到來自 Coordinator 的 abort 請求,還是等待超時,參與者都中斷事務。

階段三 doCommit

執行提交

  1. 發送提交請求:假設 Coordinator 正常工作,接收到了所有參與者的 ack 響應,那麼它將從預提交階段進入提交狀態,並向所有參與者發送 doCommit 請求;

  2. 事務提交:參與者收到 doCommit 請求後,正式提交事務,並在完成事務提交後釋放占用的資源;

  3. 反饋事務提交結果:參與者完成事務提交後,向 Coordinator 發送 ACK 信息;

  4. 完成事務:Coordinator 接收到所有參與者 ack 信息,完成事務。

中斷事務:假設 Coordinator 正常工作,並且有任一參與者反饋 No,或者在等待超時後無法接收所有參與者的反饋,都會中斷事務

  1. 發送中斷請求:Coordinator 向所有參與者節點發送 abort 請求;

  2. 事務回滾:參與者接收到 abort 請求後,利用 undo 日志執行事務回滾,並在完成事務回滾後釋放占用的資源;

  3. 反饋事務回滾結果:參與者在完成事務回滾之後,向 Coordinator 發送 ack 信息;

  4. 中斷事務:Coordinator 接收到所有參與者反饋的 ack 信息後,中斷事務。

優缺點

? 優化單點故障:相比二階段提交,三階段提交降低了阻塞範圍,在等待超時後協調者或參與者會中斷事務。避免了協調者單點問題。階段 3 中協調者出現問題時,參與者會繼續提交事務。

? 一致性問題:

四種方案

Saga

1987年普林斯頓大學的Hector Garcia-Molina和Kenneth Salem發錶了一篇Paper Sagas,講述的是如何處理long lived transaction(長活事務)。Saga是一個長活事務可被分解成可以交錯運行的子事務集合。其中每個子事務都是一個保持數據庫一致性的真實事務。

分布式事務執行過程中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那麼分布式事務提交。如果任何一個正向操作執行失敗,那麼分布式事務會去退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務回到初始狀態。

掌握這些Java開發熱門前沿知識,小米Java校招面試題_程序員_04

Saga 模式用一種非常純樸的方式來處理一致性:補償。上圖左側是正常的事務流程,當執行到 T3 時發生了錯誤,則開始執行右邊的事務補償流程,反向執行T3、T2、T1 的補償服務,其中 C3 是 T3 的補償服務、C2 是 T2 的補償服務、C1 是 T1 的補償服務,將T3、T2、T1 已經修改的數據補償掉。

Tcc

TCC是Try、Confirm、Cancel三個詞語的縮寫,TCC要求每個分支事務實現三個操作:預處理Try、確認Confirm、撤銷Cancel。

? Try操作做業務檢查及資源預留,

? Confirm做業務確認操作,

? Cancel實現一個與Try相反的操作即回滾操作。

TM首先發起所有的分支事務的try操作,任何一個分支事務的try操作執行失敗,TM將會發起所有分支事務的Cancel操作,若try操作全部成功,TM將會發起所有分支事務的Confirm操作,其中Confirm/Cancel 操作若執行失敗,TM會進行重試。

掌握這些Java開發熱門前沿知識,小米Java校招面試題_程序員_05

分支事務失敗的情况:

掌握這些Java開發熱門前沿知識,小米Java校招面試題_後端_06

TCC分為三個階段:

  1. Try 階段是做業務檢查(一致性)及資源預留(隔離),此階段僅是一個初步操作,它和後續的Confirm 一起才能 真正構成一個完整的業務邏輯。

  2. Confirm 階段是做確認提交,Try階段所有分支事務執行成功後開始執行 Confirm。通常情况下,采用TCC則 認為 Confirm階段是不會出錯的。即:只要Try成功,Confirm一定成功。若Confirm階段真的出錯了,需引 入重試機制或人工處理。

  3. Cancel 階段是在業務執行錯誤需要回滾的狀態下執行分支事務的業務取消,預留資源釋放。通常情况下,采 用TCC則認為Cancel階段也是一定成功的。若Cancel階段真的出錯了,需引入重試機制或人工處理。

TM事務管理器可以實現為獨立的服務,也可以讓全局事務發起方充當TM的角色,TM獨立出來是為了成為公用組件,是為了考慮系統結構和軟件複用。

TM在發起全局事務時生成全局事務記錄,全局事務ID貫穿整個分布式事務調用鏈條,用來記錄事務上下文, 追踪和記錄狀態,由於Confirm 和cancel失敗需進行重試,因此需要實現為幂等,幂等性是指同一個操作無論請求 多少次,其結果都相同。

可靠消息最終一致性

可靠消息最終一致性方案是指當事務發起方執行完成本地事務後並發出一條消息,事務參與方(消息消費者)一定能够接收消息並處理事務成功,此方案强調的是只要消息發給事務參與方最終事務要達到一致。

此方案是利用消息中間件完成,如下圖:

掌握這些Java開發熱門前沿知識,小米Java校招面試題_Java_07

事務發起方(消息生產方)將消息發給消息中間件,事務參與方從消息中間件接收消息,事務發起方和消息中間件之間,事務參與方(消息消費方)和消息中間件之間都是通過網絡通信,由於網絡通信的不確定性會導致分布式事務問題。

因此可靠消息最終一致性方案要解决以下幾個問題:

  1. 本地事務與消息發送的原子性問題

本地事務與消息發送的原子性問題即:事務發起方在本地事務執行成功後消息必須發出去,否則就丟弃消息。即實現本地事務和消息發送的原子性,要麼都成功,要麼都失敗。本地事務與消息發送的原子性問題是實現可靠消息最終一致性方案的關鍵問題。

最後

手繪了下圖所示的kafka知識大綱流程圖(xmind文件不能上傳,導出圖片展現),但都可提供源文件給每比特愛學習的朋友

 CodeChina開源項目:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視頻】

掌握這些Java開發熱門前沿知識,小米Java校招面試題_後端_08

版权声明:本文为[mb60ed825746281]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210919053308615f.html