版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
游戲舉不知道你有沒有玩過聯(lián)網(wǎng)的5v5即時對戰(zhàn)手游。10個人通過玩游戲,每個人都能看到其他人在游戲里的情況。雖然信號不太穩(wěn)定,可能還會臨時斷網(wǎng),但不絡條件怎么惡劣,所有人里的游戲情況都是一樣的。這就是多人游戲的正確性。關鍵術我們在第4節(jié)課和第5節(jié)課介紹了領域驅動設計。溯源是領域驅動設計論關命令狀態(tài)命令指的是系統(tǒng)收到的外部指令。比如你在玩游戲時,鍵盤和方向鍵的輸入就是命系統(tǒng)在收到外部令后,并不會馬上執(zhí)行,而是會先做一些檢查,如果合理才會執(zhí)行,不合理就不執(zhí)行。比如說游戲里的地圖都有邊界,如果你控制的角色已經(jīng)走到了墻角,再往前走就會碰到墻。這時如果游戲收到向前走令,游戲的邊界碰撞檢查算法就會判斷這個命令是的。比如在游戲里,讓角色向右走令叫作"moveright",而對應的是right"。這個小小的區(qū)別很重要,你要仔細體會當系統(tǒng)的狀態(tài)改變之后,外界會根據(jù)狀態(tài)再產(chǎn)生新令,周而復始地執(zhí)行。這就是用溯源設計的術語來描述你玩游戲的過程。命令、和狀態(tài)這三者之間的關系可以用下圖來表示賬務系統(tǒng)舉前面游戲的例子主要是為了方便讓你理解命令、和狀態(tài)這3個術語。掌握了這三個核賬務系統(tǒng)負責記賬,所以它管理著所有用戶的賬戶金額信息,比如說你的現(xiàn)金余額、等等。這些賬戶金額信息就屬于狀態(tài)。假設你現(xiàn)在賬戶余額有100元,你朋友的賬戶余額有200元,倆的金額狀態(tài)示意圖如下:假設你想通過轉賬的方式,轉給你的朋友一塊錢。這個轉賬請求是命令,會發(fā)送到賬既然合理,那么賬務系統(tǒng)就會從命令生成,一共有兩個。一個是從你的賬戶扣款一塊錢,另一個是給你朋友賬戶入賬一塊錢。從這個賬務系統(tǒng)的例子中你可以發(fā)現(xiàn),一個命令可以生成多個。在我們這個轉賬例子里,一個轉賬命令會生成兩個。示意圖如下接下來是執(zhí)行這兩個。執(zhí)行后會改變系統(tǒng)狀態(tài),也就是改變倆的余額情況。你的余額會變?yōu)?9元,而你朋友的余額則變?yōu)?01元,示意圖如下:這時候你發(fā)現(xiàn)自己賬戶上還有一些余額,于是想嘗試給你朋友轉100錢。但是當賬務系呢當命令的檢查不通過時,系統(tǒng)可以選擇不生成,或者選擇生成一個空(NOP)。生成空的好處是能在系統(tǒng)中記錄某個命令在歷史上曾經(jīng)存在過??盏膱?zhí)行結果是不改變?nèi)魏螤顟B(tài)。這里你這兩次轉錢的流程示意圖如下:掌握了溯源設計的三個術語后,我們再來看看相應的系統(tǒng)應該如何實現(xiàn)溯源設計的一個設計是所有令或者的處理都要有確定的順序。同樣的兩個命令,如果它們倆到達的順序不一樣,生成的可能就會不一樣。比如說你現(xiàn)在的余額有100元。接下來有兩個命令,一個命令是給你轉賬100元,一個命令是你打200元錢給你朋友。如果你先收到100元錢,再付出去200元錢,那么你付錢的時候賬戶里剛好有200元,因此這兩個命令的檢查都能通過。但是如果你先轉出去200元,再收到100元的話,系統(tǒng)會發(fā)現(xiàn)你在轉200元錢出去的時候余額不足,所以這個命令會失敗。保證順序的方法也不難,就是將所有令和都分別放到兩個先入先出的隊列(Firstn,F(xiàn)irstOut,F(xiàn)FO)。一般這些隊列會被保存到文件中。系統(tǒng)會從命令隊列中逐一下一個命令,判斷這個命令是否合理,然后將生成的所有放到隊列末尾。示意圖如下:在實現(xiàn)時還可以做一個小的優(yōu)化。命令隊列和隊列雖然是兩個不同的隊列,但是由于它們的先后順序是完全一致的,我們可以將這兩個隊列合并為一個隊列。這時候的處理邏輯需要做一些小的調整。命令收到了之后,我們并不會馬上下來。而是先處理這個命令,得到了對應的之后,再將命令和打包到一起,存到隊列中。下圖列出了這個優(yōu)化后的情況。你可以結合體會一下具體的區(qū)別溯源設計對于設備非常友好。無論是基于碟片的傳統(tǒng)硬盤,還是新一代的SSD存這是因為命令和這兩個隊列只會在末尾增加新的內(nèi)容,而不會修改中間的內(nèi)容。我們一般把這種方式叫作順序寫。與之對應的是隨機讀寫。你在挑選硬盤的時候,一般能看到硬盤生產(chǎn)商會公布兩個硬盤速度,一個是順序讀寫速度,另一個是隨機讀寫速度。你會發(fā)現(xiàn)順序讀寫的速度會快很多。所以溯源設計一般都能達到很高的讀寫效率。請注意,當你將每個隊列到文件時,需要的是兩個文件,而不是一個。其中一個文件顯然是隊列的內(nèi)容。另一個文件則是這個隊列的索引文件,它記錄了每個內(nèi)容在隊列在一些場景下,我們需要能定位到指定位置的內(nèi)容,比如第3個命令是什么,或者第10個是什么。由于每個命令或者的內(nèi)容大小會不一樣,我們需要額外的索引文件來由于位置信息和偏移量這兩個數(shù)據(jù)的長度都是固定的,索引文件的每個內(nèi)容都有固定大小,所以我們可以根據(jù)我們要的位置直接計算出索引文件的偏移量,然后根據(jù)索引文件找到隊列文件的位置。計算的示意圖如下:解決了如何處理命令和之后,我們就剩下最后一件事情,那就是怎么執(zhí)行和改變自動機有始無終的磁帶。你會從頭開始依次每個。之后按內(nèi)的指示來改變內(nèi)存狀態(tài)。然后挪到下一個位置,繼續(xù)處理下一個。是不是很簡單?自動機的示意圖如這里有一個非常重要的限制你要牢記:自動機在執(zhí)行的過程中不能有任何隨機行為。這是為了保證整個系統(tǒng)能準確復現(xiàn)每一步計算,因為這樣才能滿足金融行業(yè)對每一步計算過程都能審計的要求。對于沒有隨機性,我們要注意兩偽隨機數(shù)是一個算法和對應的初始值(也叫隨機數(shù)的)。初始值一旦確定,偽隨機數(shù)發(fā)生器所有接下來的隨機數(shù)也就確定了,所以偽隨機數(shù)其實并不是一個隨機的事情。你需要將隨機數(shù)的算法和初始的也記錄到中,這樣雖然看起來有隨機數(shù)這幾個字眼,另一點是不要有/O(輸入/輸出)。準確地說是不要有來自外部的輸入。外部輸入有很多不確定性,比如輸入到達的時間不確定,或者到達的內(nèi)容每次都會變化,或者消息超時,什么都收不到。由于外部輸入有太多的不確定性,一般要求不能有外部輸入。但是我們不能完全取消所有外部輸入。這時候有一個折衷處理方式。你可以提前從外部獲得輸入,然后在隊列中。這樣在執(zhí)行的時候就不會受到外部輸入不確定性的時光我們還是拿游戲舉例,給你說明什么是時光機功能。一般來說游戲都可以存檔。如果你游戲玩不下去了還可以讀檔,恢復之前的游戲狀態(tài)。這個存檔讀檔的過程就是坐時光機回到過去的過程。溯源提供了更完美的時光機(timemaie)功能。它能恢復到過去任何一個時間點的狀態(tài)。你需要做的事情也很簡單,只需要重置自動機狀態(tài),然后把一個一個執(zhí)行,直到運行到你指定的時間點。如果你按照我前面的要求,保證自動機在執(zhí)行過程中的每一步都是完全確定的,那么最終一定能準確地回到過去的狀態(tài)。時光機給了金融系統(tǒng)審計的能力。由于過去所有令都得到了保留,你能解釋狀態(tài)是怎樣一步一步從最開始的情況變到現(xiàn)在的樣子。在互聯(lián)網(wǎng)架構里我們更關注的是當前事實,所以架構設計時會傾向于記錄狀態(tài),而不是原因。但是在金融系統(tǒng)里,我們更關注的是為什么,而非是什么,所以架構設計會傾向于記錄原因。系統(tǒng)快丟失了。只要都在,溯源設計能保證一定能恢復到出問題前的狀態(tài)。但是這種容災有一個問題。系統(tǒng)恢復的時間長短和的個數(shù)有關。多了可能恢復的優(yōu)化的方法很簡單,只要將當前的系統(tǒng)狀態(tài)全都保存到文件就可以了。我們一般稱呼這個過程為打快照(Sapshot)。過了一段時間之后,如果想要恢復到系統(tǒng)的狀態(tài),你只需要先將快照文件加載到自動機里,然后從打快照的時間點開始執(zhí)行后面的。為了能讓自動機找到下一個需要執(zhí)行的,你需要將快照對應的位置也記錄到快照有了打快照這個優(yōu)化之后,系統(tǒng)恢復時間只和那些不在快照里的個數(shù)有關,跟的歷史長度無關。所以打快照的頻率決定了恢復時間,而不是的總個數(shù)。打快照頻率有多種選擇。你可以選擇頻繁地打快照,這樣會減短系統(tǒng)恢復時間。但是考慮到系統(tǒng)打快照也需要時間,系統(tǒng)的運行時間會增加?;蛘吣憧梢赃x擇偶爾打快照,這樣恢復時間變長,但是系統(tǒng)運行時間會變短。幸運的是金融系統(tǒng)不需要過多思考打快照頻率的問題。因為金融系統(tǒng)里有一個日切的念。日切指的是在每天晚上12點的時候,你需要對當天的所有業(yè)務進行清點,確認無誤后再開始下一天的工作,所以系統(tǒng)需要在每晚12點打一個快照。除了每晚12點以外,金融行業(yè)一般還需要按月、季度和年度來進行業(yè)務清點工作。通常些特殊的時間點也需要晚上12整的狀態(tài),因此可以復用每天晚上日切的快照內(nèi)容。但是到目前為止,我給你解釋了溯源設計如何進行和計算,但是還沒有說怎么查詢數(shù)據(jù)。溯源設計對于查詢有專門的術語,叫做CQRS(CommandQueryResponsibilitySegregation),就是我們通常說的讀寫分離。這里的Command就是事件溯源里的Command。和讀部分的可以根據(jù)的特點來分別做優(yōu)化。讀寫分離不僅僅是溯源需要,在其他架構中也經(jīng)常能看見。比些K/V在寫入的時候,會選擇一些寫入速度較快的數(shù)據(jù)結構,像LSM樹。在數(shù)據(jù)的時候則會選另一些速度快的數(shù)據(jù)結構,比如B+樹。溯源和其他設計不一樣的地方在于,溯源既能查到當前內(nèi)容,也能查到任何過去思路很簡單。如果隊列實時地出來,然后在另一臺機器上用自動機執(zhí)行這些,那么我們不就有的狀態(tài)了嗎?這就是狀態(tài)機的讀模式(ReadMoe)。在讀模式下,狀態(tài)機只負責執(zhí)行,不負責處理命令。示意圖如下:讀模式自動機在游戲行業(yè)也經(jīng)常能碰到。5v5即時對戰(zhàn)手游在進行比賽的時候會有現(xiàn)場直播,講解員會在電腦上實時講解當前所有選手的對戰(zhàn)情況。電腦就是用讀模式了我們再來看看怎么查詢歷史狀態(tài)。最直接的方案顯然是利用時光機的功能。我們先找到距離查詢時間最近的快照,然后從這個快照開始執(zhí)行,直到碰到查詢時間點。這時候的狀態(tài)就是我們需要的狀態(tài)。一般我們把這個重新計算歷史狀態(tài)的過程叫作回滾。多個讀模式自動機。其中一個保持在狀態(tài),剩下的根據(jù)歷史查詢的頻率來選擇定在過去某個時間點,比如日切的時候。多個讀模式自動機的示意圖如我們在開篇詞里提到會帶你透過現(xiàn)象看本質。所以在給你講完怎么實現(xiàn)溯源之后,最后我來帶你了解一下溯源正確性的本質。溯源的框架隸屬于一個更大的系列,叫做不可變架構(ImmualeArchiecure)。在不可變架構里,所有數(shù)據(jù)都不能發(fā)生變化。所有這些不能變化的數(shù)據(jù)分為兩大類,分別是(Eent)和狀態(tài)(Sae),分別用e和S來表示。我們把前面講到的自動機在數(shù)學上用函數(shù)f來表示。這個函數(shù)接受一個狀態(tài)和,返回一個新的狀態(tài)。如果我們把、狀態(tài)和自動機結合在一起看,整個溯源的運行邏輯Sn=f(Sn?1,如果你把里的所有S都展開,那么數(shù)學就會變成下面這個樣子Sn=f(f(…f(f(f(S0,e1),e2),e3)…),上面這個數(shù)學可能看不出來什么熟悉的東西。但是如果換個表現(xiàn)方式你可能就熟了。我們可以把f換成+,這樣溯源的就會變成將當前狀態(tài)和的求和,從而Sn=Sn?1+我們把簡化后的數(shù)學展開之后可以發(fā)現(xiàn),在溯源的設計里,任何一個時間點的狀態(tài)等于之前所有效果的累積,就像下面這個表現(xiàn)的一樣:Sn=S0+e1+e2+…+en?2+=∑說到這里,我就可以給你解釋,為什么在溯源里的我們會有那些假設了另外,我們在記錄的時候要求之間有順序,這是因為自動機對應的函數(shù)一般是不 也就是說函數(shù)的參數(shù)交換順序后會導致結果不一樣,這也導致數(shù)據(jù)之間是線性序(LinearOrder)的關系。這個線性序列關系導致我們在的時候選擇用FIFO隊列的由于我們可以通過邏輯推導來驗證數(shù)學計算的正確性,當溯源和數(shù)學之間有嚴格一一對應關系之后,我們就可以像驗證數(shù)學一樣來驗證溯源結果的正確性。這就是溯源能保證金融系統(tǒng)正確性的本質原理。上面這些是用求和的方式來表示最終的狀態(tài)是怎么得到的。在極限情況下,我們還可以有積分和微分表現(xiàn)形式。用積分的概念去理解的話,任何一個時間點的狀態(tài)等于過去所有的積分,表示出來就是下面這個:TS(T)= 微分的形式可能更有意義一些。每個是狀態(tài)關于時間的導數(shù),也就是下面的這個公e(t)=這節(jié)課我給你講解了溯源設計這個架構設計思路。在溯源設計里,你重點要關注命令、和狀態(tài)這三個術語。命令指的是要做什么,是我合理的行為會做出什么改變,狀態(tài)就是改變的對象和結果。命令和都需要按照的先后順序來處理。它們的也需要遵循同樣的先后順序。為了能定位到指定位置的內(nèi)容,我們需要在數(shù)據(jù)的時候還同時一個位置的索引文件。命令和都好之后,溯源設計里的狀態(tài)機就可以從零開始,按順序一一執(zhí)行所有。我們要求所有執(zhí)行的操作都具有可重復性,也就是不允許有隨機性。這樣就能確溯源設計的查詢需要遵循CQRS,也就是讀寫分離的架構。系統(tǒng)會有一個自動機負責處理所有令和,另外還有很多讀模式的自動機負責提供查詢服務。這些讀模式自我們在隊列的時候需要兩個文件。一個,另一個 的索引在現(xiàn)實中會出現(xiàn)各種異
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 13-14-Dihydro-15-keto-tetranor-prostaglandin-F1β-生命科學試劑-MCE-3578
- 2025年度智能家居安防裝飾家居裝修合同
- 二零二五年度同居關系解除并處理共同財產(chǎn)合同
- 2025年度鋼琴制作工藝技術研究與應用合同
- 2025年度海鮮池養(yǎng)殖產(chǎn)業(yè)鏈整合承包協(xié)議
- 教育創(chuàng)新在展館空間設計中的體現(xiàn)
- 解讀中藥藥理優(yōu)化日常養(yǎng)生
- 個人商業(yè)貸款保證擔保合同
- 中央空調維護合同范本
- 個人經(jīng)營性貸款借款合同樣本
- 植物芳香油的提取 植物有效成分的提取教學課件
- 肖像繪畫市場發(fā)展現(xiàn)狀調查及供需格局分析預測報告
- 名著閱讀:簡答、閱讀題(解析版)-2025年中考語文復習專練
- 2021-2022學年遼寧省重點高中協(xié)作校高一上學期期末語文試題
- 同等學力英語申碩考試詞匯(第六版大綱)電子版
- 2024義務教育道德與法治課程標準(2022版)
- 墓地個人協(xié)議合同模板
- 2024年部編版初中語文各年級教師用書七年級(上冊)
- 企事業(yè)單位公建項目物業(yè)管理全套方案
- 2024年北京市房山區(qū)初三語文一模試卷及答案
- 4P、4C、4R-營銷理論簡析
評論
0/150
提交評論