高速大量業務的應用架構關鍵

Posted sp42a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高速大量業務的應用架構關鍵相关的知识,希望对你有一定的参考价值。

高速大量業務的應用架構關鍵

微服務加上Event Sourcing儲存方式,有助實現「高速」的需求,再搭配記憶體計算、請求緩衝和當機接替,就可以打造出不怕爆量的應用架構

當你需要設計能夠支援高速和大量業務的關鍵應用系統(例如期貨交易系統)時,要銘記在心的設計的重點是:想要高速,就要盡量減少I/O,尤其是硬碟的I/O;想要大量,就要有緩衝空間。

先看「高速」的部分。想要減少硬碟I/O,就必須盡量讓計算直接在記憶體內完成。在記憶體計算的速度雖然很快,但記憶體有一個致命的缺點:一旦斷電,資料不復存在。為了這個原因,資料還是有寫入硬碟的必要,但寫入的速度必須非常快。

關連式資料庫管理系統(RDBMS)的寫入速度是很慢的,一個表面上簡單的寫入,內部卻有許多操作要進行(搜尋、定位、讀取、計算、寫入、調整相關的索引… .),所以無法滿足我們這裡對於極快速寫入的需求。這時候Event Sourcing的儲存會是比較好的選擇。

Event Sourcing的儲存方式是:一筆一筆地紀錄資料的所有操作過程,而不是只記錄資料的當前狀態。舉例說明,Event Sourcing的儲存方式不是記錄當前的帳戶餘額,而是紀錄你的帳戶從開戶以來的所有操作,包括每一個存入、取出、轉入、轉​​出、扣款、利息入帳等操作,要把這些操作記錄都累計起來,才會得到當前的帳戶餘額。

為什麼這種紀錄方式的寫入速度很快,因為每個成功的操作會化為一個事件,直接把該事件記錄到事件日誌的尾端,不需要搜尋、定位、調整索引等附帶的行為。

你現在一定有一個疑問:要把這些操作記錄都累計起來,才會得到當前的帳戶餘額,這會不會很耗費時間?其實Event Sourcing的儲存方式會在系統不繁忙的時候(例如深夜)把這些累計先算好,變成一個所謂的「快照」(snapshot)。下次只要讀取快照的狀態,加計快照後更新的那部分就好了。

附帶一提,除了寫入的效率高之外,Event Sourcing還有另外兩個明顯的好處:1. 可以輕易而快速地回到過去 2. 資料有時間維度,適合做深入的行為和趨勢分析。這不是本文章的重點,所以不展開說明。

不是所有的系統都適合使用Event Sourcing的儲存方式。 Event Sourcing的特點導致它無法像RDBMS那樣做很複雜的各種關聯查詢,所以Event Sourcing一般被視為Store(儲存空間),而不是資料庫管理系統(DBMS)。

設計良好的微服務由於獨立且體積小,更重要的是微服務內部的資料也彼此獨立,非常適合使用Event Sourcing的儲存方式。例如在賬戶的微服務裡面,我的賬戶和你的賬戶之間彼此獨立,我的事件日誌和你的事件日誌可以分開記錄在各自的軌跡(Track)中,這麼一來讀取的時候更方便,也有助於隱私權的保護和後續資料的遷移。

Event Sourcing是個實現起來簡單卻能產生特殊效益的資料儲存方式,我在「技術應用的艱辛探索」一文中提到我自己研發了一套技術框架,其資料儲存方式正是Event Sourcing,這就是為什麼我對於Event Sourcing這麼有經驗的原因。

這篇文章的主題是「高速大量業務的應用架構關鍵」,以上描述的是「高速」的部分,接下來描述「大量」的部分。當請求量大的時候,可能會處理不及,需要在記憶體內安排緩衝空間(Buffer)。這個緩衝空間可以採用經典的環狀結構,這部分我不再贅述。由於緩衝空間也是在記憶體內,如果擔心請求會丟失,也可以在這裡使用高速的Log。

上述描述的技巧讓你的系統可以滿足高速且大量的業務(例如秒殺平台),但對於非常關鍵的業務,還需要做到高可用性(High Availability),這時候最簡單的方式是部署兩套一樣的系統,同時接收相同的業務請求,兩套系統要把請求的次序統一起來,但只有其中一套真正會進行計算,另外一套會監聽主系統的心跳,一旦發現對方心跳異常,自己立刻啟動計算,進行任務的備援。

記憶體計算+微服務+Event Sourcing+請求的緩衝+當機備援,這系統很夢幻,光是想著都會讓我流口水。

如何設計鬆耦合架構的關鍵:事件處理機制

CEP的重點不在於處理業務,而是在於把各種簡單事件合併起來得到複雜事件,透過複雜事件的出現,發現某個危機、機會、趨勢,並據以做出反應。

在「鬆耦合的關鍵」一文中,我提到了鬆耦合的關鍵是訊息(message)。現在我要更清楚地說:鬆耦合的真正關鍵是「事件」。

我把訊息分為兩大類:命令(Command)和事件(Event)。當一個模組要通知其他模組「去做某件事」,送出去的訊息就是命令,例如「請讓用戶登錄」;當一個模組要通知其他模組「某個事實已經發生了」,送出去的訊息就是事件,例如「用戶已經登錄了」。這裡的重點在於:命令是「希望發生,但還沒有發生」的,事件是「已經發生」的。

關於命令和事件還有另一個重點:對於命令的發送者來說,命令的接收對象很明確,是某一個模組;而對於事件的發送者來說,事件的接收對象不明確,可以沒有,也可以一個或很多個。模組如果想接收某類事件,只要符合權限,就可以去登記要在某類事件發生時接到通知。本文章一開始提到鬆耦合的真正關鍵是事件,原因就是在於:事件的產生者不需要知道事件的接收者是誰。

命令的接收者直接執行命令,但事件的接收者不一定直接做出反應。有些事件的接收者,接收事件只是為了觀察某些「大事」的「端倪」,在累積許多端倪之後,才認定「大事」發生了,這時候才做出反應。一件「大事」是由許多小事和其他大事累積起來而形成的。大事的專業術語是「複雜事件」(Complex Event),小事的專業術語是「簡單事件」(Simple Event)。把簡單事件累積成複雜事件,再去做處理,這個機制叫做「複雜事件處理」(CEP)。

在過往的年代,CEP主要是用在核心系統或業務系統的「旁邊」,主要目的是風險控制、商業機會挖掘。這時候通常是採用中央集權式的CEP系統,也就是說,事件會從許多系統匯集過來,在一個集中點做判斷是否複雜事件發生了。有些CEP系統允許產生的複雜事件回流,成為其他複雜事件的端倪;有些CEP系統不允許這麼做,因為怕出現意外的循環。上一次的文章「技術架構設計12原則(下)」說過了:循環依賴不好。

早期的這些CEP系統通常是建構在關聯型資料庫管理系統(RDBMS)之上的,利用RDBMS的觸發器(trigger)機制,來達到複雜事件的判斷。事件先進入資料庫的表,掃描是否符合某些模式(pattern),來判斷是否發生複雜事件。有些掃描的時機是發生在每個事件來到時(耗費計算能力),有些掃描的時機是發生在事件累積了一個批次的時候(節省計算能力)。所以大多數描述複雜事件的語言,都長得很像資料庫的語言。但還是有廠商設計出抽象程度更高的語言,接近通用的程式語言。

除了我們自己描述複雜事件是如何構成的,也可以用AI來做這件事。每個簡單事件攜帶的資訊量不多,但簡單事件的數量非常龐大(尤其是物聯網),非常適合拿來做AI。

上述的傳統CEP,獨立於業務系統之外,但可能會回過頭去影響業務系統。例如:CEP發現洗錢的跡象,發命令給帳戶系統去凍結帳戶。我們在鬆耦合的微服務設計中,大量使用事件,但這是業務系統本身,不能算是CEP系統。CEP的重點不在於處理業務,而是在於把各種簡單事件合併起來得到複雜事件,透過複雜事件的出現,發現某個危機、機會、趨勢,並據以做出反應。

對於在分散式網路邊陲的系統來說,單一個簡單事件往往無足輕重,需要複雜事件才值得中央伺服器注意。隨著許多終端設備(包括各種感應器)也紛紛聯網,現在CEP又出現了新的應用價值:在邊緣計算上。試想,這些瑣碎的訊息如果大量湧入中央的雲伺服器,網路頻寬和伺服器叢集都會無法負荷。比較合理的設計,是在靠近終端設備的地方,透過邊緣計算的方式,把大量的簡單事件處理成少量的複雜事件,再遞送給中央的雲伺服器。完美!

寫這篇文章的過程,我產生一個疑惑:誰說CEP必須獨立於業務系統之外,而不能作為業務系統本身的基礎?

以上是关于高速大量業務的應用架構關鍵的主要内容,如果未能解决你的问题,请参考以下文章

ngnix適用與哪些場景

計算機架構圖

重磅!bee蜜蜂币浏览器已开发出Bee Network Browser即将发布价值公链已起航

IT行业-计算机基础知识总结

重回AS第一坑,新版本run错误INSTALL_PARSE_FAILED_NO_CERTIFICATES

重回AS第一坑,新版本run错误INSTALL_PARSE_FAILED_NO_CERTIFICATES