數據庫設計方案(分庫-分表)


水平分片方案

唯一ID:分布式ID生成算法 snowflake

一般會將一張大表的唯一鍵作為 hash 的 key,比如我們想要水平拆分的是一張擁有3千萬行數據的用戶表,我們可以利用唯一的字段用戶id作為拆分的依據,

這樣就可以依據如下的方式,將用戶表水平拆分成3張,下面是偽代碼,將老的用戶數據導入到新的3個被水平拆分的數據表中

if userId % 3 == 0:
	#insert data in user_table (user_table_0 databaseip: 127.0.0.1)
elif userId % 3 == 1:
	#insert data in user_table (user_table_1 databaseip: 127.0.0.2)
else:
	#insert data in user_table (user_table_2 databaseip: 127.0.0.3)

  我們還會對拆分后的每一個sharding 表,做一個雙主 master 的副本集備份,至於backup,我們則可以使用 percona的cluster來解決。它是比 mysql m/s 或者 m/m 更靠譜的方案。(percona : https://www.cnblogs.com/keme/p/10239838.html)

所以最后拆分的拓撲圖大致如下:

隨着我們的業務增長,數據漲到5千萬了,慢慢的發現3個sharding不能滿足我們的需求了,所以這時候BOSS打算再加2個sharding,以后會慢慢加到10個sharding。

所以我們得在之前的3台sharding服務器上分別執行導入數據代碼,將數據根據新的hash規則導入到每台sharding服務器上。幾乎5千萬行數據每行都移動了一遍,如果服務器夠牛逼,Mysql每秒的插入性能能高達 2000/s,即使這樣整個操作,都要讓服務暫停8個小時左右。這時候DBA的臉色已經不好看了,他應該是已經通宵在導數據了。

那有沒有一種更好的辦法,讓添加或者刪除 sharding 節點對整個分片系統的數據遷移量最小呢?

我們可以利用一致性哈希算法,把唯一ID散列到各個 sharding 節點,這樣就可以保證添加和刪除節點數據遷移影響較小。關於什么是一致性哈性算法,為什么它能做到數據遷移量最小?參考其算法實現

那么什么時候我們需要利用一致性哈希水平拆分數據庫單表呢?
1、當我們擁有一個數據量非常大的單表,比如上億條數據。
2、不僅數據量巨大,這個單表的訪問讀寫也非常頻繁,單機已經無法抗住 I/O 操作。
3、此表無事務性操作,如果涉及分布式事務是相當復雜的事情,在拆分此類表需要異常小心。
4、查詢條件單一,對此表的查詢更新條件常用的僅有1-2個字段,比如用戶表中的用戶id或用戶名。
最后,這樣的拆分也是會帶來負面性的,當水平拆分了一個大表,不得不去修改應用程序或者開發db代理層中間件,這樣會加大開發周期、難度和系統復雜性。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM