Mongodb 分片 手动维护chunk
去年的笔记
For instance, if a chunk represents a single shard key value, then MongoDB cannot split the chunk even when the chunk exceeds the size at which splits occur.
如果一个chunk只包含一个分片键值,mongodb 就不会split这个chunk,即使这个chunk超过了 chunk需要split时的大小。所以分片键的选择非常重要。
这里举个例子,比如我们使用日期(精确到日) 作为分片键,当某一天的数据非常多时,这个分片键值(比如2015/12/12)的对应的chunk会非常大,
超过64M,但是这个chunk是不可分割的。这会造成数据在各个分片中不平衡,出现性能问题。
所以我们要以 选择性高的字段做为分片键,如果这个字段(比如 日志级别)选择性低,我们可以再添加一个选择性高的字段,两个字段做为分片键。
如果以日期做为分片键,为了避免大的chunk,我们可以把日期精确到 时分秒 然后做分片键。
if your chunk ranges get down to a single key value then no further splits are possible and you get "jumbo" chunks。
以下是 大的chunk的例子:
http://dba.stackexchange.com/questions/72626/mongo-large-chunks-will-not-split
一个常见的错误:
Mongos version 3.0.1 Split Chunk Error with Sharding
http://dba.stackexchange.com/questions/96732/mongos-version-3-0-1-split-chunk-error-with-sharding?rq=1
手动切割分片:
http://www.cnblogs.com/xuegang/archive/2012/12/27/2836209.html
一、使用splitFind对可分割的chunk 手动分割。
splitFind(namespace, query),query的值必须包括分片键。将一个query指定的chunk,分割为两个基本相等大小的chunk。
mongos>db.users003.getShardDistribution()Shardshard1atshard1/192.168.137.111:27017,192.168.137.75:27017data:212KiBdocs:3359chunks:2estimateddataperchunk:106KiBestimateddocsperchunk:1679Shardshard2atshard2/192.168.137.138:27018,192.168.137.75:27018data:211KiBdocs:3337chunks:2estimateddataperchunk:105KiBestimateddocsperchunk:1668Shardshard3atshard3/192.168.137.111:27019,192.168.137.138:27019data:209KiBdocs:3304chunks:2estimateddataperchunk:104KiBestimateddocsperchunk:1652Totalsdata:633KiBdocs:10000chunks:6Shardshard1contains33.58%data,33.58%docsincluster,avgobjsizeonshard:64BShardshard2contains33.37%data,33.37%docsincluster,avgobjsizeonshard:64BShardshard3contains33.03%data,33.04%docsincluster,avgobjsizeonshard:64Bmongos>mongos>mongos>AllChunkInfo("test1.users003",true);ChunkID,Shard,ChunkSize,ObjectsInChunktest1.users003-_id_MinKey,shard1,106368,1662test1.users003-_id_-6148914691236517204,shard1,108608,1697test1.users003-_id_-3074457345618258602,shard3,107072,1673test1.users003-_id_0,shard3,104384,1631test1.users003-_id_3074457345618258602,shard2,110592,1728test1.users003-_id_6148914691236517204,shard2,102976,1609***********SummaryChunkInformation***********TotalChunks:6AverageChunkSize(bytes):106666.66666666667EmptyChunks:0AverageChunkSize(non-empty):106666.66666666667mongos>db.users003.count()10000
执行splitFind之后,chunk被分割为两个基本相同大小的chunk:
mongos>sh.splitFind("test1.users003",{"name":"u_100"}){"ok":0,"errmsg":"noshardkeyfoundinchunkquery{name:\"u_100\"}"}mongos>sh.splitFind("test1.users003",{"_id":ObjectId("568bdf16e05cf980cec8c455")}){"ok":1}mongos>mongos>mongos>mongos>mongos>mongos>mongos>AllChunkInfo("test1.users003",true);ChunkID,Shard,ChunkSize,ObjectsInChunktest1.users003-_id_MinKey,shard1,106368,1662test1.users003-_id_-6148914691236517204,shard1,54272,848test1.users003-_id_-4665891797978533183,shard1,54336,849test1.users003-_id_-3074457345618258602,shard3,107072,1673test1.users003-_id_0,shard3,104384,1631test1.users003-_id_3074457345618258602,shard2,110592,1728test1.users003-_id_6148914691236517204,shard2,102976,1609***********SummaryChunkInformation***********TotalChunks:7AverageChunkSize(bytes):91428.57142857143EmptyChunks:0AverageChunkSize(non-empty):91428.57142857143mongos>db.users003.getShardDistribution()Shardshard1atshard1/192.168.137.111:27017,192.168.137.75:27017data:212KiBdocs:3359chunks:3estimateddataperchunk:70KiBestimateddocsperchunk:1119Shardshard2atshard2/192.168.137.138:27018,192.168.137.75:27018data:211KiBdocs:3337chunks:2estimateddataperchunk:105KiBestimateddocsperchunk:1668Shardshard3atshard3/192.168.137.111:27019,192.168.137.138:27019data:209KiBdocs:3304chunks:2estimateddataperchunk:104KiBestimateddocsperchunk:1652Totalsdata:633KiBdocs:10000chunks:7Shardshard1contains33.58%data,33.58%docsincluster,avgobjsizeonshard:64BShardshard2contains33.37%data,33.37%docsincluster,avgobjsizeonshard:64BShardshard3contains33.03%data,33.04%docsincluster,avgobjsizeonshard:64B
二、使用splitAt对可分割的chunk 手动分割。
splitAt(namespace, query) 官方解释:
sh.splitAt() splits the original chunk into two chunks. One chunk has a shard key range
that starts with the original lower bound (inclusive) and ends at the specified shard key value (exclusive).
The other chunk has a shard key range that starts with the specified shard key value (inclusive) as the lower bound
and ends at the original upper bound (exclusive).
三、手动迁移chunk
db.runCommand( { moveChunk : "myapp.users" ,
find : {username : "smith"} ,
to : "mongodb-shard3.example.net" } )
注释:
moveChunk:一个集合的名字要加上数据库的名称:比如test.yql
find:一个查询语句,指定集合中的符合查询的数据或者chunk,系统自动查出from 的shard
to: 指向chunk的目的shard
只要目的shard和源sharad同意指定的chunk由目的shard接管,命令就返回。迁移chunk是一个比较复杂的过程,它包括两个内部通信协议:
1 复制数据,包括在复制过程中的变化的数据
2 确保所有参与迁移的组成部分:目的shard ,源shard ,config server都确定迁移已经完成!
The command will block until the migration is complete.
四、相关脚本
--显示collection的chunk分布信息db.collection.getShardDistribution()显示chunk信息脚本:AllChunkInfo=function(ns,est){varchunks=db.getSiblingDB("config").chunks.find({"ns":ns}).sort({min:1});//thiswillreturnallchunksforthensorderedbymin//somecountersforoverallstatsattheendvartotalChunks=0;vartotalSize=0;vartotalEmpty=0;print("ChunkID,Shard,ChunkSize,ObjectsInChunk");//headerrow//iterateoverallthechunks,printoutinfoforeachchunks.forEach(functionprintChunkInfo(chunk){vardb1=db.getSiblingDB(chunk.ns.split(".")[0]);//getthedatabasewewillberunningthecommandagainstlatervarkey=db.getSiblingDB("config").collections.findOne({_id:chunk.ns}).key;//willneedthisforthedataSizecall//dataSizereturnstheinfoweneedonthedata,butusingtheestimateoptiontousecountsislessintensivevardataSizeResult=db1.runCommand({datasize:chunk.ns,keyPattern:key,min:chunk.min,max:chunk.max,estimate:est});//printjson(dataSizeResult);//uncommenttoseehowlongittakestorunandstatusprint(chunk._id+","+chunk.shard+","+dataSizeResult.size+","+dataSizeResult.numObjects);totalSize+=dataSizeResult.size;totalChunks++;if(dataSizeResult.size==0){totalEmpty++};//countemptychunksforsummary})print("***********SummaryChunkInformation***********");print("TotalChunks:"+totalChunks);print("AverageChunkSize(bytes):"+(totalSize/totalChunks));print("EmptyChunks:"+totalEmpty);print("AverageChunkSize(non-empty):"+(totalSize/(totalChunks-totalEmpty)));}使用示例:mongos>AllChunkInfo("test1.users001",true);ChunkID,Shard,ChunkSize,ObjectsInChunktest1.users001-_id_MinKey,shard3,11347710,171935test1.users001-_id_-6148914691236517204,shard1,11293458,171113test1.users001-_id_-3074457345618258602,shard1,11320716,171526test1.users001-_id_0,shard3,11349096,171956test1.users001-_id_3074457345618258602,shard2,11340054,171819test1.users001-_id_6148914691236517204,shard2,11328966,171651***********SummaryChunkInformation***********TotalChunks:6AverageChunkSize(bytes):11330000EmptyChunks:0AverageChunkSize(non-empty):11330000
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。