'데이터 과학자'에 해당되는 글 7건

  1. 아빠의 육아 일기 - 50일간의 기록 (육아, 쉼 없는 시간의 연속) (4)
  2. 아빠의 육아 일기 - 50일간의 기록 (먹는 양과 체중에 대하여) (2)
  3. [경성현] Topological Data Analysis를 이용한 전국 지방자치단체의 토건예산, 복지예산, 자살률의 관계 분석 (7)
  4. 맥미니 몽고디비 분산 시스템 (4) - Replica Set (3)
  5. 맥미니 몽고디비 분산 시스템 (3) - Sharding
  6. 맥미니 몽고디비 분산 시스템 (2) - 클러스터 구축 준비
  7. 맥미니 몽고디비 분산 시스템 (1) - 개요 (2)

[아빠의 육아 일기 - 50일간의 기록] 마지막은 "육아, 쉼 없는 시간의 연속"으로 부제를 정했습니다. 육아는 (아마 100일의 기적이 이루어 지기 전까지는) 하루 24시간 중 거의 20시간 이상을 아이와 함께 보내야 하는것 입니다. 20시간을 함께 자는 것이 아니라, 20시간 동안 늘 깨어 있으며 아이의 신호를 마음으로 읽고 여러 문제들을 해결해 줘야 하는 육아 노동의 시간입니다. 

너무나도 작고 예쁜 아기와 함께 있다 보면 시간 가는 줄도 모르고 몸이 쇠약해지고 있는 줄도 모르고 정말 열심히 보는데, 그렇게 열정적으로 육아를 하다보면 조리원을 나와서 집으로 돌아 온 이후에 1-2주일 이내에 급격한 피로감에 한동안 멘붕에 시달리게 되고, 이 기간 동안 대부분의 엄마들은 '산후-우울증'에 걸리기도 합니다. 사실 아내가 조리원을 나와서 집에 오면, 저도 2주일 정도는 휴가를 내가 아내와 함께 집에서 육아를 해야지... 라고 다짐했지만, 막상 2주일 동안 휴가를 쓰겠다고 허락을 구하는 것이 너무 어려웠습니다. 그래서 슬며시 늦게 출근하고, 슬며시 일찍 퇴근하여 육아를 위한 시간을 최대한으로 확보하려고 노력하긴 했지만... 그나마도 일주일에 2일 정도는 미팅과 실험 일정으로 밤 9시는 되어야 퇴근할 수 있어서 늘 미안한 마음입니다 .

아내와 함께 '규빈이의 하루'를 구글양식에 기록하면서 육아가 얼마나 힘든 일인지 데이터를 통해서 알 수 있게 되었는데요, 50일 되기까지는 하루에 2시간 이상 쉴 수 있는 시간을 확보하는 것 자체가 거의 불가능했습니다. 왜 그럴 수 밖에 없는지 아래의 데이터를 통해서 한번 살펴 보려 합니다.

위의 그림은 하루중 육아 활동을 한 시간들을 기록한 것인데요, 가령 $t_1$에서 모유 수유를 했다고 가정해 보겠습니다. 모유를 먹고 나서 아이가 깊은 수면에 돌입하면 정말 좋겠지만, 모유량이 충분하지 않으면 $t_2$시간에 깨서 울기 시작합니다. 그럼 모유가 충분하지 않으니까 $t_2$에 분유를 줍니다. 분유를 먹이는 시간은 대략 15-30분 정도로 가변적입니다. 그런데 분유를 먹이고 났더니 조금 놀다가 또 울기 시작합니다. 이번에는 기저귀를 갈아 달라는 것입니다. 그래서 $t_3$에 기저귀를 갈아줍니다. 이제는 아이가 잘 수 있지 않을까? 기대를 해 보지만 얼마 지나지 않아서 또 울기 시작합니다. 이번에는 잠투정입니다. 정말 독하게 마음 먹고 울던지 말던지 그냥 두면 아이가 스스로 지쳐서 잠들 수도 있지만, 엄마 마음은 그렇지 않습니다. $t_4$시간에는 아이를 안고 재워줍니다. '먹는 양과 체중에 대하여'에서 언급했지만, 저의 아기는 10일에 0.5kg씩 체중이 계속 늘었기 때문에, 하루하루 점점 무거워졌습니다. 다시 말하면, 안고 있을때 엄마의 팔과 손목에 느껴지는 통증이 점점 심해지는 셈이죠. 그래도 꾹 참고 아기가 잠들때까지 계속 달래줍니다. 아기가 잠들었다고 해서 깊은 잠에 드는 경우도 있긴 하지만, 그것은 아주 운이 좋은 경우입니다. 신생아 때는 위가 작고 한번에 먹는 양도 많지 않아서, 자다가도 금방 빼고프다고 웁니다. 그러면 다시 모유수유, 분유, 소변, 대변, 재우기, 놀아주기, 이도저도 아닌데 울기 를 끊임 없이 반복합니다. 이렇게 하루 중 아기를 위한 일들이 있었던 시간 간격의 차이, 가령 $dt_2 = t_2-t_1$, $dt_3 = t_3-t_2$,$\ldots$ 이렇게 연속되는 이벤트의 시간 간격을 계산할 수가 있습니다. 그리고 이러한 $dt_i$ 들을 모아서 그 분포를 그려보면 아래와 같은 그래프를 얻을 수 있습니다.

위의 그래프에서 왼쪽은 시간 간격의 분포를 나타낸 것인데요, 가령 왼쪽 그래프에서 제일 왼쪽에 있는 점(5,0.21)을 생각해 봅시다. $y$축의 값이 확률을 나타내는 것이기 때문에 맨 왼쪽의 점은 약 5분 간격으로 '모유수유, 분유, 소변, 대변, 재우기, 놀아주기'등의 일이 발생한 빈도수가 21%나 된다는 이야기 입니다. 여기에 60분 이내의 발생하는 사건들의 모든 확률을 더하면 50%도 훌쩍 넘는데요, 아기는 엄마에게 쉴 틈을 거의 안준다고 볼 수 있습니다. 오른쪽 그래프(B)는 왼쪽의 dt vs Prob(dt)의 값에 각각 log를 취한 log-log plot입니다. 분포를 log-log plot으로 그렸을때 선형으로 fitting이 된다는 것은 $dt$가 척도 없는 분포(scale-free distribution)을 따른다고 할 수 있습니다. 이는 $dt$가 매우 큰 사건은 정말 정말 '간헐적'으로 발생한다는 의미입니다. 왼쪽 그래프(A)에서도 볼 수 있듯이 180분(약 3시간) 동안의 간격 동안 아기가 아무것도 요청하지 않고 '잘 놀거나' 또는 '잘 자는' 경우는 하루에 한번 있을까? 말까? 한 아주 발생 빈도가 적습니다. 

아기가 태어나기 전에는 '뱃속에 있을때가 좋은거야' 라는 이야기를 많이 들었습니다. 그때마다 저는 '뭔소리인가? 나는 빨리 우리 아기를 만나고 싶은데...' 라고 생각했었는데, 선배 부모님들의 말이 무슨 뜻이었는지 몸소 겪고 있습니다. 하지만, 뇌과학을 공부하는 저에게는 아기가 자라면서 하나씩 학습을 하고, 또 기억을 하며 지능을 가진 한명의 인격으로 자라가는 모습을 가까이에서 관찰하는 것보다 더욱 효과적인 배움은 없는것 같습니다. 아무튼 본인 몸이 망가지고 있는줄 알면서도 아이가 건강하게 잘 자랄 수 있도록 고생하고 있는 아내에게 늘 감사합니다.


신고

앞서 소개해 드린 구글 양식으로 기록한 50일간의 육아 노트를 살펴보고자 합니다. 지금부터 보여드릴 데이터는 저의 아기에 대한 데이터이기 때문에 모든 아이들과 같을 수도 없고, 다르다고 해서 이상하다고 생각할 필요도 없습니다. 혹시나 앞으로 태어나게될 생명을 기다리시는 분들은 아기가 50일까지 자라는데 이런 과정을 겪는구나! 를 대략적으로 파악하시는데 '참고'만 하시길 바랍니다. 

오늘은 아기가 하루동안 먹는 분유(또는 모유)의 양과 체중변화를 데이터 분석을 통해 소개해 드리려고 합니다. 아기의 위는 이제 막 처음으로 사용하는 새것이기 때문에 먹은 것을 잘 소화 시킬 수 있도록 조금씩 적응시켜 줘야 합니다. 더욱이 아기의 위는 거의 일자형으로 생겨서, 한번에 많은 양을 담고 있기도 못하고 먹은 것은 오랜시간 담고 있기에 적절한 모양이 아닙니다. 그래서 신생아때는 한번에 30-40ml 정도의 작은 양을 약 1-2시간 간격으로 먹다가, 차차 1회당 먹는양을 늘리고 시간 간격도 늘려 나가는 것이 중요한 포인트라고 생각합니다. 그래야 아기도 배불리 먹고 오랜 시간동안 놀기도 하고 잠도 자고 할 수 있으니까요.

위의 그래프는 규빈이가 하룻동안 먹은 분유의 총량(A)과 1회당 먹은양(B)를 그래프로 표시한 것입니다. 분유의 총량이 시간이 지남에 따라서 늘어난것 처럼 보이는 이유는 그만큼 엄마의 모유 수유량이 줄어들었기 때문입니다. 처음에는 모유와 분유를 거의 반반으로 먹었었는데, 30일을 기점으로 규빈이가 엄마 젖을 거부하더라고요. 엄마 젖은 아기가 자극을 줘야 양이 점점 늘어 나는데, 그러지 않다 보니까 계속해서 양이 줄어들어서 50일 정도 부터는 하루에 두번 정도 모유를 유축해서 젖병으로 먹이고 있답니다. 어쨌든, 분유 총량이 늘어난 것처럼 보이는 이유는 그만큼 모유량이 줄어들었기 때문이라는 점을 다시 한번 강조해 봅니다. 중요한 것은 1회당 먹은 분유의 양인데요, 처음에는 60ml 도 간신히 먹었습니다. 하지만, 이 시기에는 90-120분 간격으로 아기가 울며 분유를 달라고 합니다. 그런데 시간이 지나면서 아기의 소화력도 좋아지고, 위도 점점 늘어나기 때문에 한번에 먹는 량이 점점 늘어납니다. 60일 정도 부터는 (하루중에도 약간의 차이가 있지만) 많게는 한번 먹을때 160ml까지 먹기도 합니다. 저렇게 꾸준히 먹으면 좋은데, 하루중에 160ml를 먹는 경우는 두번 정도 이고, 그 밖에는 120ml~140ml 정도를 먹고 있습니다. 1회당 분유 먹는양을 늘리는 것은 좋지만, 100일 까지는 하루에 먹는 분유의 총량이 1000ml 를 넘지 않게 하는 것이 좋다고 하네요. 과유불급이라고 너무 많이 먹으면 소아 비만에 걸리는 확률이 높아 질 수 있다고 하니 주의하는게 좋을것 같습니다.

규빈이가 모유는 거부해서 많이 못 먹고 있지만, 분유라도 잘 먹어줘서 너무 고맙게 생각하고 있습니다. 잘 먹어서 그런지 체중은 거의 선형적으로 증가하고 있는데요, 허벅지가 튼튼해 보이는 것이 아주 건강해 보여서 좋습니다.

이게 말이 되는 그래프인가? 싶기도 한데, 태어날 날짜와 체중이 거의 완벽하게 선형 관계입니다. 직접 선형 회귀 모형(Linear Regression Model)을 통해 선형관계를 계산해 보니, 체중=0.048*Days+3.38 로 나오네요 (단위 생략). 규빈이가 태어날때의 몸무게가 3.46kg이니까, 선형 방정식에서 계산된 3.38과도 정말 거의 유사 합니다. 신기방기 하네요^^ 방정식의 기울기가 0.048kg/day로 나오는데, 이것의 의미는 10일마다 0.5kg 씩 증가한다는 의미입니다. 조금 걱정되는 것이 Days=365를 입력해 보면 20.93kg이 나오는데요. 첫 돌때 몸무게가 20kg 은 말이 안되죠...ㅠㅠ  체중 그래프는 시간을 두고 다시 그려봐야 겠지만, 지금까지는 급격하게 성장하는 시기임이 분명합니다. 

아무튼 70여일 동안 잘 먹고, 잘 찌고, 잘 놀아줘서 너무 고맙습니다. 

신고

Topological Data Analysis 방법에 대해 궁금한 사항은 Slideshare를 통해서 공개된 자료를 참고해 주시면 되고, 여러 논문들에서도 방법을 확인하실 수 있습니다. 뉴스타파는 제가 제일 신뢰하는 언론이기에 뉴스타파 홈페이지를 자주 방문하곤 합니다. 전국 242개 지방자치단체 토건예산, 복지예산, 자살률 자료가 공개 된지는 두어달 전이지만, 그동안 그냥 눈팅만 하다가 이제야 데이터를 직접 분석해 보기로 했습니다. Topological Data Analysis (이하 TDA)는 데이터 간의 거리 정보를 이용하여 데이터 간에 관계를 분석하는 기법으로 순수 수학인 '위상수학'에 뿌리를 두고 있습니다. 

데이터 분석을 위해서 사용한 데이터는 2009년 복지예산과 토건예산의 비율, 2012년 복지예산과 토건예산의 비율, 그리고 2012년 10만명당 자살자수(연령표준화) 데이터를 이용하여 242x3 의 크기를 갖는 데이터를 구성했고, 각 컬럼 단위로 데이터를 표준화 해서 사용했습니다. 표준화 한 후에는 자살률에 대한 효과를 극명하게 관찰하기 위해서 자살률 데이터에 x2를 하여 분석을 진행했습니다. TDA를 위해서는 거리 함수와 필터 함수가 필요한데, 거리는 각 데이터와 데이터 간의 L2-distance로 정의했고 필터 함수는 L-infinity eccentricity로 정의했습니다. 아래 그림에서 각 노드의 색깔은 필터 값을 의미합니다.

분석의 결과로 그래프가 생성되는데, 각 그래프의 노드에는 필터 값이 비슷하면서 거리가 가까운 데이터들이 몰려 있습니다. 가령 Group1에는 광주(북구), 전북(본청), 대구(북구) 가 비슷한 거리를 갖는 것으로 분석 되었는데, 아래 그림에서 볼 수 있듯이 Group1에 들어 있는 지방자치 단체의 경우에 자살률이 낮고, 2009년과 2012년의 복지예산이 토건예산보다 4배 이상 많은 것으로 나타났습니다. Group2도 자살률이 낮지만, 결과로 생성된 Topology에서는 Group1과는 다른 위치에 있습니다. 데이터를 자세히 살펴보니, Group2의 경우에는 2009년과 2012년에 모두 복지예산이 토건예산보다 많은 것은 물론이고, 3년 사이에 복지예산/토건예산의 비율이 거의 2배 이상 증가 했음을 알 수 있었습니다. Group2에 속한 지방자치 단체로는 서울(노원구), 대구(달서구), 대전(서구) 가 있습니다.


복지예산과 토건예산의 비율이 자살률과 관련이 있다는 것은 Group3의 결과를 보면 알 수 있는데요, Group3의 경우에는 자살률은 Group1과 Group2에 속한 지방자치단체보다 자살률이 2배로 높게 나타났지만, 2009년과 2012년의 복지예산과 토건예산의 비율이 자살률이 낮은 그룹에 비해서 현격하게 줄어들어 있음을 알 수 있었습니다. Group3에 포함된 지방자치단체로는 강원(홍천과 양양), 충북(단양), 전북(장수), 전남(함평), 경남(함양)이 있습니다.



Group4에 포함되어 있는 지방자치단체의 경우에는 인구 10만명당 자살률이 약 30명 정도 이고, 위의 그래프를 보면 복지예산의 비율을 점점 높여 가려는 노력을 기울이고 있다고 볼 수 있습니다.

이번 데이터 분석을 진행하면서 TDA를 통해 데이터의 insight를 찾을 수 있음에 대한 더욱 큰 확신이 들었고, 실제로 복지예산과 토건예산의 비율이 자살률과 크게 관련 있다는 결과를 지방자치단체장님들께서 인지하시어 전국 각지에 좋은 복지 정책들이 제공되었으면 좋겠다. 그래서 떠나고 싶은 나라. 살기 싫은 나라. 가 아니고, 내가 국가로부터 받은 (복지 등) 혜택을 어떻게 다 보상해야 할까? 를 고민하는 국민이 늘어나는 나라가 되었으면 좋겠다. Group1,2와 Group3에 속한 지방자치단체장의 정당 구성까지 살펴보고 싶었는데, 그렇게 하면 거의 논문 수준이 될꺼 같아서 여기까지만!

여담으로 국가수리과학연구소에서 3년간 근무하면서 얻은 가장 큰 수확은 인성의 뇌신경 상관성 연구 논문을 출판한 것이고, 두번째로 큰 수확은 Topological Data Analysis에 대한 수학적 이론과 방법을 터득하여 실제 데이터 분석에 활용할 수 있는 수준이 되었다는 것이다. 아직 해결하지 못한 부분은 필터 함수를 2차원으로 적용하는 방법인데... 음, 올해 안에 해결할 수 있도록 해야지.


작성자: 데이터과학자 경성현



신고

1. Replica Sets + Sharding 시스템 구성

대용량 처리를 위한 분산 확장이 가능하고 안전성과 높은 가용성 보장을 위해 다음 그림과 같 이 Replica Sets을 구성하고, 이것을 토대로 Sharding 시스템을 구성할 수 있습니다.

4대의 맥미니를 이용하여 Replica Sets + Sharding 시스템을 구성 하는 것을 설명해 드리고자 합니다. 우선 각각의 노드에 다음과 같이 Config 서버와 Replica Set 서버 가 작동하도록 설정해 줍니다. Replica Set1은 모두 10001번 포트를 사용하고, Replica Set2는 모두 10002번 포트를 사용하며, Replica Set3은 모두 10003번 포트를 사용하도록 설정합니다.

node1: 192.168.3.1

$ mkdir /data/config1 /data/replset1 /data/replset3
$ mongod --dbpath /data/config1 --port 20001 &
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

node2: 192.168.3.2

$ mkdir /data/replset1 /data/replset2
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 &

node3: 192.168.3.3

$ mkdir /data/config2 /data/replset1 /data/replset2 /data/replset3
$ mongod --dbpath /data/config2 --port 20001 &
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

node4: 192.168.3.4

$ mkdir /data/config3 /data/replset2 /data/replset3
$ mongod --dbpath /data/config3 --port 20001&
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

각 노드별 설정이 끝나면, Replica Set을 초기화해야 한다. Replica Set을 구성할 때 Primary 서버와 여러 대의 Replica 서버로 구성된 환경에서 Primary 서버에 장애가 발생하면 MongoDB는 10초 이내에 다음 Primary 서버가 되어야 할 노드 하나를 선택해 줍니다. 이 경우, 아비타 Arbiter 서버가 활성화 되어 있으면 아비타가 적절한 서버를 선택해 주지만 사용자가 각 서버 에 대한 우선순위를 설정해 둔 경우에는 가장 높은 값을 부여받은 서버가 Primary 서버가 됩니다.

node1 - setting replica set1 (arbiter server: node3)

$ mongo 192.168.3.1:10001/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.1:10001/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset1", "members" : [ {"_id" : 1, "host" : "192.168.3.1:10001"}, {"_id" : 2, "host" : "192.168.3.2:10001"}, {"_id" : 3, "host" : "192.168.3.3:10001", arbiterOnly:true} ] } } )

node2 - setting replica set2 (arbiter server: node4)

$ mongo 192.168.3.2:10002/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.2:10002/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset2", "members" : [ {"_id" : 1, "host" : "192.168.3.2:10002"}, {"_id" : 2, "host" : "192.168.3.3:10002"}, {"_id" : 3, "host" : "192.168.3.4:10002", arbiterOnly:true} ] } } )

node3 - setting replica set3 (arbiter server: node1)

$ mongo 192.168.3.3:10002/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.3:10002/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset3", "members" : [ {"_id" : 1, "host" : "192.168.3.3:10003"}, {"_id" : 2, "host" : "192.168.3.4:10003"}, {"_id" : 3, "host" : "192.168.3.1:10003", arbiterOnly:true} ] } } )

이제 Config 서버를 설정하고 Replica Set을 Sharding으로 구성하는 과정이 남았습니다. 우선 node1, node3, node4 에 설정되어 있는 Config 서버들을 mongos로 연결시켜야 합니다. mongos 프로세스 설정을 위해서 node2에 접속 한 후에 다음과 같은 방법으로 mongos 프로세스를 설정할 수 있습니다.

$ mongos --configdb 192.168.3.1:20001,192.168.3.3:20001,192.168.3.4:20001 --port 27017 --chunkSize 64

이제 node2의 mongos 프로세스에 접속해서 ‘addShard'를 통해서 Replica Sets을 Shard 서버로 등록하면 시스템 구축이 모두 마무리 됩니다.

$ mongo 192.168.3.2:27017/admin mongos> mongos> db.runCommand( {addShard : "replset1/192.168.3.1:10001,192.168.3.2:10001, 192.168.3.3:10001"} ) // add replset1 as shard server mongos> db.runCommand( {addShard : "replset2/192.168.3.2:10002,192.168.3.3:10002, 192.168.3.4:10002"} ) // add replset2 as shard server mongos> db.runCommand( {addShard : "replset3/192.168.3.3:10003,192.168.3.4:10003, 192.168.3.1:10003"} ) // add replset3 as shard server mongos> mongos> use config // Config 설정에서 샤딩과 관련된 사항을 확인할 수 있다 mongos> db.shards.find() // Shard 서버 목록 확인 mongos> sh.status() // Shard 서버의 상태 확인


신고

1. 샤딩Sharding 시스템 구축

MongoDB 샤딩 시스템 구축을 위한 개요도는 다음 그림과 같습니다. 3대의 Config 서버와 4대의 Sharding 서버로 구성된 시스템을 만들어 보려 합니다.


위의 그림과 같은 시스템 구성을 위해서는 각각의 node에 접속하여 아래와 같이 설정하면 샤딩 서버와 Config 서버를 구성할 수 있습니다. Config 서버는 각 Shard 서버에 어떤 데이터들이 어떻게 분산 저장되어 있는지에 대한 Meta Data가 저장되어 있으며 MogoS가 데이터를 쓰고/읽기 작업을 수행할 때 Config 서버를 통해서 처리됩니다. 

in node 1

$ mkdir /data/config1 $ mongod --configsvr --dbpath /data/config1 --port 50001 & $ $ mkdir /data/shard4 $ mongod --shardsvr --dbpath /data/shard4 --port 40001 &

in node 2

$ mkdir /data/shard1 $ mongod --shardsvr --dbpath /data/shard1 --port 40001 &

in node 3

$ mkdir /data/config2 $ mongod --configsvr --dbpath /data/config2 --port 50001 & $ $ mkdir /data/shard2 $ mongod --shardsvr --dbpath /data/shard2 --port 40001 &

in node 4

$ mkdir /data/config3 $ mongod --configsvr --dbpath /data/config3 --port 50001 & $ $ mkdir /data/shard3 $ mongod --shardsvr --dbpath /data/shard3 --port 40001 &

Config 서버는 Sharding 시스템의 필수 구조 중에 하나이고 최소 1대가 요구되며 예기치 못한 시스템 장애로 인해 서비스가 수행되지 못하는 경우를 대배해서 추가로 Config 서버의 설정이 필요합니다. 3대 이상의 Config 서버를 운영하다가 하나의 Config 서버에 장애가 발생하면 나머지 Config 서버는 읽기 전용이 되기 때문에 최소한의 Sharding 시스템 운영이 가능해 집니다.


2. MongoS 프로세스

MongoS는 데이터를 샤드 서버로 분배해주는 프로세스입니다. Application Server에서 실행 가능하고, Config 서버로부터  Meta-Data를 캐시하는 기능을 수행합니다. node1 서버에서 다음과 같이 mongos  프로세스를 활성화 할 수 있습니다.

$ mongos --configdb 192.168.3.1:50001,192.168.3.3:50001 --port 50000 --chunkSize 1

이제 mongos 프로세스에 접속해서 각 Shard 서버를 등록하는 일이 남았습니다.

$ mongo 192.168.3.2:50000/admin mongos> mongos> db.runCommand( {addshard:"192.168.3.1:40001"} ) { "shardAdded": "shard0000", "ok": 1 } mongos> db.runCommand( {addshard:"192.168.3.2:40001"} ) { "shardAdded": "shard0001", "ok": 1 } mongos> db.runCommand( {addshard:"192.168.3.3:40001"} ) { "shardAdded": "shard0002", "ok": 1 } mongos> db.runCommand( {addshard:"192.168.3.4:40001"} ) { "shardAdded": "shard0003", "ok": 1 } mongos> db.runCommand( {enablesharding: "test"} ) // test db의 Shard 기능 활성화

mongodb의 Sharding은 Collection 단위로 수행되며 해당 Collection의 특정 필드(Shard-Key)값을 기준으로 분산됩니다. Sharding을 위해 해당 Shard-Key에는 반드시 인덱스의 생성이 요구됩니다.


3. Sharding 환경 설정 확인

Shard 서버, Config 서버, MongoS 프로세스에 대한 환경설정 작업을 완료 했다면, 다음과 같은 방법으로 정상적으로 설정이 되었는지 확인해 볼 수 있습니다.

$ mongo 192.168.3.2:50000/admin mongos> db.runCommand( {listshards: 1} ) // 등록된 Shard 서버의 IP address와 port 번호 확인 mongos> use config mongos> db.locks.find( {_id:"balancer"} ) // mongos 프로세스 상태 확인 mongos> db.settings.find() // 설정된 chunk 크기 확인 mongos> db.shards.find() // shard 서버 목록 확인 mongos> db.mongos.findOne() // mongos 상태 확인 mongos> db.settings.save( {_id: "chunksize", value: <size>} ) // chunk size 변경


4. Sharding 시스템 구축시 고려사항

MongoDB의 샤딩 시스템을 구축할 때 가장 중요한 요소는 Shard Key 입니다. Shard Key를 얼마나 적절하게 선택했느냐에 따라 운영, 관리 및 MongoDB의 성능이 달라질 수 있습니다. Shard key는 분할(Partition)과 균등 분산(Load Balancing)을 위한 기준이기 때문에 적절한 카디널리티Cardinality를 가진 필드가 선택되어야 합니다. 카디널리티는 조건을 만족하는 데이터의 분산 정도를 나타내는 값으로 전체 데이터 중에서 조건을 만족하는 데이터의 분포가 넓으면 낮은 카디널리티라고 표현하고 분포가 좁으면 높은 카디널리티라고 합니다. 하나 이상의 Field로 Shard key를 구성하는 것도 가능합니다.


5. Chunk Size & Migration 임계값값

초당 발생하는 빅데이터를 여러 대의 서버로 구성된 샤딩 시스템에 저장할 때 하나의 서버에만 데이터가 저장된다면 쓰기 지연 현상이 집중적으로 발생하여 성능 저하 현상이 발생할 수도 있습니다. 이런 경우를 위해 하나의 서버에 저장되는 데이터들을 여러 개의 논리적 구조로 분할 저장해 두었다가 일정한 데이터 양에 도달했을 때 두번째, 세번 째 서버로 분할 데이터의 일부를 이동 저장하게 되는데 이 분할 단위를 청크Chunk라고 합니다. Chunk size는 기본적으로 64MB 단위로 분할되지만 어떤 필드를 Shard Key로 설정했느냐에 64MB 이상 되는 Chunk Size로 분할 될 수도 있습니다. 하지만, 이 크기에 따라 Chunk Migration 횟수와 빈도가 결정되기 때문에 샤딩 하려는 컬렉션의 데이터 양과 도큐먼트의 크기에 따라 적절한 Chunk Size를 결정해야 합니다.

신고

1. 맥미니 클러스터의 구성

MongoDB를 설치하기 위한 맥미니 클러스터의 구성은 다음과 같습니다. 원활한 설정을 위해서 hostname과, ip address를 제외한 설정은 동일하게 하는 것이 좋습니다. (각 node의 user name은 모두 skyeong로 동일하게 설정합니다.)

 Hostname

 IP

 용도 

 제품 성능

 node1

 192.168.3.1 

 Config Server
 Slave Server

 Name: Mac Mini

 CPU: 2.6GHz Inte Core i7

 Memory: 16GB

 HDD: 1TB Fusion Drive

 OS X version: 10.8.3 (mountain lion)

 node2

 192.168.3.2

 Shard Server
 Slave Server

 node3

 192.168.3.3

 Config Server
 Shard Server

 node4

 192.168.3.4

 Shard Server
 Slave Server










2. XQurtz 설치

ssh 등 네트워크를 통해서 원격으로 접속하여 프로그램을 background mode에서 실행시키기 위해서는 XQurtz를 설치해야 합니다. Mac OS를 설치한 후에 아무런 설정 변경을 하지 않았다면, 보안의 문제로 XQurtz가 설치되지 않을 것입니다. 이때는 설정Preference 메뉴에서 'Security & Privacy'의 설정을 바꿔야 합니다. <일반General> 탭에서 'Allow applications downloaded from'을 'Anywhere'로 바꾼 후에 설치를 진행하면 됩니다. XQurtz를 설치한 후에는 재부팅을 권장합니다.

3. MongoDB 다운로드 및 설치

MongoDB의 Sharding 및 ReplicaSet을 구성하기 위해서는 MongoDB(http://www.mongodb.org)를 다운로드 한 후에, 압축을 풀고, /usr/local 로 mongodb-osx-x_86_64-xxx 폴더를 이동합니다. 이동한 후에 mongodb 폴더의 권한은 사용자(user name: skyeong)에게 할당합니다 (sudo chown -R skyeong:staff /usr/local/mongodb-osxox_86_64-xxx). 

$ cd ~/Download $ tar -xvzf mongodb-osx-x86_64-2.2.2.5.tgz # 여기에서는 OS X(64bit)용 2.2.5 버전을 설치함 $ sudo mkdir -p /usr/local/ $ sudo mv mongodb-osx-x86_64-2.2.5 /usr/local $ sudo chown -R skyeong:staff /usr/local/mongodb-osx-x86_64-2.2.5 # 소유권 변경 $ sudo ln -s /usr/local/mongodb-osx-x86_64-2.2.5 /usr/local/mongodb

MongoDB 서버 프로그램(/usr/local/mongodb/bin/mongod)을 실행시키기 위해서는 데이터가 저장될 위치를 지정해 주어야 합니다. 폴더를 생성하고, 폴더의 소유권을 다음과 같이 설정해 줍니다. 

$ sudo mkdir -p /data/ $ sudo chown -R skyeong:staff /data

이제 mongodb가 설치되어 있는 경로를 .profile에서 설정해 주어야 터미널 상의 어떤 경로에서도 mongod와 mongo를 실행시킬 수 있습니다. emacs나 vi 등의 편집기를 이용해서 skyeong 계정의 홈 데렉토리에 있는 .profile 파일의 맨 아랫줄에 다음을 추가해 주면 됩니다. (만약 .profile 파일이 없으면 새로 생성하면 됩니다.)

export PATH=/usr/local/mongodb/bin:$PATH

위와 같은 방법으로 node1, node2, node3, node4를 모두 동일하게 설정해 줍니다.

신고

구글에서 분산컴퓨팅 플랫폼으로 map-Reduce 방식을 제안하면서부터 빅데이터의 저장 및 처리를 위한 기술이 급격하게 발달하고 있습니다. Map-Reduce는 분할-정복 방식으로 대용량 데이터를 병렬로 처리할 수 있는 프로그래밍 모델로, 오픈소스인 Hadoop의 Map-Reduce 프레임워크가 동일한 기능을 제공해 줍니다. MongoDB는 비정형 데이터를 다룰 수 있는 NoSQL 데이터베이스로서, 샤딩Sharding 시스템을 구성함으로써 Map-Reduce 기능을 구현할 수 있습니다.

여러대의 컴퓨터에 데이터를 분할해서 저장하겠다는 큰 포부로 컴퓨터를 여러대 구입하다 보면 예산도 이슈가 되지만, 컴퓨터를 쌓아둘 공간이 있는가? 에 대해서도 고민하지 않을 수 없습니다. OS X 기반의 맥미니를 사용한다면 기존의 40대 랙타입 PC를 설치 할 수 있는 공간에 160대의 맥미니를 설치 할 수 있으니 공간 활용도 측면에서 엄청난 이득을 볼 수 있습니다. MongoDB에서 분산처리를 하기 위해 필요한 샤딩과 리프리카셋ReplicaSet을 구성하여 데이터를 안정적으로 분산 저장하고 복제할 수 있는 방법을 소개해 드리고자 합니다.  

1. 샤딩Sharding

빅데이터 환경은 초당 몇 만 건 이상 되는 수 많은 데이터를 빠른 시간 내에 수집하고 저장해야 하며 때에 따라서 정보를 분산-집계하여 사용자가 원하는 통계 정보로 가공할 수 있어야 합니다. 이러한 시스템 환경을 구축하기 위해서는 효과적인 데이터의 분산 저장 및 처리 기술이 필요한데, MongoDB에서는 이것을 샤딩Sharding 시스템이라고 합니다. 샤딩은 여러 대의 서버를 통해서 데이터를 분산처리 하여 빅데이터를 효율적으로 저장하고 관리하는 기능을 제공해 줍니다.

2. 복제Replica와 복제셋ReplicaSet

초당 몇 만 건 이상의 데이터에 대한 읽기/쓰기 작업이 박생하는 빅데이터 환경에서는 예기치 못한 시스템 장애로 인한 데이텅 유실이 생길 수 있습니다. 하나의 서버에 데이터가 입력/수정/삭제되었을때 동일한 구조를 가진 또 다른 서버에서 자동으로 동일한 데이터의 입력/수정/삭제가 이루어 진다면, 메인 서버에 장애가 발생하더라도 복제 서버를 이용하여 메인 서버를 빠르게 복구할 수 있을 것입니다. 리프리카와 리프리카셋 기능은 데이터의 백업을 통해 안정성을 보장하기 위한 방법입니다.


신고