日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

[mongodb翻译]选择合适的shard key

發(fā)布時(shí)間:2023/11/27 生活经验 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [mongodb翻译]选择合适的shard key 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為一個(gè)集合(collection)選擇合適的shard key非常重要。如果這個(gè)集合非常龐大,那么將來(lái)再來(lái)修改shard key將會(huì)很困難。如有任何疑問(wèn)請(qǐng)到論壇或者IRC尋求幫助。

?

示例文檔

view plain
  1. {??
  2. server?:?"ny153.example.com"?,??
  3. application?:?"apache"?,??
  4. time?:?"2011-01-02T21:21:56.249Z"?,??
  5. level?:?"ERROR"?,??
  6. msg?:?"something?is?broken"??
  7. }??


基數(shù)(cardinality)

一個(gè)集合中的所有數(shù)據(jù)會(huì)被分裂為多個(gè)數(shù)據(jù)塊(chunk),一個(gè)數(shù)據(jù)塊包含了某個(gè)范圍shard key的數(shù)據(jù)。請(qǐng)選擇合適的shard key,否則你將會(huì)得到很大的不能分裂的數(shù)據(jù)塊。

使用上面的日志例子,如果你選擇了:

view plain
  1. {server:1}??


作為shard key,那么所有關(guān)于某個(gè)server的數(shù)據(jù)會(huì)存在一個(gè)數(shù)據(jù)塊中,你可以很容易想到一個(gè)server的數(shù)據(jù)會(huì)超過(guò)64MB(默認(rèn)數(shù)據(jù)塊大小)。如果shard key是:

view plain
  1. {server:1,time:1}??


你可以將單個(gè)服務(wù)器的數(shù)據(jù)分裂到毫秒級(jí)。只要你的單個(gè)服務(wù)器不會(huì)有200MB/S,就不會(huì)有不能分裂的數(shù)據(jù)塊。

保持?jǐn)?shù)據(jù)塊在一個(gè)合適大小是很重要的,這樣數(shù)據(jù)就可以在集群中均衡分布并且移動(dòng)一個(gè)數(shù)據(jù)塊代價(jià)也不會(huì)太大。

?

水平寫

使用分片的一個(gè)主要原因就是分發(fā)寫操作。為了達(dá)到這個(gè)目的,寫操作應(yīng)當(dāng)盡可能的分散到不同的數(shù)據(jù)塊。

再次使用前面的例子,選擇:

view plain
  1. {?time?:?1?}??


作為shard key,會(huì)導(dǎo)致所有的寫操作都集中到最新的數(shù)據(jù)塊中。如果shard key選擇:

view plain
  1. {server:1,application:1,time:1}??


那么每個(gè)服務(wù)器:應(yīng)用映射都會(huì)被寫到不同的地方。如果這里有100種服務(wù)器:應(yīng)用映射,和10臺(tái)服務(wù)器,那么每臺(tái)服務(wù)器將會(huì)分配約1/10的寫操作。

需要注意的是,由于ObjectId中很重要的一部分是基于時(shí)間生成的,使用ObjectId作為shard key等同于直接使用時(shí)間值。

?

查詢隔離

另外一個(gè)考慮就是任何一個(gè)查詢需要分發(fā)到多少個(gè)shard。理想情況下,一個(gè)查詢操作經(jīng)mongos直接分發(fā)到擁有期望數(shù)據(jù)的mongod。如果你知道大部分的查詢使用了那些條件,那么使用這些條件屬性作為shard key可以提高很多效率。

即使查詢條件中沒(méi)有包含shard key,查詢依然可以工作。由于mongos不知道哪個(gè)shard擁有期望的數(shù)據(jù),mongos會(huì)將這個(gè)請(qǐng)求順序分發(fā)到所有的shard中,這會(huì)增加響應(yīng)時(shí)間和網(wǎng)絡(luò)數(shù)據(jù)流量及服務(wù)器負(fù)載。

?

排序

如果查詢中包含了排序請(qǐng)求,這個(gè)查詢請(qǐng)求會(huì)同以前沒(méi)有排序要求時(shí)一樣分發(fā)到需要的shard中。每一個(gè)shard執(zhí)行查詢?nèi)缓笤诒镜刈雠判?#xff08;如果有 索引的話會(huì)使用索引)。mongos會(huì)合并從shard返回的已經(jīng)排序好的結(jié)果,然后返回合并后的數(shù)據(jù)給客戶端。這樣的話,mongos只需要做少量的工 作和很少的RAM。

可靠性

分片的一個(gè)重要方面就是如果整個(gè)shard不能訪問(wèn)了(即使使用了可靠的復(fù)制組),這將會(huì)對(duì)整個(gè)系統(tǒng)帶來(lái)多大的影響。

例如你有一個(gè)類似于twitter的系統(tǒng),評(píng)論記錄類似于:

view plain
  1. {??
  2. _id:?ObjectId("4d084f78a4c8707815a601d7"),??
  3. user_id?:?42?,??
  4. time?:?"2011-01-02T21:21:56.249Z"?,??
  5. comment?:?"I?am?happily?using?MongoDB",??
  6. }??


由于系統(tǒng)對(duì)寫操作是非常敏感的,如果你希望將寫操作分散到各個(gè)服務(wù)器中,你需要使用"_id"或者"user_id"作為shard key。"_id"可以給你較好的顆粒度和寫擴(kuò)散性。但是一旦某個(gè)shard宕機(jī)了,它將會(huì)影響到幾乎所有的用戶(有些數(shù)據(jù)丟失了)。如果你使 用"user_id"作為shard key,此時(shí)一小部分用戶會(huì)受到影響(比如在5個(gè)shard組成的集群中,這個(gè)百分比是20%),即使這些用戶再也看不到他們的任何數(shù)據(jù)了。

?

索引最佳化

正如前面章節(jié)關(guān)于索引的描述,通常經(jīng)常對(duì)一部分索引做讀/更新會(huì)帶來(lái)較好的性能表現(xiàn),這是因?yàn)檫@“活躍”的部分可以大多數(shù)時(shí)間都駐留在RAM。前面 介紹的shard key雖然可以將寫操作分散到各個(gè)shard中,但是他們還是屬于每個(gè)mongod的索引的。作為替代,將時(shí)間戳分解為某種形式并作為shard key的前綴可以帶來(lái)一些好處,這樣可以減小經(jīng)常訪問(wèn)的索引大小。

例如你有一個(gè)圖片存儲(chǔ)系統(tǒng),圖片記錄類似于:

view plain
  1. {??
  2. _id:?ObjectId("4d084f78a4c8707815a601d7"),??
  3. user_id?:?42?,??
  4. title:?"sunset?at?the?beach",??
  5. upload_time?:?"2011-01-02T21:21:56.249Z"?,??
  6. data:?...,??
  7. }??


你可以定制一個(gè)包含了上傳時(shí)間的月份和唯一的標(biāo)示符(如ObjectId,數(shù)據(jù)的md5值等)的_id來(lái)替代默認(rèn)的_id,新的記錄類似于:

view plain
  1. {??
  2. _id:?"2011-01_4d084f78a4c8707815a601d7",??
  3. user_id?:?42?,??
  4. title:?"sunset?at?the?beach",??
  5. upload_time?:?"2011-01-02T21:21:56.249Z"?,??
  6. data:?...,??
  7. }??


使用它作為shard key,同時(shí)也是訪問(wèn)一個(gè)文檔使用的_id.它可以很好的將寫操作分散到所有shard中。并且它減小了大部分查詢需要訪問(wèn)的索引的大小。

進(jìn)一步注釋:

  • ?在每個(gè)月的開始,只有一臺(tái)shard被訪問(wèn)知道均衡器開始分裂數(shù)據(jù)塊。為了避免這種潛在的低性能和數(shù)據(jù)遷移,建議在時(shí)間前面增加了一個(gè)范圍值(比如5或者更大的范圍值如果你有5臺(tái)服務(wù)器)。
  • 更進(jìn)一步的改善,你可以將用戶名(user id)納入到圖片id中,這樣可以保持同一個(gè)用戶的文檔都存儲(chǔ)到同一個(gè)shard中,例如:"2011-01_42_4d084f78a4c8707815a601d7"

?

GirdFS

根據(jù)不同的需要,這里有多種不同的方法可以對(duì)GridFS進(jìn)行分片。一種基于已經(jīng)存在的索引的分片方法是:

  • "files"集合不做分片。所有的文件記錄都將存儲(chǔ)在一個(gè)shard中,強(qiáng)烈建議保證該shard非常可靠(使用至少3節(jié)點(diǎn)的復(fù)制組)。
  • "chunks" 集合應(yīng)當(dāng)使用索引"files_id:1"進(jìn)行分片。由驅(qū)動(dòng)創(chuàng)建的已經(jīng)存在的"files_id,n"索引不能被使用在"files_id"上面進(jìn)行分片 (這是一個(gè)限制,將來(lái)會(huì)被fix)。所以你需要單獨(dú)為"files_id"創(chuàng)建一個(gè)索引。使用"files_id"進(jìn)行分片開始保證某個(gè)文件存儲(chǔ)到同一個(gè) shard中,這樣"filemd5"命令就可以工作了。運(yùn)行命令: view plain
    1. >?db.fs.chunks.ensureIndex({files_id:?1});??
    2. >?db.runCommand({?shardcollection?:?"test.fs.chunks",?key?:?{?files_id?:?1?}})??
    3. {?"collectionsharded"?:?"test.fs.chunks",?"ok"?:?1?}??

files_id默認(rèn)使用ObjectId,因此files_id是遞增的,所有新的GridFS數(shù)據(jù)塊會(huì)被送往同一個(gè)shard。如果你的寫負(fù)載太大以至于單臺(tái)服務(wù)器無(wú)法應(yīng)付,你可能需要考慮使用其他的shard key或者使用其他的值作為file的_id.

轉(zhuǎn)載于:https://www.cnblogs.com/xinghebuluo/archive/2011/11/22/2266204.html

總結(jié)

以上是生活随笔為你收集整理的[mongodb翻译]选择合适的shard key的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。