序言
圖示:Elasticsearch 在 DB-Engine 綜合排名第8
Elasticsearch 簡稱”ES”, 在DB-Engine 綜合排名第8,已經(jīng)持續(xù)了相當長的時間,按照當下熱度應該會繼續(xù)保持或者上升一個名次;ES在多數(shù)工程師印象中最深刻可能是ELK三件套或者全文檢索領(lǐng)域,但在筆者看來,應該是業(yè)務(wù)系統(tǒng)領(lǐng)域“大寬表查詢”場景,或者叫“數(shù)據(jù)庫查詢加速”場景。
下面就從微服務(wù)架構(gòu)開始,談?wù)凟S是如何解決應用系統(tǒng)中復雜查詢的,為什么應該是首選?
微服務(wù)架構(gòu)
微服務(wù) 是一種應用系統(tǒng)架構(gòu)模式,非指特定的技術(shù)框架。微服務(wù)時代人人都在談微服務(wù)架構(gòu),在Java編程領(lǐng)域,Spring Cloud技術(shù)棧體系幾乎已經(jīng)成為了微服務(wù)的代名詞或者首選,當下如果去應聘一名Java工程師,有三個必問技術(shù)框架,Spring,Spring Boot,Spring Cloud,俗稱”廚房”三件套,隨便打開一個招聘網(wǎng)站或者了解一個公司IT項目架構(gòu)設(shè)計,幾乎都有Spring XXXX。注意,這里不是跟大家討論微服務(wù)技術(shù)棧,只是為了給大家探討微服務(wù)架構(gòu)模式的一些弊端與進化。
微服務(wù)架構(gòu)模式
圖示:某電商物流微服務(wù)架構(gòu)模式示意圖,參考百度百科
在微服務(wù)架構(gòu)模式中,一般的做法會基于領(lǐng)域進行服務(wù)劃分與編排;服務(wù)劃分為基礎(chǔ)服務(wù)與業(yè)務(wù)服務(wù),基礎(chǔ)服務(wù)更抽象一些,一個基礎(chǔ)服務(wù)對應一個數(shù)據(jù)庫模型。
如圖所示,用戶基礎(chǔ)服務(wù)有用戶領(lǐng)域?qū)?DB,訂單基礎(chǔ)服務(wù)有訂單領(lǐng)域 DB,商品有商品領(lǐng)域 DB 等;業(yè)務(wù)服務(wù)一般是聚合服務(wù),按照應用系統(tǒng)交互方式組合,如訂單中心,需要查詢訂單基礎(chǔ)服務(wù)與商品基礎(chǔ)服務(wù),在訂單中心內(nèi)部進行組合,還有如商品中心、庫存中心、財務(wù)中心等都是基于組合各自需要的基礎(chǔ)服務(wù)進行。
微服務(wù)架構(gòu)弊端
基礎(chǔ)服務(wù)抽象的劃分與編排,初步看起來都非常美好,很符合微服務(wù)架構(gòu)模式規(guī)范;業(yè)務(wù)服務(wù)組合各種基礎(chǔ)服務(wù),也看起來很美好,也很符合微服務(wù)架構(gòu)模式規(guī)范。
隨著業(yè)務(wù)規(guī)模越來越大,業(yè)務(wù)變化越來越復雜,以上微服務(wù)架構(gòu)模式開始出現(xiàn)各種各樣的查詢復雜度問題;首先,用戶、訂單、商品、支付基礎(chǔ)服務(wù)大概率都需要進行分庫分表重構(gòu),在這之前訂單中心的查詢,進行一次關(guān)聯(lián)查詢,只需要跨幾個基礎(chǔ)服務(wù)查詢,性能與復雜度都還能接受,在這之后,偶然的一次關(guān)聯(lián)查詢,就需要消耗非常多的查詢資源,包括數(shù)據(jù)庫層面、基礎(chǔ)服務(wù)組合調(diào)用層面等。
圖示:訂單中心關(guān)聯(lián)查詢模式,系統(tǒng)復雜度高、查詢資源消耗大
如果能通過快速廉價的增加硬件資源方式繼續(xù)這種微服務(wù)模式,倒也無可厚非,只是越往后可選擇的余地越來越有限。
大寬表架構(gòu)
為了解決微服務(wù)應用架構(gòu)中,跨多個基礎(chǔ)服務(wù) join 聯(lián)合查詢問題,需要引入一種“大寬表”架構(gòu)模式,簡單來說就是將各種需要關(guān)聯(lián)的基礎(chǔ)服務(wù)數(shù)據(jù)提前關(guān)聯(lián)計算好,并存儲到一個強悍的數(shù)據(jù)產(chǎn)品中,基于此數(shù)據(jù)產(chǎn)品提煉新的基礎(chǔ)服務(wù)或者業(yè)務(wù)服務(wù),取名“xx數(shù)據(jù)服務(wù)”,以數(shù)據(jù)關(guān)聯(lián)為導向融入到微服務(wù)架構(gòu)體系之中。
數(shù)據(jù)架構(gòu)模式
圖示:訂單中心關(guān)聯(lián)查詢,由數(shù)據(jù)服務(wù)提供
如圖所示,訂單中心的各種復雜查詢由訂單維度數(shù)據(jù)服務(wù)完成,數(shù)據(jù)服務(wù)獨立于基礎(chǔ)服務(wù),與基礎(chǔ)服務(wù)屬于同一服務(wù)層次,數(shù)據(jù)服務(wù)依賴的數(shù)據(jù)庫采用大寬表模式構(gòu)建,數(shù)據(jù)來源于其它數(shù)據(jù)庫同步,或離線同步或?qū)崟r同步。
數(shù)據(jù)庫范式
圖示:數(shù)據(jù)庫范式示意圖,來自百度百科
我們知道,在設(shè)計數(shù)據(jù)庫表模型,必須要遵守數(shù)據(jù)庫范式,已知目前有五種,通常意義到第三范式就差不多了,但是在面對日益復雜的應用場景,反過來大大約束了數(shù)據(jù)產(chǎn)品的能力,進而導致微服務(wù)架構(gòu)模式的性能問題。
在此場景下,我們還有必要遵守范式約束嗎?答案是的,還是需要遵守,不過換個說法“反范式”。如訂單中心圖示,先必須有基礎(chǔ)服務(wù),然后才能有數(shù)據(jù)數(shù)據(jù),數(shù)據(jù)服務(wù)底層數(shù)據(jù)數(shù)據(jù)模型采用反范式設(shè)計,數(shù)據(jù)來源基礎(chǔ)服務(wù),自己不生產(chǎn)數(shù)據(jù),不修改數(shù)據(jù),也不保證數(shù)據(jù)的 ACID ,僅僅是為了查詢存在。
數(shù)據(jù)同步
在大寬表架構(gòu)模式下,數(shù)據(jù)服務(wù)不負責數(shù)據(jù)的產(chǎn)生與維護,數(shù)據(jù)來源于基礎(chǔ)服務(wù),從基礎(chǔ)服務(wù)到數(shù)據(jù)服務(wù),中間需要打通數(shù)據(jù)同步,解決了數(shù)據(jù)同步關(guān)鍵問題,也就解決了微服務(wù)架構(gòu)模式與數(shù)據(jù)架構(gòu)模式融合。
圖示:實時同步與離線同步示意圖
數(shù)據(jù)同步包含實時同步與離線同步,實時同步多數(shù)采用數(shù)據(jù)庫支持的 WAL 機制完成,如 Mysql-Binlog ;離線同步有更多的選擇方式,如 DataX 工具等。此處不深入展開數(shù)據(jù)同步話題,可以參考筆者歷史文章或公開分享內(nèi)容。
用 ES 承載大寬表架構(gòu)模式
為什么選擇 Elasticsearch 來承載數(shù)據(jù)服務(wù),實現(xiàn)大寬表架構(gòu)模式?以下簡單說幾點?
首先,ES最核心的是倒排索算法,支持任意復雜條件組合查詢,大寬表的目的就是為了便于數(shù)據(jù)查詢檢索,而不必定制化的指定字段創(chuàng)建索引,同比傳統(tǒng)數(shù)據(jù)庫左側(cè)原則檢索算法,要靈活很多;
其次,ES數(shù)據(jù)模型構(gòu)造基于 Free Schema 理念,應用層面采用 Json 填充,支持局部數(shù)據(jù)變更,提供了非常靈活的機制,大寬表模式數(shù)據(jù)構(gòu)建時,原則上無法保證所有關(guān)聯(lián)數(shù)據(jù)表完全同步更新,有了這種靈活模式,就不必拘泥于此;
最后, ES 架構(gòu)設(shè)計的特性,分布式架構(gòu),支持橫向擴展,支持超大集群規(guī)模,數(shù)據(jù)層面采用分片與副本機制,保障性能與高可用等。
圖示:ES分布式架構(gòu),數(shù)據(jù)分片與副本
結(jié)語
當傳統(tǒng)微服務(wù)架構(gòu)面臨海量數(shù)據(jù)檢索困境時,不要試圖繼續(xù)在微服務(wù)架構(gòu)模式中優(yōu)化,記得嘗試數(shù)據(jù)架構(gòu)轉(zhuǎn)變,將大寬表架構(gòu)模式融入其中。
參考文獻
關(guān)于作者
Elastic King 數(shù)據(jù)領(lǐng)域?qū)<?/p>
- Elastic Stack 國內(nèi)頂尖實戰(zhàn)專家
- ELastic Stack 技術(shù)社區(qū)分享嘉賓
- 國內(nèi)首批Elastic 官方認證工程師21人之一
- 阿里云MVP(大數(shù)據(jù)領(lǐng)域)
- DBAPlus MVP(原創(chuàng)內(nèi)容貢獻者)