샤드 키란?
샤드 키(Shard Keys)는 클러스터의 샤드들 간에 컬렉션의 도큐먼트를 어떻게 분산할 것인가를 결정하는 것입니다.
다음의 예를 들어보겠습니다.
4개의 샤드로 구성된 클러스터가 있다고 가정합니다. x
라는 도큐먼트 키를 기준으로 샤드 1(Chunk 1)에는 x
가 -75까지의 데이터를 저장하고, 샤드 2에는 25까지, 샤드 3에는 175까지, 샤드 4에는 175보다 큰 데이터를 분산하여 저장합니다. 이 때 데이터를 분산하는 기준이 되는 키인 x
를 샤드 키라고 합니다.
샤드 키의 작동 원리
만약 회원 관리를 위한 멤버 데이터베이스(members
)를 나이(age
)별로 "0-30", "31-60", "61-무한대"의 3개의 덩어리의 샤드로 나눈다고 하겠습니다. 이 때 age
는 샤드 키가 될 것이며, 이 샤드 키에 대해 다음의 쿼리에 대한 작동 원리를 알아보도록 합니다.
db.members.find({age: 17})
mongos는 age
가 17이 어느 범위에 chunk에 해당하고 있는지 알고 있습니다. 즉, {age: 17}
은 chunk 1에 해당하는 것을 알고 있기 때문에 mongos
는 이 쿼리를 chunk 1으로 직접 요청하고, 처리된 데이터는 다시 mongos
를 통해 클라이언트로 보내어 집니다.
db.members.find({age: {$gt: 40}})
mongos
는 age
가 40 보다 큰 멤버가 어느 chunk에 저장되어 있는지 알고 있습니다. 즉, {age: {$gt: 40}}
인 쿼리에 해당하는 chunk는 chunk 2와 chunk 3이므로, 직렬로 chunk 2와 chunk 3에 순차적으로 쿼리를 요청합니다. 처리된 결과는 mongos
가 취합하여 클라이언트로 보내어 집니다.
db.members.find().sort({name: 1})
이 쿼리는 name
키로 내림차순 정렬을 하는 것입니다. mongos
는 각 샤드에 쿼리를 요청하고 각 샤드로부터 정렬된 결과를 취합합니다. 샤드로부터 mongos
에 전달된 결과값은 데이터 자체가 아닌 커서(cursor) 값을 받기 때문에 전체 결과 데이터를 가져올 필요가 없으며 클라이언트에 커서 값으로 순차적으로 각 서버로 요청하여 정렬된 데이터를 보여 줍니다.
db.members.find({name: "gchoi"})
현재 샤드 키는 age
로 지정되어 있으므로, mongos
는 gchoi
라는 name
이 어느 chunk에 저장되어 있는지 알 수 없습니다. 따라서, mongos
는 모든 샤드에 대해 직렬로 쿼리를 전달하게 되고 각 샤드는 요청된 쿼리를 처리하여 mongos
로 결과를 알려줍니다. mongos
는 결과를 취합하여 클라이언트에 전달합니다.