高併發分散式事務解決之道-Actor模型(附Akka與Reactor比較)
阿新 • • 發佈:2019-01-27
----- Actor模型
(1) 事務機制來由
為什麼大多數網際網路軟體都是資料喂機器,或函式式即可,比如twitter或facebook,因為他們沒有事務要求,一般涉及到錢等重要交易都需要事務,也可以這麼說,非結構化的資料一般都沒有事務要求,結構化聚合的資料才有事務要求。
(2) 事務例子
使用者甲的操作
1.開始事務
2.訪問表A
3.訪問表B
4.提交事務
乙使用者在操作
1.開始事務
2.訪問表B
3.訪問表A
4.提交事務
如果甲使用者和乙使用者的兩個事務同時發生,甲事務鎖住了表A未釋放(因為整個事務未完成),正在準備訪問B表,而乙事務鎖住了表B未釋放(因為整個事務未完成),正在準備訪問A表,可是A表被甲事務鎖住了,等甲事務釋放,而甲事務真正等待乙事務釋放B表,陷入了無限等待,也就是死鎖Dead Lock。
(3) 高併發事務解決之道
悲觀鎖 - 資料庫表鎖或行鎖
樂觀鎖 - 版本控制
同步鎖 - 單執行緒
Actor模型 - 行為訊息佇列(適用跨節點、分散式、高併發)
* 同步鎖是單一JVM內的,對於分散式系統多個 Tomcat容器多個JVM,Actor模型能更好地“鎖”好資源。
(4) Actor模型
Actor模型內部的狀態由自己的行為維護,外部執行緒不能直接呼叫物件的行為,必須通過訊息才能激發行為,這樣就保證Actor內部資料只有被自己修改。
一個Actor如何處理多個Actor的請求呢?它先建立一個訊息佇列,每次收到訊息後,就放入佇列,而它每次也從佇列中取出訊息體來處理。通常我們都使得這個過程是迴圈的。讓Actor可以時刻處理髮送來的訊息。
解決“一個人一個坑”的效能瓶頸
參考:
http://www.jdon.com/45728
----- Akka與Reactor比較
兩者皆是非同步事件驅動框架,都構建自Actor模型;
Akka用 Scala 編寫的庫,目前更成熟,同時支援Scala和Java API;
Reactor專案始於2012年,由Spring團隊研發,但現在還常常大改。
Akka:
http://akka.io
Java程式碼Sample: http://verran.iteye.com/blog/1942393,
http://www.blogbus.com/dreamhead-logs/235916459.html,
http://www.th7.cn/Program/java/2012/03/29/67015.shtml,
https://github.com/XiaoMi/rose/tree/master/rose-example/src/main/java/sample
Sample
HelloWorld.java
Greeter.java
Reactor:
http://projectreactor.io/old/reference/
https://github.com/reactor/reactor
架構
v.s.
http://stackoverflow.com/questions/16595393/akka-or-reactor
(1) 事務機制來由
為什麼大多數網際網路軟體都是資料喂機器,或函式式即可,比如twitter或facebook,因為他們沒有事務要求,一般涉及到錢等重要交易都需要事務,也可以這麼說,非結構化的資料一般都沒有事務要求,結構化聚合的資料才有事務要求。
(2) 事務例子
使用者甲的操作
1.開始事務
2.訪問表A
3.訪問表B
4.提交事務
乙使用者在操作
1.開始事務
2.訪問表B
3.訪問表A
4.提交事務
如果甲使用者和乙使用者的兩個事務同時發生,甲事務鎖住了表A未釋放(因為整個事務未完成),正在準備訪問B表,而乙事務鎖住了表B未釋放(因為整個事務未完成),正在準備訪問A表,可是A表被甲事務鎖住了,等甲事務釋放,而甲事務真正等待乙事務釋放B表,陷入了無限等待,也就是死鎖Dead Lock。
(3) 高併發事務解決之道
悲觀鎖 - 資料庫表鎖或行鎖
樂觀鎖 - 版本控制
同步鎖 - 單執行緒
Actor模型 - 行為訊息佇列(適用跨節點、分散式、高併發)
* 同步鎖是單一JVM內的,對於分散式系統多個 Tomcat容器多個JVM,Actor模型能更好地“鎖”好資源。
(4) Actor模型
Actor模型內部的狀態由自己的行為維護,外部執行緒不能直接呼叫物件的行為,必須通過訊息才能激發行為,這樣就保證Actor內部資料只有被自己修改。
一個Actor如何處理多個Actor的請求呢?它先建立一個訊息佇列,每次收到訊息後,就放入佇列,而它每次也從佇列中取出訊息體來處理。通常我們都使得這個過程是迴圈的。讓Actor可以時刻處理髮送來的訊息。
解決“一個人一個坑”的效能瓶頸
參考:
http://www.jdon.com/45728
----- Akka與Reactor比較
兩者皆是非同步事件驅動框架,都構建自Actor模型;
Akka用 Scala 編寫的庫,目前更成熟,同時支援Scala和Java API;
Reactor專案始於2012年,由Spring團隊研發,但現在還常常大改。
Akka:
http://akka.io
Java程式碼Sample: http://verran.iteye.com/blog/1942393,
http://www.blogbus.com/dreamhead-logs/235916459.html,
http://www.th7.cn/Program/java/2012/03/29/67015.shtml,
https://github.com/XiaoMi/rose/tree/master/rose-example/src/main/java/sample
Sample
HelloWorld.java
public class HelloWorld extends UntypedActor { @Override public void preStart() { final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class), "greeter"); greeter.tell(Greeter.Msg.GREET, getSelf()); } @Override public void onReceive(Object msg) { if (msg == Greeter.Msg.DONE) { getContext().stop(getSelf()); } else { unhandled(msg); } } }
Greeter.java
import akka.actor.UntypedActor; public class Greeter extends UntypedActor { public static enum Msg { GREET, DONE } @Override public void onReceive(Object msg) { if (msg == Msg.GREET) { System.out.println("Hello World!"); getSender().tell(Msg.DONE, getSelf()); } else { unhandled(msg); } } }
Reactor:
http://projectreactor.io/old/reference/
https://github.com/reactor/reactor
架構
v.s.
http://stackoverflow.com/questions/16595393/akka-or-reactor