數據二分法:重新思考數據與服務之間的關係

大家好! 我們有好消息,OTUS 將於 XNUMX 月再次推出課程 《軟體架構師》,我們通常會與您分享有用的材料。

數據二分法:重新思考數據與服務之間的關係

如果您在沒有任何背景的情況下遇到了整個微服務問題,您會覺得這有點奇怪,這是可以理解的。 將應用程式拆分為透過網路連接的片段必然意味著在最終的分散式系統中添加複雜的容錯模式。

儘管這種方法涉及將其分解為許多獨立的服務,但最終目標不僅僅是讓這些服務在不同的電腦上運作。 我們這裡講的是與外界的交互,本質上也是分散式的。 不是在技術意義上,而是在一個由許多人、團隊、程式組成的生態系統的意義上,每個部分都需要以某種方式完成其工作。

例如,公司是分散式系統的集合,這些系統共同致力於實現某些目標。 幾十年來,我們一直忽略這一事實,試圖透過 FTP 檔案傳輸或使用企業整合工具來實現統一,同時專注於我們自己孤立的目標。 但隨著服務的出現,一切都改變了。 服務幫助我們超越視野,看到一個相互依賴、協同工作的專案的世界。 然而,為了成功工作,有必要認識和設計兩個根本不同的世界:外在世界,我們生活在許多其他服務的生態系統中;以及我們個人的內在世界,我們獨自統治。

數據二分法:重新思考數據與服務之間的關係

這個分散式世界與我們成長和習慣的世界不同。 建構傳統整體架構的原則經不起批評。 因此,正確使用這些系統不僅僅是創建一個很酷的白板圖或一個很酷的概念證明。 關鍵是要確保這樣的系統能夠長期成功運作。 幸運的是,這些服務已經存在相當長一段時間了,儘管它們看起來有所不同。 SOA 課程 即使使用 Docker、Kubernetes 和略顯破舊的時髦鬍鬚,仍然具有相關性。

因此,今天我們將了解規則是如何變化的,為什麼我們需要重新思考我們處理服務和它們相互傳遞的資料的方式,以及為什麼我們需要完全不同的工具來做到這一點。

封裝並不總是你的朋友

微服務可以彼此獨立運作。 正是這種財產賦予了他們最大的價值。 同樣的屬性允許服務擴展和增長。 與其說是擴展到千萬億用戶或拍字節數據(儘管這些也可以有所幫助),不如說是隨著團隊和組織不斷發展而在人員方面進行擴展。

數據二分法:重新思考數據與服務之間的關係

然而,獨立是一把雙面刃。 也就是說,服務本身可以輕鬆、自然地運作。 但是,如果在一個服務中實現的功能需要使用另一個服務,那麼我們最終必須幾乎同時對這兩個服務進行更改。 在單體應用程式中,這很容易做到,您只需進行更改並將其發送到發布版本,但在同步獨立服務的情況下,則會出現更多問題。 團隊和發布週期之間的協調會破壞敏捷性。

數據二分法:重新思考數據與服務之間的關係

作為標準方法的一部分,他們只是試圖避免煩人的端到端更改,在服務之間明確劃分功能。 單一登入服務就是一個很好的例子。 它具有明確定義的角色,使其與其他服務區分開來。 這種明顯的分離意味著,在周圍服務需求快速變化的世界中,單一登入服務不太可能改變。 它存在於嚴格限制的環境中。

數據二分法:重新思考數據與服務之間的關係

問題在於,在現實世界中,業務服務無法始終保持同樣純粹的角色分離。 例如,相同的業務服務可以更大程度地利用其他類似服務的資料。 如果您從事線上零售,那麼處理訂單流程、產品目錄或使用者資訊將成為您許多服務的要求。 每個服務都需要存取這些數據才能運作。

數據二分法:重新思考數據與服務之間的關係
大多數業務服務共享相同的資料流,因此它們的工作總是交織在一起。

因此,我們談到了一個值得討論的重要問題。 雖然服務對於基本上獨立運作的基礎設施元件來說效果很好,但大多數業務服務最終會更加緊密地交織在一起。

資料二分法

服務導向的方法可能已經存在,但它們仍然缺乏對如何在服務之間共享大量資料的深入了解。

主要問題是數據和服務是密不可分的。 一方面,封裝鼓勵我們隱藏數據,以便服務可以彼此分離,並促進其成長和進一步的變化。 另一方面,我們需要能夠像任何其他資料一樣自由地劃分和征服共享資料。 關鍵是能夠像在任何其他資訊系統中一樣自由地立即開始工作。

然而,資訊系統與封裝關係不大。 事實上,情況恰恰相反。 資料庫竭盡全力提供對其儲存的資料的存取。 它們配備了強大的聲明式介面,可讓您根據需要修改資料。 此類功能在初步研究階段很重要,但對於管理不斷發展的服務日益增長的複雜性並不重要。

數據二分法:重新思考數據與服務之間的關係

這裡出現了一個困境。 矛盾。 二分法。 畢竟,資訊系統是為了提供數據,而服務是為了隱藏。

這兩種力量是根本性的。 他們支撐著我們大部分的工作,不斷為我們建造的系統追求卓越而奮鬥。

隨著服務系統的成長與發展,我們在許多方面看到了資料二分法的後果。 要么服務介面將會增長,提供不斷增加的功能範圍,並開始看起來像一個非常奇特的本土數據庫,要么我們會感到沮喪,並實現某種方法來檢索或移動整個數據集從一個服務到另一個服務。

數據二分法:重新思考數據與服務之間的關係

反過來,創建看起來像精美的本土資料庫的東西將導致一系列問題。 我們不會詳細說明為什麼它是危險的 共享資料庫,我們只能說它代表著成本高昂的工程和運營 困難 對於嘗試使用它的公司。

更糟的是,資料量放大了服務邊界問題。 服務中共享的資料越多,介面就會變得越複雜,並且組合來自不同服務的資料集就越困難。

提取和移動整個資料集的替代方法也有其問題。 解決這個問題的常見方法是簡單地檢索和儲存整個資料集,然後將其本地儲存在每個消費服務中。

數據二分法:重新思考數據與服務之間的關係

問題在於不同的服務對它們消耗的數據的解釋不同。 這些數據隨時可用。 它們在本地進行修改和處理。 很快,它們就不再與來源中的資料有任何共同點。

數據二分法:重新思考數據與服務之間的關係
副本的可變性越大,資料隨時間的變化就越大。

更糟的是,這些數據事後很難修正(MDM的 這才是它真正可以發揮作用的地方)。 事實上,企業面臨的一些棘手的技術問題源於應用程式之間不斷增加的不同數據。

為了找到這個問題的解決方案,我們需要對共享資料進行不同的思考。 它們必須成為我們所建構的架構中的一流物件。 派特·海蘭德 將此類數據稱為“外部”,這是一個非常重要的特徵。 我們需要封裝,這樣我們就不會暴露服務的內部工作原理,但我們需要讓服務輕鬆存取共享數據,以便它們可以正確地完成自己的工作。

數據二分法:重新思考數據與服務之間的關係

問題是這兩種方法在今天都不再適用,因為服務介面、訊息傳遞和共享資料庫都沒有提供處理外部資料的良好解決方案。 服務介面不太適合任何規模的資料交換。 訊息傳遞會移動資料但不儲存其歷史記錄,因此資料會隨著時間的推移而損壞。 共享資料庫過於關注某一點,從而阻礙了進展。 我們不可避免地陷入數據失敗的循環:

數據二分法:重新思考數據與服務之間的關係
數據失效循環

Streams:一種去中心化的資料和服務方法

理想情況下,我們需要改變服務處理共享資料的方式。 此時,任何一種方法都面臨著前面提到的二分法,因為沒有魔法粉末可以撒在它上面讓它消失。 不過,我們可以重新思考問題並達成妥協。

這種妥協涉及一定程度的集中化。 我們可以使用分散式日誌機制,因為它提供了可靠、可擴展的串流。 我們現在希望服務能夠加入並在這些共享線程上進行操作,但我們希望避免執行此處理的複雜的集中式上帝服務。 因此,最好的選擇是將流處理建置到每個消費者服務中。 這樣,服務將能夠組合來自不同來源的資料集,並按照需要的方式使用它們。

實現這種方法的一種方法是使用串流媒體平台。 有很多選擇,但今天我們將看看 Kafka,因為使用它的狀態流處理可以讓我們有效地解決所提出的問題。

數據二分法:重新思考數據與服務之間的關係

使用分散式日誌記錄機制使我們能夠遵循常見的路徑並使用訊息傳遞來處理 事件驅動架構。 這種方法被認為比請求-回應機制提供更好的擴展和分區,因為它將流的控制權交給了接收者而不是發送者。 然而,此生的一切都需要付出代價,而這裡你需要一個經紀人。 但對於大型系統來說,這種權衡是值得的(對於普通的 Web 應用程式來說可能並非如此)。

如果代理程式負責分散式日誌記錄而不是傳統的訊息傳遞系統,則您可以利用其他功能。 傳輸幾乎可以像分散式檔案系統一樣線性擴展​​。 資料可以在日誌中保存相當長的時間,因此我們不僅得到訊息交換,而且得到資訊儲存。 可擴展存儲,無需擔心可變共享狀態。

然後,您可以使用有狀態流處理將聲明性資料庫工具新增至消費服務。 這是一個非常重要的想法。 雖然資料儲存在所有服務都可以存取的共享流中,但服務所做的聚合和處理是私有的。 他們發現自己被孤立在一個嚴格限制的環境中。

數據二分法:重新思考數據與服務之間的關係
透過分離不可變狀態流來消除資料二分法。 然後使用狀態流程處理將此功能新增至每個服務。

因此,如果您的服務需要處理訂單、產品目錄、倉庫,它將具有完全存取權:只有您才能決定要合併哪些資料、在哪裡處理資料以及隨著時間的推移如何變更資料。 儘管數據是共享的,但數據的使用是完全分散的。 它是在每項服務中產生的,在一個一切都按照您的規則進行的世界中。

數據二分法:重新思考數據與服務之間的關係
共享資料而不損害其完整性。 將功能(而不是來源)封裝在每個需要它的服務中。

碰巧資料需要集體移動。 有時,服務需要所選資料庫引擎中的本地歷史資料集。 訣竅在於,您可以保證在必要時可以透過存取分散式日誌記錄機制從來源復原副本。 Kafka 中的連接器在這方面做得很好。

因此,今天討論的方法有幾個優點:

  • 資料以公共流的形式使用,可以長期儲存在日誌中,並且在每個單獨的上下文中硬連線處理公共資料的機制,這使得服務能夠輕鬆快速地工作。 這樣就可以平衡資料的二分性。
  • 來自不同服務的資料可以輕鬆組合成集合。 這簡化了與共享資料的交互,並且無需在資料庫中維護本地資料集。
  • 有狀態流處理僅緩存數據,真實來源仍然是一般日誌,因此隨著時間的推移數據損壞的問題並不那麼嚴重。
  • 服務的核心是數據驅動的,這意味著儘管數據量不斷增加,服務仍然可以快速回應業務事件。
  • 可擴展性問題落在經紀人身上,而不是服務。 這顯著降低了編寫服務的複雜性,因為無需考慮可擴展性。
  • 新增服務不需要更改舊服務,因此連接新服務變得更加容易。

正如您所看到的,這不僅僅是 REST。 我們收到了一套工具,可讓您以分散的方式處理共享資料。

今天的文章並未涵蓋所有方面。 我們仍然需要弄清楚如何在請求回應範式和事件驅動範式之間取得平衡。 但我們下次會處理這個問題。 有些主題您需要更了解,例如,為什麼有狀態流處理如此出色。 我們將在第三篇文章中討論這個問題。 如果我們訴諸它們,我們還可以利用其他強大的結構,例如, 恰好一次處理。 它是分散式業務系統的遊戲規則改變者,因為它為分散式業務系統提供了事務保證 XA 以可擴展的形式。 這將在第四篇文章中討論。 最後,我們需要回顧這些原則的實施細節。

數據二分法:重新思考數據與服務之間的關係

但現在,請記住這一點:資料二分法是我們在建立業務服務時面臨的一種力量。 我們必須記住這一點。 訣竅是徹底改變一切,開始將共享資料視為一流物件。 有狀態流處理為此提供了獨特的折衷方案。 它避免了阻礙進步的中心化「上帝組件」。 此外,它確保了資料流管道的敏捷性、可擴展性和彈性,並將其添加到每項服務中。 因此,我們可以專注於任何服務都可以連接並處理其資料的一般意識流。 這使得服務更具可擴展性、可互換性和自主性。 因此,它們不僅在白板和假設檢定上看起來不錯,而且還可以工作和發展數十年。

了解有關課程的更多信息。

來源: www.habr.com

添加評論