一般的系統(tǒng)總是由小到大發(fā)展的。一開(kāi)始使用一個(gè)數(shù)據(jù)庫(kù),而后逐漸擴(kuò)展。在分庫(kù)過(guò)程中經(jīng)常使用對(duì)特定的鍵值進(jìn)行hash的辦法進(jìn)行分庫(kù)分表。但是使用hash來(lái)進(jìn)行分庫(kù)分表,在具體的應(yīng)用中可能不能滿足需求。比如,在SAAS平臺(tái)下,不同租戶的數(shù)據(jù)量是千差萬(wàn)別的,根據(jù)二八現(xiàn)象,20%的租戶可能占用了80%的存儲(chǔ)資源。如果使用hash算法,很可能導(dǎo)致數(shù)據(jù)分布不均勻。
這里提出一個(gè)分庫(kù)分表算法,解決SAAS平臺(tái)下,數(shù)據(jù)存儲(chǔ)的二八現(xiàn)象。
元數(shù)據(jù)準(zhǔn)備
1. 業(yè)務(wù)數(shù)據(jù)按照租戶ID進(jìn)行分庫(kù)。
2. 用一張表存儲(chǔ),租戶ID->虛擬庫(kù)ID的映射關(guān)系,(可在啟動(dòng)后,導(dǎo)入內(nèi)存)。
3. 用另一張表存儲(chǔ),虛擬庫(kù)ID->實(shí)際庫(kù)連接信息(也可以在啟動(dòng)后,導(dǎo)入內(nèi)存)。
業(yè)務(wù)數(shù)據(jù)存取
1. 需要存儲(chǔ)數(shù)據(jù)前,先根據(jù)租戶ID(數(shù)據(jù)中總是帶有租戶ID),切換數(shù)據(jù)源
2. 數(shù)據(jù)源查找的過(guò)程,基本上是對(duì)上述兩張?jiān)獢?shù)據(jù)表進(jìn)行查找,先找到虛擬庫(kù)ID,進(jìn)而找到實(shí)際的庫(kù)連接信息。
3. 需要提取數(shù)據(jù)時(shí),也按照上述方法找到實(shí)際的庫(kù)連接信息,進(jìn)行數(shù)據(jù)源切換。
分析
1. 之所以使用兩張表而不是一張表(直接租戶ID->實(shí)際庫(kù)連接信息),是為了便于管理。及減少內(nèi)存消耗。
2. 可以在虛擬庫(kù)ID上進(jìn)行某種業(yè)務(wù)劃分,如,分為散戶,小客戶,普通客戶,大客戶,超大客戶。被劃分在同一個(gè)虛擬庫(kù)ID上的租戶必將共享一個(gè)實(shí)際的物理庫(kù)。所以在開(kāi)始規(guī)劃的時(shí)候,應(yīng)當(dāng)盡量均勻地將租戶分配到不同的虛擬庫(kù)ID上。
3. 在虛擬庫(kù)ID上的數(shù)據(jù)是基本均勻的假設(shè)下,就可以將虛擬庫(kù)ID映射到實(shí)際的物理庫(kù)上。
4. 在物理庫(kù)擴(kuò)展的情況下,可以將部分虛擬庫(kù)ID的數(shù)據(jù),遷移到新的物理庫(kù)上。
實(shí)際案例模擬
1. 租戶A被分配了虛擬庫(kù)#12;虛擬庫(kù)#12實(shí)際處于物理庫(kù)#1上。
2. 由于物理庫(kù)#1已經(jīng)負(fù)載過(guò)重,決定擴(kuò)展一個(gè)物理庫(kù)#5,并把虛擬庫(kù)#12遷移到物理庫(kù)#5.
3. 停機(jī)(不知道有沒(méi)有更好的辦法),將虛擬庫(kù)#12的數(shù)據(jù)導(dǎo)出,導(dǎo)入到物理庫(kù)#5中。注意,此時(shí)虛擬庫(kù)#12的數(shù)據(jù)同時(shí)在#1和#5上。
4. 切換元數(shù)據(jù)表,進(jìn)行驗(yàn)證。如果驗(yàn)證通過(guò),則,擇機(jī)回收物理庫(kù)#1上的數(shù)據(jù)空間;如果驗(yàn)證失敗,恢復(fù)元數(shù)據(jù)信息,找到失敗原因,下次再做數(shù)據(jù)遷移。
利弊分析
1. 引入虛擬庫(kù)的原因是:一次可以將有邏輯關(guān)聯(lián)的一組租戶一并遷移,減少維護(hù)成本。
2. 該算法仍舊不支持“不停機(jī)”數(shù)據(jù)遷移,可能都不支持“部分停機(jī),大部分不停機(jī)”數(shù)據(jù)遷移。