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 性能還是比較吃緊, 所以我們想到了分庫分表的方案
這里是中間我所提出的問題和備選方案
或者說User 登錄的User 表數(shù)據(jù)存儲在什么地方。
這里有兩個方案:
Pros and crons
pros: 實現(xiàn)簡單
crons: 存在單點, 一旦引導(dǎo)庫掛了, 所有用戶都不可登錄
Pros and crons
pros:不存在登錄的單點問題;
corns:
經(jīng)過討論定下了第二套方案
我們以前DB中各表中的primary Key都是以Numberic 作為表字段類型, 輔以對ID 字段建sequence 來保證自增長來做到唯一的; 那么分庫以后問題來了, 不同庫中根據(jù)seq 生成的ID 會出現(xiàn)重復(fù)的, 這個對業(yè)務(wù)上是不允許的, 會導(dǎo)致數(shù)據(jù)正確性的問題;
這里有兩個方案:
方案1.
在cache 中使用external_ID 為key
Pros and crons
pros: 增加的冗余字段external_ID 不需要做復(fù)雜的業(yè)務(wù)邏輯
crons:
方案2.
Pros and crons
pros:
crons:分庫數(shù)據(jù)遷移過程中, 有若干業(yè)務(wù)表還沒有Customer_ID字段冗余, 這個需要做前期的準備
經(jīng)過討論定下了第二套方案
根據(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/ 的博客