共計 3047 個字符,預計需要花費 8 分鐘才能閱讀完成。
MySQL 中怎么實現數據切分,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
什么是 MySQL 數據切分
Shard 這個詞英文的意思是 碎片,而作為數據庫相關的技術用語,似乎最早見于大型多人在線角色扮演游戲中。Sharding 姑且稱之為 分片。Sharding 不是一門新技術,而是一個相對簡樸的軟件理念。眾所周知,MySQL5 之后才有了數據表分區功能,那么在此之前,很多 MySQL 的潛在用戶都對 MySQL 的擴展性有所顧慮,而是否具備分區功能就成了衡量一個數據庫可擴展性與否的一個關鍵指標(當然不是唯一指標)。
數據庫擴展性是一個永恒的話題,MySQL 的推廣者經常會被問到:如在單一數據庫上處理應用數據捉襟見肘而需要進行分區化之類的處理,是如何辦到的呢答案是:Sharding。Sharding 不是一個某個特定數據庫軟件附屬的功能,而是在具體技術細節之上的抽象處理,是水平擴展 (ScaleOut,亦或橫向擴展、向外擴展) 的解決方案,其主要目的是為突破單節點數據庫服務器的 I / O 能力限制,解決數據庫擴展性問題。
通過一系列的切分規則將數據水平分布到不同的 DB 或 table 中,在通過相應的 DB 路由或者 table 路由規則找到需要查詢的具體的 DB 或者 table,以進行 Query 操作。這里所說的“sharding”通常是指“水平切分”,這也是該篇文章討論的重點。具體將有什么樣的切分方式呢和路由方式呢? 行文至此,讀者難免有所疑問,接下來舉個簡單的例子:我們針對一個 Blog 應用中的日志來說明,比如日志文章 (article) 表有如下字段:article_id(int),title(varchar(128)),content(varchar(1024)),user_id(int).
面對這樣的一個表,我們怎樣切分呢? 怎樣將這樣的數據分布到不同的數據庫中的表中去呢? 其實分析 blog 的應用,我們不難得出這樣的結論:blog 的應用中,用戶分為兩種:瀏覽者和 blog 的主人。瀏覽者瀏覽某個 blog,實際上是在一個特定的用戶的 blog 下進行瀏覽的,而 blog 的主人管理自己的 blog,也同樣是在特定的用戶 blog 下進行操作的(在自己的空間下)。所謂的特定的用戶,用數據庫的字段表示就是“user_id”。就是這個“user_id”,它就是我們需要的分庫的依據和規則的基礎。我們可以這樣做,將 user_id 為 1~10000 的所有的文章信息放入 DB1 中的 article 表中,將 user_id 為 10001~20000 的所有文章信息放入 DB2 中的 article 表中,以此類推,一直到 DBn。
這樣一來,文章數據就很自然的被分到了各個數據庫中,達到了數據切分的目的。接下來要解決的問題就是怎樣找到具體的數據庫呢? 其實問題也是簡單明顯的,既然分庫的時候我們用到了區分字段 user_id,那么很自然,數據庫路由的過程當然還是少不了 user_id 的。考慮一下我們剛才呈現的 blog 應用,不管是訪問別人的 blog 還是管理自己的 blog,總之我都要知道這個 blog 的用戶是誰吧,也就是大家都明白了這個 blog 的 user_id,就利用這個 user_id,利用分庫時候的規則,反過來定位具體的數據庫,比如 user_id 是 234,利用該才的規則,就應該定位到 DB1,如果 user_id 是 12343,利用該才的規則,就應該定位到 DB2。以此類推,利用分庫的規則,反向的路由到具體的 DB,這個過程我們稱之為“DB 路由”。
當然考慮到數據切分的 DB 設計必然是非常規,不正統的 DB 設計。那么什么樣的 DB 設計是正統的 DB 設計呢?
我們平常規規矩矩用的基本都是。平常我們會自覺的按照范式來設計我們的數據庫,負載高點可能考慮使用相關的 Replication 機制來提高讀寫的吞吐和性能,這可能已經可以滿足很多需求,但這套機制自身的缺陷還是比較顯而易見的(下文會提及)。上面提到的“自覺的按照范式設計”。考慮到數據切分的 DB 設計,將違背這個通常的規矩和約束,為了切分,我們不得不在數據庫的表中出現冗余字段,用作區分字段或者叫做分庫的標記字段,比如上面的 article 的例子中的 user_id 這樣的字段(當然,剛才的例子并沒有很好的體現出 user_id 的冗余性,因為 user_id 這個字段即使就是不分庫,也是要出現的,算是我們撿了便宜吧)。當然冗余字段的出現并不只是在分庫的場景下才出現的,在很多大型應用中,冗余也是必須的,這個涉及到高效 DB 的設計,該篇文章不再贅述。
為什么要 MySQL 數據切分
上面對什么是數據切分做了個概要的描述和解釋,讀者可能會疑問,為什么需要數據切分呢? 像 Oracle 這樣成熟穩定的數據庫,足以支撐海量數據的存儲與查詢了? 為什么還需要數據切片呢? 的確,Oracle 的 DB 確實很成熟很穩定,但是高昂的使用費用和高端的硬件支撐不是每一個公司能支付的起的。試想一下一年幾千萬的使用費用和動輒上千萬元的小型機作為硬件支撐,這是一般公司能支付的起的嗎? 即使就是能支付的起,如果有更好的方案,有更廉價且水平擴展性能更好的方案,我們為什么不選擇呢?
但是,事情總是不盡人意。平常我們會自覺的按照范式來設計我們的數據庫,負載高點可能考慮使用相關的 Replication 機制來提高讀寫的吞吐和性能,這可能已經可以滿足很多需求,但這套機制自身的缺陷還是比較顯而易見的。首先它的有效很依賴于讀操作的比例,Master 往往會成為瓶頸所在,寫操作需要順序排隊來執行,過載的話 Master 首先扛不住,Slaves 的數據同步的延遲也可能比較大,而且會大大耗費 CPU 的計算能力,因為 write 操作在 Master 上執行以后還是需要在每臺 slave 機器上都跑一次。這時候 Sharding 可能會成為雞肋了。
Replication 搞不定,那么為什么 Sharding 可以工作呢? 道理很簡單,因為它可以很好的擴展。大家都明白每臺機器無論配置多么好它都有自身的物理上限,所以當我們應用已經能觸及或遠遠超出單臺機器的某個上限的時候,我們惟有尋找別的機器的幫助或者繼續升級的我們的硬件,但常見的方案還是橫向擴展, 通過添加更多的機器來共同承擔壓力。我們還得考慮當我們的業務邏輯不斷增長,我們的機器能不能通過線性增長就能滿足需求?Sharding 可以輕松的將計算,存儲,I/ O 并行分發到多臺機器上,這樣可以充分利用多臺機器各種處理能力,同時可以避免單點失敗,提供系統的可用性,進行很好的錯誤隔離。
綜合以上因素,數據切分是很有必要的,且我們在此討論的數據切分也是將 MySql 作為背景的。基于成本的考慮,很多公司也選擇了 Free 且 Open 的 MySql。對 MySql 有所了解的開發人員可能會知道,MySQL5 之后才有了數據表分區功能,那么在此之前,很多 MySQL 的潛在用戶都對 MySQL 的擴展性有所顧慮,而是否具備分區功能就成了衡量一個數據庫可擴展性與否的一個關鍵指標(當然不是唯一指標)。數據庫擴展性是一個永恒的話題,MySQL 的推廣者經常會被問到:如在單一數據庫上處理應用數據捉襟見肘而需要進行分區化之類的處理,是如何辦到的呢答案也是 Sharding,也就是我們所說的數據切分方案。
關于 MySQL 中怎么實現數據切分問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注丸趣 TV 行業資訊頻道了解更多相關知識。