java - 微服務架構(gòu)下跨服務查詢的聚合有什么好的方案?
問題描述
微服務架構(gòu)中,每個服務都有自己的獨立數(shù)據(jù)庫。然而現(xiàn)在有個需求,需要生成一張實時的報表,該報表包含兩個服務的數(shù)據(jù)。如服務A,服務B。B中僅包含A的主鍵id作為關聯(lián)。而此報表的搜索條件包含A服務實體中的字段也包含B服務實體中的字段。
現(xiàn)有方案1、如果搜索條件中包含A的條件,則先去服務A中搜索,得到所有結(jié)果的主鍵,在服務B中使用where A.id IN (ids) 再次查詢想法:當A.id數(shù)量龐大時,這個查詢極其緩慢! 而A.id數(shù)量龐大的情況很多
2、使用搜索引擎
想法:感覺殺雞用牛刀
請教各位大牛有更好的方案嗎
問題解答
回答1:瀉藥
如果是線上業(yè)務數(shù)據(jù)(OLTP),那么方案一是微服務的標準做法。如果線上要頻繁做這種關聯(lián)的查詢,就說明兩個服務(及其兩個庫)的耦合非常嚴重,那當初何必要把它們拆開來呢?
如果是分析報表,那就屬于OLAP范疇了,方案二確實是一種可取的方案。如果使用搜索引擎覺得殺雞用牛刀的話,不妨試試在從庫上做各種報表分析操作,比如線上的A庫和B庫都實時同步到一個只讀庫中,然后在只讀庫里JOIN一下就搞定了。
回答2:微服務的一個設計原則是業(yè)務沒有關聯(lián)的服務拆開成單獨的服務,你這個業(yè)務之間有交叉了。
回答3:其實這種問題在微服務中很常見,比如說需要通過商品上的一些信息查詢訂單,訂單和商品分別屬于兩個微服務,該類問題的解決方案除了你自己兩種方案,還有
將數(shù)據(jù)聚合放入數(shù)據(jù)倉庫,實時聚合A和B中的數(shù)據(jù)放入另外一個庫中(不一定是mysql,也可以是Hbase),報表拉的數(shù)據(jù)都從數(shù)據(jù)倉庫中拉去
表設計的時候適當冗余一些字段,就如你說的在B上可預見性的冗余一些A的字段
方法1有一個很致命的缺點,一旦涉及到分頁,這種方式必定不可行.具體采用哪種方案,還是需要根據(jù)你的數(shù)據(jù)對應的數(shù)量級來決定,如果對應的數(shù)據(jù)量不是很大,可以采用方法1,如果速度比較慢,可以多開幾個線程分批撈相應的數(shù)據(jù)(id數(shù)量太多分批拉,批量查詢都是可以減少超時情況和時間的有效解決方案);如果數(shù)據(jù)量很大,建議采用數(shù)據(jù)倉庫的方式,采用數(shù)據(jù)倉庫的主要好處是,對主庫不會產(chǎn)生壓力,因為聚合表的產(chǎn)生可以通過Binlog來獲取;因為報表還是屬于離線數(shù)據(jù)的范疇,如果真的需要像訂單查詢那樣實時,效率很高期間還伴隨著狀態(tài)的該表,并且搜索條件巨多無比,那么搜索引擎是一個很好的選擇所以,可以根據(jù)實際情況采用方法1和方法3
回答4:生成報表這樣的需求就不應該放在業(yè)務數(shù)據(jù)庫系統(tǒng)中,你可以在后端做一套otter匯聚庫,實時同步多個服務的數(shù)據(jù)進來,然后在這個匯聚庫中你想怎么玩就怎么玩
相關文章:
1. docker - 各位電腦上有多少個容器啊?容器一多,自己都搞混了,咋辦呢?2. java - spring boot 如何打包成asp.net core 那種獨立應用?3. java - 在用戶不登錄的情況下,用戶如何添加保存到購物車?4. datetime - Python如何獲取當前時間5. javascript - nginx反向代理靜態(tài)資源403錯誤?6. docker網(wǎng)絡端口映射,沒有方便點的操作方法么?7. 安全性測試 - nodejs中如何防m(xù)ySQL注入8. javascript - 關于apply()與call()的問題9. docker start -a dockername 老是卡住,什么情況?10. python - 調(diào)用api輸出頁面,會有標簽出現(xiàn),請問如何清掉?
