利用Sharding-Jdbc實(shí)現(xiàn)分表

你們團(tuán)隊(duì)使用SpringMVC+Spring+JPA框架枉证,快速開發(fā)了一個(gè)NB的系統(tǒng),上線后客戶訂單跟雪花一樣紛沓而來。

慢慢地历筝,你的心情開始變差,因?yàn)榭蛻艉彤a(chǎn)品的抱怨越來越頻繁廊谓,抱怨的最多的一個(gè)問題就是:系統(tǒng)越來越慢了梳猪。

1?常規(guī)優(yōu)化

你組織團(tuán)隊(duì),進(jìn)行了一系列的優(yōu)化蒸痹。

1.1?數(shù)據(jù)表索引優(yōu)化

經(jīng)過初步分析春弥,發(fā)現(xiàn)瓶頸在數(shù)據(jù)庫。WEB服務(wù)器的CPU閑來無事叠荠,但數(shù)據(jù)庫服務(wù)器的CPU使用率高居不下匿沛。

于是,請(qǐng)來架構(gòu)組的DBA同事榛鼎,監(jiān)控?cái)?shù)據(jù)庫的訪問逃呼,整理出那些耗時(shí)的SQL,并且進(jìn)行SQL查詢分析者娱。根據(jù)分析結(jié)果抡笼,對(duì)數(shù)據(jù)表索引進(jìn)行重新整理。同時(shí)也對(duì)數(shù)據(jù)庫本身的參數(shù)設(shè)置進(jìn)行了優(yōu)化黄鳍。

優(yōu)化后推姻,頁面速度明顯提升,客戶抱怨減少框沟,又過了一段時(shí)間的安逸日子藏古。

1.2?多點(diǎn)部署+負(fù)載均衡

慢慢的,訪問速度又不行了忍燥,這次是WEB服務(wù)器壓力很大拧晕,數(shù)據(jù)庫服務(wù)器相對(duì)空閑。經(jīng)過分析灾前,發(fā)現(xiàn)是系統(tǒng)并發(fā)用戶數(shù)太多防症,單WEB服務(wù)器不能夠支持如此眾多的并發(fā)請(qǐng)求。

于是,請(qǐng)架構(gòu)協(xié)助進(jìn)行WEB多點(diǎn)部署蔫敲,前端使用nginx做負(fù)載分發(fā)饲嗽。這時(shí)候必須要解決的一個(gè)問題就是用戶會(huì)話保持的問題。這可以有幾種不同解決方案:

1奈嘿、nginx實(shí)現(xiàn)sticky分發(fā)

因?yàn)閚ginx缺省沒有sticky機(jī)制貌虾,可以使用ip_hash方式來代替。

2裙犹、配置Tomcat實(shí)現(xiàn)Session復(fù)制

3尽狠、代碼使用SpringSession,利用redis實(shí)現(xiàn)session復(fù)制叶圃。

具體做法就不一一介紹了袄膏。其中使用SpringSession的方法,可以參考我的文章《集群環(huán)境CAS的問題及解決方案》掺冠。

2?試用當(dāng)當(dāng)?shù)腟harding JDBC框架

多點(diǎn)部署之后沉馆,系統(tǒng)又運(yùn)行了一段時(shí)間,期間增加了更多的WEB節(jié)點(diǎn)德崭,基本能應(yīng)對(duì)客戶需求斥黑。慢慢的,增加WEB服務(wù)器也不能解決問題了眉厨,因?yàn)橄到y(tǒng)瓶頸又回到了數(shù)據(jù)庫服務(wù)器锌奴。SQL執(zhí)行時(shí)間越來越長,而且無法優(yōu)化憾股。原因也很簡單鹿蜀,數(shù)據(jù)量太大。

單表數(shù)據(jù)已經(jīng)超過幾千萬行荔燎,通過數(shù)據(jù)庫的優(yōu)化已經(jīng)不能滿足速度的要求耻姥。分庫分表提到了日程上,必須解決有咨。

因?yàn)槭褂昧薐PA琐簇,如果分庫分表需要對(duì)數(shù)據(jù)訪問層做較大的改動(dòng),工作量太大座享,修改的風(fēng)險(xiǎn)也太高婉商。恰好看到當(dāng)當(dāng)開源了其Sharding-JDBC組件,摘抄一段介紹:

https://github.com/dangdangdotcom/sharding-jdbc

Sharding-JDBC直接封裝JDBC API渣叛,可以理解為增強(qiáng)版的JDBC驅(qū)動(dòng)丈秩,舊代碼遷移成本幾乎為零:

可適用于任何基于java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC淳衙。

可基于任何第三方的數(shù)據(jù)庫連接池蘑秽,如:DBCP, C3P0, BoneCP, Druid等饺著。

理論上可支持任意實(shí)現(xiàn)JDBC規(guī)范的數(shù)據(jù)庫。雖然目前僅支持MySQL肠牲,但已有支持Oracle幼衰,SQLServer,DB2等數(shù)據(jù)庫的計(jì)劃缀雳。

它支持JPA渡嚣,可以在幾乎不修改代碼的情況下完成分庫分表的實(shí)現(xiàn)。因此肥印,選擇這個(gè)框架做一次分庫分表的嘗試识椰。

先做一個(gè)最簡單的試用,不做分庫深碱,僅做分表腹鹉。選擇數(shù)據(jù)表operate_history,這個(gè)數(shù)據(jù)表記錄所有的操作歷史莹痢,是整個(gè)系統(tǒng)中數(shù)據(jù)量最大的一個(gè)數(shù)據(jù)表种蘸。

希望將這個(gè)表拆分為四個(gè)數(shù)據(jù)表,分別是 operate_history_0operate_history_1 operate_history_2 operate_history_3竞膳。數(shù)據(jù)能夠分配保存到四個(gè)數(shù)據(jù)表中,降低單表的數(shù)據(jù)量诫硕。同時(shí)坦辟,為了盡量減少跨表的查詢操作,決定使用字段 entity_key為分表依據(jù)章办,這樣同一個(gè)entity對(duì)象的所有操作锉走,將會(huì)記錄在同一個(gè)數(shù)據(jù)表中。拆分后的數(shù)據(jù)表結(jié)構(gòu)為:

3 實(shí)現(xiàn)過程

以下是針對(duì)JPA項(xiàng)目的修改過程藕届。其他項(xiàng)目請(qǐng)參考官方網(wǎng)站的文檔挪蹭。

3.1?修改pom.xml增加dependency

需要添加兩個(gè)jar,sharding-jdbc-core和sharding-jdbc-config-spring休偶。

? com.dangdang

?sharding-jdbc-core

? 1.3.0

? com.dangdang

? sharding-jdbc-config-spring

? 1.3.0

3.2?修改Spring中Database部分的配置

原Database配置

?

?

?

?

修改后的配置

?

?

?

?

?sharding-columns="entity_key"

?algorithm-class="cn.codestory.sharding.SingleKeyTableShardingAlgorithm"/>

?

?


???actual-tables="operate_history_0,operate_history_1,operate_history_2,operate_history_3"

???table-strategy="historyTableStrategy" />



3.3?編寫類SingleKeyTableShardingAlgorithm

這個(gè)類用來根據(jù)entity_key值確定使用的分表名梁厉。參考sharding提供的示例代碼進(jìn)行修改。核心代碼如下

publicCollection doInSharding(

???????? CollectionavailableTargetNames,

???????? ShardingValueshardingValue) {

?int targetCount = availableTargetNames.size();

?Collection result = newLinkedHashSet<>(targetCount);

?Collection values =shardingValue.getValues();

?for (Long value : values) {

? for (String tableNames :availableTargetNames) {

?? if (tableNames.endsWith(value % targetCount+ "")) {

??? result.add(tableNames);

?? }

? }

?}

?return result;

}

這是一個(gè)簡單的實(shí)現(xiàn)踏兜,對(duì)entity_key進(jìn)行求模词顾,用余數(shù)確定數(shù)據(jù)表名。

3.4?修改主鍵生成方法

因?yàn)閿?shù)據(jù)分表保存碱妆,不能使用identify方式生成數(shù)據(jù)表主鍵肉盹。如果主鍵是String類型,可以考慮使用uuid生成方法疹尾,但它查詢效率會(huì)相對(duì)比較低上忍。

如果使用long型主鍵骤肛,可以使用其他方式,一定要確保各個(gè)子表中的主鍵不重復(fù)窍蓝。

3.5?歷史數(shù)據(jù)的處理

根據(jù)數(shù)據(jù)分表的規(guī)則萌衬,需要對(duì)原有數(shù)據(jù)包的數(shù)據(jù)進(jìn)行遷移,分別移動(dòng)到四個(gè)數(shù)據(jù)表中它抱。如果不做這一步秕豫,或者數(shù)據(jù)遷移到了錯(cuò)誤的數(shù)據(jù)表,后續(xù)將會(huì)查詢不到這些數(shù)據(jù)观蓄。

至此混移,對(duì)項(xiàng)目的修改基本完成,重新啟動(dòng)項(xiàng)目并增加operate_history數(shù)據(jù)侮穿,就會(huì)看到新添加的數(shù)據(jù)歌径,已經(jīng)根據(jù)我們的分表規(guī)則,插入到了某一個(gè)數(shù)據(jù)表中亲茅。查詢的時(shí)候回铛,能夠同時(shí)查詢到多個(gè)實(shí)際數(shù)據(jù)表中的數(shù)據(jù)。

4?數(shù)據(jù)分表規(guī)則的一些考慮

前面的例子克锣,演示的是根據(jù)entity_key進(jìn)行分表茵肃,也可以使用其他字段如主鍵進(jìn)行分表。以下是我想到的一些分表規(guī)則:

根據(jù)主鍵進(jìn)行分配

這種方式能夠?qū)崿F(xiàn)最平均的分配方法袭祟,每生成一條新數(shù)據(jù)验残,會(huì)依次保存到下一個(gè)數(shù)據(jù)表中。

根據(jù)用戶ID進(jìn)行分配

這種方式能夠確保同一個(gè)用戶的所有數(shù)據(jù)保存在同一個(gè)數(shù)據(jù)表中巾乳。如果經(jīng)常按用戶id查詢數(shù)據(jù)您没,這是比較經(jīng)濟(jì)的一種做法。

根據(jù)某一個(gè)外鍵的值進(jìn)行分配

前面的例子采用的就是這種方法胆绊,因?yàn)檫@個(gè)數(shù)據(jù)可能會(huì)經(jīng)常根據(jù)這個(gè)外鍵進(jìn)行查詢氨鹏。

根據(jù)時(shí)間進(jìn)行分配

適用于一些經(jīng)常按時(shí)間段進(jìn)行查詢的數(shù)據(jù),將一個(gè)時(shí)間段內(nèi)的數(shù)據(jù)保存在同一個(gè)數(shù)據(jù)表中压状。比如訂單系統(tǒng)仆抵,缺省查詢一個(gè)月之內(nèi)的數(shù)據(jù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末何缓,一起剝皮案震驚了整個(gè)濱河市肢础,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碌廓,老刑警劉巖传轰,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谷婆,居然都是意外死亡慨蛙,警方通過查閱死者的電腦和手機(jī)辽聊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來期贫,“玉大人跟匆,你說我怎么就攤上這事⊥常” “怎么了玛臂?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長封孙。 經(jīng)常有香客問我迹冤,道長,這世上最難降的妖魔是什么虎忌? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任泡徙,我火速辦了婚禮,結(jié)果婚禮上膜蠢,老公的妹妹穿的比我還像新娘堪藐。我一直安慰自己,他們只是感情好挑围,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布礁竞。 她就那樣靜靜地躺著,像睡著了一般贪惹。 火紅的嫁衣襯著肌膚如雪苏章。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天奏瞬,我揣著相機(jī)與錄音,去河邊找鬼泉孩。 笑死硼端,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寓搬。 我是一名探鬼主播珍昨,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼句喷!你這毒婦竟也來了镣典?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤唾琼,失蹤者是張志新(化名)和其女友劉穎兄春,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锡溯,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赶舆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年哑姚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芜茵。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叙量,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出九串,到底是詐尸還是另有隱情绞佩,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布猪钮,位于F島的核電站品山,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏躬贡。R本人自食惡果不足惜谆奥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拂玻。 院中可真熱鬧酸些,春花似錦、人聲如沸檐蚜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闯第。三九已至市栗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咳短,已是汗流浹背填帽。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咙好,地道東北人篡腌。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像勾效,于是被迫代替她去往敵國和親嘹悼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 目錄;(一) 拆分實(shí)施策略和示例演示(二) 全局主鍵生成策略(三) 關(guān)于使用框架還是自主開發(fā)以及sharding實(shí)...
    linking12閱讀 10,468評(píng)論 1 52
  • 一.sharding jdbc簡介(這里你可以不看) 首先层宫,我要在這里先介紹一下sharding jdbc:Sha...
    1994_老葉閱讀 28,511評(píng)論 9 51
  • 舊時(shí)春風(fēng)笑影重杨伙,櫻花滿樹紅。 草長鶯飛蝶引夢(mèng)萌腿,月瘦花香濃限匣。 故地重游晨霜重,舊景處處空哮奇。 花月不改舊音容膛腐,時(shí)遷人不同睛约。
    那一年t閱讀 280評(píng)論 0 0
  • 太熱了 汗珠泌出毛孔 順著皮膚一點(diǎn)點(diǎn)往下走 有點(diǎn)異樣的感覺 以前我只想趕快擦點(diǎn) 保持干爽 不知道為什么 我任由越來...
    路人賈1閱讀 207評(píng)論 0 1