微服務架構中,每個服務都有自己的獨立資料庫。
然而現在有個需求,需要生成一張實時的報表,該報表包含兩個服務的資料。
如服務A,服務B。B中僅包含A的主鍵id作為關聯。
而此報表的搜尋條件包含A服務實體中的字段也包含B服務實體中的字段。
現有方案
1、如果搜尋條件中包含A的條件,則先去服務A中搜尋,得到所有結果的主鍵,在服務B中使用where A.id IN (ids) 再次查詢
想法:當A.id數量龐大時,這個查詢極其緩慢! 而A.id數量龐大的情況很多
2、使用搜尋引擎
想法:感覺殺雞用牛刀
請教各位大牛有更好的方案嗎
回答
其實這種問題在微服務中很常見,比如說需要通過商品上的一些資訊查詢訂單,訂單和商品分别屬于兩個微服務,該類問題的解決方案除了你自己兩種方案,還有
将資料聚合放入資料倉庫,實時聚合A和B中的資料放入另外一個庫中(不一定是mysql,也可以是Hbase),報表拉的資料都從資料倉庫中拉去
表設計的時候适當備援一些字段,就如你說的在B上可預見性的備援一些A的字段
方法1有一個很緻命的缺點,一旦涉及到分頁,這種方式必定不可行.具體采用哪種方案,還是需要根據你的資料對應的數量級來決定,如果對應的資料量不是很大,可以采用方法1,如果速度比較慢,可以多開幾個線程分批撈相應的資料(id數量太多分批拉,批量查詢都是可以減少逾時情況和時間的有效解決方案);如果資料量很大,建議采用資料倉庫的方式,采用資料倉庫的主要好處是,對主庫不會産生壓力,因為聚合表的産生可以通過Binlog來擷取;因為報表還是屬于離線資料的範疇,如果真的需要像訂單查詢那樣實時,效率很高期間還伴随着狀态的該表,并且搜尋條件巨多無比,那麼搜尋引擎是一個很好的選擇
是以,可以根據實際情況采用方法1和方法3
瀉藥
如果是線上業務資料(OLTP),那麼方案一是微服務的标準做法。如果線上要頻繁做這種關聯的查詢,就說明兩個服務(及其兩個庫)的耦合非常嚴重,那當初何必要把它們拆開來呢?
如果是分析報表,那就屬于OLAP範疇了,方案二确實是一種可取的方案。如果使用搜尋引擎覺得殺雞用牛刀的話,不妨試試在從庫上做各種報表分析操作,比如線上的A庫和B庫都實時同步到一個隻讀庫中,然後在隻讀庫裡JOIN一下就搞定了。
生成報表這樣的需求就不應該放在業務資料庫系統中,你可以在後端做一套otter彙聚庫,實時同步多個服務的資料進來,然後在這個彙聚庫中你想怎麼玩就怎麼玩
方案一采用in的方式,很多接口都需要通過in的方式查詢,當碰到分頁查詢這種根本不好處理。
方案二感覺還沒到使用搜尋引擎的地步。
1、傳統方式,在業務系統A中存入要查詢的B業務系統的備援資料,便于查詢。
至于這個備援資料何時進入A系統,要看業務。
微服務的一個設計原則是業務沒有關聯的服務拆開成單獨的服務,你這個業務之間有交叉了。
你好,我這邊也有類似的困擾,請問你采用了什麼方案呢