세월이 흘러감에 따라서 변하지 않는 것이 없거늘 어찌 Emacs 가 변하지 않으리라 생각했던가..

말 그대로 입니다. 세월이 흘러 흘러 Emacs 가 24.x 대가 나오기 시작한지도 꽤 여러해가 지났습니다. 그런데 저는 과거의 설정파일을 그대로 사용하고 있었더군요. 문제 없이 사용하고 있었던 이유는 최근 쓰고 있던 OSX 가 버젼업이 되면서 한글 '나눔고딕'이 기본으로 포함되서 별 의도하지 않게 사용하고 있었습니다.

최근 Clojure 에 관한 Online 책을 보다가 그 저자가 설정한 Emacs 설정파일을 제꺼에 포함시키는 과정에서 기본 폰트 크기를 변경시키는 로직이 있는데 제가 처음 보는 함수를 쓰고 있더군요. 찾아보니 제가 기존 설정파일에서 쓰고 있었던 폰트 설정 방법은 사라졌더군요.

예전의 폰트 설정 방법 의 내용이 현행화를 필요로 한다는 점입니다.

(set-face-font 'default "Monaco-10")
(set-fontset-font "fontset-default" '(#x1100 . #xffdc)
                  '("NanumGothicOTF" . "iso10646-1"))
(set-fontset-font "fontset-default" '(#xe0bc . #xf66e)
                  '("NanumGothicOTF" . "iso10646-1"))
(set-fontset-font "fontset-default" 'kana
                  '("Hiragino Kaku Gothic Pro" . "iso10646-1"))
(set-fontset-font "fontset-default" 'han
                  '("Hiragino Kaku Gothic Pro" . "iso10646-1"))
(set-fontset-font "fontset-default" 'japanese-jisx0208
                  '("Hiragino Kaku Gothic Pro" . "iso10646-1"))
(set-fontset-font "fontset-default" 'katakana-jisx0201
                  '("Hiragino Kaku Gothic Pro" . "iso10646-1"))

이 방법이 아주 틀린건 아니지만 살짝 달라졌습니다. 한자나 일본어 설정은 동일하게 동작하는 것 같습니다. 다만 기본 폰트 설정 방법이 변했습니다.

(when (eq system-type 'darwin)

  ;; default Latin font (e.g. Consolas)
  ;; but I use Monaco 
  (set-face-attribute 'default nil :family "Monaco")

  ;; default font size (point * 10)
  ;;
  ;; WARNING!  Depending on the default font,
  ;; if the size is not supported very well, the frame will be clipped
  ;; so that the beginning of the buffer may not be visible correctly. 
  (set-face-attribute 'default nil :height 130)

  ;; use specific font for Korean charset.
  ;; if you want to use different font size for specific charset,
  ;; add :size POINT-SIZE in the font-spec.
  (set-fontset-font t 'hangul (font-spec :name "NanumGothicCoding"))

  ;; you may want to add different for other charset in this way.
  )

이 소스는 KLDP 의 유명한 Emacs 고수이신 cinsk 님의 설정 내용입니다. 제가 좋아하는 폰트로 살짝 고쳤습니다. 다시 말씀드리지만 이건 Emacs 24.x 의 설정 방법입니다.

그리고 "NanumGothicCoding" 폰트는 OSX 에 기본으로 설치가 되어 있지 않습니다. 기본으로 설치 되어 있는 폰트는 "Nanum Gothic" 입니다. 일부러 한글 폰트를 "NanumGothicCoding" 으로 설정한 이유는 나중에 설명하기로 하고 일단 '나눔고딕코딩' 폰트를 다운 받아야 합니다.

나눔고딕코딩 폰트 받기

받아서 서체관리자를 이용해서 설치해 주시고 위의 설정을 .emacs 에 설정해 주면 영문:Monaco , 한글:나눔고딕코딩 으로 설정이 됩니다.

여기까지가 Emacs 24.x 에서 한글 폰트 설정하는 방법이였고. 이제 다른 목적인 Org Mode 에서 한글 테이블 만들 때 표 제대로 보이는 방법에 대해서 이야기 하겠습니다.

Org Mode 는 Ascii 형식의 테이블을 지원합니다. 이게 은근히 편해서 종종 쓰곤하는데 심각한 문제가 있습니다. 한글을 쓰면 테이블 표에 있는 셀(Cell) 크기가 맞질 않습니다. 그래서 궁여지책으로 영문으로 테이블 표를 작성해서 쓰곤 했는데. Emacs 24.x 에 한글을 설정하고 나서는 갑자기 한글로 된 표를 쓰고 싶어졌습니다.

온갖 삽질끝에 이유를 알아냈는데 (어떻게 보면 당연한 거지만)

기본적으로 테이블이 깨지는 이유는 한글 - 영문 폰트의 width 의 비율이 일치하지 않기 때문입니다. 즉 이상적으로는 영문 2자에 한글 1자의 폭이 일치해야 하지만 미묘하게 한글 1자의 폭이 작습니다.

따라서 폰트 크기를 재 설정해 주면 간단하게 해결 됩니다. (이 간단하게 라는 말을 쓰기 위해 고생한 걸 생각하면…)

높이 비율로 크기를 맞춰야 하는데 'Monaco' 크기가 (:height)가 130 일때 'Nanum Gothic' 은 size 가 17 , 'NanumGothicCoding' 은 size 가 16 이어야지 비율이 맞습니다. 실제로 적용은 face-font-rescale-alist 변수를 이용해서 적용해 줍니다.

(setq face-font-rescale-alist
      '((".*hiragino.*" . 1.2)
        ("NanumGothicCoding" . 1.2307692307692308)))

와 같이 .emacs 에 설정을 넣어주면 됩니다.


위와 같이 테이블이 깨지지 않고 보여집니다. 


GuestOS 가 우분투 (Linux) 고 HostOS 가 윈도 계열인 경우에 공유 폴더를 설정하는 방법입니다. 제가 있는 곳에서 화면 캡쳐 기능이 안되는 관계로 글로만 설명을 드리겠습니다.

1. 게스트 확장을 설치한다

2. 가상OS 선택하고 '설정' 을 선택합니다.

3. '공유 폴더' 탭을 설정합니다.

   오른쪽에 추가 버튼을 누르고 '폴더 경로'를 '기타'로 해서 공유해줄 폴더를 지정해 줍니다. 그리고 폴더 이름을 외우기 편한 이름으로 바꿉니다. 전 다운로드 폴더를 지정하고 이름을 'downloads' 로 지정해줬습니다. (변경했습니다)

4. 게스트OS 로 들어갑니다. (우분투겠지요?)

5. 터미널 프로그램을 실행시킨후에

EDITED: 2013-07-01 

참조: https://help.ubuntu.com/community/VirtualBox/SharedFolders

mkdir share
sudo mount -t vboxsf -o uid=$UID,gid=$GID share ~/host



downloads <-- 호스트에서 지정해준 공유폴더 (3. 에서 지정한 폴더임)
share 는 호스트와 연결될 게스트의 디렉토리임
$UID 는 자신의 아이디 
$GID 는 자신의 그룹 아이디 입니다. 

share 라고 지정해준 디렉토리에 가보시면 호스트OS 에서 지정해준 폴더의 내용이 보이는 것을 확인하실 수 있습니다.



색이 나오고 안 나오고의 차이가 무지 큽니다. 세팅도 쉽습니다. 

$ git config --global color.ui true



위에 것만  Command Line 상에서 쳐 주시면 끝!!  
푸시 기능 구현을 Node.js 에서 하기에는 너무 쉬운 관계로.. 안드로이드 쪽부터 보기로 하겠습니다. 
안드로이드는 실 기계에서 작업하지 않는 한 에뮬레이터에서 푸시 기능을 테스트 해 보기 위해서는 Google API 를 지원해야 합니다.

Android SDK Manager (Windows 메뉴에 보면 있습니다. OSX 기준) 를 실행시키고 화면을 보면 


Android 4.2 (API 17) 에 'Google APIs' 가 설치 되어 있어야 합니다. 만약 설치 안되어 있다면 체크박스에 체크 하고 설치해주시면 됩니다. 

Google API 가 설치되어 있는 형태의 '가상 기계'를 구동하셔야 푸시 이벤트 처리가 가능합니다. 

Android Virtual Device Manager 를 실행시킵니다. (역시 Windows 메뉴에 있습니다) 
그리고 새로 '가상 기계'를 설정해 주는데 OS 버젼 골라주는 곳? 그곳에서 Google API 라고 쓰여져 있는 버젼을 골라주면 됩니다. 


자 제것의 화면입니다. 같은 4.2 버젼이지만 Google API 를 쓰느냐 안 쓰느냐의 차이만 존재합니다. 

그리고 다시 Android SDK Manager 를 실행시켜줍니다.

 
위에 보이는 라이브러리를 설치해줍니다. 자 그러고 나면 

$SDK/extras/google/gcm/ 밑에 보면 프로젝트들이 설치되어 있습니다. 그중에서 samples 밑의 gcm-demo-client 를 주목해야 합니다.  (본인의 경우에는 /Users/crazia/work/android/sdk/extras/google/gcm/samples/gcm-demo-client 에 설치되어 있습니다. )

Eclipse 가 이미 구동되어 있을 테니 (안 그러면 SDK 메니져랑 가상 기계 매니져를 실행시킬 수 없었겠지요?) 위에 지정한 프로젝트를 Import 해옵니다. 

자 이제 안드로이드 쪽에서 해야 할일의 90% 는 끝이 난 셈입니다. 이제 키가 두개 필요합니다. 편의상 Project Key (SEND ID) 와 API Key 라고 부르겠습니다. 각각 클라이언트와 서버쪽에서 필요한 키입니다. 

https://code.google.com/apis/console 에 접속하셔서 


아직 등록이 안되어 있다면 'Create Project' 를 누르시면 프로젝트가 생성됩니다. 그리고 나면 URL 이 자동으로 변경이 되는데. 

https://code.google.com/apis/console/#project:4815162342

여기서 보이는 저 굵은 글자가 바로 Project Key 입니다. (SEND ID) 아이템을 얻었습니다!!

왼쪽에 탭을 보면 여러가지 메뉴가 있는데 그중에 

"Services." 탭을 선택합니다. 
"Google Cloud Messaging" 을 ON 으로 토글링 합니다. (켭니다) 


이제 구글 클라우드 메시지 서비스를 이용하기로 결정이 됐습니다. 
자 다시 왼쪽 탭을 보면 그중에서 

"API Access" 탭을 선택합니다. 
아래쪽에 보면 "Create New Server Key" 라는 버튼이 있습니다. 
보내고 싶은 IP 리스트에 대한 리스트를 작성해 주고 싶으면 작성하고 마땅히 할게 없으면 "Create" 버튼을 눌러줍니다. 



이제 중간에 나오는 화면에서 "API Key" 부분에 나와 있는 키를 따로 떼서 저장합니다. (Server Key) 아이템을 얻었습니다!!

중간 점검을 하자면 

1. Google API 를 지원할 수 있게 Virtual Device 를 생성하는 준비를 마쳤습니다. 
2. Extra/gcm 샘플 소스를 받아서 Eclipse 에서 쓸 수 있게 Import 했습니다. 
3. Sender ID 와 Server Key 로 사용할 수 있는 Project Number 와 API Key 를 받았습니다. 

여기까지 완수가 되었다면 이제 클라이언트 (Android) 쪽 코딩을 마무리 지어 봅니다. Eclipse 의 프로젝트에 포함된 파일중에서 CommonUtilities.java 파일을 열어줍니다. 

    /**

     * Base URL of the Demo Server (such as http://my_host:8080/gcm-demo)

     */

    static final String SERVER_URL = "http://192.168.0.36:3000";
    // node.js 서버가 기다리고 있는 주소와 포트를 적어 주는 것입니다. 


    /**

     * Google API project id registered to use GCM.

     */

    static final String SENDER_ID = "4815162342";
    // 위에서 얻은 Project Number 를 입력해 줍니다.

이로서 클라이언트 부분은 끝이 났습니다. 이제야 제일 핵심인 Node.js 에서의 푸시 기능 구현에 들어가겠습니다.

$ cd $PROJECT_DIRECTORY
npm install node-gcm --save

-- save 옵션을 package.json 에 해당 사항을 기입하라는 뜻입니다.  

app.js 를 열어서 다음과 같이 추가 해 줍니다. 

var main = require('main');

app.post('/register', main.regist);
app.get('/send', main.send_push);


main.js 파일을 하나 만들어서 열고 

exports.regist = function (req, res) {

console.log (req.param('regId'));
        // 원래는 DB 에 저장하는 부분이 있어야 할 것입니다. 받아서 디비에 저장하기       

res.end(); 


exports.send_push = function(req, res) {

var message = new gcm.Message();

var sender = new gcm.Sender('API Key 를 입력하는 곳입니다. ');

var registrationIds = [];


// Optional

message.addData('key1','message1');

message.addData('key2','message2');

message.collapseKey = 'demo';

message.delayWhileIdle = true;

message.timeToLive = 3;


// At least one required

registrationIds.push('이곳은 register 함수에서 받은 regId 를 입력하는 부분입니다.');
        // 만약 제대로 구현 됐다면 디비에서 읽어서 가져오겠지요?  

        

/**

 * Parameters: message-literal, registrationIds-array, No. of retries, callback-function

 */

sender.send(message, registrationIds, 4, function (err, result) {

    console.log(result);

});

// sender.sendNoRetry(message, registrationIds-array, function (err, result) {

//     console.log(result);

// }); // retry 없이 보내는 부분입니다. 보통은 이것을 더 많이 애용할 것 같습니다. 

}




너무 쉽게 끝났지요? 이게 node.js 의 힘이라고 볼 수 있습니다. 자신의 안드로이드 프로젝트에 기능을 추가하고 싶으시다면 참조 사이트를 참조하시면 됩니다. 

참조  사이트 

https://github.com/ToothlessGear/node-gcm : node.js 에 gcm 모듈 구현 
http://developer.android.com/google/gcm/gs.html : 구글의  gcm 모듈 구현하는 설명 페이지 (완전 중요!!)


 
최근에 서버가 사망하는 일이 발생했습니다. 내 다시는 LVM 에 데이터랑 OS 를 공존시키지 않으리란 다짐을 하게 만드는 사건이였습니다. 인프라를 다시 갖추는 작업을 한번쯤 정리해 볼 필요가 있을 것 같아서 정리해봤습니다. 

12.04 LTS 버젼으로 설치해 주는 것이 편합니다. 12.10 버젼은 Remote Desktop 으로 접속시 D 를 누르면 발생하는 문제가 있습니다. (모든 창이 미니마이즈 가 됩니다)

설치하자 마자 접속하면 '소프트웨어 업데이트'가 뜹니다. 이때 '설정'을 눌러서 다운로드 받는 서버를 'ftp.daum.net' 으로 수정해 줍니다. 

 $ sudo apt-get install ssh 


shell 접속이 가능하게 ssh 관련 소프트웨어를 설치해 줍니다. 특정 망회사는 ssh 기본 포트를 막아놓는 테러를 저지르기 때문에 /etc/ssh/sshd_config 에서 port 를 바꾸어 줍니다. 

$ sudo apt-get install xrdp


원격 접속이 가능하도록 xrdp 관련 소프트웨어를 설치해 줍니다. 

$ sudo apt-get install emacs23-nox 


주로 shell 로 접속해서 쓸꺼기 때문에 emacs 를 nox 버젼으로 설치해 줍니다. 

 $ sudo apt-get install gnome-session


원격 데스크탑을 원활히 돌리기 위해서 놈-세션을 설치해 줍니다. 
원격 데스크탑이 잘 돌아갈 수 있도록 조치를 취해줍니다.  예전에 올려둔 포스트 참조 

이제 쓸데 없는 하드들을 전부 한개로 묶어서 데이터 디스크를 만들어 줍니다. LVM 을 활용하는 것입니다. 
예전에 정리해 뒀습니다. 

 

 $ sudo vgchange -a n data_vg
 $ sudo vgreduce --removemissing data_vg
 $ sudo vgchange -a n data_vg
 $ sudo vgremove data_vg


LVM 을 운용하는 중에 하드가 하나 날라가 버린 가슴 아픈 사람들 (저 같은 경우..)의 경우에는 그 부분을 제거해 줘야 합니다. 이거를 먼저 실행해주고 LVM 을 생성해 주면 됩니다. 
(다시는 OS 와 Data 를 LVM 으로 묶지 않으리란 다짐을 했습니다. )

이제 다시 git 레파지토리를 생성해주면 됩니다. 제 노트북에 로컬 레파지토리는 전부 남아 있으니 서버에서 재 구성해주고 이쪽에서 그쪽으로 push 만 해주면 될 듯합니다. 

예전 정리 참조 

이렇게 또 퇴근 후 자유시간을 잡아먹게 되는 군요. 
예전 제 포스트 에서 언급된 개인용 GIT 을 설치해서 혼자 깨작 깨작 만드는 프로젝트나, 개인 emacs 설정 파일들을 올려두고 사용하고 있었습니다. 

어쩌다 보니, 팀 단위로 작업을 하게 되었고, 개인용 GIT 만으로는 한계가 존재하더군요. (어떤 사람이 올린 소스가 잘못 됐는지 파악이 되야 '마녀 사냥'을 하지요 ㅎㅎ) 따라서 조금 찾아 봤더니

http://gitlabhq.com/

이렇게 훌륭한 오픈 소스가 있더군요. http://github.com 과 사용법이 많이 유사합니다. 팀단위로 개발할 때 꼭 설치해서 관리해 주면 좋을 것 같습니다. 혼자 프로젝트 관리 하실 때도 좋구요. 

설치한 환경은

(Ubuntu 12.10 과 Ubuntu 12.04 LTS )

에 설치했습니다. 전자는 회사, 후자는 집입니다. 두개의 차이는 거의 없었습니다. 다만 Ubuntu 12.04 LTS 의 경우에는 

$ sudo apt-get install ruby1.9.1



이처럼 명시적으로 버젼을 명시해야 최신 루비 버젼으로 설치가 되더군요. (명시해 주지 않으면 1.8.7 인가가 설치됩니다)

설치법 따라하기 

https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md

귀신이 곡할 노릇이군요. 분명히 어제 위에 있는 문서가 열리고 그것을 보고 설치했는 데 지금 보니까 사러져 버렸습니다. 차이점은 unicorn 을 이용하는 방법의 차이정도라고 할 수있습니다.

유니콘 부분은 

이 부분을 참조하시면 됩니다. 
 
위에 보면 최신 버젼에 맞춰서 현행화가 잘 되어 있습니다. 순서대로 죽죽 따라서 해주기만 하면 됩니다. 
다만 몇가지 안되는 부분에 대한 것은 제가 따로 아래에 달아두겠습니다. 

루비는 위에 나온 설치법에 따르면 소스를 받아서 설치해줘야 하는데 , 그냥 패키지로 설치해도 되더군요. 

$ sudo apt-get install ruby 



Ubuntu 12.10 의 경우는 위처럼 하면 기본으로 1.9.1 이 설치됩니다. 

$ sudo apt-get install ruby1.9.1



이건 Ubuntu 12.04 LTS 입니다. 

루비 -dev 버젼을 설치해줘야 합니다. 중간에 gem install 경우에 에러가 발생하는 것을 막아줍니다. 

$ sudo apt-get install ruby1.9.1-dev


Ubuntu 12.10 버젼에서 이벤트머신이 설치 안되는 경우가 발생했었습니다. 

https://github.com/gitlabhq/gitlabhq/issues/1051

이 부분을 참조해서 해결했습니다. 
 
혹시나 ntop 어플리케이션이 PORT 3000 번을 물고 있어서 gitlab 웹서버가 스타트했다가 죽어버리는 경우가 발생할 수가 있습니다. 

$ sudo /usr/sbin/ntop -A



실행해주면 admin 패스워드가 set 됐다는 말이 뜹니다. 그때 http://localhost:3000 으로 들어가서 admin / '' (패스워드 없이) 로그인 하셔서 PORT 를 4000 으로 바꾸어 주면 해결 됩니다.  
 
 
골치 아프게 고민하지 마시고

http://localhost:631

에서 모든 것을 전부 설정해 줄 수가 있습니다.


샤딩 (Sharding) 을 하는 방법 또는 복제 셋 (Replication) 을 하는 방법에 관한 예제는 잘 나와 있습니다. 그런데 실전에서는 복제와 샤딩을 동시에 하는 것이 일반적일 것입니다. 이것에 관한 예제가  많이 없더군요. 어쩌다 찾은 것이 한개 있지만 한 기계에서 가상으로 돌려보는 예제 입니다. 이러한 예제로는 샤딩을 제대로 테스트 할 수가 없더군요. 하지만 그 문서를 바탕으로 실제로 샤딩과 복제를 클러스터 환경에서 테스트 해 봤습니다. 

http://cookbook.mongodb.org/operations/convert-replica-set-to-replicated-shard-cluster/ 

위 내용은 한 기계안에서 샤딩과 복제 셋을 테스트 하는 예제 입니다. 


원칙대로라면 복제 셋 (Replication Set) 을 설정할 때 한 머신에서 동작시키는 것이 아니라 서로 다른  서버에서 구동되게 설계를 해야 하지만 그것 까지 세팅하기가 매우 귀찮기 때문에 다음 과 같이 설계를 해 봤습니다. 

   

    Machine 1 : 

    - name : super1
    - replication : first * 3


    Machine 2 :

    - name : super2
    - replication : second * 3

    


 

 즉 2대의 머신에서 샤딩이 이루어 지게 세팅을 하는 것인데, 각각의 머신은 3개의 복제 셋을 가지게 구성 되는 것입니다. 

mongoDB 의 bin 이 path 에 걸려 있다는 가정 하에 진행 합니다. 

super1 부터 설정을 시작합니다.
  먼저 데이터들이 저장될 db 디렉토리를 만들어 줍니다. 

   

    $ mkdir ~/db/first1 
    $ mkdir ~/db/first2
    $ mkdir ~/db/first3

    
    로그를 저장할 공간도 만들어 줍니다. 

    $ mkdir ~/db/log 


    이제 몽고 데몬들을 띄워줍니다. 

 

    $ mongod --dbpath ~/db/first1 --port 10001 --replSet first > ~/db/log/first1.log &
    $ mongod --dbpath ~/db/first2 --port 10002 --replSet first > ~/db/log/first2.log &
    $ mongod --dbpath ~/db/first3 --port 10003 --replSet first > ~/db/log/first3.log &


    이제 이 세개의 몽고 디비 프로세스들을 한개의 복제셋 (여기서는 first )으로 묶어주는 작업을 합니다. 

 

  $ mongo localhost:10001/admin 

    > db.runCommand({"replSetInitiate" : {"_id" : "first", "members" : [{"_id" : 1, "host" : "super1:10001"}, {"_id" : 2, "host" : "super1:10002"}, {"_id" : 3, "host" : "super1:10003"}]}})
    {
        "info" : "Config now saved locally.  Should come online in about a minute.",
"ok" : 1
    }


    이러면 성공적으로 복제 셋이 만들어 진것 입니다. 이제 데이타를 실제로 넣어보기로 하겠습니다. 

   

PRIMARY> use test
    switched to db test
    PRIMARY> people = ["Marc", "Bill", "George", "Eliot", "Matt", "Trey", "Tracy", "Greg", "Steve", "Kristina", "Katie", "Jeff"];
    PRIMARY> for(var i=0; i<1000000; i++){
          name = people[Math.floor(Math.random()*people.length)];
 user_id = i;
 boolean = [true, false][Math.floor(Math.random()*2)];
 added_at = new Date();
 number = Math.floor(Math.random()*10001);
 db.test_collection.save({"name":name, "user_id":user_id, "boolean": boolean, "added_at":added_at, "number":number });
    }

 
    이름을 백만건 정도 랜덤으로 순서를 매겨서 집어넣는 소스코드 입니다. 


이제는 구성된 복제 셋을 가지고 샤딩으로 추가해 주는 작업을 해 줘야 할 차례 입니다. 역시  super1  서버에서 작업을 해 줍니다. 

config 서버를 띄워줄 차례 입니다. 먼저 config 데이타들이 저장 될 디렉토리를 만들어 줘야 합니다. 

   $ mkdir ~/db/config1
   $ mkdir ~/db/config2
   $ mkdir ~/db/config3


컨피그 서버는 1대 아니면 3대를 추천합니다. (제가 아니라 몽고디비 쪽이 추천하는 것입니다) 

 

   $ mongod --configsvr --dbpath ~/db/config1 --port 20001 > ~/db/log/config1.log &
   $ mongod --configsvr --dbpath ~/db/config2 --port 20002 > ~/db/log/config2.log &
   $ mongod --configsvr --dbpath ~/db/config3 --port 20003 > ~/db/log/config3.log &


혹시 컨피그 서버가 제대로 띄워지지 않으면 다른 포트로 띄워주시면 됩니다. 이제 컨피그 서버에서 정보를 가져오는 mongos (라우터 개념)를 띄워줄 차례 입니다. 

 

 $ mongos --configdb super1:20001,super2:20002,super3:20003 --chunkSize 1 > ~/db/log/mongos.log &


 chunkSize 는 테스트에서만 추가하는 것으로 생각하시면 됩니다. 크기를 1메가로 만드는  것입니다. (기본은 64메가 입니다) 이제 띄워논 mongos 에 접속해야 한다. 

 

 $ mongo super1/admin
  
 mongos> db.runCommand( { addshard : "first/super1:10001,super2:10002,super3:10003" } )

   { "shardAdded" : "first", "ok" : 1 }
   mongos>
   
  
이제 두번째 기계에서 세팅을 할 차례 입니다. super2 (Machine 2) 입니다.  먼저 데이타베이스가 저장될 디렉토리를 만들어 줍니다. 

   

   $ mkdir ~/db/second1 
   $ mkdir ~/db/second2
   $ mkdir ~/db/second3 
   

로그용 디렉토리도 만들어 줍니다. 
   

$ mkdir ~/db/log 


몽고디비 데몬을 띄워줍니다. 

   

   $ mongod --dbpath ~/db/second1 --port 10001 --replSet second > ~/db/log/second1.log &
   $ mongod --dbpath ~/db/second2 --port 10002 --replSet second > ~/db/log/second2.log &
   $ mongod --dbpath ~/db/second3 --port 10003 --replSet second > ~/db/log/second3.log &


이제 이 프로세스들을 한 개의 복제 셋(replication set)으로 묶어 줍니다. 

 

 $ mongo super2:10001/admin

   > db.runCommand({"replSetInitiate" : {"_id" : "second", "members" : [{"_id" : 1, "host" : "super2:10001"}, {"_id" : 2, "host" : "super2:10002"}, {"_id" : 3, "host" : "super2:10003"}]}})
   {
      "info" : "Config now saved locally.  Should come online in about a minute.",
      "ok" : 1
   }



방금 만들어 진 복제 셋 (replication set) 을 새롭게 샤드 (shard) 에 추가해 줍니다. 먼저 mongos 를 띄워줍니다. 지금 super2 서버고 mongos 도 super2 에서 띄우는 것이지만 바라보는 컨피그 서버 는 super1 에서 띄운 것을 쳐다봐야 합니다. 

   $ mongos --configdb super1:20001,super2:20002,super3:20003 --chunkSize 1 >  ~/db/log/mongos.log &


몽고 shell 을 이용해서 mongos (이건 super2 에 띄워 놓은 것입니다) 에 접속합니다. 

   

$ mongo super2/admin
   mongos> use admin
   switched to db admin
   mongos> db.runCommand( { addshard : "second/super2:10001,super2:10002,super3:10003" } )
     { "shardAdded" : "secondset", "ok" : 1 }


이러면 두번째 복제 셋 (replication set) 을 샤드에 추가 해 주었습니다.  제대로 되어 있는지 테스트를 확인 해 보기로 합니다. 

 

 mongos> db.runCommand({listshards:1})
   {
        "shards" : [
  {
      "_id" : "first",
      "host" : "first/super1:10001,super1:10003,super1:10002"
  },
  {
      "_id" : "second",
      "host" : "second/super2:10001,super2:10002,super2:10003"
  }
     ],
     "ok" : 1
   }


샤드로 설정되어 있는 것하고 샤드를 직접적으로 하는 것은 차이가 있습니다. 실제로 샤드를 구현해 보겠습니다. mongos 에 접속되어 있는 상태에서 

 

 mongos> db.runCommand( { enablesharding : "test" } )
   { "ok" : 1 }


 
위 처럼 입력해 주면 'test' db 를 샤딩하겠다고 정해주는 것입니다. 이제 샤딩 키 (Sharding Key) 를 정해줘야 합니다. 샤딩 키를 바탕으로 (이 키로 정렬한다는 뜻입니다) 샤드들이 나눠지게 되기 때문에 샤딩키를 적절하게 정해주는 것은 아주 중요합니다. 인덱스를 정해준다고 보셔도 무방합니다. 

 

   mongos> use test
   switched to db test
   mongos> db.test_collection.ensureIndex({number:1})

   
   생각 난 김에 인덱스도 정해줍니다. test 디비에 test_collection 이라는 컬렉션에서 number 라는 컬럼을
   인덱스로 지정해 주라는 명령입니다. 

   

mongos> use admin
   switched to db admin
   mongos> db.runCommand( { shardcollection : "test.test_collection", key : {"number":1} })
   { "collectionsharded" : "test.test_collection", "ok" : 1 }
   mongos>


   
test 디비에 test_collection 이라는 컬렉션에서 number 라는 컬럼을 샤딩키로 해서 샤딩을 해 주라는 명령입니다. 

제대로 됐는지 확인을 해 보겠습니다. 

 

   mongos> use test
   switched to db test
   mongos> db.stats()


   
db.stats() 나 db.printShardingStatus() 로 확인하시면 됩니다. 


http://maestric.com/doc/mac/fix_ssh_connection_delays

원본은 위를 참조하시면 되고요.  이 현상은 OSX 에서만 발생하는 것 같습니다. 제 OSX 는 Lion 최신 입니다. 

클라이언트 (제 경우로 말하자면 OSX Lion 입니다)

$ sudo emacs /etc/ssh_config


위 파일을 열어서 

# GSSAPIKeyExchange yes

라고 되어 있는 부분을 

GSSAPIKeyExchange no

로 바꿔 주시면 됩니다.  

서버 (제 경우로 말하자면  Ubuntu 11.10 입니다)

$ sudo emacs /etc/sshd_config


위 파일을 열어서 

#UseDNS yes

(혹시라도 ) 이런 부분이 있다면 

UseDNS no
 
로 바꾸거나 추가해 주시면 됩니다.  (대소문자 주의)


ps.
  이렇게 했는 데도 사실 조금만 빨라지는 것 같았습니다. 내부 네트워크에서는 빠른데, 외부에서 접속만 하면 느리더군요. OSX 만 그러니 미치겠더군요.  심지어 제가 가지고 있는 안드로이드 폰보다 느립니다. ㅎㅎ 

 



https://github.com/ 를 이용하면 좋지만 대중에게 공개를 하지 않고 나만의 공간에 git 서버가 있으면  좋겠다고 생각하신 분들이 있을 것입니다. 그런 분들을 위한 개인적인 세팅방법을 알려드리겠습니다. 

저도 사실은 얼마전까지 svn (subversion) 을 사용하는 사람중에 한명이였습니다. 개발 환경 세팅 과 업무에 필요한 자료 & 개인적인 메모들을 svn 서버에 올려다 두고 어디서건 동기화 시켜서 바로 업무에 활용할 수 있게 설정해 두고 있었습니다. 그러던 와중에 기생하고 있던 서버가 사라지는 바람에 개인적인 서버를 가지게 되었고 개인 서버를 가지게 된 김에 git 서버를 설치하자고 생각해서 이리 설치하게 되었습니다. 
 

1. git 서버가 설치될 위치에 git 를 설치합니다.
 

 $ sudo apt-get install git-core 


2. git 를 위한 계정을 만들고 접근할 때 필요한 패스워드를 설정해 줍니다. 

 

$ sudo adduser --system --shell /bin/bash --gecos 'git version control' --group --home /home/git git

 $ sudo passwd git 

   패스워드 입력..


3. git 프로젝트들이 저장될 디렉토리 생성합니다. 
 

 $ sudo -u git mkdir /home/git/repos 


 긴건 귀찮으니까 간단하게 repos (repositories의 약자라는 개념으로..) 라고 합니다. sudo -u git 는 그 작업을 git 계정으로 하라는 명령입니다.


4. 서버에 올릴 프로젝트를 한개 만들어 줍니다. /home/crazia/doc 이라고 텍스트 문서들이 저장된 디렉토리를 올린다고 가정을합니다. 


 $ cd /home/crazia 

 $ git init doc 

 $ cd doc

 $ git add .

 $ git commit -a -m "doc init" 


 doc 이라는 이름으로 프로젝트를 만들어 주라는 명령입니다. 

 doc 안에 있는 모든 (하부 디렉토리까지 전부) 파일을 더해줘서 서버랑 상관 없이 로컬에 커밋을 하라는 명령입니다. 


5. 서버에 git daemon 을 띄워 줍니다. 


 $ sudo -u git git daemon --export-all --syslog --base-path=/home/git/repos --reuseaddr --detach


 git 계정으로 git 를 daemon 으로 한개 띄우라는 것입니다. 다른 것은 그냥 써주시면 되고 --base-path 로 3 번에서 만들어 준 저장소를 지정해 줍니다. 이 데몬은 항상 서버에 띄워져 있어야 합니다. 


6. 4번에서 만들어준 프로젝트를 저장소로 옮겨주는 작업을 합니다. 


 $ cd /home/git/repos

 $ sudo -u git git clone --bare /home/crazia/doc 굵게


 4번에서 만들어준 프로젝트의 복사본이 /home/git/repos 안에 생성 됐습니다. 


7. 데몬을 통해서 접근이 가능할 수 있도록 간단한 추가 작업을 해 줍니다. 


 $ cd /home/git/repos/doc.git

 $ sudo -u git touch git-daemon-export-ok


자 이제 서버에서 설정해 주는 일은 끝났습니다. 이제 클라이언트에서 제대로 설정이 됐는지 테스트를 해 보겠습니다. 


 $ git clone git@HOSTNAME:repos/doc.git 


물어보는 비밀 번호에 답하면 프로젝트가 받아 질것입니다. 

 HOSTNAME git 서버를 설치한 서버의 호스트 네임 입니다. ip 번호로 쓰셔도 됩니다. 

 repos 는 서버에서 만들어준 repos 의 이름입니다. 

 doc.git 는 서버에서 만들어준 프로젝트의 이름입니다. (제 경우라서 doc.git)로 설정해 줬습니다. 


혹시나 SK 브로드밴드의 일부 지역에서는 SSH 의 기본 포트인 22 번을 쓸 수가 없습니다. 망 차원에서 막혀있더군요 (이것 때문에 몇시간을 고생했는지.. ㅜ.ㅜ ) 그래서 다른 포트를 부득이 하게 쓰고 계신 분들은 (서버쪽 /etc/ssh/sshd_config 에서 Port 값을 변경하신 경우겠지요?) 

 git 는 기본적으로 ssh 를 이용해서 파일을 가져오는 데 포트를 변경해서 서비스 하는 경우에는 포트값을 입력할 수가 없겠지요? 따라서 클라이언트의 

 

 $ emacs $HOME/.ssh/config 


 를 열고 아래와 같이 추가해 줍니다. 


 Host  super.mavel.com

      User crazia

      Hostname super.mavel.com

      Port 2222


super.mavel.com 은 서비스하는 호스트 이름이고 Port 가 변경해준 포트 입니다. 여기서는 2222 입니다. 



+ Recent posts