-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 하는 방법으로 해결해야함