1為什麼需要數據分片技術

資料庫產品的市場
在互聯網行業內,絕大部分開發人員都會遇到數據表的性能問題,特別是當單表數據量特別大的時候,就算是添加索引,性能也都差強人意。對於億級別的數據,有些大的企業會選擇性能非常好的Oracle,Oracle屬於中大型資料庫,能在數據量大的情況下有好的數據處理性能。但是絕大部分小型企業是不會選擇昂貴的oracle的,況且幾乎所有的互聯網巨頭公司選擇的也都是免費開源的Mysql資料庫。

螞蟻金服自主研發的金融級分散式關係資料庫OceanBase前一陣子打破了Oracle保持了9年的記錄,刷新了國際資料庫知名排行榜的最高記錄。因此對於未來資料庫產品市場的變化,我相信中國的廠商是能夠開闢出資料庫市場份額的。

mysql小型資料庫瓶頸
互聯網行業企業都傾向於mysql資料庫,雖說mysql單表能支援億級別的數據量,加上索引優化下查詢速度,勉強能使用,但是對於追求性能和效率的互聯網企業,這是遠遠不夠的。Mysql資料庫單表數據量到達500萬左右,達到性能最佳點,可是對於需要億級別的業務來說,500萬是遠遠不夠的。既然數據放在一個位置不行,那我們就把數據拆分放到多個位置。如果尋找數據位置的時間成本忽略不計的話,那麼在億級別的數據量裡面查詢數據的時間成本就相當於從單張表力查詢數據的時間成本一樣。這就是分庫分表的最初思想。

2. 四種數據分區方式簡述 (筆者這裡只探討水平分區)

對錶進行分區,是為了能最大限度的提高資料庫的IO能力,分區能讓資料庫將同一張表中的數據放在不同的磁碟下,提高資料庫IO能力,類似多核多執行緒的思想。因此分區能提高單標的高並發能力。

range分區
range方式創建分區語句如下:

#根據表結構中的時間欄位來作為分區鍵,如下的year()方法,或者to_char()方法
create table table_range( 
     id int(11), 
     amt int(11) unsigned not null, 
     created_on datetime 
  )partition by range(year(created_on))( 
  partition p2018 values less than (2018), 
  partition p2019 values less than (2019), 
  partition p2020 values less than (2020) 
  partition pdefault values less than maxvalue  #MAXVALUE 表示最大的可能的整數值
  );
#或者使用id作為範圍分區
create table table_range( 
     id int(11), 
     amt int(11) unsigned not null, 
     created_on datetime 
  )partition by range(id)( 
  partition p10000 values less than (10000), 
  partition p20000 values less than (20000), 
  partition p30000 values less than (30000) 
  partition pdefault values less than maxvalue  #MAXVALUE 表示最大的可能的整數值
  );

 

範圍分區

  • 所有範圍區間不能重疊。
  • 查詢條件里包括分區鍵,免全表掃描,分區表查詢都應該注意這個。
  • 分區鍵一般是時間或是唯一的索引值,一般都會在每條數據上計算並保存分區欄位。

list分區

create table table_list( 
  id int(11), 
  type int(4) 
  )(partition by list (type) 
  partition p0 values in (1,3,5,7,9), 
  partition p1 values in (2,4,6,8,0) 
);

 

  • 分區鍵的值是個有限的枚舉值集合,分區欄位值都要在枚舉列表裡找到。
  • list分區可用在對業務類型進行分割切分。

hash分區

CREATE TABLE table_hash(
    id INT NOT NULL,
    name VARCHAR(30),
    id_card INT
)
PARTITION BY HASH(id_card)
PARTITIONS 4;

 

  • hash分區可以自定義hash演算法
  • 分區數量要符合2的n次方倍數,擴容的時候就不會發生大規模數據的遷移
  • hash值只能是整數類型欄位或者整數表達式

key
key分區類似hash分區,只不過key分區不能自定義hash規則,只能使用mysql的方法。

CREATE TABLE table_key (
    id INT NOT NULL,
    name CHAR(5),
    date DATE
)
PARTITION BY LINEAR KEY (id)
PARTITIONS 3;

 

  • key分區鍵除了blob和txt類型欄位不能使用之外,其他類型都能作為分區鍵。
  • key分區是mysql自帶的一種分區方式

3. 分片技術原理概述

分區,這兩個字的關鍵在於分這個字,即分而治之的思想。

分而治之,體現在軟體設計的各個方面:

應用層服務:採用載均衡伺服器+服務集群的方式,拆分系統訪問流量,均分請求的響應和處理壓力。

服務層:採用分散式架構,利用分散式框架,註冊中心+客戶端負載均衡機制,耦合各個服務的依賴關係。採用消息隊列,耦合併拆分複雜的業務流程。

數據層:一個資料庫部署在一台伺服器上,資料庫的性能就會被伺服器資源所限制,那麼我們就需要拆分資料庫的讀寫請求流量,這時候分庫的方法就是我們所需要的解決方案。

總而言之,言而總之;數據分片技術的核心思想就是拆分流量,拆分壓力。

那麼對於分區而言,它拆分的是磁碟IO的壓力,我們要有個基本的認識,每台伺服器的磁碟存儲是由很多歌磁碟組成的磁碟陣列構成,每個磁碟的IO能力是有上限的,而mysql單表數據是放在一個文件內的,因此單表的所有讀寫壓力都會聚集到一個磁碟。但是分區表會將分區放在不同的磁碟上,那麼對單表的讀寫壓力就會拆分到多個磁碟上。

因此,分區就是拆分磁碟IO壓力。

4. 對單表分區的時機

  • 表數據大,且增量數據也多,業務只會訪問靠後的熱點數據,例如即時通訊聊天記錄數據。

  • 單表查詢速度慢,需要優化查詢速度。

  • 經常維護數據,定期刪除歷史數據,可以通過分區的方式來實現。

  • 因單表情況下數據IO集中在少量的設備上,需要均衡IO,把數據訪問壓力平均據分配到各個硬體設備,改善系統性能。