라벨이 database인 게시물 표시

2018년 16번째 주

이 포스팅은 그냥 지난 한 주간 읽었던 것들을 정리하는 포스트입니다. 그냥 예전에 봤던 글 중 나중에 필요한데 뭐였는지 기억 안 나는 글들이 있어서 쓰기 시작했습니다. 보통 하는 일과 관련된 글들이 올라오겠지만 딱히 정해둔 주제는 없고, 그때그때 관심 있었던 것을 읽었기 때문에 지난주에 쓰인 글일 수도 있고 몇 년 전에 쓰인 글일 수도 있습니다. ISO week date 오늘이 올해의 몇 번째 주인지 정하는 기준은 말하는 사람마다 다르다. 그래서 이 요약정리 시리즈는 ISO 8601 기준으로 몇 번째 주인지 표기한다. ISO 8601에 따르면 1월 4일이 포함된 주를 그 해의 첫 번째 주로 취급한다. 다른 말로 한 주의 시작을 월요일로 봤을 때 4일 이상 포함된 첫 번째 주가 그 해의 첫 번째 주인 것이다. TextQL 머신 러닝이나 데이터 마이닝을 할 때 데이터의 경향성을 대강 파악하고 싶을 때가 있다. 이럴 때 사용되는 데이터는 보통 매우 큰 데이터이기 때문에 에디터로 열어서 보는 것은 무리가 있고, 간단하게 스크립트를 짜서 실행하게 된다. 근데 이때 하는 일은 대부분 비슷한 일이기 때문에 꽤나 귀찮은 작업이었는데, 스크립트를 짜지 않고 파일을 SQL 을 실행시켜주는 프로젝트가 있었다. 아직 사용해보지는 않아서 직접 스크립트를 짜는 것과 비교하면 어떨지는 모르겠지만 꽤 많은 사람이 쓰고 있는 것 같다. Writing 수학을 배워야 하는 이유가 사고하는 법을 익히기 위해서이듯이, 글쓰기를 배우는 이유는 무엇을 생각했는지 명확하게 하기 위해서다. 사람은 모든 것을 기억할 수 없기 때문에 자신이 생각한 것을 써서 정리해야 한다는 것이다. 게다가 글을 쓰는 것은 내가 글 쓰는 주제에 대해 나보다 모르는 독자를 가정하고 글을 쓰게 된다. 그래서 평소에는 당연하게 생각하고 넘어갔던 것들에 대해서도 한 번 더 생각하고 넘어갈 시간을 가지게 한다. How quantum computing could wreak havoc on cryptocurren

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 consistency 와 A 를 보장하는 시스템에서는 실제로 존재할 수 없는 데이터 조합이 생길 수도 있다. P 는 partition 상황에서도 시스템이 정상 동작해야 한다는 것이다. 여기서 시스템이 정상 동작한다는 것이 언제나 최신 데이터를 보장하거나 에러가 아닌 값을 준다는 것이 아니다. 그것은 C 와 A 가 보장하는 것이고 partition 상황에서도 partition이 아닌 상황과 같은 것을 보장하면 P를 보장한다고 할 수 있다. 근데 여기서 partition은 정말 네트워크 레이어에 문제가 생겨 물리적으로 다른 망이 구성되는 상황을 말하는 것이 아니다. partition은 일부 메시지가 전달되지 않는 상황도 포함된다. 이는 분산환경에서 매우 흔히 발생하는 일이고 P 를 포기한다는 것은 결국, 분산 환경을 포기한다는 말이 되기 때문에 분산 데이터 스토리지를 만들 때는 결국 CP 와 AP 중 하나를 선택해야 한다. 개인적으로 생각하기에 CP 와 AP 중 구현하기 더 어려운 것은 CP 라고 생각된다. 모든 노드가 언제나 같은

[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을 사용하기도 한다. 부하 분산 서버별로 다른 슬레이브에서 값을 읽게 한다 혹은 쿼리를 분산시키기 위한 목적으로도 사용된다. 대부분의 웹 서비스는 데이터의 변경에 비해서 데이터를 읽는 작업이 많다.

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

이미지
지난번 글 에서는 replication이 무엇인지 알아보았다. 이번에는 MySQL replication이 어떻게 동작하는지 살펴볼 것이다. replication은 다음과 같은 순서로 진행된다. 마스터 데이터베이스가 binary log를 만들어 이벤트를 기록한다. 각 슬레이브는 어떤 이벤트까지 저장되어 있는지를 기억하고 있다. 슬레이브의 IO thread를 통해서 마스터에 이벤트를 요청하고 받는다. 마스터는 이벤트를 요청받으면 binlog dump thread를 통해서 클라이언트에게 이벤트를 전송한다. IO thread는 전송받은 덤프 로그를 이용하여 relay log를 만든다. 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를 읽고 바로 락을 해제한다. 마스터는 슬레이브에 대

[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을 사용한다.

[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 (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 (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가지 군으로 나뉜다. Shards Config Servers 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 Ser

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

RAII는 무엇인가

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API