在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 大數(shù)據(jù)/ Sharding 分片模式
索引表模式
Sharding 分片模式
外部配置存儲模式
命令和查詢職責(zé)分離(CQRS)模式
靜態(tài)內(nèi)容托管模式
運(yùn)行重構(gòu)模式
計(jì)算資源整合模式
Throttling 節(jié)流模式
斷路器模式
事件獲取模式
實(shí)體化視圖模式
緩存預(yù)留模式
守門員模式
聯(lián)合身份模式
補(bǔ)償交易模式
重試模式
領(lǐng)導(dǎo)人選舉模式
優(yōu)先級隊(duì)列模式
健康端點(diǎn)監(jiān)控模式
消費(fèi)者的競爭模式
基于隊(duì)列的負(fù)載均衡模式
仆人鍵模式
管道和過濾器模式
調(diào)度程序代理管理者模式

Sharding 分片模式

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

背景和問題

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

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

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

解決方案

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

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

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

何時(shí)將一個(gè)數(shù)據(jù)存儲成碎片,決定哪些數(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)用程序存儲和檢索數(shù)據(jù),該分片的邏輯指示應(yīng)用到相應(yīng)的碎片。此拆分邏輯可在應(yīng)用程序中被實(shí)現(xiàn)為數(shù)據(jù)訪問代碼的一部分,或者它可以由數(shù)據(jù)存儲系統(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è)子庫的關(guān)鍵。

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

分片策略

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

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

http://wiki.jikexueyuan.com/project/cloud-design-patterns/images/s.png" alt="" />

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

分片鍵和物理存儲的映射關(guān)系可以基于物理分塊,每個(gè)分片鍵映射到一個(gè)物理分區(qū)。可替換地,這種技術(shù)提供了重新平衡碎片時(shí)更大的靈活性是使用虛擬分區(qū)方法,其中分片鍵映射到虛擬碎片的數(shù)量相同,這又映射到較少的物理分區(qū)。在這種方法中,一個(gè)應(yīng)用程序通過使用指的是一個(gè)虛擬碎片一個(gè)碎片鍵定位數(shù)據(jù),并在系統(tǒng)的虛擬分片透明地映射到物理分區(qū)。進(jìn)行修改,以使用一組不同的碎片的鍵的虛擬碎片和物理分區(qū)可以改變,而不需要對應(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è)月的所有命令被存儲在日期和時(shí)間的順序在同一個(gè)分片。如果每個(gè)訂單被存儲在不同的碎片,它們將必須通過進(jìn)行大量的點(diǎn)查詢(返回單個(gè)數(shù)據(jù)項(xiàng)的查詢)的單獨(dú)取出。圖2示出了這種策略的一個(gè)例子。

http://wiki.jikexueyuan.com/project/cloud-design-patterns/images/s1.png" alt="" />

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

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

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

http://wiki.jikexueyuan.com/project/cloud-design-patterns/images/s2.png" alt="" />

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

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

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

Lookup 查找

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

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

Range 范圍

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

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

Hash 哈希

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

請求路由可以直接通過使用哈希函數(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ù)。對于其他租戶的數(shù)據(jù)訪問的速度可以提高作為結(jié)果。
  • 可以分片根據(jù)租戶的位置數(shù)據(jù)。它可能會采取對租戶的數(shù)據(jù)在一個(gè)特定的地理區(qū)域離線期間在該地區(qū)非高峰期備份和維護(hù),而對于住戶在其他地區(qū)的數(shù)據(jù)仍然在他們上班時(shí)間上網(wǎng)和訪問。
  • 高價(jià)值的住戶能分到自己的私人高性能,輕載碎片,而價(jià)值較低的住戶可能有望分享更密集堆積,忙碎片。
  • 對于需要數(shù)據(jù)隔離和隱私的高度可以存儲一個(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ù)存儲為脫機(jī),因?yàn)閿?shù)據(jù)必須被分割和整個(gè)碎片合并的一些限制。移動(dòng)的數(shù)據(jù),以重新平衡碎片可能無法解決不均勻負(fù)荷的問題,如果大多數(shù)的活性是對相鄰分片密鑰或數(shù)據(jù)標(biāo)識符是相同的范圍之內(nèi)的。范圍的策略可能也需要進(jìn)行維護(hù),以圖范圍內(nèi)的物理分區(qū)的一些狀態(tài)。

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

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

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

  • 分片是互補(bǔ)的其他形式的分區(qū),如垂直分區(qū)和功能劃分。例如,單個(gè)子庫可以包含已垂直劃分實(shí)體和功能劃分可以被實(shí)現(xiàn)為多個(gè)碎片。有關(guān)分區(qū)的詳細(xì)信息,請參閱數(shù)據(jù)分區(qū)指導(dǎo)。
  • 保持平衡碎片,使他們都處理的I / O相似的體積。作為數(shù)據(jù)被插入和刪除,它可能有必要定期地重新平衡的碎片,以保證均勻分布,并減少熱點(diǎn)的機(jī)會。再平衡可能是一個(gè)昂貴的操作。為了降低頻率與再平衡成為必要,你應(yīng)該確保每個(gè)碎片中含有足夠的可用空間來處理變化的預(yù)期貨量計(jì)劃增長。你還應(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)識,并分布在不同的碎片兩個(gè)不同的項(xiàng)目可能被分配相同的ID。

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

注意: 如果在一個(gè)子庫的實(shí)體引用存儲在另一個(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ù)訪問邏輯。
  • 對于許多應(yīng)用來說,產(chǎn)生的小碎片更大數(shù)目可以比具有少量的大碎片,因?yàn)樗鼈兛梢蕴峁┯糜谪?fù)載平衡的機(jī)會增加更加有效。如果預(yù)計(jì)需要碎片從一個(gè)物理位置移動(dòng)到另一個(gè)這樣的方法也可以是有用的。移動(dòng)小碎片比移動(dòng)一個(gè)大的更快。
  • 確保提供給每個(gè)分片存儲節(jié)點(diǎn)的資源足以處理數(shù)據(jù)的規(guī)模和吞吐量方面的可擴(kuò)展性要求。欲了解更多信息,請參閱數(shù)據(jù)分區(qū)引導(dǎo)部分“設(shè)計(jì)分區(qū)的可擴(kuò)展性”。
  • 考慮復(fù)制參考數(shù)據(jù)所有碎片。如果從一個(gè)子庫中檢索數(shù)據(jù)的操作還引用靜態(tài)或緩慢移動(dòng)的數(shù)據(jù)作為同一查詢的一部分,這個(gè)數(shù)據(jù)添加到碎片。然后,應(yīng)用程序可以讀取所有用于容易地查詢中的數(shù)據(jù),而無需進(jìn)行額外的往返行程到一個(gè)單獨(dú)的數(shù)據(jù)存儲中。

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

  • 它可以是難以維持的碎片之間的參照完整性和一致性,所以你應(yīng)該盡量減少影響在多個(gè)碎片數(shù)據(jù)操作。如果應(yīng)用程序必須通過碎片修改數(shù)據(jù),評估完整的數(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)最終一致性的更多信息,請參閱數(shù)據(jù)一致性底漆。
  • 配置和管理大量碎片可能是一個(gè)挑戰(zhàn)。任務(wù),例如監(jiān)控,備份,檢查一致性,并記錄或?qū)徲?jì)必須完成對多個(gè)碎片和服務(wù)器,在多個(gè)位置有可能保持。這些任務(wù)可能會通過使用腳本或其他自動(dòng)化解決方案,但腳本和自動(dòng)化可能無法完全消除額外的行政要求執(zhí)行。
  • 碎片可以是地理定位的,使得它們包含的數(shù)據(jù)是靠近使用它的應(yīng)用程序的實(shí)例。這種方法可以顯著改善的性能,但是需要額外考慮為必須訪問多個(gè)分塊中的不同位置的任務(wù)。

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

使用這種模式:

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

注意: 分片的主要焦點(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ù)原。欲了解更多信息,請參閱數(shù)據(jù)分區(qū)指導(dǎo)。

例子

下面的示例使用了一組充當(dāng)碎片的 SQL Server 數(shù)據(jù)庫。每個(gè)數(shù)據(jù)庫包含一個(gè)應(yīng)用程序使用的數(shù)據(jù)的一個(gè)子集。應(yīng)用程序檢索該被分布在整個(gè)碎片通過使用它自己的分片邏輯(這是一個(gè)扇出查詢的一個(gè)例子)的數(shù)據(jù)。將位于每個(gè)子庫中的數(shù)據(jù)的細(xì)節(jié)是通過這樣的方法稱為 GetShards 返回。此方法返回 ShardInformation 對象,其中 ShardInformation 類型包含一個(gè)標(biāo)識符為每個(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 對象名單進(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);