初探奧爾良(Orleans)


 

由於工作上關系目前經常被各種並發數據問題搞得焦頭爛額,要么要性能舍棄數據上得一致性,要么要一致性但是卻得到了特別糟糕的響應。難道魚和熊掌真的無法兼得嗎?

然后找到了類似奧爾良這種基於Actor模型的kuangjia

 

首先本人因為是C#系的所以暫不考慮Java系那套,那擺在面前的此類型的框架其實就2個。 Akka.Net和Orleans。

 

什么是Actor?

Actor應該說是一種編程模型,一個Actor是一個最基本的計算單原,他能接收消息並執行計算(一個行為)

它最重要的特性是每個Actor之間互相隔離,互補共享內存,也就是說每個Actor都能維持一個私有狀態且不能被別人所改變。

這對於我們意味着什么呢?想下一般我們遇到的並發問題,是不是在我們執行某個操作的時候,一個數據不正確的被另一個操作所干擾,導致數據最終混亂,而Actor則確保自己的數據不能被別人改變(獨立維護自己的狀態)以便使得最終一致。

wait

如果Actor自己數據不能被別人改變,那就是順序執行?那會不會很慢?

對於一個Actor來說,沒錯,他還真的就順序執行,因此能確保准確性

但是你真正系統里肯定不會只有一個Actor,而是由很多Actor組成,每個Actor之間是能並行的(因為他們不共享數據,所以他們可以互相獨立的正確處理)

 

具體來說,當並行的消息到達一個Actor的時候,它會存儲到一個MailBox(郵箱)里(你可以簡單理解為一個隊列),然后Actor從MailBox撈數據,一條一條順序的撈

然后不同的Actor則並行着處理一樣的事情

由於大家都是互相獨立的處理各自的事情,數據不會發生沖突,也就無需類似鎖之類的機制來確保數據一致性問題

image

由於Actor類文章網上搜索一大片, 在此就不再過多闡述了。

 

 

什么是奧爾良?

簡單一句話,微軟的一個基於Actor模型的實現,具體介紹可以更多參考官網

奧爾良官網

他跟正兒八經的Actor相比,微軟習慣就是將其做更加上層的封裝,Actor都變成了Grains,萬事萬物皆是Grains的感覺

 

我干了什么?

我也剛開始入門,發這篇文章主要是想證實下,Actor那套是不是真的那么神,本文涉及的所有代碼均在 https://github.com/virtualcca/OrleansTest/tree/master 上面

 

既然他們說他們是以單線程來處理同一個Actor,那我就想測試下用Orleans搞一個並發轉賬的場景,和我常規的多線程並發轉賬場景的一個對比,而我想看到的結果是,常規版的由於多線程的問題數據總是錯亂的,而奧爾良則能始終正確

 

轉賬代碼

 

image

我有一個賬戶,賬戶上面有Money, 我能做2個操作,要么轉錢過來,要么查看我還有多少錢,當然,轉賬總要點時間的對吧,所以轉賬時候Delay了1ms

 

實際轉賬的執行代碼

image

可以注意下奧爾良版和原始版唯一區別在於

奧爾良版是通過client.GetGrain來獲取了一個IAccount,這樣獲取到的是屬於奧爾良托管的一個Client實例,對其執行的操作其實會發送到Host里執行,然后Host里就是正兒八經的Actor架構來去處理所有操作

但是正如之前介紹Actor的時候談到單個Actor是單線程,而多個Actor之間是並發,如何確定你是一個還是多個Actor,是通過一個Id來區分(具體奧爾良官網有介紹),而GetGrain后面的那個0的參數就是他的Id,也就是我的這個IAccount是屬於一個Actor

常規版直接new一個實例執行同樣操作

 

然后代碼運行,可以看到結果

image

原始版的結果僅供參考,我每次運行得出來的結果也都不一樣(多線程執行順序是不確定的)

而奧爾良版則能正確的恆定輸出4950

 

至此,可以明確奧爾良完美的實現了Actor里關於單個Actor單線程的這么個處理。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM