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

한줄짜리 코드에도 반드시 괄호를 써야한다.

이미지
https://www.reddit.com/r/ProgrammerHumor/comments/1rfstw/there_are_two_types_of_people/ 위의 meem에서 알 수 있듯이 프로그래머는 괄호를 같은 라인에 붙여 쓰는가 띄어 쓰는가 하는 별 중요하지 않은 것으로 끊임없이 논쟁을 벌이고 있다. 여기에 조건문뿐 아니라 함수의 선언에 괄호를 어디에 붙이는가 까지 해서 4가지 조합을 가지고 끊임없이 싸운다. 뭐 나는 개인적으로 함수의 선언이나 조건문에 붙는 괄호를 한 라인에 붙여 쓰는 걸 선호하지만, 그에 대해서 딱히 내 의견을 강요하지 않는다. 그냥 프로젝트에서 기존에 쓰이던 것이나, 다른 팀원들이 원하는 스타일을 따른다. 하지만 괄호에 관해서 절대 양보 못 하는 것이 하나 있다. 한 줄짜리 statement를 위해서 괄호를 사용할 것인가 말 것인가 하는 것이다. 이유를 알 수 없지만, 조건문이나 for 문에 한 줄짜리 statement가 들어갈 일이 있으면, 괄호를 생략하고 쓰는 사람들이 많다. 괄호를 생략하는 사람들은 이것저것 이상한 주장을 한다. 쓸데없이 바이트를 낭비한다거나, 오히려 한 줄짜리 코드라는 것을 명시해주어야 한다거나, 이유 없이 타이핑할 이유가 없다거나, 뭐 이것저것 이유를 대는데 전부 20세기라면 의미 있을지도 모르지만, 지금이라면 전혀 의미 없는 이유다. 21세기에는 괄호를 생략할 이유가 전혀 없다. 오히려 괄호를 생략해서는 안되는 절대적인 이유가 있다. 코딩할 때 언제나 버젼 컨트롤 시스템을 사용하기 때문이다. git을 사용하든 머큐리얼을 사용하든 심지어 subversion을 사용하든 상관없지만 어찌 됐든 코딩할 때는 언제나 버젼 컨트롤 시스템과 함께하며 소스의 변경을 추적한다. 이때, 괄호를 생략했던 한 문장의 코드가 여러 줄로 나누어지면 괄호를 해서 불필요한 변경사항이 두 코드의 diff에 나오게 된다. 이러한 불필요한 변경 이력이 코드에 나오는 것을 막기 위해서 한 줄의 코드에도 반드시 괄호를 써

C는 C++의 부분집합이 아니다

오늘 황당한 글을 봤다. 잘 짜인 C 프로그램은 C++ 프로그램이다. 따라서 잘 짜인 C 프로그램은 C++ 컴파일러로 컴파일할 수 있어야 한다. 일단 저 말은 C++의 창시자인 비야네 스트롭스투룹 이 한 말이다. 하지만 저 말은 틀린 말이다. "네가 뭔데 감히 비야네님을 틀리다고 하느냐"라는 생각이 들겠지만 잠시만 진정하자. 나는 비야네님이 틀렸다고 하지 않았다. 내가 틀리다고 하는 것은 아무런 문맥도 없이 그냥 저 문구만 따와서 말하는 사람을 틀리다고 하는 것이다. 저 말은 분명히 1999년 이전까지는 맞았던 말이다. 분명히 비야네 스트롭스트룹은 C++을 만들면서 C와의 호환성을 고려하였고, 당시의 표준(ANSI C)을 잘 지킨 C 코드는 C++ 컴파일러로 정상적으로 컴파일 되었다. 하지만 그것은 어디까지나 C99가 나오기 전의 이야기다. C99에서는 여러 가지 새로운 기능을 도입하였고, C++은 그것을 이미 다른 방식으로 구현하고 있었거나, 혹은 필요하지 않은 기능이라고 생각하여 가지고 오지 않았다. 게다가 새로운 표준인 C11이 나오고, C++도 새로운 표준인 03, 11을 거쳐 14까지 나오면서 둘 사이의 간극은 이미 어떻게 할 수 없을 정도로 커졌다. 그런 연유로 비야네 스트롭스트룹은 잘 짜인 C 프로그램이 C++ 프로그램이라고 말할 때 조건을 붙인다. "단, 이건 C89에 한정한다."라고. 하지만 요새 C89를 쓰는 프로그램이 얼마나 있나? 액티브하게 작업이 진행되는 프로젝트 중에서 C89를 쓰는 프로그램 있으면 가지고 와봐라. 찾으려고 노력해본 적은 없지만 찾기 어려울 것이다. 따라서 요새 저런 말을 하는 사람은 그냥 공부를 안 한 사람이다. 그것도 한 20년 전에 공부했던 사람이니 대선배님일 수도 있겠다. 그 사람에게 C99 이후 C++과 스펙이 변경되어 C99 표준을 지킨 코드는 C++컴파일러로 컴파일 안 될 수도 있다고 했더니, 거기에 달린 답변은 더 황당했다. 표준이 문제가 아니라 잘

[Scala] 관련있는 데이터를 묶어서 사용하기 - alias와 case class

Scala에서 여러 개의 값을 묶어서 새로운 타입을 정의하는 방법은 여러 가지가 있다. Type alias 가장 쉬운 방법은 Tuple 의 alias를 만드는 것이다. 위의 코드의 4번째 줄에서 month와 date를 선언하면서 Date 타입의 변수를 쪼개 새로운 값에 할당하는 것을 decomposition이라고 한다. 이렇게 decomposition을 이용하면 구조체의 값들을 쉽게 다른 값에 할당할 수 있고, 혹은 아래와 같이 패턴매칭을 이용해서 사용할 수 있다. 하지만 튜플의 alias를 만드는 방식은 큰 문제가 있다. 이런 방식은 타입 세이프 하지 않다. 예를 들어 위에서 정의한 Address 타입과 함께 아래와 같이 정의된 Date 타입이 같이 사용된다면 둘 다 실제로는 같은 Tuple2[String, Int] 타입이기 때문에 패턴매칭으로는 Address 와 Date 를 구분할 방법이 없다. case class 튜플의 alias가 타입 세이프 하지 않다는 문제를 해결하기 때문에 보통은 data composition에 case class 를 사용한다. case class 를 사용하면, 실제로는 다른 같은 타입들의 묶음과 구분할 수 있을 뿐 아니라, 내부 값에 이름으로 접근해 꺼낼 수 있어서 내부 값을 더 쉽게 읽을 수도 있다.

[C++] Object slicing

Object slicing 이란 상속받은 class의 instance를 부모 class의 instance로 복사함으로써 상속받은 class가 가지고 있던 정보가 손실되는 것을 말한다. 이는 기능이 아니라 stack에 값을 할당하는 value 타입의 특성 때문에 생기는 버그다. 그래서 heap에 값을 할당하는 reference 타입밖에 없는 Java 같은 언어에서는 발생하지 않는다. Object slice 때문에 value type에 대해서는 upcasting을 해서는 안된다. 대부분 upcasting이 필요한 경우는 이미 무언가 잘못된 경우이니 코드를 수정해야 한다. 만약 무슨 일이 있어도 upcasting을 해야 한다면 반드시 heap에 값을 할당해야 한다.

Glowing Bear - 터미널에서 하던 IRC 웹에서 그대로

이미지
나는 freenode를 구경하거나 친구들과 놀기 위한 용도로 IRC를 사용한다. 데스크탑 어플리케이션도 많이 쓰이지만, IRC라는 프로토콜의 특성상 접속하여 있지 않으면 대화를 볼 수 없어서 freenode에 있는 사람들은 IRC를 계속 접속해놓을 방법을 찾는다. 가장 쉬운 방법은 컴퓨터를 끄지 않고 다니는 방식이지만, 보통 개발자 중에 이런 방식을 사용하는 사람은 없다. 보통은 서버에 터미널 기반의 IRC 클라이언인 WeeChat 이나 Irssi 띄우거나, IRC Cloud 라는 서비스를 사용한다. 하지만 터미널 클라이언트를 사용하면 언제서나 접속할 수 있는 웹 클라이언트가 아쉬워지고, IRC Cloud를 사용하기에는 한 달에 5$ 하는 비용뿐 아니라 WeeChat의 plug-in기능이 아쉬워진다. 그래서 보통은 WeeChat과 IRC Cloud 양쪽을 사용하는 방식을 택하지만, 그렇게 되면 2개의 접속이 연동되지 않기 때문에 불편한 건 어쩔 수 없다. 그래서 WeeChat plug-in을 이용해 위와 같은 웹 서비스를 만들어볼 계획이었다. 우선 채팅 로그를 DB에 저장하는 스크립트를 만들던 중 WeeChat에 완전히 같은 목적을 가진 relay protocol 이 있다는 것을 알게 되었다. Relay protocol은 WeeChat client가 relay 서버가 되어, Relay 클라이언트와 TCP socket을 이용해 통신을 하게 된다. Relay protocol을 사용하면 WeeChat과 완전히 같은 화면을 볼 수 있는 데다가 WeeChat plug-in을 그대로 사용할 수 있다는 장점이 있다. Relay protocol을 사용하는 client는 여러 가지가 있다. Qt를 사용해서 데스크탑 애플리케이션을 만든 QWeeChat , node.js를 이용한 웹 서버 WeeCloud 등도 많이 사용된다. 하지만 내가 사용하는 클라이언트는 Glowing Bear 다. Glowing Bear는 완전히 static 한 web page에서 We

이 블로그의 인기 게시물

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

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

RAII는 무엇인가

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

[Web] SpeechSynthesis - TTS API