數(shù)據(jù):每服務(wù)每數(shù)據(jù)庫

背景

假設(shè)你正在采用微服務(wù)架構(gòu)構(gòu)建一個在線商城。大多數(shù)服務(wù)需要將數(shù)據(jù)持久化到數(shù)據(jù)庫。例如,訂單服務(wù)存儲訂單信息,客戶服務(wù)存儲客戶信息

數(shù)據(jù)庫設(shè)計

問題

微服務(wù)應(yīng)用的數(shù)據(jù)庫架構(gòu)是什么?

限制

  • 服務(wù)必須松散耦合,因此它們可以獨(dú)立的開發(fā),部署和擴(kuò)展
  • 某些業(yè)務(wù)事務(wù)必須強(qiáng)制跨多個服務(wù)執(zhí)行。比如,Place Order用例必須驗證一個新訂單沒有超出客戶的信用額度。其他業(yè)務(wù)服務(wù),必須更新多個服務(wù)擁有的數(shù)據(jù)。
  • 一些業(yè)務(wù)事務(wù)需要查詢多個服務(wù)擁有的數(shù)據(jù)。比如,View Available Credit用例必須查詢客戶服務(wù)找出creditLimit,查詢訂單服務(wù)計算未結(jié)算訂單的總金額。
  • 一些查詢必須關(guān)聯(lián)多個服務(wù)擁有的數(shù)據(jù)。比如,查詢指定區(qū)域的顧客和他們最近的訂單,需要顧客和訂單的關(guān)聯(lián)。
  • 數(shù)據(jù)庫有時必須復(fù)制和分區(qū),以便擴(kuò)展。參見Scale Cube。
  • 不同服務(wù)擁有不同的數(shù)據(jù)存儲需求。一些服務(wù),關(guān)系型數(shù)據(jù)庫是最好的選擇。其他服務(wù)可能需要NoSQL數(shù)據(jù)庫,比如MongoDB,因為它適合存儲復(fù)雜的非結(jié)構(gòu)化數(shù)據(jù),或者Neo4J,它設(shè)計來有效存儲和查詢圖形數(shù)據(jù)。

解決方案

將每個服務(wù)微服務(wù)的存儲保持為服務(wù)私有,僅通過它的API提供訪問。下圖展示了這個模式的結(jié)構(gòu)。

每服務(wù)每數(shù)據(jù)庫

服務(wù)的數(shù)據(jù)庫是服務(wù)實現(xiàn)的有效部分。它不能被其他服務(wù)直接訪問。

有幾種不同的方式可以將服務(wù)的數(shù)據(jù)持久保持為服務(wù)私有。你沒有必要為每個服務(wù)準(zhǔn)備一個數(shù)據(jù)庫服務(wù)器
比如,如果你雜橫在使用關(guān)系型數(shù)據(jù)庫,那么選擇是:

  • 每個服務(wù)私有的表 - 每個服務(wù)擁有一組僅能被它訪問的表
  • 每個服務(wù)一個schema - 每個服務(wù)都有一個私有的數(shù)據(jù)庫schema
  • 每個服務(wù)一個數(shù)據(jù)庫 - 每個服務(wù)有自己的數(shù)據(jù)庫服務(wù)器。

每個服務(wù)私有的表,和每個服務(wù)一個schema,有最小的開銷。使用每個服務(wù)一個schema由于使關(guān)系更清晰,因此更吸引人。一些高吞吐量的服務(wù)也許需要自己的數(shù)據(jù)庫服務(wù)器。

創(chuàng)建一個柵欄來強(qiáng)制模塊化是個好主意。例如,你可以為不同服務(wù)分配不同的數(shù)據(jù)庫賬號,使用數(shù)據(jù)庫訪問機(jī)制,比如授權(quán)。如果沒有一些類型的柵欄限制封裝,開發(fā)人員往往被誘惑繞過服務(wù)的API,而直接訪問它的數(shù)據(jù)。

結(jié)果

使用每服務(wù)每數(shù)據(jù)庫有如下優(yōu)勢:

  • 有利于確保服務(wù)是松散耦合的。對某個服務(wù)數(shù)據(jù)庫的修改不會影響到其他服務(wù)。
  • 每個服務(wù)可以使用最適合它需要的數(shù)據(jù)庫。比如,進(jìn)行文本查詢的服務(wù)可以使用 ElasticSearch。操作社交圖片的服務(wù)可以使用 Neo4j。

使用每服務(wù)每數(shù)據(jù)庫有如下弊端:

  • 無法簡單直接的實現(xiàn)跨多個服務(wù)的業(yè)務(wù)事務(wù)。由于CAP理論,最好避免分布式事務(wù)。此外,大多數(shù)現(xiàn)代的(NoSQL)數(shù)據(jù)庫不支持。最好的解決方案是使用Saga模式。當(dāng)服務(wù)更新數(shù)據(jù)時,發(fā)布消息。其他服務(wù)訂閱消息,并在響應(yīng)時更新它們的數(shù)據(jù)。
  • 實現(xiàn)查詢并關(guān)聯(lián)多個數(shù)據(jù)庫的數(shù)據(jù)具有挑戰(zhàn)性。

有各種各樣的解決方案:

  • API聚合 - 應(yīng)用執(zhí)行關(guān)聯(lián),而不是數(shù)據(jù)庫。比如,服務(wù)(或網(wǎng)關(guān))獲取客戶和他們的訂單信息,可以首先從客戶服務(wù)獲取客戶信息,接著從訂單服務(wù)查詢客戶最近的訂單。
  • 命令查詢職責(zé)分離(CQRS) - 維護(hù)一個或多個包含多個服務(wù)數(shù)據(jù)的物化視圖。視圖由服務(wù)維護(hù),該服務(wù)訂閱了其他服務(wù)更新數(shù)據(jù)時發(fā)布的事件。例如,在線商城實現(xiàn)查詢特定區(qū)域的顧客和他們最近的訂單時,應(yīng)該維護(hù)一個關(guān)聯(lián)了顧客和訂單數(shù)據(jù)的視圖。這個視圖由訂閱了顧客和訂單事件的服務(wù)更新。
  • 管理多個 SQL 和 NoSQL 數(shù)據(jù)庫的復(fù)雜性

相關(guān)模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容