DB 分庫分表專案改造心得

2021-09-01 14:05:01 字數 2227 閱讀 2874

目前筆者在主導公司乙個已有產品的改造專案, 目前在方案討論階段。

先介紹下目前系統的現狀, 目前系統中訂單相關的資料日新增量已經到了百萬級別,圍繞訂單相關的訂單分揀, 打包,發貨相關操作的transaction 達到近千萬級別每日。 在做了歷史歸檔以後, db 效能還是比較吃緊, 所以我們想到了分庫分表的方案

這裡是中間我所提出的問題和備選方案

或者說user 登入的user 表資料儲存在什麼地方。

這裡有兩個方案:

所有user 表相關的crud 操作都在乙個含有user 表的引導庫上進行, 其他業務庫不需要user 表;

高階許可權使用者的新建使用者, 更新和刪除使用者操作都會根據操作型別被路由到引導庫上進行

使用者的登入操作(讀 user 表操作) 也會被路由到引導庫上進行

pros  and  crons

pros: 實現簡單

crons: 存在單點, 一旦引導庫掛了, 所有使用者都不可登入

所有寫操作在引導庫上發生, 寫操作限定在引導庫上是為了使用我們user 表中的id sequence 保證id唯一和便於同步

各業務庫中也存在user 表, 業務庫上user 表只做讀操作, 引導庫上和業務庫之間使用db 複製工具對user 表資料做同步複製。

登入操作可以任選引導庫和業務庫中的任何乙個db 例項做登入操作

pros  and  crons

pros:不存在登入的單點問題;

corns:

需要對db做額外的同步, 不過相對來說這個代價還不是太高;

新建使用者後的時效性依賴於db 複製的時效性;

經過討論定下了第二套方案

我們以前db中各表中的primary key都是以numberic 作為表字段型別, 輔以對id 欄位建sequence 來保證自增長來做到唯一的; 那麼分庫以後問題來了, 不同庫中根據seq 生成的id 會出現重複的, 這個對業務上是不允許的, 會導致資料正確性的問題;

這裡有兩個方案:

方案1.

保留老的numberic 的id 字段,

再新增char 型別的external_id 字段,external_id 欄位對應用來說可讀不可寫, 

各庫對各表建create trigger, 在新增完成以後 external_id = $+ "_"+ $ + "_"+ $,

應用根據external_id 中的$ 做read,update 和delete 的db路由;

$ 和 $根據商戶id 和base 表名做規則匹配產生, 這個規則也就是固化在db的trigger 中

在cache 中使用external_id 為key

pros  and  crons

pros: 增加的冗餘欄位external_id 不需要做複雜的業務邏輯

crons:

今後如果要把 db1 中的部分資料遷移到新增的db 中去的時候需要對資料進行清洗(update external_id)

需要新增大量的trigger, 會帶來dba 大量的工作

trigger 會帶來插入操作額外的db 開銷

方案2.

保留老的numberic 的id 字段, 為每個表新增customer_id的冗餘字段,

pros  and  crons

pros:

不需要大量的trigger帶來的額外開銷

可以根據customer_id和db 的對應關係自由的建立db 路由規則, 今後如果把某個db 例項中的部分customer_id相關的資料遷移到新的例項中, 只要更改路由規則就可以了, 可以對db 和應用的業務層透明

crons:分庫資料遷移過程中, 有若干業務表還沒有customer_id欄位冗餘, 這個需要做前期的準備

經過討論定下了第二套方案

根據我們現在的業務模型, 按照customer_id 做水平切分以後, 讓客戶相關的操作在乙個request 訪問的生命週期的db hit 都落在乙個db 例項上, 從而規避掉這個問題。

talk is cheap, show me the code. 

好吧, 我來上**, 這個demo 是基於mybatis 官網上的jpetstore 的例子, 這個例子做了以下幾個功能點的演示:

1. 根據規則hit 到不同的db 例項(例項0 和例項1)上

2. 在db 例項0 上, 我們對product 表做了分表處理, 根據規則hit 不同的表

它的實現思路是:

2. 分表實現: 使用開源框架shardbatis, 詳細資訊可以參考 的部落格

mysql分表分庫實現 MySql分表分庫思路

一.資料庫瓶頸 1.1io瓶頸 第一種 磁碟讀io瓶頸,熱點資料太多,資料庫快取放不下,每次查詢時會產生大量的io 分庫和垂直分表 第二種 網路io瓶頸,請求的資料太多,網路頻寬不夠 分庫 1.2cpu瓶頸 第一種 sql問題,如sql中包含join,group by,order by,非索引字段條...

MySQL範圍分表分庫 mysql 分表分庫策略

唯一id的生成 下面列舉幾種常見的唯一id生成方案,需要滿足兩大核心需求 1.全域性唯一 2趨勢有序 1.用資料庫的auto increment 自增id 來生成,每次通過寫入資料庫一條記錄,利用資料庫id自增的特性獲取唯一,有序的id。優點 使用資料庫原有的功能,相對簡單 能夠保證唯一 能夠保證遞...

mysql 分庫分表實戰 MySQL分庫分表實戰

為什麼要分庫分表 在大型 中,當使用者量以及使用者產生的業務資料量達到單庫單錶效能極限時,為了支撐業務可持續發展,對於重要的核心業務必然要進行分庫分表來儲存業務資料。對於非核心業務產生的大量資料,例如爬蟲爬取的資訊,論壇產生的資料等,可以考慮把資料儲存在像mongodb這樣的nosql儲存裡面,這些...