1. 程式人生 > >利用多租戶模式演化成分庫分表和讀寫分離

利用多租戶模式演化成分庫分表和讀寫分離

前言

最近兩週我都發了隨筆寫關於利用EF core實現多租戶,並且給出了一些關於EF 自動遷移的內容。

這個系列的隨筆是想要把這部分的程式碼優化和做成類庫的。

我已經整理和抽象好了,本來想介紹一下整理的思路的。但後來發現這裡的程式碼量太少了,好像沒什麼可以說的。

所以這篇隨筆會講解利用這個類庫可以實現的功能。

 

多租戶介紹

按照系列的隨筆介紹,現在主要支援3種模式。分別是: 按表、按Schema和按資料庫分離資料。

支援的資料庫有MySql和SqlServer,並且在我重構的時候,把Postgre也整合進去了。

通過這次的程式碼重構,程式碼的結構已經不像前面的文章一樣,停留在Demo層面。

程式碼修改後,我的目標是同時支援最基本的多租戶,多租戶演變成讀寫分離。

典型的模式

1. 按資料庫分離的模式,可以看到一個DbContext會同時連線3個不同的資料庫,每個庫裡面都有一個Product表.

 

 2. 按表分離的模式,這裡可以看到一個DbContext只會同時連線一個數據庫,資料庫裡面有3個結構相同的Product表,但是它們的名稱是根據字首區分的。

 

 3. 按Schema分離的模式,這裡是一個DbContext只會同時連線一個數據庫,資料庫裡面有3個Schema,3個Schema同時具有Product表

 

 

在多租戶的場景下的變型

通過通過資料庫的結構,我們能知道,資料庫、Schema和表是有層級關係的。一個數據庫有n個Schema,一個Schema有n個表。

通過這個層級特性,我們是可以把他變型成4種模式:資料庫和表混合模式、資料庫和Schema混合模式、Schema和表混合模式、資料庫和Schema和表混合模式

但一般來說,後面2中模式把更加多的壓力都同時在一個數據庫,並沒有從硬體/資料庫例項方面進行分離,資料量繼續增長的情況下,最終還是需要通過多個數據庫分離資料。

 

1. 資料庫和表混合模式,可以看到DbContext裡面有3個連線分別連線到3個Store Container的資料庫,裡面各自存在3個結構相同的資料表。

通過3個Store container,共有9個租戶

 

 

2. 資料庫和Schema混合模式,一個DbContext裡面有3個連線連線到3個Store Container的資料庫,裡面各自有3個Schema,每個Schema下都有一個結構相同的資料表

通過3個Store Container, 共有9個租戶

 

 

轉變為讀寫分離

在目前的系統中,讀寫分離是的應用更加廣泛。通過下面的圖看出,同一個DbContext下有3個連線分別連結到不同的資料庫。資料庫裡見面有完全相同的表

其中一個是主庫,2個是從庫。

如果對比我們典型的多租戶模式,其實是非常型別的,顯而易見他們之間是可以互相演變的。事實上我專案中其實就是通過多租戶模式下演變成讀寫分離的。

 

讀寫分離&多租戶圖解

我們這裡先看看下圖中的結構。其實這裡的圖就是我整個系列的主要流程。其中有幾個關鍵步驟

A. Http Request通過asp.net core的中介軟體或者攔截器。通過AOP的模式,通過http header和url等, 呼叫Tenant Generator。

B. Tenant Generator根據呼叫的介面引數,獲取這是哪一個租戶和API的操作型別(讀或寫),並且講租戶資訊和操作型別返回

C. Connection Resolver接收租戶和操作資訊的組合,通過配置檔案或配置中心獲取具體的連線字串,並且把連線字串作為引數傳入到DbContext的建構函式。

D. Db Context利用接收到連線字串,通過EF core的封裝,自動連線到不同的資料庫。

注:租戶和操作資訊的組合,拿store1 & read的組合舉個例子,他的配置的連線字串的鍵值是 store_read。同理 store2 & write 的鍵值就是store2_write

 

 通過上圖的結構,其實讀寫分離在我們的封裝下,也是能輕而易舉的實現的。估計讀者來到這裡會發現有3個關鍵元件是需要使用者自定義才能完成。

分別是中介軟體或攔截器、Tenant Generator和Connection Resolver。他們3者需要同時維護和使用一個TenantInfo。

 

總結

好了,來到這裡已經是本文的結束。是的,本文並沒有貼出任何程式碼,僅僅是一個介紹的隨筆。

本文的目的是,讓閱讀者對多租戶和讀寫分離模式有抽象的概念,利用圖和抽象物件儘量描述出這個模式實現下的關鍵是什麼。

從系列的第一篇開始,是對多租戶的入門,之後的隨筆是對該模式的深入理解和加深實施辦法。

經過了前面幾篇文章的基礎,通過本文的抽象概念和之前的實施程式碼進行融合,從而希望讀者能夠系統地瞭解到分庫分表。

 

關於程式碼

由於之前的程式碼都只停留在Demo階段,所以後來我重構了,並且使用了新的Github Repository.

並且我把如何使用的示例程式碼都放在了同一個Repository下。

請到這個github地址下獲取重構的程式碼:

https://github.com/woailibain/kiwiho.EFcore.MultiTenant

對於這份程式碼,由於我也是在最近2天寫的,只做了基礎功能測試,並且事例程式碼量有限,我會隨著系列文章的進行中,不斷補充事例程式碼也同時修復bug。

其中事例程式碼,我會包含今天講到的所有內容。並且我在編寫example的同時,也會發文寫關於怎麼使用,為什麼這樣使用的詳細。

 

往期文章

如果讀者是首次閱讀本系列,建議閱讀系列的其他文章。因為本文是對前文的總結

Asp.net core下利用EF core實現從資料實現多租戶(1)

Asp.net core下利用EF core實現從資料實現多租戶(2) : 按表分離

EF core (code first) 通過自定義 Migration History 實現多租戶使用同一資料庫時更新資料庫結構

EF core (code first) 通過自動遷移實現多租戶資料分離 :按Schema分離資料

&n