本文由雲+社區發表 作者:騰訊雲資料庫 Introduction 導言 任何看到顯著增長的應用程式或網站,最終都需要進行擴展,以適應流量的增加。以確保數據安全性和完整性的方式進行擴展,對於數據驅動的應用程式和網站來說十分重要。人們可能很難預測某個網站或應用程式的流行程度,也很難預測這種流行程度會持續 ...
本文由雲+社區發表
作者:騰訊雲資料庫
Introduction 導言
任何看到顯著增長的應用程式或網站,最終都需要進行擴展,以適應流量的增加。以確保數據安全性和完整性的方式進行擴展,對於數據驅動的應用程式和網站來說十分重要。人們可能很難預測某個網站或應用程式的流行程度,也很難預測這種流行程度會持續多久,這就是為什麼有些機構選擇“可動態擴展的”資料庫架構的原因。
在這篇概念性文章中,我們將討論一種“可動態擴展的”資料庫架構:分片資料庫。近年來,分片(Sharding)一直受到很多關註,但許多人並沒有清楚地瞭解它是什麼,或者對資料庫進行分片可能有意義的場景。我們將討論分片是什麼,它的一些主要優點和缺點,以及一些常見的分片方法。
下方是本文目錄,幫助您接下來的閱讀
What is Sharding? 什麼是分片?
分片(Sharding)是一種與水平切分(horizontal partitioning)相關的資料庫架構模式——將一個表裡面的行,分成多個不同的表的做法(稱為分區)。每個區都具有相同的模式和列,但每個表有完全不同的行。同樣,每個分區中保存的數據都是唯一的,並且與其他分區中保存的數據無關。
從水平切分(horizontal partitioning)與垂直切分(vertical partitioning)的關係,可能會有所幫助。在垂直切分表中,所有的列被分離出來,並放入新的不同的表中。每個垂直切分內的數據,獨立於所有其他分區中的數據,並且每個分區都包含不同的行和列。下圖說明瞭如何在水平和垂直方向上對錶進行分區:
添加描述
分片(Sharding)將一個數據分成兩個或多個較小的塊,稱為邏輯分片(logical shards)。然後,邏輯分片(logical shards)分佈在單獨的資料庫節點上,稱為物理分片(physical shards)。物理分片(physical shards)可以容納多個邏輯分片(logical shards)。儘管如此,所有分片中保存的數據,共同代表整個邏輯數據集。
資料庫分片(Database shards)是無共用架構的一個例子。這意味著分片是自治的:分片間不共用任何相同的數據或伺服器資源。但是在某些情況下,將某些表複製到每個分片中作為參考表是有意義的。例如,假設某個應用程式的資料庫依賴於重量測量的固定轉換率。通過將包含必要轉換率數據的表複製到每個分片中,有助於確保查詢所需的所有數據都保存在每個分片中。
通常,分片(Sharding)在應用程式級別進行實現。這意味著應用程式包含“要向哪個分片發送讀和寫”的代碼。但是,某些資料庫管理系統內置了分片功能,允許您直接在資料庫級別實現分片。
以上是分片(Sharding)的概述,接下來讓我們來看一下,這種資料庫架構的優點和缺點。
Benefits of Sharding 分片的好處
資料庫分片的主要吸引力在於,它可以幫助促進水平擴展(horizontal scaling),也稱為向外擴展(scaling out)。水平擴展是將更多的機器添加到現有堆棧中,以分散負載,允許更多的流量和更快的處理。這通常與垂直擴展(vertical scaling)形成對比,垂直擴展也稱為向上擴展(scaling up),是指升級現有伺服器的硬體,通常是添加更多記憶體或CPU。
讓一個關係資料庫在單個機器上運行,並按需升級其伺服器資源進行向上擴展是相對簡單的。但最終,任何非分散式資料庫在存儲和計算能力方面都會受到限制,因此可以自由地水平擴展資料庫,會使您的架構更加靈活且適應性強。
選擇分片資料庫架構的另一個原因,是為了加速查詢響應的時間。當您對尚未分片的資料庫提交查詢時,必須先搜索您查詢的表中的每一行,然後才能找到您要查找的結果集。對於具有大型單片資料庫的應用程式,查詢可能變得極其緩慢。但是,通過將一個表分成多個,查詢過程會遍歷更少的行,並且返回結果集的速度要快得多。
分片還可以通過減少宕機(outage)的影響,使應用程式更穩定可靠。如果您的應用程式或網站依賴於未分片的資料庫,則宕機可能會導致整個應用程式不可用。但是,對於分片資料庫,宕機可能只會影響單個分片。即使這可能使某些用戶無法使用應用程式或網站部分功能,但仍會低於整個資料庫崩潰帶來的影響。
Drawbacks of Sharding 分片的缺點
雖然對資料庫進行分片可以使擴展更容易並提高性能,但它也可能會帶來某些限制。在這裡,我們將討論其中的一些限制,以及為什麼這些限制會讓我們避免對資料庫全部分片。
正確實現分片資料庫架構,是十分複雜的,所以這是分片遇到的第一個困難。如果操作不正確,則分片過程可能會導致數據丟失或表損壞,這是一個很大的風險。但是,即使正確地進行了分片,也可能對團隊的工作流程產生重大影響。與從單個入口點訪問和管理數據不同,用戶必須跨多個分片位置管理數據,這可能會讓某些團隊存在工作混亂。
在對資料庫進行分片後,用戶有時會遇到的一個問題是分片最終會變得不平衡。舉例來說,假設您有一個資料庫,其中有兩個單獨的分片,一個用於姓氏以字母A到M開頭的客戶,另一個用於名字以字母N到Z開頭的客戶。但是,您的應用程式為姓氏以字母G開頭的人提供了過多的服務。因此,A-M分片逐漸累積的數據比N-Z分片要多,這會導致應用程式速度變慢,並對很大一部分用戶造成影響。A-M分片已成為所謂的數據熱點。在這種情況下,資料庫分片的任何好處都被慢速和崩潰抵消了。資料庫可能需要修複和重新分片,才能實現更均勻的數據分佈。
另一個主要缺點是,一旦對資料庫進行了分片,就很難將其恢復到未分片的架構。分片前資料庫的備份數據,都無法與分片後寫入的數據合併。因此,重建原始的非分片架構,需要將新的分區數據與舊備份合併,或者將分區的資料庫轉換回單個資料庫,這兩種方法都是昂貴且耗時的。
要考慮的最後一個缺點是,並不是每個資料庫引擎本身都支持分片。例如,儘管可以手動分片PostgreSQL資料庫,但PostgreSQL本身並不包括自動分片功能。有許多Postgres分支包括自動分片功能,但這些分支通常落後於最新的PostgreSQL版本,並且缺乏某些其他的功能特性。一些專業的資料庫技術——如MySQL Cluster或某些資料庫即服務產品(如MongoDB Atlas)確實包含自動分片功能,但這些資料庫管理系統的普通版本卻並不包含。因此,分片通常需要“自己動手”的方法。這意味著通常很難找到有關分片或故障排除技巧的文檔。
現在我們已經介紹了一些分片的缺點和好處,我們將討論一些分片資料庫的不同架構。
一旦你決定對資料庫進行分片,接下來你需要弄清楚的是如何進行分片。在運行查詢或將傳入的數據分發到分片表或資料庫時,關鍵是要將其分配到正確的分片。否則,它可能導致數據丟失或查詢速度緩慢。在本節中,我們將介紹一些常見的分片架構,每個架構使用稍微不同的流程來跨分片分發數據。
Key Based Sharding 基於鍵的分片
添加描述
為了確保數據記錄以正確的方式被放置在正確的分片中,哈希函數中輸入的值都應該來自同一列。此列稱為分片鍵。簡單來說,分片鍵與主鍵類似,因為它們都是列,用於為各個行建立唯一標識符。一般來說,分片鍵應該是靜態的,這意味著它不應包含可能隨時間變化的值。否則,它會增加更新操作的工作量,並可能降低性能。
雖然基於鍵的分片是一種相當常見的分片架構,但在嘗試動態添加或刪除資料庫中的其他伺服器時,它會使事情變得棘手。在添加伺服器時,每個伺服器都需要一個相應的哈希值,並且許多現有條目(如果不是全部)都需要重新映射到新的正確哈希值,然後遷移到相應的伺服器。當您開始重新平衡數據時,新舊哈希函數都不會有效。因此,在遷移期間,您的伺服器將無法編寫任何新數據,您的應用程式可能會停機。
這種策略的主要吸引力在於,它可以用於均勻分佈數據,從而防止熱點。此外,由於它以演算法方式分配數據,因此無需維護所有數據所在位置的映射,而其他策略(如範圍或基於目錄的分片)必須維護數據位置的映射。
Range Based Sharding 基於範圍的分片
基於範圍的分片(Range based sharding),基於給定值的範圍進行數據分片。為了說明,假設您有一個資料庫,用於存儲零售商目錄中所有產品的信息。您可以創建一些不同的分片,並根據每個產品的價格範圍分配每個產品的信息,如下所示:
添加描述
基於範圍的分片的主要好處是,它實現起來相對簡單。每個分片都包含一組不同的數據,但它們都具有相同的模式,以及原始資料庫。應用程式代碼只讀取數據所屬的範圍,並將其寫入相應的分片。
另一方面,基於範圍的分片並不能預防數據不均勻分佈的現象,而有可能會出現前面提到的數據熱點現象。查看示例圖,即使每個分片擁有相同數量的數據,特定產品比其他產品獲得更多關註的可能性也會很大。相應的,各個的分片將接收不成比例的讀取操作。
Directory Based Sharding 基於目錄的分片
要實現基於目錄的分片,必須創建並維護一個查找表,該查找表使用分片鍵來跟蹤哪個分片包含哪些數據。簡而言之,查找表是一個表,其中包含有關可以找到特定數據的靜態信息集。下圖顯示了基於目錄的分片的簡單示例:
添加描述
此處,Delivery Zone列被定義為分片鍵。將來自分片鍵的數據,連同每一行應該寫入的分片寫入查找表。這與基於範圍的分片類似,但不是確定分片鍵的數據落入哪個範圍,而是將每個鍵綁定到其自己的特定分片。如果分片鍵的基數很低,並且分片鍵存儲鍵的範圍沒有意義,那麼基於目錄的分片比基於範圍的分片要更好。請註意,它也不同於基於密鑰的分片,因為它不通過散列函數處理分片鍵; 它只是根據查找表檢查鍵值,以查看數據需要寫入的位置。
基於目錄的分片的主要吸引力在於其靈活性。基於範圍的分片架構只能指定鍵值範圍,而基於鍵的分片架構只能使用固定的哈希函數,如前所述,在以後更改該函數非常困難。另一方面,基於目錄的分片允許您使用任何系統或演算法將數據項分配給分片,使用這種方法動態添加分片也相對容易。
雖然基於目錄的分片是這裡討論的最靈活的分片方法,但是在每次查詢或寫入之前連接到查找表,可能會對應用程式的性能產生不利影響。此外,查找表可能出現單點故障:如果查詢表損壞或出現其他故障,它可能會影響資料庫寫入新數據或訪問現有數據的能力。
Should I Shard? 我應該分片嗎?
是否應該實現分片資料庫架構,幾乎總是一個爭論的問題。有些人認為分片對於達到一定規模的資料庫來說,是不可避免的結果。而另一些人則認為這是一個令人頭疼的問題,除非絕對必要,否則應該避免,因為分片增加了操作的複雜性。
由於這種增加的複雜性,通常僅在處理非常大量的數據時才執行分片。以下是一些常見方案,可能對資料庫分片的操作有所幫助:
· 應用程式數據量增長到超過單個資料庫節點的存儲容量。
· 對資料庫的讀寫量,超過單個節點或其只讀副本可以處理的量,從而導致響應時間增加或超時。
· 應用程式所需的網路帶寬,超過單個資料庫節點和任何只讀副本可用的帶寬,從而導致響應時間增加或超時。
在分片之前,您應該用盡所有其他選項來優化資料庫。您可能需要考慮的一些優化包括:
設置遠程資料庫。如果您使用的是一個整體應用程式,其中所有組件都位於同一個伺服器上,那麼可以通過將資料庫移到它自己的機器上來提高資料庫的性能。由於資料庫的表保持不變,因此這不會增加分片的複雜性。但是,它仍然允許您垂直伸縮資料庫,使其與基礎結構的其他部分分離。
實現緩存。如果您的應用程式的讀取性能導致您遇到麻煩,那麼緩存是一種可以幫助改進它的策略。緩存涉及臨時存儲已在記憶體中請求的數據,以便您以後更快地訪問它。
創建一個或多個只讀副本。另一種有助於提高讀取性能的策略,包括將數據從一個資料庫伺服器(主伺服器)複製到一個或多個從伺服器。在此之後,每次新的寫操作在複製到從伺服器之前都要先到主伺服器,而讀操作只對從伺服器進行。像這樣分發讀寫可以防止任何一臺機器承擔過多的負載,從而有助於防止速度下降和崩潰。請註意,創建讀副本需要更多的伺服器資源,因此花費更多的錢,這對一些人來說可能是一個很大的限制。
升級到更大的伺服器。在大多數情況下,將一個資料庫伺服器擴展到具有更多資源的電腦比分片需要更少的工作量。與創建只讀副本一樣,具有更多資源的伺服器升級可能會花費更多的錢。因此,只有當它確實是您的最佳選擇時,您才應該進行伺服器擴容。
請記住,如果您的應用程式或網站增長超過某個點,這些策略本身都不足以提高性能。在這種情況下,分片可能確實是您的最佳選擇。
Conclusion 結語
對於那些希望橫向擴展資料庫的人來說,分片是一個很好的解決方案。但是,它還會增加很多複雜性,併為您的應用程式創建更多潛在的故障點。分片對於某些人來說可能是必要的,但是創建和維護分片架構所需的時間和資源可能會超過對其他人的好處。
通過閱讀這篇概念性文章,您應該更清楚地瞭解分片的優缺點。接下來,您可以使用這些見解來對分片資料庫架構是否適合您,做出更明智的決定。
版權聲明:本文由騰訊雲資料庫產品團隊整理,頁面原始內容來自於db weekly英文官網,若轉載請註明出處。翻譯目的在於傳遞更多全球最新資料庫領域相關信息,並不意味著騰訊雲資料庫產品團隊贊同其觀點或證實其內容的真實性。如果其他媒體、網站或其他任何形式的法律實體和個人使用,必須經過著作權人合法書面授權並自負全部法律責任。不得擅自使用騰訊雲資料庫團隊的名義進行轉載,或盜用騰訊雲資料庫團隊名義發佈信息。
此文已由騰訊雲+社區在各渠道發佈
獲取更多新鮮技術乾貨,可以關註我們騰訊雲技術社區-雲加社區官方號及知乎機構號