(二十一)——Sharding 分片模式

2018-02-24 15:44 更新

云計(jì)算設(shè)計(jì)模式(二十一)——Sharding 分片模式

將一個(gè)數(shù)據(jù)存儲(chǔ)到一組水平分區(qū)或碎片。存儲(chǔ)和訪問大量數(shù)據(jù)時(shí),這個(gè)模式可以提高可擴(kuò)展性。

背景和問題

由一個(gè)單一的服務(wù)器托管的數(shù)據(jù)存儲(chǔ)區(qū)可能會(huì)受到以下限制:

  • 存儲(chǔ)空間。一種數(shù)據(jù)存儲(chǔ)為一個(gè)大型云應(yīng)用可以預(yù)期含有數(shù)據(jù)量巨大,可以隨著時(shí)間的推移顯著增加。服務(wù)器通常提供的磁盤存儲(chǔ)僅是有限的,但它可以是能與較大的取代現(xiàn)有的磁盤,或者添加另外的磁盤的機(jī)器作為數(shù)據(jù)量的增加。然而,由此,不能夠容易地增加一個(gè)給定的服務(wù)器上的存儲(chǔ)容量的系統(tǒng)最終將達(dá)到一個(gè)硬限制。
  • 計(jì)算資源。云應(yīng)用程序可能需要支持大量并發(fā)用戶,每一個(gè)運(yùn)行檢索的數(shù)據(jù)存儲(chǔ)信息的查詢。一個(gè)單一的服務(wù)器托管的數(shù)據(jù)存儲(chǔ)可能無法提供所需的計(jì)算能力,以支持該負(fù)載,從而延長(zhǎng)反應(yīng)時(shí)間,為用戶和故障頻作為應(yīng)用程序試圖存儲(chǔ)和檢索數(shù)據(jù)超時(shí)。它可能會(huì)增加存儲(chǔ)器或升級(jí)的處理器,但是當(dāng)其不能夠提高計(jì)算資源的任何進(jìn)一步的系統(tǒng)將達(dá)到極限。
  • 網(wǎng)絡(luò)帶寬。最后,在單個(gè)服務(wù)器上運(yùn)行的數(shù)據(jù)存儲(chǔ)區(qū)的性能是通過在該服務(wù)器可以接收請(qǐng)求并發(fā)送回復(fù)率的約束。這是可能的網(wǎng)絡(luò)流量的量可能會(huì)超過用于連接到該服務(wù)器,從而導(dǎo)致失敗的請(qǐng)求的網(wǎng)絡(luò)的容量。
  • 地理??赡苄枰獮榇鎯?chǔ)由特定的用戶在同一個(gè)區(qū)域中產(chǎn)生的那些用戶為合法,合規(guī)性,或性能原因,數(shù)據(jù),或減少數(shù)據(jù)訪問延滯。如果用戶在不同的國(guó)家或地區(qū)的分散,也未必能夠存儲(chǔ)整個(gè)數(shù)據(jù)為在一個(gè)單一的數(shù)據(jù)存儲(chǔ)區(qū)中的應(yīng)用。

垂直縮放通過添加更多的磁盤容量,處理能力,內(nèi)存和網(wǎng)絡(luò)連接可能會(huì)推遲一些這些限制的效果,但它很可能是只是一個(gè)臨時(shí)的解決方案。能夠支持大量用戶和大量數(shù)據(jù)的商業(yè)云應(yīng)用程序必須能夠擴(kuò)展幾乎無限,所以垂直縮放不一定是最好的解決方案。

解決方案

劃分?jǐn)?shù)據(jù)存儲(chǔ)到水平分區(qū)或碎片。每個(gè)碎片都有相同的模式,但保存的數(shù)據(jù)其獨(dú)特的子集。甲碎片是在自己的權(quán)利(它可以包含許多不同類型的實(shí)體的數(shù)據(jù))的數(shù)據(jù)存儲(chǔ)器,用作存儲(chǔ)節(jié)點(diǎn)的服務(wù)器上運(yùn)行。

這種模式具有以下優(yōu)點(diǎn):

  • 您可擴(kuò)展系統(tǒng),通過添加額外的存儲(chǔ)節(jié)點(diǎn)上運(yùn)行的進(jìn)一步碎片。
  • 系統(tǒng)可以使用現(xiàn)成的商品硬件,而不是專門的(和昂貴)的計(jì)算機(jī)為每個(gè)存儲(chǔ)節(jié)點(diǎn)。
  • 您可以通過平衡跨越碎片的工作量減少爭(zhēng)用和改進(jìn)的性能。
  • 在云中,碎片可以位于物理上接近將要訪問數(shù)據(jù)的用戶。

何時(shí)將一個(gè)數(shù)據(jù)存儲(chǔ)成碎片,決定哪些數(shù)據(jù)應(yīng)該被放置在每個(gè)碎片。甲碎片通常包含倒在數(shù)據(jù)中的一個(gè)或多個(gè)屬性所確定的指定范圍內(nèi)的物品。這些屬性形成的分片密鑰(有時(shí)也被稱為分區(qū)鍵)。分片的關(guān)鍵應(yīng)該是靜態(tài)的。它不應(yīng)該根據(jù)可能發(fā)生變化的數(shù)據(jù)。

分片身體組織的數(shù)據(jù)。何時(shí)一個(gè)應(yīng)用程序存儲(chǔ)和檢索數(shù)據(jù),該分片的邏輯指示應(yīng)用到相應(yīng)的碎片。此拆分邏輯可在應(yīng)用程序中被實(shí)現(xiàn)為數(shù)據(jù)訪問代碼的一部分,或者它可以由數(shù)據(jù)存儲(chǔ)系統(tǒng)中實(shí)現(xiàn),如果它透明地支持分片。

抽象的拆分邏輯的數(shù)據(jù)的物理位置提供了一個(gè)高層次的控制在其上的碎片包含的數(shù)據(jù),并且使數(shù)據(jù)分片之間遷移,而再加工的應(yīng)用程序的業(yè)務(wù)邏輯應(yīng)該需要在碎片的數(shù)據(jù)后面將要引入的(例如,如果碎片變得不平衡)。的折衷是在確定的每個(gè)數(shù)據(jù)項(xiàng)的位置,因?yàn)樗粰z索所需的附加數(shù)據(jù)存取的開銷。

為了確保最佳的性能和可擴(kuò)展性,分裂的數(shù)據(jù)的方式,適合的查詢類型的應(yīng)用程序執(zhí)行是重要的。在許多情況下,這是不可能的拆分計(jì)劃將完全符合每個(gè)查詢的要求。例如,在一個(gè)多用戶系統(tǒng)中的應(yīng)用,可能需要通過使用承租者ID來檢索租戶數(shù)據(jù),但它也可能需要基于其它屬性這個(gè)數(shù)據(jù)查找,如承租人的名稱或位置。為了處理這些情況,實(shí)行分片策略,即支持最常用的查詢執(zhí)行的一個(gè)子庫(kù)的關(guān)鍵。

如果查詢通過使用屬性值的組合來定期檢索數(shù)據(jù),這可能是可以定義通過將屬性一起的復(fù)合分片鍵。另外,使用模式,如索引表,以提供快速的查找到未覆蓋的碎片關(guān)鍵基礎(chǔ)屬性數(shù)據(jù)。

分片策略

選擇所述分片密鑰,并決定如何跨碎片分發(fā)數(shù)據(jù)時(shí)的三種策略是常用的。注意,并不需要成為碎片和承載它們 - 在單個(gè)服務(wù)器可以承載多個(gè)分塊中的服務(wù)器之間的一對(duì)一的對(duì)應(yīng)關(guān)系。這些戰(zhàn)略包括:

  • 查找策略。在上述策略中,分片的邏輯實(shí)現(xiàn)了一個(gè)圖,路由對(duì)數(shù)據(jù)的請(qǐng)求到包含碎片,通過使用分片密鑰數(shù)據(jù)。在一個(gè)多用戶應(yīng)用將租戶的所有數(shù)據(jù)可能通過使用租戶 ID 作為分片密鑰一起存儲(chǔ)在一個(gè)碎片。多個(gè)租戶可能共享相同的碎片,但對(duì)于單個(gè)租戶的數(shù)據(jù)將不被跨越多個(gè)碎片散布。圖1示出了這種策略的一個(gè)例子。

圖1 - 基于租戶ID的分片租戶數(shù)據(jù)

分片鍵和物理存儲(chǔ)的映射關(guān)系可以基于物理分塊,每個(gè)分片鍵映射到一個(gè)物理分區(qū)??商鎿Q地,這種技術(shù)提供了重新平衡碎片時(shí)更大的靈活性是使用虛擬分區(qū)方法,其中分片鍵映射到虛擬碎片的數(shù)量相同,這又映射到較少的物理分區(qū)。在這種方法中,一個(gè)應(yīng)用程序通過使用指的是一個(gè)虛擬碎片一個(gè)碎片鍵定位數(shù)據(jù),并在系統(tǒng)的虛擬分片透明地映射到物理分區(qū)。進(jìn)行修改,以使用一組不同的碎片的鍵的虛擬碎片和物理分區(qū)可以改變,而不需要對(duì)應(yīng)用程序代碼之間的映射。

范圍的策略。這在同一個(gè)分片相關(guān)的項(xiàng)目一起策略組,并把它們的訂單通過分片密鑰分片鍵是連續(xù)的。它是用于應(yīng)用程序通過使用范圍查詢(即返回一組數(shù)據(jù)項(xiàng)的為落在給定范圍內(nèi)的碎片鍵查詢)經(jīng)常檢索項(xiàng)集有用的。例如,如果應(yīng)用程序經(jīng)常需要找到放置在給定月份所有的訂單,該數(shù)據(jù)可被檢索更快如果一個(gè)月的所有命令被存儲(chǔ)在日期和時(shí)間的順序在同一個(gè)分片。如果每個(gè)訂單被存儲(chǔ)在不同的碎片,它們將必須通過進(jìn)行大量的點(diǎn)查詢(返回單個(gè)數(shù)據(jù)項(xiàng)的查詢)的單獨(dú)取出。圖2示出了這種策略的一個(gè)例子。

圖2 - 數(shù)據(jù)中的碎片存儲(chǔ)順序集合(范圍)

在這個(gè)例子中,分片鍵是一個(gè)組合鍵,包括訂單月作為最顯著元件,其次是為了日和時(shí)間。創(chuàng)建和附加到一個(gè)碎片新訂單時(shí),訂單中的數(shù)據(jù)自然排序。一些數(shù)據(jù)存儲(chǔ)支持包括識(shí)別所述碎片和行密鑰唯一地標(biāo)識(shí)該子庫(kù)中的項(xiàng)分區(qū)鍵元件的兩部分分片密鑰。數(shù)據(jù)通常是在碎片中排鍵順序舉行。該受的范圍內(nèi)的查詢和需要的項(xiàng)目組合在一起可以使用一個(gè)分片鍵具有用于分區(qū)鍵但該行鍵的唯一值相同的值。

哈希策略。這種策略的目的是減少在數(shù)據(jù)熱點(diǎn)的機(jī)會(huì)。它的目的是分配在實(shí)現(xiàn)每個(gè)碎片的大小和平均負(fù)載,每個(gè)碎片會(huì)遇到之間的平衡的方式在整個(gè)碎片中的數(shù)據(jù)。分片的邏輯計(jì)算,其中基于所述數(shù)據(jù)的一個(gè)或多個(gè)屬性的散列來存儲(chǔ)中的項(xiàng)目的子庫(kù)。所選擇的散列函數(shù)應(yīng)該均勻地分布在整個(gè)數(shù)據(jù)碎片,可能通過引入一些隨機(jī)元素插入的計(jì)算。圖2示出了這種策略的一個(gè)例子。

圖3 - 基于租戶ID的哈希分片租戶數(shù)據(jù)

了解超過其他分片策略哈希策略的優(yōu)勢(shì),考慮如何依序錄取新租戶多租戶應(yīng)用程序可能分配租戶碎片中的數(shù)據(jù)存儲(chǔ)。當(dāng)使用范圍的策略,租戶1到n的數(shù)據(jù)都將存儲(chǔ)在分片 A 中,數(shù)據(jù)為住戶的 n+1 到 m 都將存儲(chǔ)在分片 B,依此類推。如果最近登記的租戶也是最活躍,最數(shù)據(jù)活動(dòng)將發(fā)生在少數(shù)碎片,這可能會(huì)導(dǎo)致熱點(diǎn)。與此相反,哈希策略分配租戶基于對(duì)其租戶ID的散列碎片。這意味著順序租戶是最有可能被分配到不同的碎片,如圖 3 所示為住戶 55 和 56,這將在這些碎片分配負(fù)載。

下表列出的主要優(yōu)點(diǎn)和考慮這三個(gè)分片策略。

Lookup 查找

更好地控制碎片的配置和使用方式。

重新平衡數(shù)據(jù)時(shí),因?yàn)樾碌奈锢矸謪^(qū)可以被添加到拉平工作量使用虛擬碎片減少的影響??梢栽诓挥绊懯褂靡粋€(gè)分片鍵來存儲(chǔ)和檢索數(shù)據(jù)的應(yīng)用程序代碼被修改的虛擬碎片和實(shí)現(xiàn)該分片的物理分區(qū)之間的映射。

Range 范圍

易于實(shí)現(xiàn)和使用范圍查詢工作得很好,因?yàn)樗鼈兺ǔ?梢匀≡趩蝹€(gè)操作中從單個(gè)分片的多個(gè)數(shù)據(jù)項(xiàng)。

更簡(jiǎn)便的數(shù)據(jù)管理。例如,如果用戶在相同的區(qū)域是在相同的子庫(kù),更新可以安排在基于本地負(fù)載和需求模式的每個(gè)時(shí)區(qū)。

Hash 哈希

一個(gè)甚至更多的數(shù)據(jù)和負(fù)荷分布的更好的機(jī)會(huì)。

請(qǐng)求路由可以直接通過使用哈希函數(shù)來實(shí)現(xiàn)。沒有必要來維護(hù)一個(gè)地圖。

最常見的拆分方案實(shí)現(xiàn)上述方法之一,但你也應(yīng)該考慮你的應(yīng)用程序的業(yè)務(wù)需求和他們的數(shù)據(jù)使用模式。例如,在一個(gè)多用戶應(yīng)用:

  • 可以分片根據(jù)工作負(fù)載數(shù)據(jù)。你可以分開在不同的碎片極易揮發(fā)租戶的數(shù)據(jù)。對(duì)于其他租戶的數(shù)據(jù)訪問的速度可以提高作為結(jié)果。
  • 可以分片根據(jù)租戶的位置數(shù)據(jù)。它可能會(huì)采取對(duì)租戶的數(shù)據(jù)在一個(gè)特定的地理區(qū)域離線期間在該地區(qū)非高峰期備份和維護(hù),而對(duì)于住戶在其他地區(qū)的數(shù)據(jù)仍然在他們上班時(shí)間上網(wǎng)和訪問。
  • 高價(jià)值的住戶能分到自己的私人高性能,輕載碎片,而價(jià)值較低的住戶可能有望分享更密集堆積,忙碎片。
  • 對(duì)于需要數(shù)據(jù)隔離和隱私的高度可以存儲(chǔ)一個(gè)完全獨(dú)立的服務(wù)器上租戶的數(shù)據(jù)。

縮放和數(shù)據(jù)移動(dòng)操作

每個(gè)分片策略意味著不同的功能和復(fù)雜性管理的規(guī)模,向外擴(kuò)展,數(shù)據(jù)移動(dòng),并保持水平狀態(tài)。

查找策略允許縮放和數(shù)據(jù)移動(dòng)操作來進(jìn)行,在用戶層面,無論是在線還是離線。該技術(shù)暫停部分或全部用戶活動(dòng)(也許是在非高峰時(shí)段),移動(dòng)數(shù)據(jù)到新的虛擬分區(qū)或物理碎片,改變映射,無效或刷新持有該數(shù)據(jù)的緩存,然后讓用戶活動(dòng)恢復(fù)。通常這種類型的操作可以進(jìn)行集中管理。查找戰(zhàn)略要求的狀態(tài)是高度可緩存和副本友好。

的范圍的策略規(guī)定了結(jié)垢和數(shù)據(jù)移動(dòng)操作,這通常必須進(jìn)行時(shí)的一部分或全部的數(shù)據(jù)存儲(chǔ)為脫機(jī),因?yàn)閿?shù)據(jù)必須被分割和整個(gè)碎片合并的一些限制。移動(dòng)的數(shù)據(jù),以重新平衡碎片可能無法解決不均勻負(fù)荷的問題,如果大多數(shù)的活性是對(duì)相鄰分片密鑰或數(shù)據(jù)標(biāo)識(shí)符是相同的范圍之內(nèi)的。范圍的策略可能也需要進(jìn)行維護(hù),以圖范圍內(nèi)的物理分區(qū)的一些狀態(tài)。

哈希策略使得擴(kuò)展和數(shù)據(jù)移動(dòng)操作更為復(fù)雜,因?yàn)榉謪^(qū)鍵是碎片密鑰或數(shù)據(jù)標(biāo)識(shí)符的哈希值。每個(gè)碎片的新位置,必須從散列函數(shù)來確定,或者該函數(shù)修改,以提供正確的映射。然而,哈希策略不需要維護(hù)狀態(tài)。

問題和注意事項(xiàng)

在決定如何實(shí)現(xiàn)這個(gè)模式時(shí),請(qǐng)考慮以下幾點(diǎn):

  • 分片是互補(bǔ)的其他形式的分區(qū),如垂直分區(qū)和功能劃分。例如,單個(gè)子庫(kù)可以包含已垂直劃分實(shí)體和功能劃分可以被實(shí)現(xiàn)為多個(gè)碎片。有關(guān)分區(qū)的詳細(xì)信息,請(qǐng)參閱數(shù)據(jù)分區(qū)指導(dǎo)。
  • 保持平衡碎片,使他們都處理的I / O相似的體積。作為數(shù)據(jù)被插入和刪除,它可能有必要定期地重新平衡的碎片,以保證均勻分布,并減少熱點(diǎn)的機(jī)會(huì)。再平衡可能是一個(gè)昂貴的操作。為了降低頻率與再平衡成為必要,你應(yīng)該確保每個(gè)碎片中含有足夠的可用空間來處理變化的預(yù)期貨量計(jì)劃增長(zhǎng)。你還應(yīng)該制定戰(zhàn)略和腳本,你可以用它來快速重新平衡碎片這應(yīng)該成為必要。
  • 使用穩(wěn)定的數(shù)據(jù)分片的關(guān)鍵。如果分片鍵的變化,相應(yīng)的數(shù)據(jù)項(xiàng)可能需要碎片之間移動(dòng),增加工作通過更新操作執(zhí)行的工作量。出于這個(gè)原因,避免立足于潛在的波動(dòng)信息的碎片關(guān)鍵。相反,尋找那些不變的或自然形成的關(guān)鍵屬性。
  • 確保碎片鑰匙都是獨(dú)一無二的。例如,應(yīng)避免使用自動(dòng)遞增的字段作為分片的關(guān)鍵。在一些系統(tǒng)中,自動(dòng)遞增字段可以不橫跨碎片協(xié)調(diào),從而可能導(dǎo)致在具有相同分片鍵不同的碎片的項(xiàng)目。

注意:在不包括分片鍵也可能導(dǎo)致問題字段自動(dòng)遞增值。例如,如果您使用自增字段來生成唯一標(biāo)識(shí),并分布在不同的碎片兩個(gè)不同的項(xiàng)目可能被分配相同的ID。

  • 它可能無法設(shè)計(jì)出符合針對(duì)數(shù)據(jù)的每個(gè)可能的查詢要求一個(gè)分片鍵。分片的數(shù)據(jù),以支持最經(jīng)常進(jìn)行的查詢,并在必要時(shí)創(chuàng)建二級(jí)索引表,以支持通過使用基于不屬于分片鍵的一部分的屬性標(biāo)準(zhǔn)檢索數(shù)據(jù)的查詢。欲了解更多信息,請(qǐng)參見索引表模式。
  • 查詢?cè)L問僅單個(gè)碎片會(huì)比那些來自多個(gè)分塊中檢索數(shù)據(jù)的效率,從而避免執(zhí)行一個(gè)分片方案,該方案導(dǎo)致在執(zhí)行該連接在不同碎片保持的數(shù)據(jù)的查詢的大量應(yīng)用程序。請(qǐng)記住,碎瓷片可以包含的數(shù)據(jù)為多個(gè)類型的實(shí)體??紤]非規(guī)范化的數(shù)據(jù)保持相同的碎片常常被認(rèn)為是一起查詢(如客戶的詳細(xì)信息和訂單,他們已經(jīng)把)相關(guān)實(shí)體,以減少單獨(dú)讀取數(shù)的應(yīng)用程序執(zhí)行。

注意:如果在一個(gè)子庫(kù)的實(shí)體引用存儲(chǔ)在另一個(gè)分片的一個(gè)實(shí)體,包括分片鍵用于第二實(shí)體,作為第一實(shí)體的架構(gòu)的一部分。這可以幫助提高引用跨碎片相關(guān)數(shù)據(jù)查詢的性能。

  • 如果應(yīng)用程序必須執(zhí)行檢索來自多個(gè)分塊數(shù)據(jù)的查詢,有可能通過使用并行任務(wù)來獲取這些數(shù)據(jù)。例子包括扇出查詢,其中來自多個(gè)分片的數(shù)據(jù)檢索平行,然后匯總到一個(gè)結(jié)果。然而,這種方法不可避免地增加了一些復(fù)雜性的溶液的數(shù)據(jù)訪問邏輯。
  • 對(duì)于許多應(yīng)用來說,產(chǎn)生的小碎片更大數(shù)目可以比具有少量的大碎片,因?yàn)樗鼈兛梢蕴峁┯糜谪?fù)載平衡的機(jī)會(huì)增加更加有效。如果預(yù)計(jì)需要碎片從一個(gè)物理位置移動(dòng)到另一個(gè)這樣的方法也可以是有用的。移動(dòng)小碎片比移動(dòng)一個(gè)大的更快。
  • 確保提供給每個(gè)分片存儲(chǔ)節(jié)點(diǎn)的資源足以處理數(shù)據(jù)的規(guī)模和吞吐量方面的可擴(kuò)展性要求。欲了解更多信息,請(qǐng)參閱數(shù)據(jù)分區(qū)引導(dǎo)部分“設(shè)計(jì)分區(qū)的可擴(kuò)展性”。
  • 考慮復(fù)制參考數(shù)據(jù)所有碎片。如果從一個(gè)子庫(kù)中檢索數(shù)據(jù)的操作還引用靜態(tài)或緩慢移動(dòng)的數(shù)據(jù)作為同一查詢的一部分,這個(gè)數(shù)據(jù)添加到碎片。然后,應(yīng)用程序可以讀取所有用于容易地查詢中的數(shù)據(jù),而無需進(jìn)行額外的往返行程到一個(gè)單獨(dú)的數(shù)據(jù)存儲(chǔ)中。

注意:如果在多個(gè)分塊的變化保持的基準(zhǔn)數(shù)據(jù),該系統(tǒng)必須同步所有碎片這些變化。而此同步發(fā)生時(shí),系統(tǒng)可能會(huì)出現(xiàn)一定程度的混亂。如果你按照這種方法,你應(yīng)該設(shè)計(jì)自己的應(yīng)用程序能夠處理這個(gè)矛盾。

  • 它可以是難以維持的碎片之間的參照完整性和一致性,所以你應(yīng)該盡量減少影響在多個(gè)碎片數(shù)據(jù)操作。如果應(yīng)用程序必須通過碎片修改數(shù)據(jù),評(píng)估完整的數(shù)據(jù)一致性是否實(shí)際上是一個(gè)要求。相反,在云中一個(gè)常用的方法是實(shí)現(xiàn)最終一致性。每個(gè)分區(qū)中的數(shù)據(jù)分別進(jìn)行更新,并在應(yīng)用程序邏輯必須承擔(dān)保證責(zé)任的更新都成功完成,以及處理,可以從查詢數(shù)據(jù)的最終一致的運(yùn)行操作時(shí)產(chǎn)生的不一致。有關(guān)實(shí)現(xiàn)最終一致性的更多信息,請(qǐng)參閱數(shù)據(jù)一致性底漆。
  • 配置和管理大量碎片可能是一個(gè)挑戰(zhàn)。任務(wù),例如監(jiān)控,備份,檢查一致性,并記錄或?qū)徲?jì)必須完成對(duì)多個(gè)碎片和服務(wù)器,在多個(gè)位置有可能保持。這些任務(wù)可能會(huì)通過使用腳本或其他自動(dòng)化解決方案,但腳本和自動(dòng)化可能無法完全消除額外的行政要求執(zhí)行。
  • 碎片可以是地理定位的,使得它們包含的數(shù)據(jù)是靠近使用它的應(yīng)用程序的實(shí)例。這種方法可以顯著改善的性能,但是需要額外考慮為必須訪問多個(gè)分塊中的不同位置的任務(wù)。

何時(shí)使用這個(gè)模式

使用這種模式:

  • 當(dāng)數(shù)據(jù)存儲(chǔ)可能需要擴(kuò)展超越了一單個(gè)存儲(chǔ)節(jié)點(diǎn)的資源的限制。
  • 通過減少爭(zhēng)用的數(shù)據(jù)存儲(chǔ)來提高性能。

注意:分片的主要焦點(diǎn)是改進(jìn)系統(tǒng)的性能和可擴(kuò)展性,而作為副產(chǎn)物,也可以借助于其中數(shù)據(jù)被劃分成單獨(dú)的分區(qū)的方式提高可用性。在一個(gè)分區(qū)中的故障不一定阻止應(yīng)用程序訪問的其他分區(qū)中保存的數(shù)據(jù),并且操作者無需使得整個(gè)數(shù)據(jù)為應(yīng)用程序無法訪問的可以執(zhí)行的一個(gè)或多個(gè)分區(qū)的維護(hù)或復(fù)原。欲了解更多信息,請(qǐng)參閱數(shù)據(jù)分區(qū)指導(dǎo)。

例子

下面的示例使用了一組充當(dāng)碎片的 SQL Server 數(shù)據(jù)庫(kù)。每個(gè)數(shù)據(jù)庫(kù)包含一個(gè)應(yīng)用程序使用的數(shù)據(jù)的一個(gè)子集。應(yīng)用程序檢索該被分布在整個(gè)碎片通過使用它自己的分片邏輯(這是一個(gè)扇出查詢的一個(gè)例子)的數(shù)據(jù)。將位于每個(gè)子庫(kù)中的數(shù)據(jù)的細(xì)節(jié)是通過這樣的方法稱為 GetShards 返回。此方法返回 ShardInformation 對(duì)象,其中 ShardInformation 類型包含一個(gè)標(biāo)識(shí)符為每個(gè)碎片和 SQL Server 的連接字符串,應(yīng)用程序應(yīng)該使用連接到碎片的枚舉列表(在連接字符串中沒有代碼示例所示)。

private IEnumerable<ShardInformation> GetShards()  
{  
  // This retrieves the connection information from a shard store   
  // (commonly a root database).  
  return new[]  
  {  
    new ShardInformation  
    {  
      Id = 1,  
      ConnectionString = ...  
    },  
    new ShardInformation  
    {  
      Id = 2,  
      ConnectionString = ...  
    }  
  };  
}

下面的代碼顯示了如何在應(yīng)用程序使用 ShardInformation 對(duì)象名單進(jìn)行了從并行每個(gè)碎片獲取數(shù)據(jù)的查詢。查詢的細(xì)節(jié)沒有示出,但在本實(shí)施例中所檢索的數(shù)據(jù)包括可以存放信息,如客戶的名稱,如果碎片包含客戶的細(xì)節(jié)的字符串。該結(jié)果由應(yīng)用聚集成 ConcurrentBag 集合進(jìn)行處理。

// Retrieve the shards as a ShardInformation[] instance.   
var shards = GetShards();  
?
var results = new ConcurrentBag<string>();  
?
// Execute the query against each shard in the shard list.  
// This list would typically be retrieved from configuration   
// or from a root/master shard store.  
Parallel.ForEach(shards, shard =>  
{  
  // NOTE: Transient fault handling is not included,   
  // but should be incorporated when used in a real world application.  
  using (var con = new SqlConnection(shard.ConnectionString))  
  {  
    con.Open();  
    var cmd = new SqlCommand("SELECT ... FROM ...", con);  
?
    Trace.TraceInformation("Executing command against shard: {0}", shard.Id);  
?
    var reader = cmd.ExecuteReader();  
    // Read the results in to a thread-safe data structure.  
    while (reader.Read())  
    {  
      results.Add(reader.GetString(0));  
    }  
  }  
});  
?
Trace.TraceInformation("Fanout query complete - Record Count: {0}",   
                        results.Count);
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)