5. Why Sharding
Index
Ram 추가
t
Se
a
성능
lic
p
Re
디스크 성능
읽기 분산
! !
ng
수평적 분산
di
ar
쓰기 분산
Sh
Scale-up
확장성 Manual
! !
ng
Scale-out
di
ar
Auto
Sh
t
Se
a
ic
pl
가용성
Re
11. Sharding Collection
cloud-docs 의 spreadsheets 컬렉션에 저장되는 문서 구
조
{
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-
16T10:02:43.623Z”),
data: “raw ducoment data”
}
12. Sharding Collection
Shard 가 데이터 범위를 책임지도록 하는 경우
[Abbott, Harris] [Harris, Peter] [Peter,
Zackery]
A1 A2 A3
Collection A
B
C
Shard A Shard B Shard C
13. Sharding Collection
Shard 가 데이터 범위를 책임지도록 하는 경우
[Abbott, Harris] [Harris, Peter] [Peter,
Zackery]
Shard A Shard B Shard C
그림 : Mongo DB 활용 가이드 24p
14. Sharding Collection
Shard 가 데이터 범위를 책임지도록 하는 경우
[Abbott, Fred] [Fred, Peter] [Peter,
Zackery]
Shard A Shard B Shard C
그림 : Mongo DB 활용 가이드 24p
15. Sharding Collection
Shard A 에 데이터가 늘어나는 경우
Shard A Shard B Shard C
500 GB 500 GB 300 GB
100 GB
400 GB 600 GB
300 GB
150 GB
400 GB 450 GB 450 GB
그림 : Mongo DB 활용 가이드 25p
16. Sharding Collection
새로운 샤드가 추가된 경우
Shard A Shard B Shard C Shard D
500 GB 500 GB 500 GB 0 GB
100 GB 200 GB 300 GB
400 GB 400 GB 400 GB 300 GB
600 GB!!
그림 : Mongo DB 활용 가이드 25p
17. Chunk
하나의 Shard 안에 있는 데이터는 청크라는 논리적 단위
로 나누어진다 .
Shard A Shard B Shard C
C1 C3 C6 C2 C7 C8 C4 C5 C9
Collection A
B
C
18. Chunk
Shard A 에 데이터가 늘어나는 경우
Shard A Shard B Shard C
C1 C3 C6 C2 C5 C7 C4
500 GB 500 GB 300 GB
100 GB 50GB
C1 C3 C6 C2 C5 C7 C4 C6 C7
400 GB 450 GB 450 GB
19. Chunk
새로운 샤드가 추가된 경우
Shard A Shard B Shard C Shard D
C1 C3 C6 C2 C7 C8 C4 C5 C9
500 GB 500 GB 500 GB 0 GB
100 GB 100 GB 100 GB
C1 C3 C6 C2 C7 C8 C4 C5 C9 C6 C8 C9
400 GB 400 GB 400 GB 300 GB
300 GB!!
20. Chunk
샤드된 컬렉션의 데이터는 Shard Key 에 의해 청크로 분할
된다 .
{
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-16T10:02:43.623Z”),
data: “raw ducoment data”
}
Shard Key: username
• 샤드 키가 없는 문서를 입력하는 것은 허용하지 않음
• 샤드 키로 입력된 값을 변경하는 것도 허용하지 않음
21. Chunk
샤드된 컬렉션의 데이터는 Shard Key 에 의해 청크로 분할
된다 .
Chunk 시작 끝 샤드
C1 -∞ abbott A
C2 abbott dayton B
C3 dayton harris A
C4 harris norris C
… … …
표 : Mongo DB In Action 258p
22. Quiz.
Dayton 이라는 이름을 가진 사용자는 어느 청크에 있을까요
?
Chunk 시작 끝 샤드
C1 -∞ abbott A
C2 abbott dayton B
C3 dayton harris A
C4 harris norris C
… … …
Answer: C3
24. Chunk Split
청크는 일정 크기 (64MB, 혹은 100,000 다큐먼트 ) 에
도달하면 분할된다 .
C1 C1 C2
abbott dayton abbott brad dayton
B B
Local Disk Local Disk
25. Chunk Migration
샤드 간 청크 수의 불균형이 일어나면 Balancer 가 Chunk
Migration 작업을 수행한다 .
Shard A Shard B
C1 C3 C6 C7 C8 C2 C4 C5
C9
9 C10
10 C11
11 C12
12 C13
C14 C15
Banalcer
샤드 간 청크 수가 8 개 이상 차이
날 때 Migration
26. Chunk Migration
Migration Process Config
mongos
Config
balancer
Config
C2 C4 C4
Shard A Shard B
1. Config 서버에 분산 락 잠금
2. Shard A 에 청크 이동 명령
3. Shard A 에서 Shard B 로 청크 복사
4. 복사가 완료되면 Config 서버의 청크 정보를 업데이트하고 락
해제
5. Shard A 에서 청크 삭제
28. Target Query
샤드 키가 쿼리에 포함되어 있어 데이터가 어느 샤드에 있
는지 알 수 있는 쿼리
Application
Chunk 시작 끝 샤드
C1 -∞ abbott A db.spreadsheets.find({username: “Abbott”})
C2 abbott dayton B mongos
C3 dayton harris A
C4 harris norris C
… … …
Primary Primary
Secon- Secon-
Shard A dary dary Shard B
Arbiter Arbiter
29. Global Query
샤드 키가 쿼리에 포함되어 있지 않아 데이터가 어느 샤드
에 있는지 알 수 없는 쿼리
Application
db.spreadsheets.find({filename: “sheet-#1”})
mongos
Index: filename
Primary Primary
Secon- Secon-
Shard A dary dary Shard B
Arbiter Arbiter
30. Index
• 각 샤드는 자신만의 인덱스를 가지고 있다 .
• 각 샤드가 샤드 컬렉션에 대해 다른 인덱스를
가질 경우 질의어 성능이 일관되지 못하다 .
• 샤드 컬렉션은 _id 필드와 샤드 키에 대해서만
고유 인덱스를 허용한다 .
31. Shard Key
고르지 못한 분포
• _id
• timestamp {
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
Application filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-
16T10:02:43.623Z”),
data: “raw ducoment data”
mongos
}
Shard A Shard B Shard C
• 쓰기 분산 불가능
32. Shard Key
작은 Cardinality
• type (ex. “excel”, “word”, “ppt”, “pdf”)
• sex {
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
Application type: “excel”,
filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-
16T10:02:43.623Z”),
mongos
data: “raw ducoment data”
}
Shard A Shard B Shard C
• 확장이 제한적임
33. Shard Key
지역성 (locality) 결핍
• MD5
{
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
Application filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-
16T10:02:43.623Z”),
data: “raw ducoment data”,
mongos
md5: d131dd02c5e6eec4…
}
Shard A Shard B Shard C
• 과중한 읽기 부하
• 모든 Index 페이지가 메모리에 존재해야 함
34. Shard Key
지역성 (locality) 결핍 MD5 Index
a1c.. pxd..
a1c.. go2..
삽입된 데이터의 인덱스 생성은 무작위로 일어난다 .
따라서 모든 인덱스 페이지가 메모리에 존재해야 한다
.
35. Shard Key
분할될 수 없는 청크
• User Id
{
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
Application filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-
16T10:02:43.623Z”),
data: “raw ducoment data”,
mongos
md5: d131dd02c5e6eec4…
}
Shard A Shard B Shard C
• Henry 라는 사용자가 대량이 데이터를 계속 삽입해도 청크가 분할되지 않음
36. Shard Key
이상적인 Shard Key
• 삽입 연산을 샤드 간에 고르게 분산
• CRUD 연산이 참조 지역성의 장점을 이용
• 청크가 분할 가능해야 함
{
_id: ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”, {username: 1, _id: -1}
filename: “spreadsheet-1”,
updated_at: ISODate(“2013-02-
16T10:02:43.623Z”),
data: “raw ducoment data”,
md5: d131dd02c5e6eec4…
}
37. Quiz.
웹로그 분석 시스템
{
_id:
ObjectId(“4d6e9b89b600c2c196442c21”),
domain: “org.mongodb”,
url: “/downloads”,
views: 256
}
Answer: {domain: 1, url: 1}
38. Quiz.
카드 사용 분석 시스템
{
_id:
ObjectId(“4d6e9b89b600c2c196442c21”),
username: “henry”,
cardnumber: “1234-5678-1234-2345”,
amount: 2150000
month: “2013-02”
}
Answer: {month: 1, username: 1}
40. Failover
샤드 Member 장애
Config
Application
mongos Config
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
41. Failover
샤드 Member 장애
Config
Application
mongos Config
읽기 전용
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
42. Failover
샤드 전체 장애
Config
Application
일부 데이터 및 에러 반환
> db.foo.find()
{_id: 1}
mongos Config
{_id: 2}
Error: mongos connectionpool:
…
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
43. Failover
Config 서버 장애 읽기만 가능
분할 , 이동 중지
Config
Application
mongos Config
읽기 쓰기 가능
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
44. Failover
Data 파일 복사 후
Config 서버 복구 Restart
Config
Application
mongos Config
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
45. Failover
mongos 서버 장애
Config
Application
Application 서버
복구 후 mongos
시작
mongos Config
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
46. Failover
mongos 서버 장애
Config
Application Application
mongos mongos Config
Config
Primary Primary
Shard A Secon- Secon- Shard B
dary dary
Arbiter Arbiter
47. Deployment
Shard A Shard A
Primary Secondary
Shard B
Config #1 Config #3
Arbiter
Shard B Shard B
Primary Primary
Config #2 Shard A
Arbiter
그림 : Mongo DB In Action 285p
48. Deployment
Shard A Shard A
Primary Secondary
Shard B
Config #1 Config #3
Arbiter
Shard B Shard B
Primary Primary
Config #2 Shard A
Arbiter
49. Deployment
Shard A Shard A
Primary Secondary
Shard B
Config #1 Config #3
Arbiter
Shard B Shard B
Primary Primary
Config #2 Shard A
Arbiter
50. Deployment
Shard A Shard A
Config #1
Primary Secondary
데이터 센터
( 메인 )
Shard B Shard B
Config #2
Primary Secondary
데이터 센터
Shard A Shard B
( 복구 ) Secondary
Config #3
Secondary
그림 : Mongo DB In Action 286p
51. Tips
클러스터 크기 산정
• 가능한 적은 샤드를 유지
• 100G 정도까지는 샤드를 하지 않아도 나쁘지 않
음
• SSD 사용 시 메모리의 3 배까지 용량 수용 가능
52. Tips
기존 컬렉션 샤딩
• Migration 시 분당 100MB ~ 200MB 전송
• 50GB 컬렉션 샤딩 시 대략 8 시간 소요
• 수동으로 선분할 조치
• 성능 저하 발생하기 이전에 미리 샤딩 필요
55. Management
config 데이터베이스
Collection 설명
mongos 과거부터 현재까지 모든 mongos 프로세스 일람
shards 클러스터에 저장된 모든 샤드 정보
database 샤딩 여부에 상관없이 클러스터 내에 있는 모든 데이터베
이스 정보
collections 샤딩된 모든 컬렉션 정보
chunks 클러스터에 저장된 모든 청크 정보
changelog 청크 분할 및 마이그레이션에 대한 이력 정보
locks Mongos 가 여러 개 있을 때 데이터 일관성을 관리하기 위
한 분산 락 정보
56. Management
샤드 추가
• sh.addShard() 명령으로 새로운 샤드 추가
• 인덱스와 작업 데이터가 램의 90% 에 도달하기
최소 몇 주 전에 새 샤드 추가
sh.addShard(“shard-
c/new1.server.com:27017,new2.server.com:27017”)
57. Management
샤드 추가
RAM
Application
Disk
Application mongos
청크를 이동시키기 위해 데
Disk 이터를 메모리로 로드
Application mongos
Working Set 영역이 작아
져 데이터 작업을 위한
Disk I/O 증가
그림 : Mongo DB 활용 가이드 61p
58. Management
샤드 삭제
• removeshard 명령으로 샤드 삭제
• 삭제하려는 샤드가 Primary 로 설정된 데이터베
이스가 있으면 Primary 샤드 변경
db.runCommand(
{removeshard: “shard-b/Hyewon-PC:30100/Hyewon-PC:30101”}
)
db.runCommand(
{moveprimary: “test”, to: “shard-a”}
)
59. Management
샤드에서 컬렉션 삭제
• 컬렉션을 샤드에서 제거하는 방법은 없음
• 컬렉션을 덤프하고 , 다른 이름의 컬렉션으로 복
구
mongodump -h Hyewon-PC --port 40000 -d cloud-docs –c foo
DATABASE: cloud-docs to dump/cloud-docs
cloud-docs.foo to dump/cloud-docs/foo.bson
mongorestore -h Hyewon-PC --port 40000 -d cloud-docs –c foo
Dump/cloud-docs/foo.bson
going into namespace [cloud-docs.bar]
60. Management
Backup
• 각 설정서버와 샤드에서 mongodump
• mongos 를 통해 mongodump 실행
• 설정 서버와 샤드의 데이터 파일 카피
어떤 백업 방법이든 Balancer 를 중지시켜 청크
의 이동을 막음 .
61. Management
Balancer 중지
• 설정 데이터베이스의 settings 컬렉션 업데이
트
> use config
• Locks 컬렉션을 조회하여 Balancer 상태 확인
> db.settings.update({_id: “balancer”}, {$set: {stopped:
true}}, true);
> use config
> db.locks.find({_id: “balancer”})
{
"_id" : "balancer",
"process" : "Sejoon-PC:40000:1360158269:41",
"state" : 0,
…
}
Hinweis der Redaktion
청크 사이즈가 64 MB 인 이유 : 청크 사이즈가 너무 크면 마이그레이션 비용 ( 메모리 , 네트워크 트래픽 등 ) 이 비싸진다 . 실제로 청크 사이즈가 너무 커져서 512MB 가 넘어가면 청크를 옮기지 않는다 . 반면 청크 사이즈가 너무 작으면