MongoDB分片方式及片鍵選擇

(一)分片方式 shell

MongoDB提供了基於哈希(hashed)和基於範圍(Range)2種分片方式:數據庫

(1.1)哈希分片
哈希分片使用hash索引來在分片集羣中對數據進行劃分。哈希索引計算某一個字段的哈希值做爲索引值,這個值被用做片鍵。
哈希分片以減小定向操做和增長廣播操做爲代價。分片集羣內的數據更加均衡。
從MongoDB4.0開始,mongo shell提供了convertShardKeyToHashed()方法,用於查看鍵的hash值。spa

選擇做爲hash分片鍵的字段應該有良好的基數或者該字段包含大量不一樣的值,hash分片很是適合選取具備像objectId或時間戳那樣單調更改的字段做爲片鍵。code

使用sh.shardCollection()方法,來對集合進行hash分片blog

sh.shardCollection("database.collection",{<field> : "hashed" } )

 

(1.2)範圍分片
基於範圍的分片會將數據劃分爲由片鍵值肯定的連續範圍。在範圍分片模型中,具備「接近」片鍵的文檔可能位於相同的chunk或者shard中,連續範圍讀取文檔將變得高效,可是若是片鍵選擇不佳,則讀取和寫入的想你將會下降。
若是未選擇其它選項(如hash分片或者zone),則基於範圍的分片是默認的分片方式。
範圍分片片鍵的選擇:索引

  • 基數大
  • 頻率低
  • 非單調變化

使用sh.shardCollection()方法,來對集合進行範圍分片,能夠選擇單字段或者多字段路由

sh.shardCollection("database.collection",{<shard key>})

 

(二)片鍵選擇因素
分片鍵決定了集合內的文檔如何在集羣的多個分片上分佈數據,分片鍵要麼是一個索引字段,要麼是一個存在於集合全部文檔中的符合索引字段。MongoDB嘗試在集羣中的各個分片之間平均分配數據塊(chunk),特別注意,shard之間平均分配的數據塊(chunk),而不是數據量,分片鍵的選擇直接關係到分片結果的好壞。文檔

NOTE:
在MongoDB4.2以前,文檔的分片字段是不能夠修改的。從4.2版本開始,除非分片鍵是不可變的_id字段,不然你能夠更新文檔的分片字段。hash

全部須要分片的集合都必須具備支持分片的索引,即分片鍵上必須有索引,可使分片鍵的索引,也能夠是符合索引,對於符合索引,分片鍵必須是索引的前綴。io

  • 若是集合爲空,則sh.shardCollection()在分片鍵上自動建立索引,無需認爲干預
  • 若是集合存在數據,則必須先建立索引,而後再使用sh.shardCollection()來爲集合分片。

分片鍵的選擇須要綜合考慮分片鍵的基數、頻率和變化率。

  • 基數。分片鍵的基數決定了分片集羣能夠建立的最大chunk的數目。在任何給定的時間,惟一的分片值只能存在一個chunk上。例如:使用性別進行分片,則只能分爲「男」和「女」2個chunk,不能隨着數據增多而分裂爲更多的chunk,由於一個分片值只能存儲在同一個chunk中。
  • 頻率。頻率表明給定值在該列中出現的比率,與關係型數據庫中select distinct ...殊途同歸。若是大多數文檔包含了這些值的子集,那麼存儲這些文檔的chunk將成爲集羣中的瓶頸,隨着數據的增加,他們將會成爲不可分割的數據塊,下降了集羣水平擴展的有效性。例如:集合people用來統計各個名族的人信息,使用名族做爲分片字段,那麼根據我國56個名族的人數分佈,佔據人口總數92%的漢族將佔據一個chunk,這樣會致使該chunk很是巨大,失去了分片的意義。
  • 變化率。單調遞增或單調遞減的分片鍵可能將數據寫到集羣中的單個分片上。若是分片鍵值始終在增長,則全部新插入都將路由到以maxKey爲上限的塊。 若是分片鍵值始終在減少,則全部新插入都將路由到以minKey爲下限的塊。 包含該塊的分片將成爲寫操做的瓶頸。

【完】

相關文章
相關標籤/搜索