레이블이 database인 게시물을 표시합니다. 모든 게시물 표시
레이블이 database인 게시물을 표시합니다. 모든 게시물 표시

2018-04-22

2018년 16번째 주

이 포스팅은 그냥 지난 한 주간 읽었던 것들을 정리하는 포스트입니다. 그냥 예전에 봤던 글 중 나중에 필요한데 뭐였는지 기억 안 나는 글들이 있어서 쓰기 시작했습니다.
 보통 하는 일과 관련된 글들이 올라오겠지만 딱히 정해둔 주제는 없고, 그때그때 관심 있었던 것을 읽었기 때문에 지난주에 쓰인 글일 수도 있고 몇 년 전에 쓰인 글일 수도 있습니다.


ISO week date

오늘이 올해의 몇 번째 주인지 정하는 기준은 말하는 사람마다 다르다. 그래서 이 요약정리 시리즈는 ISO 8601 기준으로 몇 번째 주인지 표기한다. ISO 8601에 따르면 1월 4일이 포함된 주를 그 해의 첫 번째 주로 취급한다. 다른 말로 한 주의 시작을 월요일로 봤을 때 4일 이상 포함된 첫 번째 주가 그 해의 첫 번째 주인 것이다.

TextQL

머신 러닝이나 데이터 마이닝을 할 때 데이터의 경향성을 대강 파악하고 싶을 때가 있다. 이럴 때 사용되는 데이터는 보통 매우 큰 데이터이기 때문에 에디터로 열어서 보는 것은 무리가 있고, 간단하게 스크립트를 짜서 실행하게 된다. 근데 이때 하는 일은 대부분 비슷한 일이기 때문에 꽤나 귀찮은 작업이었는데, 스크립트를 짜지 않고 파일을 SQL을 실행시켜주는 프로젝트가 있었다.

아직 사용해보지는 않아서 직접 스크립트를 짜는 것과 비교하면 어떨지는 모르겠지만 꽤 많은 사람이 쓰고 있는 것 같다.

Writing

수학을 배워야 하는 이유가 사고하는 법을 익히기 위해서이듯이, 글쓰기를 배우는 이유는 무엇을 생각했는지 명확하게 하기 위해서다. 사람은 모든 것을 기억할 수 없기 때문에 자신이 생각한 것을 써서 정리해야 한다는 것이다. 게다가 글을 쓰는 것은 내가 글 쓰는 주제에 대해 나보다 모르는 독자를 가정하고 글을 쓰게 된다. 그래서 평소에는 당연하게 생각하고 넘어갔던 것들에 대해서도 한 번 더 생각하고 넘어갈 시간을 가지게 한다.

How quantum computing could wreak havoc on cryptocurrency

양자 컴퓨터가 상용화되면 현재 사용되는 암호화 기법 중 많은 것들이 쉽게 풀리게 된다. Cryptocurrency들은 이날을 대비해서 post-quantum cryptography로 넘어갈 준비를 해야 한다는 글이다. NSA는 수십 년 안에 양자 컴퓨터가 실제 암호를 해킹할 수 있을 정도로 발전할 것이라는 보고서를 작성한 적이 있다. 하지만 윗글의 글쓴이는 수십 년까지 가지 않고 십수 년 내에 양자 컴퓨터가 암호학에 실질적인 위험이 될 것이니 대비를 해두어야 한다고 주장한다.

OLPC’s $100 laptop was going to change the world — then it all went wrong

10년 전쯤 유행했던 OLPC라는 프로젝트가 있다. One Laptop Per Child라는 이름 그대로 모든 아이에게 노트북을 제공하겠다는 프로젝트였다. XO-1이라는 100$짜리 노트북을 제작하여 개발도상국의 어린이에게 노트북을 하나 더 제공하겠다는 프로젝트였다.

하지만 모든 아이에게 XO-1을 제공하겠다는 프로젝트는 결국 실패했다. XO-1 이후 출시할 계획이었던 XO-2는 나오지도 못했다. 실패한 원인은 여러 가지 있다. 애초에 목표했던 100$ 가격에 도달하지 못하기도 했고, 인텔에서 나온 넷북이 XO-1보다는 비싸지만, 훨씬 훌륭한 성능과 보편성 때문에 더 인기 있었다.

나는 이것을 뜻은 크지만, 기술이 뒤받쳐주지 못해서 생긴 OLPC의 완벽한 실패라고 생각한다. 하지만 윗글의 저자는 OLPC가 넷북의 보급을 가지고 왔고 덕분에 저가형 노트북 시장이 커졌으므로 어느 정도 목표를 이루었다고 보는듯하다.

The latest trend for tech interviews: Days of unpaid homework

최근 유행하고 있는 테크회사들이 인터뷰 시 단순히 면접으로 끝내는 것이 아니라 시간이 오래 걸리는 과제를 내는 것을 비판하는 글이다. 말하고자 하는 바는 이해하지만, 딱히 더 좋은 해결법은 생각나지 않는다. 나는 회사에서 줄 수 있는 가장 큰 복지 중 하나는 좋은 팀을 구성해주는 것이라고 생각한다. 그런 면에서 충분히 검증되지 않은 사람과 일하고 싶지 않다. 물론 검증에 필요한 비용을 구직자에게 전가하는 방식은 옳지 못하다. 개선할 필요가 있다. 하지만 그게 윗글에서 말하는 한 시간 내외의 코딩면접인지는 잘 모르겠다.

Why Is SQLite Coded In C

SQLite가 어째서 C를 사용하는지에 관한 글이다. 개인적으로 C를 좋아하지는 않지만, 이 글에서 주장하는 바는 전부 타당하다고 생각한다.

Conceptual compression means beginners don’t need to know SQL — hallelujah!

Ruby on Rails(a.k.a. RoR)의 제작자, DHH가 쓴 글이다. RoR은 잘 만들어진 ORMActive Record로 유명하다. 사실 지금까지 Active Record 외에는 쓸만한 수준으로 동작하는 ORM을 본 적이 없다. 하지만 여전히 ORM이 SQL을 대체할 수 있는가에 대해서는 회의적이다. 아마 DHH도 완전히 대체할 것으로 생각하지는 않았는지 beginners에 한정시켜 말하기는 했다.

하지만 나는 여기에도 회의적이다. 프로그래머가 쓰는 시간 대부분은 사실 코딩이 아니라 전체적인 구조를 설계하는 것과 문제가 생겼을 때 디버깅하는데 들어간다. SQL을 모른다는 것은 사실 RDBMS(Relational database management system)의 동작을 이해하지 못했다는 것인데 아무리 적절한 수준의 추상화가 문제를 단순화시키는 데 도움을 준다고 해도, 내부 동작을 모른 채로 적절한 설계를 하거나, 문제가 생겼을 때 원인을 찾아낼 수 있다고 생각되지 않는다.

Analysis of the Bitcoin UTXO set

Bitcoin은 Unspent Transaction Output(a.k.a. UTXO) set을 이용해 현재 상태를 표현한다. 위 논문은 bitcoin에서 UTXO를 어떻게 저장하고 UTXO set이 어떻게 변해왔는지를 분석했다.

2018-03-25

CAP theorem

CAP theorem은 분산 스토리지는 consistency(a.k.a. C), availability(a.k.a A), partition tolerance(a.k.a. P)를 동시에 만족시킬 수 없다는 것이다. 여기서 C, A, P는 각자 일반적으로 사용되는 용어와 다른 용어로 사용되기 때문에 CAP theorem을 이해하려면 각자가 정의하는 것을 이해하는 것이 중요하다.

C는 모든 read operation이 최신 데이터를 받는 것을 보장하는 것이다. C를 보장하는 시스템은 만약 최신 데이터를 돌려줄 것을 보장하지 못한다면 에러를 돌려줘야 한다. 개인적으로 분산 스토리지를 구현할 때 C, A, P 중 가장 구현하기 어려운 특성은 C라고 생각한다.

A는 모든 operation이 에러가 아닌 데이터를 돌려주는 것이다. 이때 돌려주는 값은 최신 값이 아니어도 상관없다. 심지어 eventual consistencyA를 보장하는 시스템에서는 실제로 존재할 수 없는 데이터 조합이 생길 수도 있다.

P는 partition 상황에서도 시스템이 정상 동작해야 한다는 것이다. 여기서 시스템이 정상 동작한다는 것이 언제나 최신 데이터를 보장하거나 에러가 아닌 값을 준다는 것이 아니다. 그것은 CA가 보장하는 것이고 partition 상황에서도 partition이 아닌 상황과 같은 것을 보장하면 P를 보장한다고 할 수 있다.

근데 여기서 partition은 정말 네트워크 레이어에 문제가 생겨 물리적으로 다른 망이 구성되는 상황을 말하는 것이 아니다. partition은 일부 메시지가 전달되지 않는 상황도 포함된다. 이는 분산환경에서 매우 흔히 발생하는 일이고 P를 포기한다는 것은 결국, 분산 환경을 포기한다는 말이 되기 때문에 분산 데이터 스토리지를 만들 때는 결국 CPAP 중 하나를 선택해야 한다.

개인적으로 생각하기에 CPAP 중 구현하기 더 어려운 것은 CP라고 생각된다. 모든 노드가 언제나 같은 상태를 유지하게 하는 것은 생각보다 어렵고 비싸다. 게다가 CP는 근본적으로 AP보다 latency와 throughput이 떨어진다.

하지만 이런 문제에도 불구하고 데이터 스토리지를 사용하는 application을 선택하는 입장에서는 AP보다 CP를 선호해야 한다고 생각한다. CP 대신 AP를 선택하는 이유는 가용성 때문이다. 가용성은 분명 중요하다. 하지만 스토리지의 가용성과 application 전체의 가용성은 다른 말이다. 데이터 스토리지가 정상적으로 동작하고 있다고 하더라도, 데이터의 일관성이 보장되지 못해서 잘못된 값을 돌려주었다면 이 application은 정상적으로 동작했다고 말할 수 있을까.

이런 일을 방지하기 위해서 AP인 스토리지를 사용하는 로직에는 데이터를 체크하는 복잡한 로직이 들어간다. 복잡한 로직은 높은 버그 가능성과 같은 의미이다. application 로직이 복잡해져서 버그가 발생했고 이를 고치기 위해 서비스를 종료했다면 이 application의 가용성은 떨어지게 된다. 게다가 버그로 인해 잘못된 응답을 준 경우는 오히려 처리하기 쉽다. 만약 버그로 인해 잘못된 데이터가 스토리지에 저장됐다면 이는 잡기도 어려울뿐더러, 고치기도 어렵다.

APCP보다 latency와 throughput이 떨어지기 때문에 성능이 필요한 application을 위해서는 AP인 스토리지를 선택해야 주장하는 사람들도 있다. 하지만 성능도 가용성과 마찬가지로 스토리지의 성능은 스토리지를 사용하는 application의 성능과는 별개다. AP인 스토리지를 사용하여 CP인 스토리지를 사용할 때보다 높은 성능을 보여준다는 것을 주장하기 위해서는 데이터 스토리지의 처리 시간이 application 처리 시간의 대부분을 차지한다는 것을 증명해야 한다. 여기서 측정하는 시간은 단순히 데이터 스토리지에 요청한 operation의 처리속도가 아니라, 네트워크 전송 속도를 제외한 데이터 스토리지 내부의 소요 시간이어야 한다.

설령 스토리지가 처리 속도에 충분한 영향을 준다고 하더라도 AP인 데이터 스토리지를 선택하기 전에 중요한 것이 처리 속도인지, 스토리지를 바꾸지 않으면 처리 속도를 올릴 방법이 없는지 고민해봐야 한다.

2015-05-24

[MySQL] Replication (3) - Replication을 사용하는 이유

 지난번 글에서 MySQL replication이 무엇인지 설명하면서, replication은 cluster와 다르게 동기화되는 것을 기다리지 않아도 돼서 빠르므로, 실시간 동기화가 필요하지 않은 경우에 사용된다고 하였다. 그렇다면 실시간 동기화가 필요 없는 경우는 어떤 경우들이 있을까?
 이번 글에서는 MySQL이 추천하는 적절한 replication 사용 방법에 대해서 알아보도록 하겠다.

백업

 replication의 주목적은 데이터를 백업하는 것이다. MySQL은 데이터의 지속성을 보장해준다. 하지만 아쉽게도 데이터베이스 이외의 다양한 이유(e.g. 하드디스크)로 데이터베이스를 복구할 수 없게 되는 일이 있다. 이런 경우를 대비하여, 다른 컴퓨터에 데이터를 복사하여 마스터 데이터를 복구할 수 없으면 복사된 슬레이브의 데이터를 이용하여 데이터를 복구할 수 있게 한다.

아카이브

 단순 백업을 위해서 뿐 아니라 아카이브를 만들기 위해서도 replication이 사용된다. mysqldump를 이용하면 데이터를 복사하여 아카이브를 만들 수 있다. 하지만 쿼리를 수행 중인 데이터베이스에 mysqldump를 실행하면, 깨진 데이터가 들어올 수 있다. 이는 MySQL enterprise backup을 이용하면 해결할 수 있지만, replication을 이용해서 해결할 수도 있다.

 지난번 글에서 설명하였듯이, 슬레이브의 SQL thread를 정지시키면, 마스터의 데이터를 읽어와서 relay log를 만들지만, 데이터베이스는 업데이트하지 않는다. 따라서 SQL thread만 정지시켜 놓으면, 안전하게 mysqldump를 실행할 수 있다. 이를 이용하여 서비스 중인 데이터베이스의 데이터를 서비스를 중지시키지 않고 아카이브를 만들기 위해서 replication을 사용하기도 한다.

부하 분산

 혹은 쿼리를 분산시키기 위한 목적으로도 사용된다.
서버별로 다른 슬레이브에서 값을 읽게 한다

 대부분의 웹 서비스는 데이터의 변경에 비해서 데이터를 읽는 작업이 많다. 이런 경우 슬레이브를 이용하여 부하를 분산시킬 수 있다. 혹은 로그 분석기처럼 고정된 데이터를 다양하게 하는 서비스의 경우도 replication을 사용하는 것이 좋다. 이런 서비스들은 replication을 이용하여 데이터를 읽는 것을 슬레이브에서 수행하면 부하를 분산시킬 수 있다.

지역 분산

 혹은 글로벌 서비스를 위하여 지역별로 다른 슬레이브를 구성할 수도 있다.
지역별로 슬레이브를 만든다.
 간혹 전 세계를 상대로 같은 데이터를 서비스해야 하지만, 레이턴시도 매우 중요한 서비스들이 있다. 보통 이런 서비스의 경우 데이터베이스는 공유하고, 지역별로 서버를 둔 뒤, 서버 메모리 캐시 같은 것을 사용하는 것이 일반적이다. 하지만 replication을 사용하면 위의 복잡한 작업을 간단하게 해결할 수 있다.


 이상으로 replication의 다양한 사용방법을 알아보았다. 하지만 이는 어디까지나 MySQL 매뉴얼에서 추천하는 일반적인 사용법이고, 실제로 활용할 방법은 무궁무진하다. 중요한 것은 cluster와 차이점을 이해하고 적절한 지점에 사용하는 것이다.

MySQL Replication

2015-05-23

[MySQL] Replication (2) - Replication은 어떻게 동작하는가

 지난번 글에서는 replication이 무엇인지 알아보았다. 이번에는 MySQL replication이 어떻게 동작하는지 살펴볼 것이다.


 replication은 다음과 같은 순서로 진행된다.
  1. 마스터 데이터베이스가 binary log를 만들어 이벤트를 기록한다.
  2. 각 슬레이브는 어떤 이벤트까지 저장되어 있는지를 기억하고 있다.
  3. 슬레이브의 IO thread를 통해서 마스터에 이벤트를 요청하고 받는다.
  4. 마스터는 이벤트를 요청받으면 binlog dump thread를 통해서 클라이언트에게 이벤트를 전송한다.
  5. IO thread는 전송받은 덤프 로그를 이용하여 relay log를 만든다.
  6. SQL thread는 relay log를 읽어서 이벤트를 다시 실행하여 슬레이브에 데이터를 복사한다.


 각각을 자세히 설명하면 다음과 같다.

binary log

 MySQL은 데이터 혹은 스키마를 변경하는 이벤트들을 저장할 수 있다. 이 이벤트들이 저장된 것을 binary log라고 부른다.

 binary log의 주목적은 데이터를 복구하는 것이다. 아카이브된 데이터가 있고, 아카이브 된 다음에 들어온 이벤트를 기록한 binary log가 있으면, 원하는 시점으로 데이터를 복구할 수 있다.
 데이터베이스를 변경하는 모든 이벤트가 저장되어 있으므로 이를 슬레이브에서 다시 실행하는 것만으로도 복사된 데이터베이스가 만들어진다.


binlog dump thread

 replication을 위해서는 마스터에 저장된 binary log를 슬레이브로 전송해야 한다. 이를 위해 마스터에서는 스레드를 만드는데 이를 binlog dump thread라고 부른다.
 binlog dump thread가 하는 일은 단순하다. 슬레이브가 이벤트를 요청하면 binary log에 락을 걸고, event를 읽어 슬레이브로 이벤트를 전송한다. 이때, binary log를 너무 긴 시간 락하지 않기 위해서 슬레이브에 전송하기 전에 binary log를 읽고 바로 락을 해제한다.


 마스터는 슬레이브에 대한 정보를 전혀 가지고 있지 않다. 슬레이브가 있는지 없는지, 몇 개의 슬레이브가 붙어있는지, 각 슬레이브가 어디까지 데이터를 복사했는지, 보내야 할 이벤트가 있는지 전혀 모른다. 그저 슬레이브가 이벤트를 요청하면 그에 해당하는 이벤트를 보내줄 뿐이다. 덕분에 마스터는 큰 부하 없이 데이터를 복사할 수 있다.

 binlog dump thread는 슬레이브가 마스터에 컨넥트할 때 생성되지만, 여러 개의 슬레이브가 붙어도 단 하나의 스레드만 생성된다.

I/O thread


 슬레이브는 마스터에 없는 2개의 스레드가 있다. 그중 하나가 I/O thread다. 각 슬레이브는 자신이 어디까지 데이터를 복사했는지 기억하고 있다.
I/O thread는 슬레이브가 마지막으로 읽었던 이벤트를 기억하고 있다가, 마스터에게 다음 이벤트를 전송해 달라고 요청한다. 마스터의 binlog dump thread가 이벤트를 보내주면 이것을 Relay log에 저장한다.
 따라서 I/O thread가 정지된 상황에서 마스터의 binary log가 지워지면, 슬레이브는 마스터의 데이터를 복제할 수 없다.

Relay log

 슬레이브는 I/O thread를 통해서 받은 이벤트를 로컬에 있는 file에 저장한다. 이를 relay log라고 부른다.
 보통 relay log는 SQL thread가 이벤트를 읽고 나면 지운다. 따라서 어느 정도 이상의 크기가 되지 않는다. 하지만 SQL thread가 멈추어 있으면 relay log는 계속해서 크기가 커지게 된다. 그렇게 되면 I/O thread는 자동으로 새 relay log 파일을 만들어, 파일이 너무 커지는 것을 막는다.

SQL thread

 SQL thread는 I/O thread가 만든 relay log를 읽어 실행을 시키고, relay log를 지운다. SQL을 실행시키는 스레드와 마스터로부터 값을 복사해오는 스레드가 분리되어 있다는 것은 매우 중요한 특징이다.

 보통 MySQL의 데이터를 백업하여 아카이브를 만드는 것은 mysqldump를 이용한다. 하지만 mysqldump는 MySQL이 쿼리를 실행하고 있을 때 실행되면 데이터가 깨지는 문제가 발생한다. 하지만 replication을 이용하면, 슬레이브의 SQL thread만 정지시키면 되기 때문에 안전하게 백업을 만들 수 있다.

MySQL Replication

2015-05-15

[MySQL] Replication (1) - Replication은 무엇인가

 MySQL replication은 데이터베이스를 그대로 복사하여 데이터베이스를 한 벌 더 만드는 기능이다. 언뜻 보면 MySQL cluster와 비슷하지만, 말 그대로 분산환경을 만들어서 single point of failure를 없애려는 cluster와는 달리 MySQL replication은 단순히 데이터를 복제한다.

 따라서 모든 데이터가 동기화되는 cluster와는 달리, replication은 동기화가 비동기적으로 발생한다. 따라서 어떤 데이터베이스에는 데이터가 업데이트되어 있지만, 다른 데이터베이스에서는 업데이트되지 않을 수도 있다.

 또한, 마스터와 슬레이브로 나누어지기 때문에 데이터를 변경하는 쿼리는 단 하나의 데이터베이스에만 요청할 수 있다. 다시 말해서 슬레이브의 데이터를 변경하면, 마스터에 그 변경은 반영되지 않고, 동기화하는 도중 에러를 발생시키기도 한다.

 cluster와 비교하면 replication은 동기화도 보장되지 않고 쿼리를 분산할 수도 없어 cluster 대신 사용할 이유가 없어 보인다. replication은 어떤 용도로 사용될까?

 replication이 cluster에 비해서 가지는 가장 큰 장점은 cluster에 비해서 값의 변경이 매우 빠르다는 것이다. cluster는 값을 변경하려고 하면 클러스터 군을 이루는 다른 서버들도 값이 변경되었다는 것을 확인해 주어야 한다. 하지만 replication은 마스터의 값만 변경하면 되기 때문에, 값을 변경하는 쿼리가 매우 빠르게 실행된다.

 그래서 주로 실시간 동기화가 필요 없는 경우 cluster대신 replication을 사용한다.

MySQL Replication

2014-08-07

[MongoDB] Sharding (3) - shard key

 MongoDB는 auto sharding을 해주기 때문에 사용자가 어떤 shard에 저장할지 신경 쓰지 않아도 된다.
 그렇다면 어떤 document를 어떤 shard에 저장할지 어떻게 결정할까?

Shard Key

 MongoDB는 shard key를 이용하여 구분한다.
 별도로 지정하지 않았다면 shard key는 object ID(_id)이다. 하지만 해당 collection에 모든 document에 존재하는 field index 혹은 compound field index라면 shard key로 지정할 수 있다.
 하지만 compound index는 shard key로 지정할 수 없다.

Shard key의 제약 조건

 shard key에는 몇 가지 제약이 있다. 우선 shard key는 512 byte를 넘을 수 없다.
 하지만 이는 시스템적 제약조건이지 실제로 512 byte를 넘는 field를 shard key로 만들 일은 거의 생기지 않는다. (사실 512 byte가 넘는 index를 지정하는 일도 거의 생기지 않는다.)

 또한 한번 sharding한 collection에 shard key는 변경할 수 없다.
 만약 변경하고 싶다면 새 collection을 만들어 shard key를 설정하고 collection 전체를 복사해서 새로운 collection을 만들어야 한다.

 그다음 제약은 꽤 까다로운데 shard key로 지정된 field의 value는 변경할 수 없다. Update 때 document를 다른 shard로 옮겨야 할 일이 없도록 하기 위해서다. 변경할 일 없는 field들만을 shard key로 지정해야 한다.

 특별히 튜닝해야 할 일이 없다면 기본값인 object id를 shard key로 사용하는 것을 추천한다.

MongoDB Sharding

2014-08-06

[MongoDB] Sharding (2) - Primary shard

 MongoDB는 collection 별로 sharding을 할지 안 할지를 결정할 수 있다.
 이때 sharding되지 않은 collection들이 저장되는 shard를 "Primary Shard"라고 부른다.

 sharding되지 않은 data들이 들어 있기 때문에 이는 Single point of failure이다.

 혹시 primary shard인 머신을 down시켜야 한다면 movePrimary command로 다른 shard를 primary로 만들고 down시켜야 한다. movePrimary는 sharding되지 않은 collection들을 모두 copy해가기 때문에 무거운 작업이다. 될 수 있으면 movePrimary를 호출할 상황이 오지 않도록 노력해야 한다.

 별도로 primary shard를 정하지 않았다면, 가장 먼저 cluster에 붙은 shard가 primary shard가 된다.


 p.s. 솔직히 말하면 난 아직 primary shard를 사용해야 하는 경우를 보지 못했다.
 아마 내 MongoDB 튜닝 경험이 적어서 그럴 것이다.
 혹시 primary shard를 이용해야 했던 경험이 있다면 공유해주기 바란다.

MongoDB Sharding

2014-08-05

[MongoDB] Sharding (1) - Sharded cluster의 구성

Scale up과 Scale out

 한 머신이 처리하지 못할 정도로 부하가 들어왔을 때의 해결책을 크게 scale up과 scale out 두가지로 분류한다.
 Scale up은 머신 자체의 성능을 올리는 것으로 vertical scaling이라고 불린다.
 효과는 확실하지만, scale out보다 비용이 많이 든다.
 Scale out은 기존의 머신을 그대로 두고 새로운 머신을 추가하는 방식이다. 다른 말로는 horizontal scaling이라고 부른다.

 Sharding은 scale out의 일종으로 data를 여러 서버에 나눠서 저장하는 방식을 말한다.
 이때 data가 저장된 서버들을 shard라고 부르고 shard들을 포함한 몽고디비 환경을 sharded cluster라고 부른다.

Sharded cluster

 MongoDB의 sharded cluster는 크게 3가지 군으로 나뉜다.
  1. Shards
  2. Config Servers
  3. Query Routers

Shard

 Shard는 실제 data가 저장되는 곳이다. MongoDB는 보통 하나의 data를 세 군데의 shard에 저장하여 특정 shard가 Single point of failure(a.k.a. SPOF)가 되는 것을 막는다. Scaling을 위해 수를 줄이고 늘리고 하는 것이 이 shard이다.

Config Server

 Config server에는 shard된 data들의 metadata. 즉, 어떤 data가 어떤 shard들에 저장되어 있는지에 관한 정보가 저장되어 있다.
 하나의 Config server만을 이용할 수도 있지만 보통 3개의 Config server를 사용하여 특정 Config server가 SPOF가 되는 것을 막는다.

 Config server에 저장되는 정보는 two-phase commit으로 저장하여 consistency를 보장해준다.

 Config server는 shard와 달리 scaling의 대상이 아니다. 보통 3개의 Config Server를 실행하는 것을 기본으로 하고, 만약 하나의 config server라도 name 혹은 address가 변하면 모든 mongod(shard + config server)와 mongos(query router)를 재 시작하여야 한다. 혹시 address가 변경될 것을 대비하여 CNAME을 사용하는 것을 권장한다.

Query Router

 Query router는 Query router를 실행시키는 binary의 이름을 따서 mongos라고 부르기도 한다.
 Query router는 일종의 client interface이다. client는 data가 들어 있는 shard에게 직접 command를 날릴 수 없고, router를 통해서만 요청할 수 있다. Router는 client가 요청한 command를 어떤 shard에게 명령해야 하는지를 보고 필요한 shard에게 명령을 날리고 수행된 결과를 취합한다.
 Router가 어떤 shard에 어떤 data가 들어 있는지 알기 위해 항상 Config server에 물어보는 것은 아니다. Router는 Config server에 저장된 metadata를 cache 해둔다.

MongoDB Sharding