分庫分表學習和思考

學習總結(jié)

寫這篇文章主要想解一下自己在大數(shù)據(jù)量下寫數(shù)據(jù)或者頻繁寫數(shù)據(jù)的疑問,工作或者和他人閑聊中一般遇到的大數(shù)據(jù)量寫的場景其實不多歹河,多是密集讀的場景,或者大部分情況下的解決方案都比較不徹底,或者比較“臟”妒穴,維護起來比較煩心搪哪,于是不如就花時間把這個問題想一想蛙卤。

分庫分表的原因

分庫分表是一個實施的方案,我們要做分庫分表要解決的問題具體來說是:
要解決數(shù)據(jù)庫寫壓力大的問題噩死;
或者數(shù)據(jù)量大導致讀寫慢的問題颤难;
或者是MySQL集群水平擴展問題;

解決這些問題的辦法并不只有分庫或者分表已维,數(shù)據(jù)量大的問題通過做冷熱數(shù)據(jù)分離也是可以解決的行嗤;業(yè)務密集寫導致機器負載高的問題也是可以通過產(chǎn)品同學和開發(fā)同學一起商量去解決的;數(shù)據(jù)量如果不是很大的情況下垛耳,通過垂直分表也是一個解決問題的辦法栅屏,例如在業(yè)務或架構(gòu)上解耦,不同服務讀取該服務單獨的庫堂鲜,或者單個服務內(nèi)將大表分離為多個表栈雳,業(yè)務端分散寫壓力,自然也都是可以解決問題的缔莲。
這里我們只是來研究討論一下水平擴展下的分庫分表方案和設計哥纫。

分布算法設計/數(shù)據(jù)分布設計

我們接下來遇到的問題是我們要怎么設計我們的數(shù)據(jù)分布,分庫痴奏、分表蛀骇、分區(qū)都是分散數(shù)據(jù)分布的方式,由于單純分區(qū)還是在單臺機器上的配置读拆,所以主要討論的是架構(gòu)上分庫(或是分庫+分表)的實現(xiàn)和方案擅憔。
數(shù)據(jù)的分布一般最常見的有按范圍分和按哈希分,當然能用的不止這兩種檐晕,詳細可以參考MyCat支持的分庫分表方式暑诸。

自定義分布

存一個將ID和庫的Mapping關(guān)系的單獨的記錄庫,分布算法用另外的服務實現(xiàn),分布算法服務可能會迭代个榕,所以這種方式可能適合經(jīng)常變動的業(yè)務啦逆,數(shù)據(jù)分布的關(guān)系自然就被記錄在該mapping表里,實際中可能不太常見笛洛。
缺點是會引入新的單點夏志,也就是引入了該mapping服務的高可用問題。

按范圍分區(qū)間

按范圍區(qū)分在實際應用中很常見苛让,這個范圍字段通常是某唯一 id 或時間字段沟蔑,優(yōu)點是自然增長,不需要考慮以后數(shù)據(jù)規(guī)模再次變大數(shù)據(jù)要重分布的問題狱杰;
缺點也是明顯的瘦材,一般情況下密集訪問的都是最近時間內(nèi)的數(shù)據(jù),密集訪問其實還是集中在最近時間內(nèi)產(chǎn)生的數(shù)據(jù)上仿畸,并發(fā)規(guī)模若再變高依舊存在密集訪問的問題食棕。

按某業(yè)務字段 Hash

通過業(yè)務字段值 Hash 處理后的值分布數(shù)據(jù),這個數(shù)據(jù)分布方式也是很常見的實現(xiàn)方式错沽,比如希望分 N 個庫簿晓,可以按用戶 ID 取模 N ,可以均勻地將用戶相關(guān)的數(shù)據(jù)分布到不同的庫上千埃,若希望在數(shù)據(jù)庫內(nèi)再對表進行劃分憔儿,可以再對該 ID 作 Hash 處理。Hash 算法的設計可能會業(yè)務不同而異因放可,我們可以學習一下美團技術(shù)團隊分庫分表方案上 Hash 算法的設計谒臼。

分庫方案討論

確定我們的業(yè)務的數(shù)據(jù)分布,技術(shù)選型就是接下來很重要的事情耀里,我們了解發(fā)現(xiàn)現(xiàn)在業(yè)界現(xiàn)在分庫分表的實現(xiàn)基本有在業(yè)務側(cè)實現(xiàn)和通過中間件實現(xiàn)的方式蜈缤。我可能還是偏向于用中間件的方式將分庫分表的處理邏輯與業(yè)務剝離開,由運維或者 devops 去單獨維護冯挎,好處是對開發(fā)完全透明底哥,不使得已經(jīng)比較復雜的業(yè)務代碼變得更復雜。

分庫中間件或開源庫調(diào)研

現(xiàn)在業(yè)內(nèi)使用的開源庫或者中間件有多種织堂,包括:Cobar叠艳、TDDL奶陈、Atlas易阳、Sharding-jdbc、MyCat吃粒、kingshard潦俺。

業(yè)務端分庫分表開源庫

Sharding-jdbc:Sharding-jdbc 可能是 Java 系同學的福音,也是經(jīng)常會看到的,已經(jīng)發(fā)展到 ShardingSphere 了事示,有興趣的同學自己去了解吧早像,我們這里不作研究了。

中間件

我們接下來對業(yè)界比較常見的肖爵,或者是我比較感興趣的分庫分表中間件作一下對比或者深入了解卢鹦。

MyCat

mycat 的安裝和啟動方式我們這里就不做討論了,mycat 官方文檔都有描述劝堪。mycat 是用 Java 寫的中間件冀自,前身是或者參考了阿里的內(nèi)部分布式中間件,在官網(wǎng)也能看到其功能介紹秒啦,使用于生產(chǎn)環(huán)境的公司等等熬粗,能看出來技術(shù)功底還是相當靠譜的,說是最常見最靠譜的中間件也不為過余境。與其它中間件一樣驻呐,前面做一層負載均衡,比如用HAProxy等芳来,也能作為一個常見的高可用方案含末。
另外社區(qū)還是相當活躍的,有大神在維護即舌,用于生產(chǎn)環(huán)境比較讓人安心的答渔。具體介紹和操作都可以翻閱官方的文檔,都解釋得非常詳細侥涵。

配置我們可以詳細討論一下沼撕,在結(jié)構(gòu)上有這么幾個概念:

  • Schema:邏輯庫,也就是邏輯意義上的數(shù)據(jù)庫芜飘,像是司機信息庫等务豺。
  • Table:邏輯表,表會綁定對應的一個或多個 DataNode (邏輯數(shù)據(jù)節(jié)點)嗦明×ぃ可以指定表的分片規(guī)則,不指定會使用默認規(guī)則娶牌。
  • DataNode:邏輯數(shù)據(jù)節(jié)點奔浅,該邏輯數(shù)據(jù)節(jié)點還會綁定 DataHost (物理物理數(shù)據(jù)節(jié)點)。
  • DataSource或DataHost:定義物理節(jié)點诗良,同時保存物理節(jié)點信息諸如IP汹桦、最大連接數(shù)、heartbeat等鉴裹。
  • 分片規(guī)則(rule):也就是我們設計的數(shù)據(jù)分布方式舞骆,數(shù)據(jù)會按該分片規(guī)則分布到對應的節(jié)點上钥弯。有多種默認的分片規(guī)則如哈希、范圍督禽,也可以根據(jù)業(yè)務情況自定義脆霎。

配置文件主要有:

  • schema.xml 配置邏輯表及數(shù)據(jù)節(jié)點
  • rule.xml 配置分片規(guī)則
  • server.xml 配置服務器權(quán)限

可以參考這個實例的 schema.xml 配置,rule.xml 和 server.xml 暫不作展示了:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- 數(shù)據(jù)庫配置狈惫,與server.xml中的數(shù)據(jù)庫對應 -->
    <schema name="db_person" checkSQLschema="false" sqlMaxLimit="100">
        <table name="person" dataNode="dn1"  />
        <table name="vehicle" dataNode="dn1"  />
        <table name="images" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2"  rule="mod-long" />
    </schema>

<!-- 分片配置 -->
    <dataNode name="dn1" dataHost="internal-01" database="db_person" />
    <dataNode name="dn2" dataHost="internal-02" database="db_person" />

<!-- 物理數(shù)據(jù)庫配置 -->
    <dataHost name="internal-01" maxCon="1000" minCon="10" balance="0"  writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="172.190.0.2" url="172.190.0.2:3306" user="root" password="123456"> 
        </writeHost>
    </dataHost>

    <dataHost name="internal-02" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="172.190.0.3" url="172.190.0.3:3306" user="root" password="123456"> 
        </writeHost>
    </dataHost>
</mycat:schema>

MyCat 的官方文檔描述得非常詳細睛蛛,包括 MyCat 使用的網(wǎng)絡 IO 并發(fā)模型都有闡述,如果對 MyCat 有興趣胧谈,閱讀一遍官方文檔是非常有益于理解 MyCat 的玖院。

kingshard

了解 kingshard 是因為 kingshard 是用 go 寫的,在學習上成本會低很多第岖,kingshard 是一位 go 大神維護的难菌,聽說將其使用在生產(chǎn)環(huán)境的公司也有不少,應該也是比較好的一款分庫分表中間件蔑滓,后面有時間我們可以來分析學習一下 kingshard 的具體實現(xiàn)郊酒。
kingshard 的結(jié)構(gòu)或概念相對比較簡單,支持多個表放在單個庫上键袱,后面再擴容在配置上也非常友好燎窘。

配置實例(/etc/ks.yaml):

user_list:
-
    user :  kingshard
    password : kingshard

# the web api server
web_addr: 0.0.0.0:9797
#HTTP Basic Auth
web_user: admin
web_password: admin

log_path: /Users/jerry/log
log_level: debug
log_sql: on

nodes :
-
    name : node1
    user :  root
    password : 123456
    max_conns_limit : 32
    master : 127.0.0.1:3307

    # slave represents a real mysql salve server,and the number after '@' is-
    # read load weight of this slave.
    #slave : 192.168.59.101:3307@2,192.168.59.101:3307@3
    down_after_noalive : 32
-
    name : node2
    user :  root
    password : 123456
    max_conns_limit : 32
    master : 127.0.0.1:3308
    down_after_noalive: 32
-
    name: node3
    user: root
    password: 123456
    master: 127.0.0.1:3309
    down_after_noalive: 32
-
    name: node4
    user: root
    password: 123456
    master: 127.0.0.1:3310
    down_after_noalive: 32

# schema defines sharding rules, the db is the sharding table database.
schema_list :
-
    user: kingshard
    nodes: [node1,node2,node3,node4]
    default: node1
    shard:
    -
        db : db_driver
        table: t_join_driver
        key: driver_join_id
        type: hash
        nodes: [node1, node2, node3, node4]
        locations: [4,4,4,4]

可以看到配置還是很簡單的,定義節(jié)點( Node )信息蹄咖,以及分庫分表的 schema 信息褐健,如表名、使用哪些節(jié)點澜汤、分庫分表方式(如 hash )蚜迅、數(shù)據(jù)分布等。接下來就是分別搭建每個數(shù)據(jù)庫節(jié)點俊抵,即可啟動谁不。
不過我的客戶端連接 kingshard 上一直連接不上,一直沒找到問題所在徽诲,后面有時間我們可以來學習一下 MySQL 協(xié)議以及 kingshard 的實現(xiàn)刹帕。

Postgres-XL(pgsql)

以上都是使用 MySQL 作為后端數(shù)據(jù)庫服務器的,但是數(shù)據(jù)庫服務器界還有 pgsql 這么個泰斗級的存在谎替,pgsql 功能強大偷溺,如果使用 pgsql 存儲,那么也有已經(jīng)使用于生產(chǎn)的分庫分表方案钱贯,其中一個便是 Postgres-XL挫掏。
Postgres-XL是一個可橫向擴展的開源數(shù)據(jù)庫集群,基于Postgres-XC喷舀,而Postgres-XC又是基于PostgreSql砍濒。PostgreSQL許可證是一種自由開源許可證淋肾,類似于BSD或MIT許可證硫麻。
這里我們只展示一下 Postgres-XL 的架構(gòu)爸邢,權(quán)作記錄。


Postgres-XL架構(gòu)圖

后結(jié)

我們這里對于分庫分表的學習和討論還是偏于表層的拿愧,對于分庫分表其實一直沒有非掣芎樱“干凈”、從容又高效的解決方案浇辜,具體對每個不同中間件的使用還是要實際中磨合才能真正合適不同的業(yè)務券敌。事實上現(xiàn)在不少大型互聯(lián)網(wǎng)公司的存儲引擎或者方案都是自研的,所以我們在使用開源中間件滿足業(yè)務的同時柳洋,其實更有必要的是研究底層實現(xiàn)待诅,比如什么樣的網(wǎng)絡IO并發(fā)模型是最合適本業(yè)務的、底層存儲引擎是否真的是我們最想要的等等熊镣,因為很有可能分布式數(shù)據(jù)水平擴展問題并沒有簡單粗暴的“銀彈”卑雁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市绪囱,隨后出現(xiàn)的幾起案子测蹲,更是在濱河造成了極大的恐慌,老刑警劉巖鬼吵,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扣甲,死亡現(xiàn)場離奇詭異,居然都是意外死亡齿椅,警方通過查閱死者的電腦和手機琉挖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涣脚,“玉大人粹排,你說我怎么就攤上這事∩瑁” “怎么了顽耳?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長妙同。 經(jīng)常有香客問我射富,道長,這世上最難降的妖魔是什么粥帚? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任胰耗,我火速辦了婚禮,結(jié)果婚禮上芒涡,老公的妹妹穿的比我還像新娘柴灯。我一直安慰自己卖漫,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布赠群。 她就那樣靜靜地躺著羊始,像睡著了一般。 火紅的嫁衣襯著肌膚如雪查描。 梳的紋絲不亂的頭發(fā)上突委,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音冬三,去河邊找鬼匀油。 笑死,一個胖子當著我的面吹牛勾笆,可吹牛的內(nèi)容都是我干的敌蚜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窝爪,長吁一口氣:“原來是場噩夢啊……” “哼弛车!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酸舍,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤帅韧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后啃勉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忽舟,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年淮阐,在試婚紗的時候發(fā)現(xiàn)自己被綠了叮阅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡泣特,死狀恐怖浩姥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情状您,我是刑警寧澤勒叠,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站膏孟,受9級特大地震影響眯分,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柒桑,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一弊决、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧魁淳,春花似錦飘诗、人聲如沸与倡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纺座。三九已至,卻和暖如春貌嫡,著一層夾襖步出監(jiān)牢的瞬間比驻,已是汗流浹背该溯。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工岛抄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狈茉。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓夫椭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親氯庆。 傳聞我的和親對象是個殘疾皇子蹭秋,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355