為什么說集中管理數據是個壞主意?
微服務架構是現代應用程序和系統的一個常見模型。其特點是把一個大型應用的業務責任分割成不同的、獨立的組件,可以獨立開發、管理、操作和擴展。
微服務架構為應用程序本身的擴展提供了一個有效的模型,允許更大的、更不連貫的開發團隊獨立完成他們的部分工作,同時仍然參與大型應用程序的構建中。
在一個典型的微服務架構中,單獨的服務被創建,該服務包含了一個特定的業務邏輯子集。當相互連接時,整個微服務集形成一個完整的、大規模的應用程序,包含完整的業務邏輯。
這種模式對代碼來說是很好的,但對數據呢?通常,為特定業務邏輯創建單獨服務的公司覺得有必要把所有的應用數據放到一個單一的、集中的數據存儲中。這個想法是為了確保所有的數據對可能需要它的每個服務都是可用的。管理單個數據存儲很容易,也很方便,而且數據建模對整個應用程序來說是一致的,與使用它的服務無關。
不要這樣做,集中你的數據是一個壞主意。這里有三個原因:
集中的數據很難擴展
當整個應用程序的數據都在一個集中的數據存儲中時,隨著應用程序的增長,你必須擴展整個數據存儲以滿足應用程序中所有服務的需求。這顯示在圖1的左邊。如果你為每個服務使用單獨的數據存儲,只有需求增加的服務需要擴展,而被擴展的數據庫是一個較小的數據庫。這在圖1的右邊顯示。
將小型數據庫擴展到更大的規模要比將大型數據庫擴展到更大的規模容易得多。

圖1. 按服務劃分數據可以簡化擴展
集中的數據以后很難分割
新開發應用程序的開發者通常的想法是:“我現在不需要擔心擴展的問題,在以后需要的時候再擔心吧”。這種觀點雖然很普遍,但在某些時候卻會導致擴展問題。當應用程序變得流行時,你必須重新思考架構決策,以滿足客戶的增量需求。
一個常見的架構變化是需要將你的數據存儲分割成更小的數據存儲。問題是,在應用程序剛創建時比在應用程序生命周期的后期更容易進行分割。當應用程序已經存在了幾年,并且應用程序的所有部分都可以訪問對應的數據時,要確定數據集的哪些部分可以被分割成一個單獨的數據存儲而不需要對使用數據的代碼進行重大重寫就變得非常困難。即使是簡單的問題也變得很困難。哪些服務在使用Profiles表?是否有服務同時需要系統表和項目表?
而且,更糟糕的是,是否有任何服務使用這兩個表來執行連接?它的用途是什么?在代碼中的什么地方完成的?我們怎樣才能重構這種變化?
一個數據集在一個數據存儲中停留的時間越長,以后就越難把這個數據存儲分成更小的部分。
通過將數據按功能分成獨立的數據存儲,你可以避免以后將數據從連接的表中分離出來的相關問題,也可以減少代碼中存在的數據之間意外關聯的可能性。
集中的數據使數據所有權無法實現
將數據劃分為多個服務的一大優勢是能夠將應用所有權劃分為不同的、可分離的部分。單個開發團隊的應用程序所有權是現代應用開發的一個核心原則,它可以促進更好的組織擴展,并在問題發生時提高響應能力。這種所有權模式在面向單一團隊的服務架構(STOSA)開發模式中進行了討論。
當你有大量的開發團隊都在為一個大型的應用程序做貢獻時,這種模式非常有效,但即使是有較小團隊的小型應用程序也能從這種模式中受益。
問題是,一個團隊要擁有一個服務的所有權,他們必須同時擁有該服務的代碼和數據。這意味著一個服務(服務A)不應該直接訪問另一個服務(服務B)的數據。如果服務A需要存儲在服務B中的東西,它必須調用服務B的一個服務入口點,而不是直接訪問該數據。

圖2. 服務A永遠不應該直接訪問服務B的數據
這允許服務B對其數據、如何存儲以及如何維護擁有完全的自主權。
那么,有什么選擇呢?當你構建面向服務的架構(SOA)時,每個服務應該擁有自己的數據。這些數據是服務的一部分,并被納入服務中。

圖3. 每個服務都有自己的數據
這樣,服務的所有者可以管理該服務的數據。如果需要對數據進行模式改變或其他結構性改變,服務所有者可以在沒有任何其他服務所有者參與的情況下實現更改。隨著應用程序(及其服務)的增長,服務所有者可以做出擴展決策和數據重構決策,以處理增加的負載和變化的需求,而無需其他服務所有者的參與。
一個問題經常出現,那些真正需要在應用程序之間共享的數據怎么辦?諸如用戶配置文件數據,或其他在應用程序的許多常用的數據。一個誘人的快速解決方案可能是只在多個服務之間共享所需的數據,如圖4所示。每個服務可能有它自己的數據,同時也可以訪問共享的數據。

圖4. 不建議在服務之間共享數據
更好的方法是將共享數據放入一個由所有其他服務使用的新服務中,如圖5所示。

圖5. 使用服務是訪問共享數據的正確方式
服務C這一新的服務也應該遵循STOSA的要求。特別是,它應該有一個單一的、明確的團隊來擁有該服務,從而擁有共享數據。如果任何其他服務,如圖中的服務A或服務B,需要訪問共享數據,它必須通過服務C提供的API來實現。這樣,服務C的所有者是唯一負責共享數據的團隊,可以就擴展、重構和更新方面做出適當的決策。只要維護一個一致的API供服務A和服務B使用,服務C就可以做出任何關于更新數據的決定。
這與圖4相反,圖4中服務A和服務B都直接訪問共享數據。在這個模型中,沒有一個團隊可以在不涉及直接訪問數據的所有其他團隊的情況下對數據的結構、布局、擴展或建模做出任何決定,這限制了應用程序開發過程的可擴展性。
使用微服務或其他SOA是管理從事大型應用的大型開發團隊的一個好方法。但是,服務架構也必須包含應用程序的數據,否則真正的服務獨立性--也就是開發組織的擴展獨立性--將不可能實現。
作者:Lee Atchison是云計算和應用現代化領域公認的思想領袖。Lee在產品開發、架構、擴展和現代化方面有三十多年的經驗,曾在亞馬遜、亞馬遜網絡服務(AWS)、New Relic和其他現代應用組織工作。