天天看點

資料庫的切分和優化

資料庫的切分和優化

1.引言

随着網際網路應用的普及,海量資料的存儲和通路成為了系統設計的瓶頸問題。對于一個大型的網際網路應用,每天幾十億pv無疑對資料庫造成了相當高的負載。對于系統的穩定性和擴充性造成了極大的問題。

通過資料切分來提高網站性能,橫向擴充資料層已經成為架構研發人員首選的方式:

(1)水準切分資料庫:可以降低單台機器的負載,同時最大限度的降低了當機造成的損失;

(2)通過負載均衡政策:有效的降低了單台機器的通路負載,降低了當機的可能性;

(3)通過叢集方案:解決了資料庫當機帶來的單點資料庫不能通路的問題;

(4)通過讀寫分離政策:最大限度提高了應用張讀取資料的速度和并發量

2.基本原理與概念

(1)什麼是資料切分

如果在單一資料庫上處理應用資料捉襟見肘而需要進行分區化之類的處理,是如何辦到的呢?答案就是:Sharding。

Sharding不是某個特定資料庫附屬的功能,而是在具體實作技術的抽象,是水準擴充的解決方案,主要目的是為了實作單點伺服器的i/o能力限制,解決資料庫擴充性問題。也就是: 通過一系列的切分規則将資料水準分布到不同的DB或table中,再通過相應的DB路由或者table路由規則找到需要查詢的具體的DB或者table,進行query操作。

舉一個例子:我們針對一個Blog應用中的日志來說明,比如日志文章article表有如下字段:

[sql] view plain copy

  1. article_id(int),tile(varchar(128)),contnet(varchar(1024)),user_id(int)

這樣一張表我們怎樣切分呢?怎樣将這樣的資料分不到不同的資料庫中的表中呢?其實分析blog應用,我們可以得出如下結論:可以使用user_id字段作為我們分庫的規則基礎

将user_id為1-10000的所有文章放入DB1的article表中,将user_id為10001-20000的所有文章放入DB2的article表中,以此類推,一直到DBn。

這樣一來,文章資料就被分到了各個資料庫中,達到了資料切分的目的。接下來要解決的就是怎麼找到具體的資料庫呢?解決方法也很明顯:既然分庫的時候我們使用了分區字段user_id,那麼資料庫路由的時候當然少不了user_id。我們知道了user_id,利用分庫時的規則,反過來定位具體資料庫,比如user_id=234,利用剛才的規則,就會定位到DB1,降入user_id是12343,利用該規則,就會定位到DB2.以此類推,利用分庫的規則,反向路由到具體的DB,這個過程我們稱為DB路由。

(2)如何資料切分

1)分庫

也就是實體上的資料切分。将資料通過一系列的切分規則将資料分布到不同的DB伺服器上,通過路由規則通路特定的資料庫。這樣一來,每次通路的就不是單台伺服器了,而是N台,這樣就可以降低單台機器的負載壓力。

分庫方式:

1>按号段分

如用user_id來區分,1-1000的對應DB1,1001-2000的對應DB2,以此類推。

優點:可部分遷移

缺點:資料分布不均

2>hash取模分

對user_id進行hsah(如果user_id是數字的話,直接用user_id也行),然後用一個特定的數字,比如需要将一個資料庫切分成4個資料庫的話,我們就用4對user_id進行取模,也就是user_id%4,這樣的話就有4種結果:1的時候對應DB1,2的時候對應DB2,3的時候對應DB3,0的時候對應DB4,這樣一來資料就會非常均勻的将資料配置設定到4個DB中。

優點:資料分布均勻

缺點:不能按照近期性能分攤資料

2)分表

也就是資料庫内的資料切分。對資料通過一系列的切分規則,将資料分不到一個資料庫的不同表中,如将article表分為article_001,article_002等子表,若幹個表水準拼接會在邏輯上組成一個完整的article表。

這麼做作用是十分明顯的。舉個例子:比如article表中有5000w條資料,此時我們在表中insert一條新的資料,insert完成之後,資料庫會針對這張表重建立立索引,而5000w條資料建立索引的系統開銷是不容忽視的。但是如果我們把表分為100個子表呢?從article_001一直到article_100,5000w資料平均下來,每個子表中就隻有50w條資料,這時候我們向一張隻有50w條資料的表中insert之後建立索引的時間就會成數量級的下降,極大的提高了DB運作時的效率,提高了DB的并發量。

綜上:分庫降低了單點機器的負載;分表提高了了資料操作的效率,尤其是寫操作的效率

原文位址

http://www.bieryun.com/3281.html