Mysql分庫分表方案
Mysql分庫分表方案
1.為什麼要分表:
當一張表的資料達到幾千萬時,你查詢一次所花的時間會變多,如果有聯合查詢的話,我想有可能會死在那兒了。分表的目的就在於此,減小資料庫的負擔,縮短查詢時間。
mysql中有一種機制是表鎖定和行鎖定,是為了保證資料的完整性。
表鎖定表示你們都不能對這張表進行操作,必須等我對錶操作完才行。
行鎖定也一樣,別的sql必須等我對這條資料操作完了,才能對這條資料進行操作。
-
mysql proxy:amoeba
做mysql叢集,利用amoeba。
從上層的java程式來講,不需要知道主伺服器和從伺服器的來源,即主從資料庫伺服器對於上層來講是透明的。可以通過amoeba來配置。
3.大資料量並且訪問頻繁的表,將其分為若干個表
比如對於某網站平臺的資料庫表-公司表,資料量很大,這種能預估出來的大資料量表,我們就事先分出個N個表,這個N是多少,根據實際情況而定。
某網站現在的資料量至多是5000萬條,可以設計每張表容納的資料量是500萬條,也就是拆分成10張表,那麼如何判斷某張表的資料是否容量已滿呢?可以在程式段對於要新增資料的表,在插入前先做統計表記錄數量的操作,當<500萬條資料,就直接插入,當已經到達閥值,可以在程式段新建立資料庫表(或者已經事先建立好),再執行插入操作。
-
利用merge儲存引擎來實現分表
如果要把已有的大資料量表分開比較痛苦,最痛苦的事就是改程式碼,因為程式裡面的sql語句已經寫好了。用merge儲存引擎來實現分表, 這種方法比較適合.
舉例子:
資料庫架構
1、簡單的MySQL主從複製:
MySQL的主從複製解決了資料庫的讀寫分離,並很好的提升了讀的效能,其圖如下:
其主從複製的過程如下圖所示:
但是,主從複製也帶來其他一系列效能瓶頸問題:
-
寫入無法擴充套件
-
寫入無法快取
-
複製延時
-
鎖表率上升
-
表變大,快取率下降
那問題產生總得解決的,這就產生下面的優化方案,一起來看看。
2、MySQL垂直分割槽
如果把業務切割得足夠獨立,那把不同業務的資料放到不同的資料庫伺服器將是一個不錯的方案,而且萬一其中一個業務崩潰了也不會影響其他業務的正常進行,並且也起到了負載分流的作用,大大提升了資料庫的吞吐能力。經過垂直分割槽後的資料庫架構圖如下:
然而,儘管業務之間已經足夠獨立了,但是有些業務之間或多或少總會有點聯絡,如使用者,基本上都會和每個業務相關聯,況且這種分割槽方式,也不能解決單張表資料量暴漲的問題,因此為何不試試水平分割呢?
3、MySQL水平分片(Sharding)
這是一個非常好的思路,將使用者按一定規則(按id雜湊)分組,並把該組使用者的資料儲存到一個資料庫分片中,即一個sharding,這樣隨著使用者數量的增加,只要簡單地配置一臺伺服器即可,原理圖如下:
如何來確定某個使用者所在的shard呢,可以建一張使用者和shard對應的資料表,每次請求先從這張表找使用者的shard id,再從對應shard中查詢相關資料,如下圖所示:
拆分策略選擇
其實拆分很靈活,有的是
垂直切分,將一個庫拆成兩個或多個,將有相關聯的表放在一個庫裡。有的是
水平切分將資料量大的表按照一定邏輯進行拆分。
個人感覺垂直切分的相對來說緩解了IO的瓶頸,而水平切分,目的是減輕了單個表或某些表讀寫的壓力。
我們專案根據個人需求,採用的水平切分,沒有去分庫。之後要看看需要採用何種的切分了。
瞭解到的有: 分表、分割槽、MERGE引擎分表。
MERGE引擎分表
簡介
先介紹merge表,此方法只適用於MyISAM。我資料庫的表都是採用InnoDB引擎的,所以首先就被pass了,但是還是在這裡簡單介紹下吧。
mysql 5.1 手冊裡的說的
改變到MERGE引擎表,意味著成為一個被分割槽的表,這樣將單一的表各分割槽儲存在分離的檔案中。分割槽可以使一些操作效率更顯著,並且不受MyISAM儲存引擎的限制。(蹩腳的英語,各位看官多擔待吧。)
以上應該是使用merge表的主要原因吧。
建立使用
能夠建立MERGE表的要求,首先是一組資料結構完全相同的表,並且儲存引擎為MyISAM。
讓我們先建立一個
之後查詢
你建立了total表,只是相當於在t1,t2的表的基礎上建立的,需要注意的是在單個表中的主鍵或唯一索引,放在MERGE後的total表中就不能再當唯一索引用了,這點應該比較好理解但還是要說一下的。
同時你可以drop或者ALTER TABLE tbl_name UNION=(...)改變表的資料集,這樣可以讓其動態變化,剔除不需要的。
使用場景
如果你的資料記錄呈現一定時間規律,比如每天產生的一些需要記錄的日誌,可能你只需要最近一個月的或者最近幾個月的,這樣你可以每天或者一定時間建立一個資料表,當需要查詢一段時間的資料,你只要將這段時間的資料表建立一張總計的MERGE表。這樣資料集可以控制在可控的範圍呢,不錯吧。so easy。
分表
分表其實想法上很簡單,顧名思義就是將現有的一張資料量大的表去拆分。如果資料庫的效能瓶頸在幾個關鍵表上,這時你可以將分表列入你考慮的範圍。
遇到的問題
我說說我在實驗分表時遇到的問題和相關解決方式
1.如何去分表
根據什麼策略把現有表中的資料分到多個表中,並且還有考慮到以後的擴充套件性上。
是建立一張索引表,使用者id與資料庫id對應,(這裡他將相同結構的表分在了不同的資料庫中進一步減少壓力,但同時對於資料的同步也需要通過其他手段來解決),其本質也是分表了同時分庫了。這麼做的好處是便於以後的擴充套件,但損耗一點效能,因為會多一次查詢嘛。
個人想法,這樣索引表可能會成為新的瓶頸,除非使用者不會一直增長哈。
我的做法屬於另一種,寫了個演算法通過計算某列值,按照一定規律將資料大致均分在每個分表中。至於擴充套件性,寫演算法時候考慮進去了以後增加分表數的問題了。
選擇哪種策略,是要看自己的表的業務特點了,方法沒有絕對的優缺,還是要根據自己的需求選取。
2.分表之後主鍵的維護
分表之前,主鍵就是自動遞增的bigint型。所以主鍵的格式已經提早被確定了,像什麼uuid之類的就被直接pass掉了。
還有想過自己寫一個主鍵生成程式,利用Java 的Atomic原子量特性,但是考慮還需要增加工作量並且高併發下,這裡很可能是個隱患。
還有就是通過應用層上管理主鍵,如redis中有原子性的遞增。
網上較有名的策略是《Ticket Servers: Distributed Unique Primary Keys on the Cheap》, 大致意思是使用一張名Tickets64的MyISAM儲存引擎表,專門用來儲存主鍵,資料只有一行,用的話通過
來取。並且設定了兩個庫,相同的方法,只是每次增長的步長不同,防止一個宕掉,還可以穩定執行。
2.動態選擇表名
表分好之後,問題又來了,資料庫層我們的專案使用的是Mybatis框架。SQL語句都寫在了xml檔案中,現在我需要動態的設定表名。
其實設定mybatis本身,就可以解決這個問題
只要把屬性statementType設定為STATEMENT,表名就可以以引數形式傳入。傳入引數時要以美元符${columnName}這樣傳入引數,至於Statement,PreparedStatement 的區別我想大家應該都能知道的。
另一種解決方式,是使用《shardbatis外掛》,它是開源的,可以實現資料水平切分功能,有興趣的朋友可以瞭解下。
分割槽表
從mysql5.1之後,提供了一種partition引擎的表,看這句
在我的理解,如果把一張表分割槽之後,不同分割槽放在不同磁碟位置上,對整體的讀取是否更有益?
分割槽表優缺點
這裡主要是看的mysql手冊,我也就起到了個翻譯的作用。
在選擇mysql 分割槽方案時,還有一個需要考慮的,在mysql的bug中有一個關於mysql分割槽表查詢快取的bug: 《Partitioning + Query Cache》,因為這個問題,mysql已經將分割槽表的查詢快取disable了,無論你是否開啟查詢快取,都不會啟用查詢快取。如果你在意這點,請慎重選擇方案。
以上是關於,mysql三個拆分方案的總結,資料方面都是自己查詢的所以不免有些會不準確,如有發現請務必告知,希望與各位共成長~~~。
相關文章
- MySQL 分庫分表方案,總結太全了。。MySql
- MySQL分庫分表MySql
- [Mysql]分庫分表MySql
- MySQL 常用分庫分表方案,都在這裡了!MySql
- MySQL資料庫之分庫分表方案MySql資料庫
- 常用分庫分表方案
- 【Mysql】OneProxy分庫分表MySql
- 分庫分表的理想方案
- MySQL 資料庫之網際網路常用分庫分表方案MySql資料庫
- 徹底搞清MySQL分庫分表(垂直分庫,垂直分表,水平分庫,水平分表)MySql
- MySQL:網際網路公司常用分庫分表方案彙總!MySql
- 3.1 MYSQL分庫分表實踐MySql
- MySQL分庫分表的原則MySql
- MySQL全面瓦解28:分庫分表MySql
- 分庫分表架構方案設計架構
- Linux MySQL分庫分表之MycatLinuxMySql
- MySql分表、分庫、分片和分割槽MySql
- MySQL分庫分表總結參考MySql
- MySQL:網際網路公司常用分庫分表方案彙總!(轉載)MySql
- MYSQL效能最佳化分享(分庫分表)MySql
- 分庫分表系列:分庫分表的前世今生
- 分庫分表
- 一種簡單易懂的 MyBatis 分庫分表方案MyBatis
- 10億級別訂單的分庫分表方案
- 分庫分表注意
- MySQL分表後原分割槽表處理方案MySql
- 資料庫分庫分表資料庫
- Mysql分庫分表的主鍵生成演算法MySql演算法
- MySQL訂單分庫分表多維度查詢MySql
- 使用TiDB把自己寫分庫分表方案推翻了TiDB
- mycat配置分庫分表
- Mycat分庫分表配置
- 分庫分表總結
- Mycat分庫分表(一)
- 基因法分庫分表
- [資料庫][分庫分表]分庫分表之後,id主鍵如何處理資料庫
- MySQL運維9-Mycat分庫分表之列舉分片MySql運維
- 使用淘寶中介軟體cobar實現mysql分庫分表MySql