MySQL筆記(分庫(kù)分表)

摘自 https://zhuanlan.zhihu.com/p/50650224
參考
https://tech.meituan.com/2016/11/18/dianping-order-db-sharding.html
https://crossoverjie.top/2019/07/24/framework-design/sharding-db-03/
https://zhuanlan.zhihu.com/p/50652826

需要考慮分庫(kù)分表的場(chǎng)景

規(guī)劃期內(nèi)的數(shù)據(jù)量和性能問題,嘗試能否用下列方式解決:

  • 當(dāng)前數(shù)據(jù)量:如果沒有達(dá)到幾百萬(wàn)至千萬(wàn)卓箫,通常無(wú)需分庫(kù)分表而账;
  • 數(shù)據(jù)量問題:增加磁盤铐殃、增加分庫(kù)(不同的業(yè)務(wù)功能表,整表拆分至不同的數(shù)據(jù)庫(kù))探颈;
  • 性能問題:升級(jí)CPU/內(nèi)存败匹、讀寫分離、優(yōu)化數(shù)據(jù)庫(kù)系統(tǒng)配置僻肖、優(yōu)化數(shù)據(jù)表/索引、優(yōu)化 SQL卢鹦、分區(qū)檐涝、數(shù)據(jù)表的垂直切分;
  • 最后數(shù)據(jù)表的水平切分。

建議的規(guī)劃期:預(yù)估未來(lái)三年的數(shù)據(jù)量

分庫(kù)分表引入的問題

分布式事務(wù)

若兩階段/三階段提交對(duì)性能損耗過(guò)大谁榜,可改用事務(wù)補(bǔ)償機(jī)制。

跨節(jié)點(diǎn) JOIN

規(guī)避方案
全局表: 一些穩(wěn)定的共用數(shù)據(jù)表凡纳,在各個(gè)數(shù)據(jù)庫(kù)中都保存一份窃植;
字段冗余: 一些常用的共用字段,在各個(gè)數(shù)據(jù)表中都保存一份荐糜;
應(yīng)用組裝:應(yīng)用獲取數(shù)據(jù)后再組裝巷怜。
最近關(guān)聯(lián):某個(gè) ID 的用戶信息在哪個(gè)節(jié)點(diǎn),他的關(guān)聯(lián)數(shù)據(jù)(比如訂單)也在哪個(gè)節(jié)點(diǎn)暴氏,可以避免分布式查詢延塑。

跨節(jié)點(diǎn)聚合

只能在應(yīng)用程序端完成。
但對(duì)于分頁(yè)查詢答渔,每次大量聚合后再分頁(yè)关带,性能欠佳。

節(jié)點(diǎn)擴(kuò)容

節(jié)點(diǎn)擴(kuò)容后沼撕,新的分片規(guī)則導(dǎo)致數(shù)據(jù)所屬分片有變宋雏,因而需要遷移數(shù)據(jù)。

全局ID生成策略

DB自動(dòng)增長(zhǎng)列
  1. 設(shè)置自增偏移和步長(zhǎng)
## 假設(shè)總共有 10 個(gè)分表
## 級(jí)別可選: SESSION(會(huì)話級(jí)), GLOBAL(全局)
SET @@SESSION.auto_increment_offset = 1; ## 起始值, 分別取值為 1~10
SET @@SESSION.auto_increment_increment = 10; ## 步長(zhǎng)增量
  1. 全局ID映射表
    在全局 Redis 中為每張數(shù)據(jù)表創(chuàng)建一個(gè) ID 的鍵务豺,記錄該表當(dāng)前最大 ID磨总;
    每次申請(qǐng) ID 時(shí),都自增 1 并返回給應(yīng)用笼沥;
    Redis 要定期持久至全局?jǐn)?shù)據(jù)庫(kù)蚪燕。
COMB

參考資料:The Cost of GUIDs as Primary Keys
組合 GUID(10字節(jié)) 和時(shí)間(6字節(jié)),達(dá)到有序的效果奔浅,提高索引性能馆纳。

Snowflake

1bit: 符號(hào)位,總是 0(為了保證數(shù)值是正數(shù))乘凸。
41bit: 毫秒數(shù)(可用 69 年)厕诡;
10bit: 節(jié)點(diǎn)ID(5bit數(shù)據(jù)中心 + 5bit節(jié)點(diǎn)ID,支持 32 * 32 = 1024 個(gè)節(jié)點(diǎn))
12bit: 流水號(hào)(每個(gè)節(jié)點(diǎn)每毫秒內(nèi)支持 4096 個(gè) ID营勤,相當(dāng)于 409萬(wàn)的 QPS灵嫌,相同時(shí)間內(nèi)如 ID 遇翻轉(zhuǎn),則等待至下一毫秒)

擴(kuò)展開源庫(kù)
UidGenerator
Leaf

分片策略

分片策略 原理 缺點(diǎn) 優(yōu)點(diǎn)
連續(xù)分片 根據(jù)特定字段(比如用戶ID葛作、訂單時(shí)間)的范圍寿羞,值在該區(qū)間的,劃分到特定節(jié)點(diǎn)赂蠢。 如果按時(shí)間劃分绪穆,數(shù)據(jù)熱點(diǎn)分布不均(歷史數(shù)冷當(dāng)前數(shù)據(jù)熱),導(dǎo)致節(jié)點(diǎn)負(fù)荷不均。 集群擴(kuò)容后玖院,指定新的范圍落在新節(jié)點(diǎn)即可菠红,無(wú)需進(jìn)行數(shù)據(jù)遷移。
MOD 根據(jù)ID取模 擴(kuò)容后需要遷移數(shù)據(jù)
一致性Hash算法 環(huán)形hash空間;映射數(shù)據(jù)到環(huán);映射節(jié)點(diǎn)到環(huán);數(shù)據(jù)順時(shí)針取最近節(jié)點(diǎn)存儲(chǔ) 擴(kuò)容后無(wú)需遷移數(shù)據(jù)

分庫(kù)分表方案

方案 原理 中間件
代理層 部署一臺(tái)代理服務(wù)器偽裝成 MySQL 服務(wù)器难菌,代理服務(wù)器負(fù)責(zé)與真實(shí) MySQL 節(jié)點(diǎn)的對(duì)接试溯,應(yīng)用程序只和代理服務(wù)器對(duì)接 MyCAT;
Sharding-Sphere
應(yīng)用層 業(yè)務(wù)層和 JDBC 層中間,是以 JAR 包方式提供給應(yīng)用調(diào)用郊酒,對(duì)代碼有侵入性 Sharding-Sphere

節(jié)點(diǎn)擴(kuò)容方案

常規(guī)方案

如果增加的節(jié)點(diǎn)數(shù)和擴(kuò)容操作沒有規(guī)劃遇绞,那么絕大部分?jǐn)?shù)據(jù)所屬的分片都有變化,需要在分片間遷移:

  1. 預(yù)估遷移耗時(shí)燎窘,發(fā)布停服公告摹闽;
  2. 停服(用戶無(wú)法使用服務(wù)),使用事先準(zhǔn)備的遷移腳本褐健,進(jìn)行數(shù)據(jù)遷移付鹿;
  3. 修改為新的分片規(guī)則;
  4. 啟動(dòng)服務(wù)器铝量。
免遷移擴(kuò)容

采用雙倍擴(kuò)容策略倘屹,避免數(shù)據(jù)遷移。擴(kuò)容前每個(gè)節(jié)點(diǎn)的數(shù)據(jù)慢叨,有一半要遷移至一個(gè)新增節(jié)點(diǎn)中纽匙,對(duì)應(yīng)關(guān)系比較簡(jiǎn)單。
具體操作如下(假設(shè)已有 2 個(gè)節(jié)點(diǎn) A/B拍谐,要雙倍擴(kuò)容至 A/A2/B/B2 這 4 個(gè)節(jié)點(diǎn)):

  1. 無(wú)需停止應(yīng)用服務(wù)器烛缔;
  2. 新增兩個(gè)數(shù)據(jù)庫(kù) A2/B2 作為從庫(kù),設(shè)置主從同步關(guān)系為:A=>A2轩拨、B=>B2践瓷,直至主從數(shù)據(jù)同步完畢(早期數(shù)據(jù)可手工同步);
  3. 調(diào)整分片規(guī)則并使之生效:
    原 ID%2=0 => A 改為 ID%4=0 => A, ID%4=2 => A2亡蓉;
    原 ID%2=1 => B 改為 ID%4=1 => B, ID%4=3 => B2晕翠。
  4. 解除數(shù)據(jù)庫(kù)實(shí)例的主從同步關(guān)系,并使之生效砍濒;
  5. 至此完成擴(kuò)容
  6. 擇機(jī)清除冗余數(shù)據(jù)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末淋肾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子爸邢,更是在濱河造成了極大的恐慌樊卓,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杠河,死亡現(xiàn)場(chǎng)離奇詭異碌尔,居然都是意外死亡浇辜,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門唾戚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)柳洋,“玉大人,你說(shuō)我怎么就攤上這事颈走∩旁睿” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵立由,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我序厉,道長(zhǎng)锐膜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任弛房,我火速辦了婚禮道盏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘文捶。我一直安慰自己荷逞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布粹排。 她就那樣靜靜地躺著种远,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顽耳。 梳的紋絲不亂的頭發(fā)上坠敷,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音射富,去河邊找鬼膝迎。 笑死,一個(gè)胖子當(dāng)著我的面吹牛胰耗,可吹牛的內(nèi)容都是我干的限次。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼柴灯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼卖漫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起弛槐,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤懊亡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后乎串,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體店枣,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡速警,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸯两。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闷旧。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钧唐,靈堂內(nèi)的尸體忽然破棺而出忙灼,到底是詐尸還是另有隱情,我是刑警寧澤钝侠,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布该园,位于F島的核電站,受9級(jí)特大地震影響帅韧,放射性物質(zhì)發(fā)生泄漏里初。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一忽舟、第九天 我趴在偏房一處隱蔽的房頂上張望双妨。 院中可真熱鬧,春花似錦叮阅、人聲如沸刁品。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挑随。三九已至,卻和暖如春及刻,著一層夾襖步出監(jiān)牢的瞬間镀裤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工缴饭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暑劝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓颗搂,卻偏偏與公主長(zhǎng)得像担猛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丢氢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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