Actor-ES框架:Ray
并發(fā)
1. 并發(fā)和并行
并發(fā):兩個或多個任務(wù)在同一時間段內(nèi)運行。關(guān)注點在任務(wù)分割。
并行:兩個或多個任務(wù)在同一時刻同時運行。關(guān)注點在同時執(zhí)行。
本文大多數(shù)情況下不會嚴(yán)格區(qū)分這兩個概念,默認(rèn)并發(fā)就是指并行機制下的并發(fā)。
2. 好處
隨著多核處理器的出現(xiàn),并發(fā)編程可以提高程序的性能(吞吐量和響應(yīng)能力)。
3. 并發(fā)實現(xiàn)方式
共享內(nèi)存模型
因為并發(fā)能提高程序的性能,為了解決并發(fā)的需求,許多編程語言提供了共享內(nèi)存通信機制(本文稱為共享內(nèi)存模型),體現(xiàn)是引入了Thread(線程)等概念。線程的出現(xiàn)解決了兩個問題,一是GUI出現(xiàn)后急切需要并發(fā)機制來保證用戶界面的響應(yīng);二是互聯(lián)網(wǎng)發(fā)展后帶來的多用戶問題。但編寫正確的并發(fā)、容錯、可擴展的程序并不容易,對開發(fā)人員要求比較高,需要開發(fā)人員有能力處理避免死鎖、互斥等待、競爭條件等問題。 當(dāng)對程序進行縱向擴展(Scale Up)和橫向擴展(Scale Out)時,問題會變得更加復(fù)雜。
為什么這么難:
We believe that writing correct concurrent, fault-tolerant and scalable applications is too hard. Most of the time it’s because we are using the wrong tools and the wrong level of abstraction. ——Akka
譯:
我們認(rèn)為寫正確的并發(fā)、容錯、可擴展的程序如此之難,是因為我們用了錯誤的工具和錯誤的抽象。——Akka
開發(fā)人員采用共享內(nèi)存模型進行并發(fā)編程時,需要特別關(guān)注共享的數(shù)據(jù)結(jié)構(gòu)及線程間的資源競爭導(dǎo)致的死鎖等問題,這是一個非常大的難點,Actor模型可以很大程度地解決這些問題。
Actor模型
Actor模型這么好,Actor模型是什么?
Actor模型是一個概念模型,用于處理并發(fā)計算。它定義了一系列系統(tǒng)組件應(yīng)該如何動作和交互的通用規(guī)則,最著名的使用這套規(guī)則的編程語言是Erlang。
Actor由3部分組成:狀態(tài)(State)+行為(Behavior)+郵箱(Mailbox),State是指actor對象的變量信息,存在于actor之中,actor之間不共享內(nèi)存數(shù)據(jù),actor只會在接收到消息后,調(diào)用自己的方法改變自己的state,從而避免并發(fā)條件下的死鎖等問題;Behavior是指actor的計算行為邏輯;郵箱建立actor之間的聯(lián)系,一個actor發(fā)送消息后,接收消息的actor將消息放入郵箱中等待處理,郵箱內(nèi)部通過隊列實現(xiàn),消息傳遞通過異步方式進行。
Actor是分布式存在的內(nèi)存狀態(tài)及單線程計算單元,一個Id對應(yīng)的Actor只會在集群種存在一個(有狀態(tài)的 Actor在集群中一個Id只會存在一個實例,無狀態(tài)的可配置為根據(jù)流量存在多個),使用者只需要通過Id就能隨時訪問不需要關(guān)注該Actor在集群的什么位置。單線程計算單元又保證了消息的順序到達,不存在Actor內(nèi)部狀態(tài)競用問題。
Actor框架--Orleans
Actor模型這么好,怎么實現(xiàn)?
可以通過特定的Actor工具或直接使用編程語言實現(xiàn)Actor模型,Erlang語言含有Actor元素,Scala可以通過Akka框架實現(xiàn)Actor編程。目前C#語言中有兩類比較流行,Akka.NET框架和Orleans框架。本文主要關(guān)注Orleans框架。
Orleans是微軟開發(fā)的開源、分布式、跨平臺的Virtual Actor框架,可以方便C#開發(fā)者開發(fā)分布式、高擴張、高并發(fā)、低延時的應(yīng)用程序。
架構(gòu)落地
1. N-Tier架構(gòu)(代表三層)
N-Tier架構(gòu)的代表是三層架構(gòu),實際項目分了很多層,多數(shù)是三層的延伸。傳統(tǒng)的三層體系結(jié)構(gòu)包括無狀態(tài)的前端,無狀態(tài)的中間層和存儲層。
這種架構(gòu)存在兩個比較大的問題:
由于存儲層在延遲和吞吐量方面的限制,系統(tǒng)很難處理高并發(fā)的場景。這種結(jié)構(gòu)下通常的辦法是在中間層和存儲層之間添加緩存層來提高性能。如果引入的是分布式緩存,又會引入狀態(tài)同步問題,這時候就需要考慮如何精準(zhǔn)快速的更新緩存。
這種無狀態(tài)的N-Tier架構(gòu),中間層內(nèi)獨立的應(yīng)用實體之間通信很不方便,當(dāng)一個請求需要多實體之間調(diào)用時,為業(yè)務(wù)代碼的實現(xiàn)帶來了困難。
Actor在架構(gòu)層面上提供了一個簡單的方式來構(gòu)建無鎖分布式大規(guī)模的應(yīng)用程序,而不需要學(xué)習(xí)和應(yīng)用復(fù)雜的并發(fā)和分布式控制,有效的解決了上述兩個問題。
Orleans提供了一種直接的方式構(gòu)建有狀態(tài)的中間層,大量的業(yè)務(wù)邏輯實體分布式地部署在集群中,彼此相互獨立,又可以相互訪問。
缺點:
Orleans技術(shù)很優(yōu)秀,許多人想用,但是目前國內(nèi)圈子里的資料很少,代碼多是Demo,Actor初接觸通常覺得不易理解,使得大家找不到Orleans落地的方式。
2. Event Sourcing
在Orleans中,actor中的數(shù)據(jù)(State)存在于內(nèi)存中,內(nèi)存中的數(shù)據(jù)在斷電、重啟的場景下會丟失,可以使用Event Sourcing技術(shù)解決這一問題,Actor的狀態(tài)修改是由事件驅(qū)動的,事件被持久化起來,然后通過Event Sourcing的技術(shù),還原特定Actor的最新狀態(tài)到內(nèi)存。不僅如此,Event Sourcing還會極大地降低系統(tǒng)的耦合性。
什么是事件溯源
一個對象從創(chuàng)建開始到消亡會經(jīng)歷很多事件,以前我們是在每次對象參與完一個業(yè)務(wù)動作后把對象的最新狀態(tài)持久化保存到數(shù)據(jù)庫中,也就是說我們的數(shù)據(jù)庫中的數(shù)據(jù)是反映了對象的當(dāng)前最新的狀態(tài)。而事件溯源則相反,不是保存對象的最新狀態(tài),而是保存這個對象所經(jīng)歷的每個事件,所有的由對象產(chǎn)生的事件會按照時間先后順序有序的存放在數(shù)據(jù)庫中。
事件溯源:
不保存對象的最新狀態(tài),而是保存對象產(chǎn)生的所有事件。
通過事件溯源(Event Sourcing,ES)得到對象最新狀態(tài)。
Actor內(nèi)數(shù)據(jù)的修改,是ACID強一致性的;跨Actor的數(shù)據(jù)修改,是最終一致性的,通過EventSourcing實現(xiàn)。這樣可以讓我們最大化的降低并發(fā)沖突,從而最大化的提高整個系統(tǒng)的吞吐。Actor和DDD,CQRS,Event Soucing(事件溯源)設(shè)計模型有天然的融合性,基于Actor可以很好的進行以上實踐。
EventSourcing的概念通常跟CQRS放在一起,CQRS/ES的概念常常出現(xiàn)在DDD中,在DDD中,有許多程序員向往的實現(xiàn),但是里面的抽象概念比較多,只熟悉三層的開發(fā)人員很難駕馭這些概念,基于這些概念提出的架構(gòu)設(shè)計更是難以捉摸,一些前輩為探索DDD最佳實踐,開發(fā)了一些DDD框架,但實際項目中,很難保證系統(tǒng)性能。
Actor不好理解,CQRS/ES、DDD不好理解,恰恰這些技術(shù)交織在一起能很好的使彼此落地。
3. Ray
說了這么多,目的是為了引出Ray。
Ray是一個集成Actor、Event Sourcing(事件溯源)、Eventual Consistency(最終一致性)的無數(shù)據(jù)庫事務(wù)、高性能分布式云框架。Ray是一個非常精致小巧的Actor/ES框架,來自生產(chǎn)環(huán)境,踩了很多坑,降低了Actor、ES的開發(fā)難度。
來自生產(chǎn)環(huán)境
ASP.NET Core、Redis、MongoDB、跨平臺、gRPC、RabbitMQ、Dapper……許多朋友都掌握了,但依舊好像缺些什么,或許可以嘗試一下新的旅程。這是項目的地址:?https://github.com/RayTale, 歡迎大家討論、參與、使用。
設(shè)計圖
這張圖方便大家初步了解Ray,但是太過強調(diào)細(xì)節(jié),對DB太過突出,而Event沒有突出出來。
這張圖更簡潔明了一些。
參考:
Orleans Github文檔
并發(fā)之痛 Thread,Goroutine,Actor
高并發(fā)解決方案之Actor——第一節(jié)
.NET的Actor模型:Orleans
下一代的 Actor 模型框架 Proto Actor
10 分鐘了解 Actor 模型
為什么Actor模型是高并發(fā)事務(wù)的終極解決方案?
深度長文:我對CQRS/EventSourcing架構(gòu)的思考
原文地址:http://www.cnblogs.com/CharlesZHENG/p/8327388.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的Actor-ES框架:Ray的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AspectCore动态代理中的拦截器详
- 下一篇: Entity Framework Cor