前言:分庫分表雖然能帶來效能提公升,但同時會提出
問題一:跨庫關聯查詢
我們有幾種主要的解決方案:
1、字段冗餘
比如我們查詢合同庫的合同表的時候需要關聯客戶庫的客戶表,我們可以直接把一
些經常關聯查詢的客戶字段放到合同表,通過這種方式避免跨庫關聯查詢的問題。
2、資料同步:比如商戶系統要查詢產品系統的產品表,我們乾脆在商戶系統建立一
張產品表,通過etl 或者其他方式定時同步產品資料。
3、全域性表(廣播表) 比如行名行號資訊被很多業務系統用到,如果我們放在核心
系統,每個系統都要去關聯查詢,這個時候我們可以在所有的資料庫都儲存相同的基礎
資料。4、er 表(繫結表)
我們有些表的資料是存在邏輯的主外來鍵關係的,比如訂單表order_info,存的是匯
總的商品數,商品金額;訂單明細表order_detail,是每個商品的**,個數等等。或者
叫做從屬關係,父表和子表的關係。他們之間會經常有關聯查詢的操作,如果父表的數
據和子表的資料分別儲存在不同的資料庫,跨庫關聯查詢也比較麻煩。所以我們能不能
把父表和資料和從屬於父表的資料落到乙個節點上呢?
比如order_id=1001 的資料在node1 , 它所有的明細資料也放到node1 ;
order_id=1002 的資料在node2,它所有的明細資料都放到node2,這樣在關聯查詢的
時候依然是在乙個資料庫。
上面的思路都是通過合理的資料分布避免跨庫關聯查詢,實際上在我們的業務中,
也是盡量不要用跨庫關聯查詢,如果出現了這種情況,就要分析一下業務或者資料拆分
是不是合理。如果還是出現了需要跨庫關聯的情況,那我們就只能用最後一種辦法。
5、系統層組裝
在不同的資料庫節點把符合條件資料的資料查詢出來,然後重新組裝,返回給客戶
端。問題二:分布式事務
分布式事務有幾種常見的解決方案:
1、全域性事務(比如xa 兩階段提交;應用、事務管理器(tm)、資源管理器(db)),
例如atomikos
2、基於可靠訊息服務的分布式事務
3、柔性事務tcc(try-confirm-cancel)tcc-transaction
4、最大努力通知,通過訊息中介軟體向其他系統傳送訊息(重複投遞+定期校對)
問題三: 排序、翻頁、函式計算問題
跨節點多庫進行查詢時,會出現limit 分頁,order by 排序的問題。比如有兩個節點,
節點1 存的是奇數id=1,3,5,7,9……;節點2 存的是偶數id=2,4,6,8,10……
執行select * from user_info order by id limit 0,10
需要在兩個節點上各取出10 條,然後合併資料,重新排序。
max、min、sum、count 之類的函式在進行計算的時候,也需要先在每個分片上執
行相應的函式,然後將各個分片的結果集進行彙總和再次計算,最終將結果返回。
問題四:全域性主鍵避重問題
mysql 的資料庫裡面欄位有乙個自增的屬性,oracle 也有sequence 序列。如果
是乙個資料庫,那麼可以保證id 是不重複的,但是水平分表以後,每個表都按照自己的
規律自增,肯定會出現id 重複的問題,這個時候我們就不能用本地自增的方式了。
我們有幾種常見的解決方案:
1)uuid(universally unique identifier 通用唯一識別碼)
uuid 是主鍵是最簡單的方案,本地生成,效能高,沒有網路耗時。但缺點也很明顯,
由於uuid 非常長,會占用大量的儲存空間;另外,作為主鍵建立索引和基於索引進行
查詢時都會存在效能問題,在innodb 中,uuid 的無序性會引起資料位置頻繁變動,導
致分頁。
2) 資料庫
把序號維護在資料庫的一張表中。這張表記錄了全域性主鍵的型別、位數、起始值,
當前值。當其他應用需要獲得全域性id 時,先for update 鎖行,取到值+1 後並且更新後
返回。併發性比較差。
3)redis
基於redis 的int 自增的特性,使用批量的方式降低資料庫的寫壓力,每次獲取一
段區間的id 號段,用完之後再去資料庫獲取,可以大大減輕資料庫的壓力。
4)雪花演算法snowflake(64bit)
核心思想:
a)使用41bit 作為毫秒數,可以使用69 年
b)10bit 作為機器的id(5bit 是資料中心,5bit 的機器id),支援1024 個
節點c)12bit 作為毫秒內的流水號(每個節點在每毫秒可以產生4096 個id)
d)最後還有乙個符號位,永遠是0。
**:snowflake.snowflaketest
優點:毫秒數在高位,生成的id 整體上按時間趨勢遞增;不依賴第三方系統,穩定
性和效率較高,理論上qps 約為409.6w/s(1000*2^12),並且整個分布式系統內不會
產生id 碰撞;可根據自身業務靈活分配bit 位。
不足就在於:強依賴機器時鐘,如果時鐘回撥,則可能導致生成id 重複。
分表分庫後帶來問題(主鍵衝突)
主鍵衝突問題 分庫分表的環境中,資料分布在不同的分片上,不能再借助資料庫自增長特性直接生成,否則會造成不同分片上的資料表主鍵會重複。新增資料 主鍵生成中心 分庫決策中心 切換相應庫 執行新增 事務問題 在執行分庫分表之後,由於資料儲存到了不同的庫上,資料庫事務管理出現了困難。如果依賴資料庫本身的分布...
分庫分表引起的問題
1 按照新舊分片規則,對新舊資料庫進行雙寫。2 將雙寫前按照舊分片規則寫入的歷史資料,根據新分片規則遷移寫入新的資料庫。3 將按照舊的分片規則查詢改為按照新分片規則查詢 4 將雙寫資料庫邏輯從 中下線,只按照新的分片規則寫入資料。5 刪除按照舊分片規則寫入的歷史資料。常見的解決方式 1 在多個分片表...
分庫分表實戰問題
1.分庫分表中水平拆分和垂直拆分的區別?水平拆分 將表資料拆分到不同的資料資料庫中。垂直拆分 把乙個大表拆成多個小表。字段進行拆分。分表 是指的是把表資料拆分到多張表裡面。range分發 每個月生成乙個新錶。如果訪問新的資料還好,但是訪問舊的資料就麻煩一些。hash分發 平均分配,但是擴容的話會比較...