當邏輯程式設計遭遇CQRS時

banq發表於2016-11-25
我們將看到邏輯程式設計能做的最令人興奮的事情之一是實現CQRS模式。Eve語言將CQRS這個理想的設計模式變成了現實。

你知道Eve是一種邏輯程式語言嗎?Eve是基於Dedalus ,這是一個Datalog的擴充套件資料記錄 ,Datalog是基於Prolog的邏輯程式語言的。

邏輯程式設計的工作方式是:你寫下一堆事實,然後你能基於這些事實立即得到一個世界,其中所有他們的邏輯含義是真實的。

Datalog自20世紀70年代以來一直存在。但是,如果邏輯程式設計如此偉大,為什麼它沒有走向主流呢? 也許是因為它比過程化或函數語言程式設計不那麼直觀?

不,我認為邏輯程式設計魅力到現在還沒有完全釋放出來。Dedalus的研究報告在2009年就出來了,它看起來對我來說,一個重大的理論進步。

Dedalus不同於傳統的邏輯程式設計,顯式地透過不可靠的非同步通訊通道隨時間根據發生的事實不斷更新模型,。 Joseph M. Hellerstein,Dedalus的合著者之一,是這樣描繪它 :

對於那些喜歡資料庫理論者,Datalog可能會使一些人驚訝,因為沒有辦法更新和刪除模型。透過將時間合併到Dedalus邏輯中,將更新和刪除操作作為對邏輯時間戳(版本化)資料的演繹的捕獲。

當然,Eve現在才出來。 所以我們剛剛開始看到邏輯程式設計的潛力。

我想我們將看到邏輯程式設計能做的最令人興奮的事情之一是實現CQRS模式。

命令查詢責任分離(CQRS)是一種長時間時髦的詞語,它只是意味著讀取模式從你寫模型中分離。
例如,在CQRS和事件溯源中 ,您的應用程式的寫模型就像是事件物件的單隻追加序列:

{event: “deposited", accountId: 123, amount: 100}
{event: “deposited", accountId: 456, amount: 100}
{event: “withdrew", accountId: 123, amount: 30}

而你的應用程式的讀模型看起來更像:
{accountId: 123, balance: 70}
{accountId: 456, balance: 100}

當應用程式接收到事件(例如,存款)時,它會向寫模型發出更新。當您的應用程式需要資料,例如獲取帳戶的當前餘額時,它會查詢讀取模型。同時,你會告訴資料庫層如何始終保持讀模型與寫模型同步。

事件溯源天然具有高可擴充套件性,高可靠性和高可靠性等應用流行模式。 這句話是Greg Young講的。

即使你不關心事件溯源,你可能關心資料的非規範化 。好的,只要你認為你只是“反規範化資料”,你實際上是在“預計算一個CQRS的讀取模型”。

CQRS好像是一個無關緊要的簡單的嗡嗡聲, 但你可以看到它其實是一個重要的概念,對於命名和關注來說。


問題:CQRS現在不可能?
CQRS的問題是,從來沒有一個好的方法來“告訴你的資料庫層如何始終保持讀模型與寫模型同步”。 理論上,CQRS是偉大的。 但在實踐中,它不夠靈活和強勁。

那些聲稱能幫助實施CQRS的系統通常是流處理系統,例如:
1.事件儲存
2.Apache Samza和卡夫卡為基礎的解決方案


你也可以使用一個SQL資料庫實現CQRS:只要把你寫模型放入一個或多個表,然後使用觸發器來應對變化併發出相應的INSERT / UPDATE / DELETE操作來同步你讀模型資料庫。

不幸的是,無論你選擇上述哪一個,你都必須滾動自己的混亂過程邏輯來對輸入的寫操作做出反應。 也就是說,你必須告訴資料庫如何保持兩個模型同步。你不能夠只是宣告一下這兩種模式之間的關係應該這樣就行了。

此外,一致性保證是iffy。當寫入模型更改時,您不能保證整個讀取模型相應地從一個一致的快照到下一個快照。

物化檢視模式
好吧,嗯.....使用物化檢視模式實行CQRS?理論上,物化檢視模式是偉大的。 但是在實踐中 - 儘管有自己的MSDN頁面 - 它缺少一個令人滿意的實現! 物化檢視僅適用於基本資料轉換。 它們不夠聰明,不能在寫入模型操作的反應中增量更新自己。 加上它們的一致性保證是弱的。

我以前曾經指出物化檢視的限制,當我渴望一個“反規範引擎”,我基本上是指任何優雅和健壯地實現物化檢視模式的東西。

CQRS在我看來是一個關鍵模式,我們應該使用我們的資料層 -但目前很少看到一個具有優雅的CQRS架構的生產系統,甚至在談話中提到“CQRS”時也是這樣。

邏輯程式設計符合CQRS
很快,我們不需要物化檢視模式,SQL觸發器或流處理 - 因為我們會有Eve。
最新版本的Eve,0.2,只是一個記憶體中的演示; 它還沒有頂得上資料庫但足夠了。但我敢說它已經走上了成為最佳實施的CQRS。

在Eve,使用search和bind的塊是像定義一個物化檢視。 這裡是一個記錄物化檢視/ CQRS事情:

search
   [a]
   [b]

bind
   [c:a+b]
<p class="indent">


search
   [a]
   [b]
   [c]

bind @view
   [value value: "a={{a}}, b={{b}}, c={{c}}"]
<p class="indent">


結果:
a=5,b=6,c=11


這裡我將c總是繫結等於a + b 。 現在a是5 , b是6 ,c就是11 。 如果我增加b至7 ,然後我會自動顯示的c值12 。

看,這是CQRS! 我的寫入模式是a和b ,以及我的讀-模型是c 。

這是一個簡單的例子,但它說明了核心概念。


使用Eve的bind操作,你可以用你寫模型同步到您的讀模型,使得模式CQRS成為現實。


現在,我們已經看到,邏輯程式設計是一種很有前途的方法,使CQRS變成現實,我還要提到Datomic ,今天也許是在市場上最知名的邏輯程式設計資料庫。



When logic programming meets CQRS

相關文章