談談 分庫 分表 怎麼用

2021-10-20 19:35:19 字數 3632 閱讀 8985

重中之重,什麼是分庫分表?什麼情況下用到分庫分表?其次為分庫分表的方式?怎麼用?

二、資料分庫:

三、注意點

什麼是?

顧名思義,將乙個庫的資料分散到多個庫中,把乙個表的資料分到多個表中儲存。

什麼情況下用到?

當乙個庫被建立後,隨著時間和業務量的增加,或者業務流量本來就很多的情況下,資料庫中的資料會越來越多,弊端就開始顯現:併發量變大,吞吐量變大,處理資料的能力下降,對資料的操作開銷也越大,這是就必須用到分庫分表了。

分庫分表的方式

分庫:主從資料庫擴容、雙寫資料庫擴容

分表:垂直分表、水平分表

一、資料分表:

如果單錶資料量過大,例如千萬級別甚至更多,每次查詢會消耗資料庫大量資源,如果聯表更明顯。如mysql在插入資料的時候,會對錶進行加鎖(表鎖或行鎖),當併發高時,都會影響資料庫的效率。

這個時候將表進行分散可以一定程度上提高效率。一般來說mysql資料庫單錶最好控制在一千萬條資料以內。

1、垂直分表:

概念:根據業務把乙個表中的字段分到不同的表中,每個表的字段至少有一列交集,一般是主鍵。

這些被分出去的資料通常根據業務需要,例如分出去一些不常用的字段,長度較長的字段。

場景:字段很多,並且熱點資料和非熱點資料在一起,單行所需儲存空間大,以至資料庫快取的資料行減少,迫使查詢時回去都磁碟資料產生大量隨機讀io,造成io瓶頸。

2、水平分表

以某字段為依據,按照一定策略(hash、range等),將乙個表中的資料拆分到多個表中。

分析:每個表的結構都一樣,但是每個表的資料不一樣,沒有交集,所有的表資料合起來為乙個整體。

場景:併發量不高,但是單錶的資料量很多,加重了cpu負擔,可以考慮分表。

二、資料分庫:

每個物理資料庫支援資料都有限的,每一次的資料庫請求都會產生一次資料庫連線,當乙個庫無法支援更多訪問的時候,一般會把原本單個資料庫分成多個,分擔壓力。

2、根據冷熱資料進行分庫,用資料訪問頻率劃分。

3、根據訪問資料的地域、時間範圍進行分庫。

1、垂直分庫

概念:以表為依據,按照業務歸屬不同,將不同的表拆分到不同的庫中。

如原本庫中存放a\b兩表,垂直分庫後,一庫存a表,二庫存b表。

分析:每個庫的結構都不一樣,每個庫的資料也不一樣,沒有交集。

2、水平分庫

概念:同水平分表,以字段為依據,按照一定策略(hash、range等),將乙個庫中的資料拆分到多個庫中。

場景:系統絕對併發量上來了。分表難以解決根本問題,並且沒有明顯的業務歸屬來垂直分庫的情況下。

三、注意點

分庫分表能緩解單庫或單錶帶來的效能瓶頸,但同時也帶來了一些問題。

1、分庫分表帶來的問題及考慮

1.1 分布式事務

當更新內容同時存在於不同庫中時,這就帶來了跨庫的事務問題。跨分片事務也是分布式事務,一般使用「xa協議」和「兩階段提交」處理。

分布式事務能最大限度保證了資料庫操作的原子性。但在提交事務時需要協調多個節點,推後了提交事務的時間點,延長了事務的執行時間,導致事務在訪問共享資源時發生衝突或死鎖的概率增高。

1.2 最終一致性

對於那些效能要求很高,但對一致性要求不高的系統,往往不苛求系統的實時一致性,只要在允許的時間段內達到最終一致性即可,可採用事務補償的方式。與事務在執行中發生錯誤立刻回滾的方式不同,事務補償是一種事後檢查補救的措施,一些常見的實現方法有:對資料進行對賬檢查,基於日誌進行對比,定期同標準資料**進行同步等。

1.3 全域性表

全域性表,也可看做「資料字典表」,就是系統中所有模組都可能依賴的一些表,為了避免庫join查詢,可以將這類表在每個資料庫中都儲存乙份。這些資料通常很少修改,所以不必擔心一致性的問題。

1.4 字段冗餘

利用空間換時間,合理冗餘部分字段,為了效能而避免join查詢。不過需要注意冗餘的字段,它的一致性是否對業務產生影響。

1.5 全域性主鍵問題

在分庫分表環境中,由於表中資料同時存在不同資料庫中,主鍵值平時使用的自增長將無用武之地,某個分割槽資料庫自生成id無法保證全域性唯一。因此需要單獨設計全域性主鍵,避免跨庫主鍵重複問題。

uuid:uuid標準形式是32個16進製制數字,分為5段,形式是8-4-4-4-12的36個字元。這是最簡單的方案,但缺點也明顯,uuid的無序性會導致索引位置頻繁變動,另外占用儲存空間多。

*snowflake(雪花演算法):*twitter的snowfalke演算法解決了分布式系統生成全域性id的需求,生成64位long型數字。

1.6 雪花演算法demo

從網路上摘錄乙個雪花演算法demo:雪花演算法的原理和實現

public class idworker 

public long getdatacenterid()

public long gettimestamp()

public idworker(long workerid, long datacenterid, long sequence)

if (datacenterid > maxdatacenterid || datacenterid < 0)

this.workerid = workerid;

this.datacenterid = datacenterid;

this.sequence = sequence; }

// 這個是核心方法,通過呼叫nextid()方法,讓當前這台機器上的snowflake演算法程式生成乙個全域性唯一的id

public synchronized long nextid()

// 下面是說假設在同乙個毫秒內,又傳送了乙個請求生成乙個id

// 這個時候就得把seqence序號給遞增1,最多就是4096

if (lasttimestamp == timestamp)

} else

// 這兒記錄一下最近一次生成id的時間戳,單位是毫秒

lasttimestamp = timestamp;

// 這兒就是最核心的二進位制位運算操作,生成乙個64bit的id

// 先將當前時間戳左移,放到41 bit那兒;將機房id左移放到5 bit那兒;將機器id左移放到5 bit那兒;將序號放最後12 bit

// 最後拼接起來成乙個64 bit的二進位制數字,轉換成10進製就是個long型

return ((timestamp - twepoch) << timestampleftshift) |

(datacenterid << datacenteridshift) |

(workerid << workeridshift) | sequence; }

/*** 當某一毫秒的時間,產生的id數 超過4095,系統會進入等待,直到下一毫秒,系統繼續產生id

* @param lasttimestamp

* @return

*/private long tilnextmillis(long lasttimestamp)

return timestamp;

} //獲取當前時間戳

private long timegen()

/*** main 測試類

* @param args

*/public static void main(string args)

}}

mysql分表分庫實現 MySql分表分庫思路

一.資料庫瓶頸 1.1io瓶頸 第一種 磁碟讀io瓶頸,熱點資料太多,資料庫快取放不下,每次查詢時會產生大量的io 分庫和垂直分表 第二種 網路io瓶頸,請求的資料太多,網路頻寬不夠 分庫 1.2cpu瓶頸 第一種 sql問題,如sql中包含join,group by,order by,非索引字段條...

MySQL範圍分表分庫 mysql 分表分庫策略

唯一id的生成 下面列舉幾種常見的唯一id生成方案,需要滿足兩大核心需求 1.全域性唯一 2趨勢有序 1.用資料庫的auto increment 自增id 來生成,每次通過寫入資料庫一條記錄,利用資料庫id自增的特性獲取唯一,有序的id。優點 使用資料庫原有的功能,相對簡單 能夠保證唯一 能夠保證遞...

mysql 分庫分表實戰 MySQL分庫分表實戰

為什麼要分庫分表 在大型 中,當使用者量以及使用者產生的業務資料量達到單庫單錶效能極限時,為了支撐業務可持續發展,對於重要的核心業務必然要進行分庫分表來儲存業務資料。對於非核心業務產生的大量資料,例如爬蟲爬取的資訊,論壇產生的資料等,可以考慮把資料儲存在像mongodb這樣的nosql儲存裡面,這些...