-1. balancer scheduling 하는 법

mongos> use config;
switched to db config
mongos> db.settings.update(
... {_id:"balancer"},
... {$set: {activeWindow: {start : "02:00", stop: "06:00"}}},
... {upsert : true})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "balancer" })
=> config 에서 balancer 수행 시간대 설정
 
mongos>sh.status()
  balancer:
        Currently enabled:  yes
        Currently running:  no
                Balancer active window is set between 02:00 and 06:00 server local time
 

-. schedule 설정 시 balancer 동작 테스트

 
mongos> for (var i = 1; i <= 100000; i++) {
...    db.chunk_test3.insert( { t : i } )
... }
WriteResult({ "nInserted" : 1 })

mongos> db.chunk_test3.getShardDistribution()
Shard repl_shard1 at repl_shard1/mongo_shard1:27018,mongo_shard2:27018,mongo_shard3:27018
 data : 3.14MiB docs : 100000 chunks : 7
 estimated data per chunk : 460KiB
 estimated docs per chunk : 14285

Totals
 data : 3.14MiB docs : 100000 chunks : 7
 Shard repl_shard1 contains 100% data, 100% docs in cluster, avg obj size on shard : 33B
mongos> db.changelog.find({ $and:[ {ns:"test.chunk_test3"} , {what:/^moveChunk/}]} )
 
=> split 은 수행되지만 balanacer 는 정해진 시간에만 돌아가게 됨
chunk balancing 작업은 샤드 노드 간 move chunk 하는 chunk에 대해 copy 해오고 원본 지우는 등의
부하를 줄 수 있는 동작이기 때문에 위처럼 스케쥴링 설정하면 그 시간대에만 수행됨
 

 

-2. 수동 move chunk

balancer 에 의해 chunk 불균형이 발생하면 밸런싱 작업이 자동으로 수행되지만 balancer는 chunk 의 개수만 확인하기 때문에

RDBMS의 HOT Block 처럼 HOT Chunk 로 인한 I/O 집중 등은 해결하지 못하는 문제가 있음

이때 HOT chunk 를 Split 하고 다른 샤드로 move 하는 작업을 수동으로 수행하기도함

mongos> db.chunks.find( {ns:"test.chunk_test"} )
{ "_id" : "test.chunk_test-t_2.0", "lastmod" : Timestamp(3, 1), "lastmodEpoch" : ObjectId("5d92e79f2ce99004d7291d2c"), "ns" : "test.chunk_test", "min" : { "t" : 2 }, "max" : { "t" : 31776 }, "shard" : "repl_shard1", "jumbo" : false, "history" : [ { "validAfter" : Timestamp(1569908639, 6), "shard" : "repl_shard1" } ] }

{ "_id" : "test.chunk_test-t_31776.0", "lastmod" : Timestamp(2, 2), "lastmodEpoch" : ObjectId("5d92e79f2ce99004d7291d2c"), "ns" : "test.chunk_test", "min" : { "t" : 31776 }, "max" : { "t" : 47663 }, "shard" : "repl_shard1", "history" : [ { "validAfter" : Timestamp(1569908639, 6), "shard" : "repl_shard1" } ] }

=> min : { "t" : 2 } ~ max : { "t" : 31776 } chunk 가 HOT Chunk 라고 가정

mongos> sh.splitAt("test.chunk_test",{t:20000})
{
"ok" : 1,
}

mongos> db.chunks.find( {ns:"test.chunk_test"} )
{ "_id" : "test.chunk_test-t_2.0", "lastmod" : Timestamp(3, 5), "lastmodEpoch" : ObjectId("5d92e79f2ce99004d7291d2c"), "ns" : "test.chunk_test", "min" : { "t" : 2 }, "max" : { "t" : 20000 }, "shard" : "repl_shard1", "history" : [ { "validAfter" : Timestamp(1569908639, 6), "shard" : "repl_shard1" } ] }

{ "_id" : "test.chunk_test-t_20000.0", "lastmod" : Timestamp(3, 6), "lastmodEpoch" : ObjectId("5d92e79f2ce99004d7291d2c"), "ns" : "test.chunk_test", "min" : { "t" : 20000 }, "max" : { "t" : 31776 }, "shard" : "repl_shard1", "history" : [ { "validAfter" : Timestamp(1569908639, 6), "shard" : "repl_shard1" } ] }
=> 기존 2~31776 이 하나의 chunk 에 있었지만 split 작업을 통해 2~20000  / 20000~ 31776 두개로 나뉘어짐
 
mongos> sh.moveChunk("test.chunk_test",{t:19999},"repl_shard2")
{
"millis" : 1690,
"ok" : 1,
}

mongos> db.chunks.find( {ns:"test.chunk_test", _id:"test.chunk_test-t_2.0"} )
{ "_id" : "test.chunk_test-t_2.0", "lastmod" : Timestamp(4, 0), "lastmodEpoch" : ObjectId("5d92e79f2ce99004d7291d2c"), "ns" : "test.chunk_test", "min" : { "t" : 2 }, "max" : { "t" : 20000 }, "shard" : "repl_shard2", "history" : [ { "validAfter" : Timestamp(1570081379, 8609), "shard" : "repl_shard2" } ] }
=> max 값 20000은 "미만" 범위
t: 2~19999  가 속한 chunk 를 repl_shard2 로 move 
 
 

-. jumbo chunk 는 move 불가 

mongos> use admin
switched to db admin

mongos> db.runCommand({moveChunk:"test.jumbo_chunk", find: {name:"kimdubi"}, to:"repl_shard2"} )
{
"ok" : 0,
"errmsg" : "Cannot move chunk: the maximum number of documents for a chunk is 26728, the maximum chunk size is 1048576, average document size is 51. Found 300000 documents in chunk  ns: test.jumbo_chunk { name: MinKey } -> { name: MaxKey }",
"code" : 153,
"codeName" : "ChunkTooBig",
}
=> jumbo chunk 는 move chunk 가 안되는데 jumbo chunk 가 생기는 이유는 잘못된 샤드키 설계때문임
mongodump 로 데이터를 덤프 받은 뒤 새로운 샤드 키로 생성된 컬렉션에 다시 mongorestore 하는 방법으로 해결해야함