国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
DB 分庫分表項目改造心得

http://wangbt5191-hotmail-com.iteye.com/blogs/1736589

 

目前筆者在主導(dǎo)公司一個已有產(chǎn)品的改造項目, 目前在方案討論階段。

先介紹下目前系統(tǒng)的現(xiàn)狀, 目前系統(tǒng)中訂單相關(guān)的數(shù)據(jù)日新增量已經(jīng)到了百萬級別,圍繞訂單相關(guān)的訂單分揀, 打包,發(fā)貨相關(guān)操作的transaction 達到近千萬級別每日。 在做了歷史歸檔以后, db 性能還是比較吃緊, 所以我們想到了分庫分表的方案

 

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

 

問題1. 分庫以后登錄如何做?

或者說User 登錄的User 表數(shù)據(jù)存儲在什么地方。
   這里有兩個方案:

    方案1:

  1.     所有User 表相關(guān)的CRUD 操作都在一個含有User 表的引導(dǎo)庫上進行, 其他業(yè)務(wù)庫不需要User 表;
  2.     高級權(quán)限用戶的新建用戶, 更新和刪除用戶操作都會根據(jù)操作類型被路由到引導(dǎo)庫上進行
  3.     用戶的登錄操作(讀 User 表操作) 也會被路由到引導(dǎo)庫上進行

    Pros  and  crons
    pros: 實現(xiàn)簡單
    crons: 存在單點, 一旦引導(dǎo)庫掛了, 所有用戶都不可登錄

    方案2: 是方案1 的折中

  1.  所有寫操作在引導(dǎo)庫上發(fā)生, 寫操作限定在引導(dǎo)庫上是為了使用我們User 表中的ID sequence 保證ID唯一和便于同步
  2.   各業(yè)務(wù)庫中也存在User 表, 業(yè)務(wù)庫上User 表只做讀操作, 引導(dǎo)庫上和業(yè)務(wù)庫之間使用DB 復(fù)制工具對User 表數(shù)據(jù)做同步復(fù)制。
  3.   登錄操作可以任選引導(dǎo)庫和業(yè)務(wù)庫中的任何一個db 實例做登錄操作

    Pros  and  crons
    pros:不存在登錄的單點問題;
    corns:

  1. 需要對DB做額外的同步, 不過相對來說這個代價還不是太高;
  2. 新建用戶后的時效性依賴于DB 復(fù)制的時效性;

 

   經(jīng)過討論定下了第二套方案

問題2. 分庫分表對象ID 如何做到全局唯一?

     我們以前DB中各表中的primary Key都是以Numberic 作為表字段類型, 輔以對ID 字段建sequence 來保證自增長來做到唯一的; 那么分庫以后問題來了, 不同庫中根據(jù)seq 生成的ID 會出現(xiàn)重復(fù)的, 這個對業(yè)務(wù)上是不允許的, 會導(dǎo)致數(shù)據(jù)正確性的問題;
     這里有兩個方案:

    方案1.

  1.     保留老的numberic 的ID 字段,
  2.     再新增char 類型的external_ID 字段,external_ID 字段對應(yīng)用來說可讀不可寫, 
  3.     各庫對各表建create trigger, 在新增完成以后 external_ID = ${db instance number}+ "_"+ ${table_postfix} + "_"+ ${ID},
  4.     應(yīng)用根據(jù)external_ID 中的${db instance number} 做read,update 和delete 的db路由;
  5.     ${db instance number} 和 ${table_postfix}根據(jù)商戶ID 和base 表名做規(guī)則匹配產(chǎn)生, 這個規(guī)則也就是固化在DB的trigger 中

    在cache 中使用external_ID 為key
    Pros  and  crons
    pros: 增加的冗余字段external_ID 不需要做復(fù)雜的業(yè)務(wù)邏輯
        crons:

  1. 今后如果要把 db1 中的部分數(shù)據(jù)遷移到新增的db 中去的時候需要對數(shù)據(jù)進行清洗(update external_ID)
  2.  需要新增大量的trigger, 會帶來DBA 大量的工作
  3.  trigger 會帶來插入操作額外的db 開銷

  


    方案2.

  1.     保留老的numberic 的ID 字段, 為每個表新增Customer_ID的冗余字段,
  2.     業(yè)務(wù)上的新增操作由業(yè)務(wù)層指定Customer_ID, 作為App 中的唯一性ID external_ID 是由 ${Customer_ID} + "_" + ${table_postfix} +"_"+ ${ID} 產(chǎn)生的, 由App自己拼裝, App 也可以根據(jù)Base 表名決定, 某些對象的ID只是 ${table_postfix} +"_"+ ${ID} 或者 ${Customer_ID} + "_" + ${ID}
  3.       在App中, app 以external_ID 作為cache 層的Key, DB 的read, update, delete 操作是做一次split, 拿到Customer_ID根據(jù)db 路由規(guī)則定位db和表, 路由到db中的表后后還是以原始id 來做底層的讀寫。

    Pros  and  crons
        pros:

  1. 不需要大量的trigger帶來的額外開銷
  2. 可以根據(jù)Customer_ID和db 的對應(yīng)關(guān)系自由的建立db 路由規(guī)則, 今后如果把某個db 實例中的部分Customer_ID相關(guān)的數(shù)據(jù)遷移到新的實例中, 只要更改路由規(guī)則就可以了, 可以對DB 和應(yīng)用的業(yè)務(wù)層透明

        crons:分庫數(shù)據(jù)遷移過程中, 有若干業(yè)務(wù)表還沒有Customer_ID字段冗余, 這個需要做前期的準備

 

經(jīng)過討論定下了第二套方案

 

 

問題3. 分庫后跨DB實例的事務(wù)如何處理?

根據(jù)我們現(xiàn)在的業(yè)務(wù)模型, 按照Customer_ID 做水平切分以后, 讓客戶相關(guān)的操作在一個request 訪問的生命周期的DB hit 都落在一個db 實例上, 從而規(guī)避掉這個問題。

 

 

 

代碼演示

Talk is cheap, show me the code. 

好吧, 我來上代碼, 這個Demo 是基于mybatis 官網(wǎng)上的jpetstore 的例子, 這個例子做了以下幾個功能點的演示:

1. 根據(jù)規(guī)則hit 到不同的db 實例(實例0 和實例1)上

2. 在db 實例0 上, 我們對product 表做了分表處理, 根據(jù)規(guī)則hit 不同的表

 

 

它的實現(xiàn)思路是:

1. 分庫實現(xiàn): 是改寫SqlSessionDaoSupport 和MapperFactory Bean , 在SqlSessionDaoSupport 中的 SqlSession sqlSession 屬性換成   List<SqlSession> sqlSessions, 在拿getSqlSession() 方法中寫入規(guī)則來動態(tài)獲取SqlSession;

2. 分表實現(xiàn): 使用開源框架shardbatis, 詳細信息可以參考http://seanhe.iteye.com/ 的博客

 

 

 

 

 

 

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
數(shù)據(jù)庫水平切分的實現(xiàn)原理解析---分庫,分表,主從,集群,負載均衡器
Mysql海量數(shù)據(jù)存儲和解決方案之一
數(shù)據(jù)庫水平切分的實現(xiàn)原理解析
MyCat分庫分表中間件研究
MySQL關(guān)于分庫分表及其平滑擴容方案實例講解
億級訂單數(shù)據(jù)分庫分表設(shè)計方案(含整體架構(gòu)圖)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服