數據庫耦合-解耦

隨着業務越來越複雜,數據量越來越大,併發量越來越大,數據庫的性能越來越低。好不容易找運維申請了兩臺機器,讓DBA部署了幾個實例,想把一些業務庫拆分出來,卻發現拆不出來,擴不了容,尷尬!

 

因爲數據庫強關聯在一起,無法通過增加數據庫實例擴容,就是一個耦合的典型案例。

 

場景還原

有一個公共用戶數據庫DB_USER,裏面table_user存放了通用的用戶數據

table_user (uid, name, passwd, …)

 

在數據量比較小,併發量比較小,業務還沒有這麼複雜的時候,爲了提高資源利用率(程序員纔沒有考慮什麼資源利用率,更多的是圖方便),業務A把用戶個性化的數據也放在這個庫裏:

table_A(uid, A業務的個性化屬性)

 

業務A有一個需求,即要展現用戶公共屬性,又要展現業務A個性化屬性,程序員經常這麼實現的:

select * from table_user, table_A

      where table_user.uid = table_A.uid

      and table_user.uid = $uid

 

初期關聯查詢沒有任何問題,單條記錄訪問,命中索引,一次查詢所有數據,簡單高效。

 

如何產生各業務數據耦合?

通過join實現業務,導致通用表table_user和業務表table_A必須存在於一個數據庫實例裏。


如果業務B也這麼做,業務C也這麼做,會導致公用業務,業務A,業務B,業務C都必須存在於一個數據庫實例


會產生什麼潛在問題呢?

假如A業務線上線了一個新功能,不小心進行了全表掃描,導致數據庫CPU100%,數據庫實例性能下降,由於實例共用,通用業務,業務B和業務C都會受影響。

 

即某個業務線的數據庫性能急劇下降導致所有業務都受影響,這種耦合,歷史總是驚人的相似:

  • 業務B的大boss在羣裏首先發飆:“技術都幹啥了,怎麼系統掛了

  • 業務B的rd一臉無辜:“業務A上線了,所以我們掛了

額,然而,這個理由,好像在大boss那解釋不通…

  • 業務B的大boss:“趕緊加幾臺機器,拆分開

  • 業務B的rd一臉無奈:“加機器加實例也擴容不了

  • 業務B的大boss對業務2的rd吼道“還想甩鍋,拖出去祭天

... 


唉,加了幾臺機器,加了幾個實例,然而並沒有什麼卵用,都耦合在一個實例裏,完全擴不了容。

 

那,如何解除公共數據庫與業務數據庫的耦合?

第一步:公共數據訪問下沉服務化


還是上面的例子,當公共的user數據訪問服務化之後,依據服務化的原則:

  • 業務層只能通過服務RPC接口訪問數據

  • 底層user庫屬於user服務私有

  • 任何上游不允許跨過服務訪問底層的user庫


第二步:垂直拆分,個性化數據訪問上浮

原來業務方:

  • 通過join一次性獲取通用的數據和個性化的業務數據數據

服務化+垂直拆分後,變成兩次訪問:

  • 一次取得業務數據(業務可以直接調用自己的數據庫,也可以自己做業務服務調用RPC接口)

  • 一次取得共性數據(調用通用的RPC接口)


兩種方式相比:

  • 之前的方式其實業務代碼可能會更簡單一些,因爲它是將這個業務邏輯放在了SQL語句中,但是導致數據庫耦合在了一起

  • 後面這種方式就是業務的代碼會更復雜,會變成多次訪問,將原來在SQL中進行的邏輯計算變成業務代碼中的邏輯計算,但是數據庫解耦了

業務複雜,數據量大,併發老大,對擴展性要求更高的架構,一定是後者。


此時各業務有自己的庫,公共有公共的庫:

  • 早期:可以放在一個數據庫實例裏

  • 後期:可以很容易地通過新增數據庫實例,把user庫或者業務A/B/C的庫拆分出來,實現增加機器增加實例就實現擴容


個性業務數據訪問垂直拆分,共性數據訪問服務化下沉,只是一個很小的優化點,但對於數據庫解耦卻是非常的有效。


希望大家每天收穫一點點,這樣架構就能美好一點點。

你痛過嗎,你見過一個庫裏耦合了幾百個表嗎?那幫下。


轉自:https://mp.weixin.qq.com/s/4_HjTSi8cF5BZpK94-oF6w


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章