作者 | Jeff Carpenter, InfoWorld
翻譯 | Jackyrong
你的微服務架構需要多種資料模型。你是應該選擇混合持久化呢還是多模型資料庫?
如何為微服務選擇資料庫 在過去的十年,大規模的分布式系統呈現爆炸式增長。這一趨勢促使在資料庫領域産生了一股巨大的創造力,這在軟體業的曆史上無疑是沒有先例的。其結果是誕生了一個健康和充滿競争的資料庫市場,我們可以是以在大量的平台中各取所需。但是我們應該如何抉擇?
在本文中,我們将探讨如何根據應用程式去選擇合适的資料庫模式(可以有一種以上的選擇)。我們還将分析對資料模式的選擇要如何幫助确定在資料層中将選用哪些技術。
雲架構,NoSQL 和微服務架構
随着開發人員開始建立可擴充的Web應用,曆史上在資料架構上占主導地位的關系型資料庫所面臨的壓力日益凸顯。我們開發了非常流行的社交應用,并開始将越來越多的裝置連接配接到物聯網(IoT)。使用者大量的讀取和寫入資料要求我們必須擴充資料層,進而誕生了新型的資料庫來滿足這些高可擴充性需求。
在許多情況下,這些新的資料庫“NoSQL”或“非關系”的解決方案,所基于的資料模型和傳統的關系資料庫模型不同。NoSQL資料庫包括有文檔型、鍵值對型(key-value)、列式資料庫甚至圖資料庫。通常情況下,這些資料庫犧牲了一些關系資料庫的常見的的特性,如強一緻性、ACID事務特性和Join連接配接。
與此同時,和資料庫技術的變革一樣,在本世紀初的SOA(面向服務的架構),正逐漸演變為微服務架構的體系架構,許多企業也開始逐漸抛棄重量級的SOA體系架構如企業服務總線(ESB),并傾向使用“去中心化”的架構方法。微服務架構的魅力在于其開發、管理和擴充服務都是相對獨立的。這給了我們很多在實施方面的靈活性,包括基礎架構技術,如資料庫。
舉個例子,我們假設正在為微服務架構做開發工作,并期待着大規模的可擴充性的需求。無論這個項目是一個新的應用還是對現有應用的重構,我們都有機會針對資料庫做出新的選擇。
混合持久化(Polyglot persistence)
微服務架構風格的一大關鍵優勢是持久性的封裝。我們可以根據每個服務的需要,去選擇不同的持久化技術。根據每種資料類型的特點而去選擇資料存儲的方法,被稱為混合持久化,這一術語起初是由Martin Fowler等人推廣起來的。混合持久化和微服務架構可謂是天作之合。
下圖中,展示了一系列的微服務,以及我們如何為每個服務選擇不同的資料模式。我不想在本文中,為每種類型的資料庫去選擇合适的用例。我的意圖是要突出各類型資料庫的優勢,以及為什麼混合持久化的方法是值得稱道的。
如何為微服務選擇資料庫 其中,開發服務A的團隊,因為該服務是基于大規模資料管理的核心應用,可能使用如Apache Cassandra這樣的表格模型資料庫。例如,一個零售應用庫存應用,可能很适合使用Apache Cassandra。Cassandra提供了一系列協調機制工具,如可調一緻,批處理和輕量級的事務機制,可以作為完整ACID事務機制的替代。
服務B支援用衆所周知的關鍵字查找值的方式,例如針對産品目錄的描述性資料。對于鍵值存儲模型來說,這是一個很好的例子,在這裡,我們通過一個衆所周知的鍵值(如産品ID)查找一系列的資料。很多記憶體緩存都使用鍵值對資料模式去支援大規模的快速讀取。
服務C可能主要關注半結構化内容,例如Web站點的表單或頁面,而文檔存儲可能非常适合該類型資料。文檔存儲與鍵值存儲有許多相似之處,但是一個關鍵的差別是文檔型資料支援資料上增加結構,例如對特定屬性進行索引以支援快速檢索。
服務D可能涉及資料之間的複雜關系導航,例如客戶資料和與組織中各部門的客戶聯系曆史資料。這可能涉及其他服務所擁有的資料類型之間的關系。這是一個有趣的案例,因為它開始與上面提到的服務有各自的資料類型的限制相反。在這種情況下,你可以選擇為你的服務建立一個具有對底層表的隻讀通路的圖,然後通過這個“前門”處理所有的變化——即通過這個“前門”去調用那些“擁有”這些資料類型的其他服務的API。
最後,我們可能還有一個使用關系資料庫技術的遺留系統或服務,或者我們有一個服務來管理那些資料量較少,或者不經常變更的資料。關系資料庫可能完全适合于這些場景。
單個服務是否應該使用混合持久化?
還有一種可能就是我們可以設計一個服務,這個服務需要多種資料庫支撐。例如,我們可以建立一個使用鍵值存儲模式作為索引的酒店服務,在酒店名稱和ID之間實作映射,而存将關于酒店的描述性資料存儲在Cassandra中。
如何為微服務選擇資料庫 注意,名稱映射到ID可以在Cassandra中采用規範化的設計方法去實作,其中一個單獨表去維護名稱至ID的映射關系。這使用了更多的存儲空間,但降低了管理單獨鍵值存儲的操作複雜性。
這是我推薦的做法- 針對某個微服務,隻要可行,就應該堅持使用單一資料模型(資料庫)。如果你發現一種情況,認為單個服務需要兩個不同資料庫支撐,那麼請考慮該服務的粒度是否可能變得太大。你可能需要考慮将該服務拆分為較小的服務。
混合持久化局限性的權衡
混合持久化的主要缺點在于支援多種技術的成本,無論是在最初的開發階段還是将來的營運方面。
主要的開發成本,是在需要教育訓練每個開發人員去掌握每個新的資料庫技術。這是非常重要的,尤其是在開發人員頻繁流動團隊中。
另一個成本是支援多個資料庫的操作成本。這會成為一個問題,尤其是當資料庫是集中管理,并且團隊必須在多種技術的掌握上維持高水準,但這在DevOps環境下,該問題并不會太突出,因為開發團隊需要支援他們在生産環境中選擇的資料庫。
多模型資料庫(Multi Model Databases)
作為另外的選擇方案或混合持久化模式的補充, 資料庫廠商已經開始建立和推廣多模型的資料庫。術語“模型”指的是資料存儲所提供的核心抽象,如表(關系和非關系)、列存儲、鍵值、文檔或圖。我們可以将一個多模型應用程式看作一個使用多個資料存儲類型的應用程式,而多模型資料庫是支援多個抽象模型的資料庫。
DataStax企業版(DSE)是多模型資料庫的典型例子,它核心支援Cassandra的分區行存儲(表格)模型,同時也支援基于在其之上的圖的抽象層(DSE圖)。DSE在核心模型之上建構對應的鍵值和文檔模型也是很簡單的,如下圖所示。這樣,我們可以修改上面的混合持久化的方法,進而利用一個基礎資料庫引擎為我們所有的服務提供對應的服務,而使用單獨的Cassandra keyspaces在不同服務擁有的資料間維護清晰的邊界。
如何為微服務選擇資料庫 下面是它能實作的功能:
- 表格:我們主要的應用服務A可以通過Cassandra的查詢語言(CQL)直接和DSE的資料庫打交道。
- 鍵值對:雖然Apache和Cassandra的分布式版本DataStax都沒有提供明确的鍵值對API,但是象服務B可以通過表設計去支援單個鍵值和列的方法,去通路Cassandra,例如:
CREATE TABLE hotel.hotels (key uuid PRIMARY KEY,value text); // 或者選擇blob類型
- 文檔型:Cassandra通過使用JSON檔案支援文檔型風格的資料,這可以用在服務C中。注意因為Cassandra需要針對表定義schema模式,是以不能插入新增任意的JSON列,這是一個可能通常和文檔型資料庫有關的特性。
- 圖:對于象服務D那樣相關度很高的資料,DSE的圖是一個高度可擴充的圖形資料庫,它建構于DSE資料庫之上。DSE圖支援來自Apache tinkerpop項目中強大的功能和表現力的Gremlin API。
多模型資料庫的優點和限制
在考慮是否投資使用多模型資料庫(或你已經在使用的資料庫的多模型的特性)時,你要考慮我們前文讨論的關于混合持久化中,同樣的開發和營運成本的問題。
使用多模型資料庫可以讓營運變得簡單。即使不同的開發團隊使用不同的API和不同的互動模式和後端資料庫平台打交道,我們也隻需要管理一個平台而已,進而提高了效率。
在選擇多模型資料庫時要考慮的一個問題是如何支援各種模型。一種常見的方法,是基于單一的原生的基礎模型的資料庫引擎,而其他模型都是建構在其之上。分層資料模型更能展現底層基本模型的特性。
例如,ThoughtWorks技術雷達第16期(https://assets.thoughtworks.com/assets/technology-radar-vol-16-en.pdf)中,讨論了基于Cassandra建構的DSE圖資料庫的特性,并且也提到其中需要權衡的内容:
基于Cassandra 建構的DSE圖資料庫定位是大規模的資料集,相比之下我們長期喜愛的Neo4j開始表現出一定的局限性。這是需要取舍的;比如,你會失去了ACID的事務特性和Neo4j運作時的模式自由的特性,但卻可以通路Cassandra的基礎表,以及針對分析工作負載和Spark的整合,還有強大的TinkerPop/Gremlin查詢語言可以使用,這的确是一個值得考慮的選擇。
如果考慮Web應用中的各種資料類型,你可能會發現不同的資料類型對一緻性有不同的需求,而且實際需要立即一緻性的資料類型數量相對較少。
上面引用的ThoughtWorks的觀點中,還提到了在考慮多模型資料庫中另一個重要的因素 - 在不同的模型和資料引擎間的整合和互動問題,以及為通路資料的各種操作和分析的用例。DSE支援通過Spark(DSE分析)通路圖資料以進行資料分析,并且DSE搜尋引擎提供了針對DSE資料庫中的資料建立各種查詢索引的能力。
微服務資料模型操作的四個步驟
既然我們已經探讨混合持久化和多模型兩種方式的優缺點,我們應該如何去決定哪些資料模型适用于大規模可擴充的微服務應用呢?可以按照以下步驟:
1. 識别你的應用程式中主要的資料類型,為其中每種類型建立一個服務,并讓每個服務掌控相應的持久層。在可能的情況下,為所有服務都使用多模型資料庫,允許服務在與資料互動的模型中是不相同的。
2. 用Tabular(例如DSE資料庫)作為網絡水準的可擴充性和可用性的主要模型,然後根據需要在此之上建構分層的鍵值對和文檔資料模型。請務必考慮在操作和分析用例中通路資料的各種方法,以便提前計劃如何将搜尋索引和複制等特性用于資料分析中心。
3. 用圖的方法去表示(即DSE圖)高度關聯的資料,特别是在實體之間的關系有多個或多個屬性,并且數量比實體自己的屬性多的時候,或者需要在相同的實體之間捕捉多對多的關系的時候。
4. 在不需要變更的情況下,保留關系資料庫技術中的遺留投資。例如,當你的案例是需要大規模、低延遲和高可用性的時候,那就使用傳統的關系型資料庫吧。
我希望本文為讀者提供了一個有用的架構,來考慮在應用程式中如何和怎麼樣去支援多資料模型,以及何時考慮使用多模型資料庫。
Jeff Carpenter是DataStax公司的技術傳道者,他利用自己在系統架構、微服務和Apache Cassandra的知識去幫助開發者和營運工程師去建構可擴充的、可靠的、安全的分布式系統,同時是《Cassandra:權威指南 第二版》的作者。
翻譯原文:https://www.infoworld.com/article/3236291/database/how-to-choose-a-database-for-your-microservices.html