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,把資料訪問壓力平均據分配到各個硬體裝置,改善系統效能。