Category Archives: Uncategorized

[입 개발] Redis Internals : PubSub

오늘은 Redis 를 사용하는 큰 이유중에 하나인 Publish/Subscribe 에 대해서 알아보려고 합니다.

먼저 Redis에서 사용하는 pubsub 관련 command 들은 다음과 같은 것들이 있습니다.

  • subscribe
  • unsubscribe
  • psubscribe
  • punsubscribe
  • publish

 

사실 publish 관련 명령은 하나 뿐이니 간단하게 이해할 수 있을 것이고,  앞에 p가 붙느냐 아니냐는 이게 pattern 으로 등록을 하느냐, 정확한 채널명인가를 지정하게 됩니다. 예를 들어서 subscribe 는 그냥 채널명과 일치하는 것의 데이터를 가져오게 되고, 앞에 p가 붙는 psubscribe 는 패턴을 등록해서 그 패턴과 일치하면 데이터를 전달하게 됩니다.

 

pub/sub의 구현을 위해서 redisServer 구조체 안에는 다음과 같은 구조체가 2개가 있습니다. key변경에 대한 notification 부분이 추가되었는데, 이 부분은 그냥  pub/sub을 이용하기 때문에 일단 생략하도록 하겠습니다.

 


/* Pubsub */
 dict *pubsub_channels; /* Map channels to list of subscribed clients */
 list *pubsub_patterns; /* A list of pubsub_patterns */

 

보면 채널은 dict 고 pattern은 list인걸 알 수 있습니다. 이건 channel은 같은 이름을 hash로만 찾으면 되는데, pattern은 해당 pattern이 모두 일치하는 지를 확인해야 하기 때문에 그렇습니다. 즉 여기서 pattern을 많이 사용하면, 느려질꺼라는 것을 예상할 수 있습니다.

 

subscribe 와 psubscribe에서 등록 과정은 각각 dict 에 넣거나 list에 넣는 것이 전부라 크게 볼 부분이 없고, publish 부분을 살펴보도록 하겠습니다. publish 과정은 두 단계로 이루어집니다.

  1. channel 에 있는 것중에 일치하는 것을 dictFind 로 찾아서 있으면 해당 등록된 클라이언트에게 모두 전송
  2. pattern 에 일치하는 것을 찾아서 해당 등록된 클라이언트에게 모두 전송

코드는 간단합니다. 다음과 같습니다.


/* Publish a message */
int pubsubPublishMessage(robj *channel, robj *message) {
 int receivers = 0;
 struct dictEntry *de;
 listNode *ln;
 listIter li;

/* Send to clients listening for that channel */
 de = dictFind(server.pubsub_channels,channel);
 if (de) {
 list *list = dictGetVal(de);
 listNode *ln;
 listIter li;

listRewind(list,&li);

while ((ln = listNext(&li)) != NULL) {
 redisClient *c = ln->value;

addReply(c,shared.mbulkhdr[3]);
 addReply(c,shared.messagebulk);
 addReplyBulk(c,channel);
 addReplyBulk(c,message);
 receivers++;
 }
 }
 /* Send to clients listening to matching channels */

if (listLength(server.pubsub_patterns)) {
 listRewind(server.pubsub_patterns,&li);
 channel = getDecodedObject(channel);
 while ((ln = listNext(&li)) != NULL) {
 pubsubPattern *pat = ln->value;

if (stringmatchlen((char*)pat->pattern->ptr,
 sdslen(pat->pattern->ptr),
 (char*)channel->ptr,
 sdslen(channel->ptr),0)) {
 addReply(pat->client,shared.mbulkhdr[4]);
 addReply(pat->client,shared.pmessagebulk);
 addReplyBulk(pat->client,pat->pattern);
 addReplyBulk(pat->client,channel);
 addReplyBulk(pat->client,message);
 receivers++;
 }
 }
 decrRefCount(channel);
 }
 return receivers;
}

 

위의 소스 코드를 보면 실제 pubsub_channels 과 pubsub_patterns 가 전부 내부에 리스트로 클라이언트를 관리하고 있는 것을 알 수 있습니다.  Redis 안에서 pub/sub은 굉장히 쉽게 구현되어 있습니다.

 

[돌머리] 돌머리를 깨기 위한 간단한 알고리즘 문제 – 매트릭스 90도 회전하기

Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place?

 

solve) Draw the mapping table. and easy you can find the rule

after 90 degrees rotation, map[y*n+x] ==> new_map(n-1-x)*n+y

and just write!!

 


#include <stdio.h>
#include <stdlib.h>

void printMap( int *map, int n ) {
 printf("=====map====\n");
 for( int y = 0; y < n; y++ ) {
 for( int x = 0; x < n; x++ ) {
 printf("%d ", map[y*n+x]);
 }
 printf("\n");
 }
}

void transform( int *map, int *new_map, int n )
{
 for( int y = n-1; y >= 0; y-- ){
 for( int x = 0 ; x < n; x++ ) {
 new_map[y*n+x] = map[(n-1-x)*n+y];
 }
 }
}

int main( int argc, char *argv[] ) {
 int n = atoi(argv[1]);

int *map = new int[n*n];
 for( int i = 0; i < n*n; i++ ) {
 map[i] = i;
 }

printMap(map, n);
 int *new_map = new int[n*n];
 transform(map, new_map, n);
 printMap(new_map, n);
 return 0;

}

[발 번역] Leveled Compaction in Apache Cassandra

해당 블로그는 KT Ucloud의 지원을 받고 있습니다.

해당 글은 
http://www.datastax.com/dev/blog/leveled-compaction-in-apache-cassandra
 의 글을 발 번역한 것입니다. HBase 나 Cassandra의 경우 Compaction이라는 단계가 있습니다. Write 속도를 빠르게 해주기도 하고 Locality를 높일 수 있으므로 성능을 높여주는 요소이기도 하지만, 또한 자바의 GC 처럼, 한번 Major Compaction이 일어나면, 시스템에 큰 부담을 주는 기능이기도 합니다. HBase의 경우 내부적으로 HDFS를 사용하고 있고, Cassandra의 경우는 로컬 파일시스템을 사용합니다. mongodb 역시 로컬 파일시스템을 사용합니다. GC가 꾸준히 발전하는 것처럼 Cassandra에서도 Leveled Compaction 이라는 기능을 추가했습니다.(다만, 아직까지 Major Compaction 일 때 큰 성능 저하는 피할 수 없는 듯 합니다.) 그럼 Apache Cassandra에서 사용하는 Leveled Compaction에 대해서 간략하게 알아보도록 하겠습니다. 오역에 주의하세요.

Leveled Compaction in Apache Cassandra

By Jonathan Ellis | October 10, 2011

Introduction to Compaction

카산드라의 로그 스토리지 엔진은 모든 업데이트를 sstables 이라는,순차적으로 디스크에 저장하는 방식을 이용하여, 놀라운 성능과 application-transparent compression 같은 기능을 가능하게 합니다. 이미 쓰여진 데이터를 업데이트 하지 않고( 이것은 Random I/O를 요구하기 때문에 ), 새로운 sstable 에 새로운 버전의 컬럼을 삽입하거나 업데이트 정보를 추가합니다.(역자 주, sstable 은 딱 한번만 쓰여지기 때문에, 컬럼의 업데이트 역시 insert 같이 처리됩니다. 그래서 하나의 컬럼 내용을 여러 sstable에서 읽어와서 최종 버전의 값을 확인해서 보여주게 됩니다. )

Figure 1: adding sstables with size tiered compaction

Figure 1: adding sstables with size tiered compaction

그래서, 시간이 지나면, 많은 버전의 row 가 다른 sstable 들에 존재할 수 있습니다. 각 버전들은 각각 다른 부분의 컬럼을 가지고 있습니다. 하나의 row를 읽기 위해서는 많은 파일을 찾아서 그 결과를 합쳐서 보내야만 합니다.

읽기 속도 악화를 방지하기 위해서, sstable들을 합치는 compaction 이 백그라운드로 동작합니다.( 각 sstable들에 들어있는 row들이 primary key로 정렬되어 있어서  Random I/O 없이,  해당 작업을 효과적으로 수행할 수 있습니다. )

Tiered Compaction

Figure 2: sstables under size-tiered compaction after many inserts

Figure 2: sstables under size-tiered compaction after many inserts

카산드라의 size-tiered compaction 전략은  Google’s Bigtable paper 에 묘사된 것과 매우 유사합니다. 비슷한 사이즈의 sstable들이 충분히 있으면(기본적으로 4개), 카산드라는 그 sstable 들을 합칠 것입니다. figure 1 에서 각 녹색 바는 하나의 sstable을 나타내고, 화살표는 compaction을 의미합니다. 새로운 sstable이 생성되고, 처음에는 아무일도 발생하지 않습니다. 4개가 되고 나면, 서로 합치기 시작합니다. 그리고 다시 새로운 4개가 발생하면 다시 반복하게 됩니다. Figure 2는 나중에 기대할 수 있는 결과를 보여줍니다. 2 tier의 sstable 들이 합쳐져서 3 tier의 sstable을 생성하고, 3 tier들이 합쳐져서 4 tier sstable을 생성합니다. 이게 계속 됩니다.

size-tiered compaction 는 update 가 많은 환경에서 3가지 문제점이 있습니다.

  • 성능이 일정하지 못합니다. 하나의 row 가 얼마나 많은 sstable에 걸쳐있을지 모르기 때문에, 최악의 경우에는, 모든 sstable 에서 해당 row를 찾아야 할지도 모릅니다.
  • 안쓰는 컬럼에 대해서 얼마나 빨리 병합해서 없앨지에 대해서 보장하지 않기 때문에, 상당한 양의 공간이 낭비될 수 있습니다. 특히 높은 비율로 삭제가 발생하면, 특별히 발생하기 쉽습니다.
  • 반복되는 Compaction으로 인해서 쓸모 없는 sstable이 병합되어  완전하게 쓰여지기 전까지, 너무 커지는 것도 공간에 문제가 됩니다.  최악의 경우에는 굉장히 큰 하나의 sstable 이 지울 수 있는 삭제된 row들이 없을 수 있습니다. 카산드라는 compaction이 진행될 때, 병합된 sstable을 쓰기 위해서 그 만큼의 빈 공간이 필요합니다.

Leveled Compaction

Figure 3: adding sstables under leveled compaction

Figure 3: adding sstables under leveled compaction

카산드라 1.0에서는 구글의 Chromium 팀에서 개발한 LevelDB 에 기반한  Leveled Compaction 전략을 제공하고 있습니다.(역자 주: 저도 이래서 이름이 그런건 처음 알았네요.)

Leveled compaction 은 sstable을 “levels” 로 그룹화되는 고정된 크기에 상대적으로 적은 크기(기본적으로 5MB)로 생성합니다. 그리고 각 레벨 내에서는 데이터가 겹치지 않는 다는 것을 보장하고, 각 레벨은 이전 레벨보다 10배 크기가 큽니다.

Figure 3에서 새로운 sstable이 첫번째 레벨에 저장이 됩니다. 그리고 L1에서 즉시 sstable 들은 compaction 됩니다.(파란색) L1이 가득 찼을 때, 추가된 sstable들이 L2로 올라가게 됩니다.(보라색). 상당 수의 L1에서 생성된 sstable 들이 compaction 되면서 L2 로 올라가게 됩니다.(이 때, 데이터가 겹칠 수 있습니다.) 데이터가 더더욱 추가되면, leveled compaction의 결과로 Figure 4 처럼 되게 됩니다.

Figure 4: sstables under leveled compaction after many inserts

Figure 4: sstables under leveled compaction after many inserts

tiered compaction 을 이용해서 위의 문제를 해결할 수 있습니다.

  • Leveled compaction 은 모든 읽기의 90%를 하나의 sstable 에서 히트시킬 것입니다.( 거의 같은 크기의 row 라고 가정했을 때 ), 최악의 경우에도 레벨의 최대 수에 한정됩니다. 예를 들어, 10TB 데이터를 위해서 7레벨 정도 입니다.
  • 삭제된 row 에 의해서 10% 정도 공간이 낭비될 수 있습니다.
  • compaction을 위해서 임시로 사용되는 공간을 위해서 오직 sstable의 10배 크기만 남아있으면 됩니다.

compaction_strategy 옵션을 LeveledCompactionStrategy로 설정하고, Column Family를 생성하면(업데이트 함으로써) Leveled compaction 을 활성화 할 수 있습니다. 존재하는 Column Family를 수정할 때 백그라운드로 현재 존재하는 sstable들의 레벨링이 수행되는 동안 , 읽기와 쓰기는 정상적으로 수행됩니다.

Considerations

leveled compaction이 위의 얘기들을 보장해주도록 해주기 때문에, size-tiered compaction 보다 대략 2배 정도 많은 i/o를 수행합니다. 주로 쓰기 중심의 작업에서, 거기에 삭제된 row 가 거의 포함되지 않았다면, 이 추가적인 i/o는 어떠한 도움도 되지 않습니다.

Leveled compaction 은 concurrent_compactors 옵션을 무시합니다. 병렬 compaction은 compaction 시스템이 큰 sstable 셋을 처리한다고 바쁜 동안에, 백로그에 작은 compaction 셋들이 임시적으로 멈추어 있는 tiered compaction의 문제를 피하기 위해서 디자인되었습니다. Leveled compaction에는 모든 compaction이 거의 같은 사이즈를 가지기 때문에 이러한 문제가 발생하지 않습니다. Leveded compaction은 하나의 스레드가 몇개의 sstable을 처리할 것인지를 결정하는 multithreaded_compaction 옵션을 compaction의 속도 향상을 위해서 이용합니다. 그러나, 대부분의 compaction 튜닝은 compaction_throughput_mb_per_sec 을 이용해서(기본: 16)  compaction의 속도를 조절합니다.

[Setting] Nginx + Tornaldo + Django + python 2.7.2

까먹을까봐 기록해두자.

1] python

apt-get install zlib1g-dev

apt-get install libbz2-dev

apt-get install libssl-dev

wget http://www.python.org/ftp/python/2.7.2/Python-2.7.2.tar.bz2

tar jxvf  Python-2.7.2.tar.bz2

./configure

make; make install

ln -sf /usr/local/bin/python2.7 /usr/bin/python

2] setuptools, pip

wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f613b509fb44feefe74e

tar zxvf  setuptools-0.6c11.tar.gz

python setup.py build

python setup.py install

ezsy_install pip (이후론 전부 pip)

3]virtualenv

pip install virtualenv

virtualenv –no-site-packages project1

./project1/bin/activate

pip install pycurl

pip install simplejson

pip freeze > pip-req.txt

4]  django

pip install django

5] tornaldo

pip install http://github.com/downloads/facebook/tornado/tornado-2.1.1.tar.gz

6]nginx

sudo apt-get install libpcre3 libpcre3-dev

wget http://nginx.org/download/nginx-1.0.11.tar.gz

tar zxvf nginx-1.0.11.tar.gz

./configure

make; make install

[nginx.conf]
worker_processes 1;

events {

worker_connections 1024;
use epoll;
}
http {
upstream tornadoserver {
server 127.0.0.1:8888;
}
include mime.types;
default_type application/octet-stream;

sendfile on;

keepalive_timeout 65;

#gzip on;
include /usr/local/nginx/conf.d/*.conf;

server {
listen 80;
server_name localhost;

location / {
proxy_pass http://127.0.0.1:8888;
}

error_page 500 502 503 504 /50x.html;

location = /50x.html {
root html;
}

}


			

[발 번역] MongoDB Best Practices

해당 글은 
http://www.engineyard.com/blog/2011/mongodb-best-practices/
 의 MongoDB Best Practice 를 발 번역한 글입니다. 오역에 주의하세요.

MongoDB Best Practices

안녕하세요. Engine Yard Data Team 입니다. 지난번에 블로깅한 이후로 무슨 일이 있었는지 알려드리길 바랍니다.

데이터 팀은 올해 초에 만들어진 후, 첫번째 작업은 MongoDB stack을 확장하는 것이었습니다. 그러나, 관계형 DB의 업데이트 없이  NoSQL 저장소를 추가한다면, 고객에게 몹쓸짓을 하게 된다는 것을 느꼈습니다. 그래서 MongoDB 개발을 멈추고 MySQL과 PostgreSQL 의 업데이트 하기로 결정했습니다.  최근에 MySQL 5.5 베타가 출시되었고 PostgresSQL 9.1 베타는 곧 나올 것입니다. 그리고 2012년 1분기쯤 GA버전을 출시할 계획입니다.

이제 MongoDB에 더 초점을 맞추고, 몇몇 고객의 MongoDB 사용을 돕고 있습니다.  이 작업 동안에 다양한 잠재된 문제점을 발견했습니다. 이번 기회에 MongoDB를 위한 Engine Yard의 best practices를 공유하고 싶습니다.
MongoDB를 개별적으로 설치했다면, 해당 글에 맞춰서 설치를 체크하시길 바랍니다. 필요하다면, 설정을 바꾸길 권장합니다. 만약 도움이 필요하다면, Professional Services 조직에 도움을 요청하시길 바랍니다.

General NoSQL best practices

NoSQL을 선택하는 방법에 대한 많은 문서들이 있습니다. Read/Write 성능, 안정성, 데이터 일관성, 네트웍 응답속도 등 여러 특징들을, 어플리케이션에서 요구하는 것을 고민해서 잘 선택해야 합니다. 해당 문제에 대해서  Nathan Hurst in가  “Visual Guide to NoSQL Systems” 에 잘 요약해두었습니다.

올바른 NoSQL을 선택하는 것은 이 문서의 범위를 넘어가므로, 직접 조사하시기 바랍니다.  모든 상황에 맞는 하나의 솔루션을 없을 것입니다. 해당 문서도 MongoDB가 요구하는 어플리케이션에 적합하다고 가정하고 넘어갑니다. Engine Yard 에서 추천하는 부분은 다음과 같습니다.

미친듯이 테스트 하라 – Test exhaustively

어플리케이션이 실제 서비스 하는 시스템에서 받을 수 있는 트래픽 상황에 맞추어서 테스트 해야 합니다. 실서비스에는 성능 병목 현상이 발견되거나,아키텍처 디자인에서에서 문제가 발생해도, 테스트 시스템에서는 재현되지 않습니다. 쿼리를 실서비스와 비슷하게 테스트하고, 측정값들을 항상 수집 해야합니다.( 역자 주: 실제로, NoSQL 서비스의 벤치마크만 믿고 시작하면, 문제가 발생할 여지가 많습니다. 이것은, 자신의 상황에 맞춰서 테스트를 해보지 않아서 그렇습니다. – 이렇게 테스트를 해도 실제 환경에서는 좀 더 문제가 발생할 수 있습니다. – 예를 들어, 하루 정도 테스트 할 때는 문제가 없었는데, 일주일 이상 실 서비스에 돌려보니, 메모리 부족으로 GC가 발동해서, 서비스가 확 떨어지는 문제가 나올 수도 있고, 테스트 시에는 10개 정도의 필드만 사용했는데, 실 서비스는 100개 이상이라, 속도 차이가 현저히 발생할 수 있습니다. )

RDBMS를 그대로 대체할 수 있다고 가정하지 말라 – Don’t assume that what worked for your RDBMS will translate

 SQL 데이터베이스에서 도는 작업은 뭐든지,  MongoDB에서 동작하지 않을 수 있습니다.  그래서 기대는 현실적인지, 실제 데이터베이스의 기능을 적용할 수 있을지 확인해야 합니다. 좀 더 좋은 성능을 위해서, documents(역자주: MongoDB는 Document 기반), 와 Query를 10gen에서 추천한 방법을 따르는게 좋습니다.  비 관계형 저장소로 넘어가기 위해서 어플리케이션이 다시 설계되어야할 필요가 있다는 것을 이해해야합니다.  NoSQL로 의 이전을 위해 더 정보가 필요하다면  “The cost of Migration” 를 일기 바랍니다.(역자 주: 보통 가장 많이 하는 실수가 기존의 RDBMS 의 데이터 모델을 NoSQL로 그대로 넘어가길 원한다는 것입니다. 먼저 자신의 데이터가 NoSQL에 적합한가를 고민하는 것이 최우선입니다. 그리고, 그게 아니라면, 그냥 RDBMS를 써야 합니다. 참고로, 어떤 NoSQL도 현재 중요한 데이터를 혼자 저장하는데 사용하라고 추천하는 곳은 없습니다. 모든 곳에서 중요한 데이터는 넣지 마시오라고 가이드합니다. 여기서 중요한 데이터는, 중요한데, 새로 만들 수 없는 데이터를 의미합니다. 만약 쉽게 다시 만들 수 있는 데이터라면, 날라가도 다시 만들 수 있으니 큰 문제가 없을 수 있습니다.)

데이터에 대한 일관성과 안전성이 필요한지 고민하라 – Think about the consistency and durability needs of your data.

데이터 일관성과 안전성이 필요한지 고민해야 합니다. 이것은 강요할 수 없습니다. 직접 MongoDB에서 제공하는 리플리케이션을 통한 안전성을 판단해야 합니다. 실 서비스 동안 MongoDB 하나만 사용하는 것을 절대로 추천하지 않습니다. 왜 그래야 하는지 확인하시기 바랍니다.

EBS Volumes에서 무엇을 기대할 수 있는지 이해하십시오 – Understand what to expect from EBS volumes

만약 Engine Yard Cloud(AWS EC2) 고객이라면  아마존 Elastic Block Storage(EBS)의 성능이 항상 같지 않다는 것을 알아야 합니다. 어플리케이션 벤치마킹을 하거나, 데이터를 구성하는 동안에, 시간에 따른 지표를 수집해야 합니다.  Engine Yard는 고객이 이런 불편함이 없도록 관리합니다.

MongoDB Best Practices

MongoDB를 우리의 Stack에 릴리즈 하는데 따라야 하는 지침은 다음과 같습니다.

항상 Replica Sets을 사용하라 – Always use replica sets

Replica Sets은 장애시 자동 FailOver를 통해서 HA(고 가용성)를 제공합니다. Primary 노드에 장애가 난다면, Secondary 노드가 Primary 로 선출됩고, 서비스는 계속 동작합니다. 실서비스 환경에서 Replicate 하지 않는 MongoDB는 Engine Yard에서는 서포팅하지 않습니다. Mongo 디비를 Replication 하는 비용이 너무 비싼것 같다면 Hosted 솔루션을 고려해보시기 바랍니다. Engine Yard는 MongoHQ 와 MongoLabs와 파트너쉽을 가지고 있습니다.  더 많은 정보가 필요하다면 Partners page 를 보시기 바랍니다.

최신 버전을 유지하라 – Keep current with versions

최신 버전을 MongoDB를 유지하길 바랍니다. 10gen 에서는 매 릴리즈마다, 클러스터를 좀 더 안정적으로 돌 수 있게 하는 많은 패치를 냅니다. Version 2.0.x 의 경우 클러스터를 쉽게 증가시킬 수 있는 중요한 성능, 동시성 증대, 인덱스 변경, 버그 픽스, Compaction 커맨드등을 포함하고 있습니다. 만약 1.6.3을 사용한다면, 가능한 업그레이드 하길 바랍니다.( 역자 주: 지속적으로 발전하는 NoSQL등의 경우, bug fix를 보는 것이 상당히 중요합니다. Mysql등의 오래된 패키지는 새 버전이 나오면 검증을 오래하고 적용하게 되지만, MongoDB의 경우도 2.0.0에서 Consistency 문제가 있어서 긴급히 2.0.1이 발표되었습니다.)

MongoDB를 32bit에서 사용하지 말라 – Don’t run MongoDB on 32-bit systems

32bit 시스템에서는 MongoDB는 2.5GB 의 데이터 밖에 사용할 수 없습니다. Storage Engine이 성능상의 이유로 Memory-Mapped Filed을 사용하고, 이로 인해 메모리 어드레싱이 2.5 까지 밖에 사용할 수 없기 때문입니다. Engine Yard Cloud 에서는 기본적으로 Large Instance를 이용합니다. 그리고 64bit MongoDB 만 지원합니다.( 역자 주: 모든 NoSQL이 64bit에 풍부한 메모리를 권장합니다. 이 이유는 대부분 빠른 속도를 위해서 많은 메모리를 사용하고, 데이터 량이 예전과 다르게 많기 때문입니다.  특히 MongoDB의 경우 index가 메모리 사이즈보다 커지면, 속도에 큰 저해가 오기 때문에, 메모리를 많이 다시는 게 좋습니다. 포스퀘어 같은 경우는 65G가 메모리를  MongoDB 서버 한대당 사용한다고 합니다. )

기본적으로 Journaling을 사용하라 – Turn journaling on by default

 MongoDB는  장애 복구나 노드의 안전성을 위해서 Write-Ahread 저널링을 지원합니다. 우리는 저널링을 기본적으로 사용하기를 강력하게 추천합니다.(역자 주: 현재 MongoDB 개발 트리는 기본적으로 저널링이 enable 되어있다고 합니다.)

데이터 파일의 위치를 확인하라  - Mind the location of your data files

MongoDB 데이터 파일이 영구저장되는 볼륨에 있는지 확인해야합니다.(예: /data/mongodb) 임시 드라이브에도 저장할 수 있지만, 클러스터 아키텍처에 영향을 주므로 매우 조심해야 합니다. MongoDB 데이터를 EBS에 저장하는 것을 추천합니다.(역자 주: 개인적으로 DB내용을 임시 노드에 올려둔다는 것은 조금 이해가 안갑니다. 다만 주의할 것은 /tmp 노드에 기본적으로 저장되는 것에 주의해야 합니다. 간단하게 mysql의 경우 /tmp/mysql.sock 이 기본 통신 채널인데 /tmp를 정기적으로 삭제하는 정책이 있을 경우, 서비스에 문제를 일으킬 수 있습니다. NoSQL 을 사용하면서 데이터가 이상해라고 말하는 케이스 중에, 이렇게 /tmp를 NoSQL 정보의 임시 저장소로 만들어두고, 해당 영역이 지워지거나 꽉 차서 발생하는 케이스가 많습니다.)

Working Set은 메모리 사이즈에 적합하게 유지하라 – Your working set should fit in memory

 Working Set(Index)을 메모리에 두는 것은 클러스의 영향을 미치는 매우 중요한 요소입니다. Page Fault 가 증가하는 것을 알면, 가용 메모리보다 Working Set 의 사이즈가 커진다는 것을 알 수 있는 알 수 있는 매우 좋은 기회입니다.  가용 메모리보다 Working Set 데이터가 증가하면 두 가지 방법이 있습니다. MongoDB의 메모리 사이즈를 증가시키거나, 샤딩을 하는 것입니다. MongoDB의 메모리 사이즈를 증가시키는 것을 먼저 추천합니다. ( 역자 주: 다만 데이터 양이 너무 많아지면, 결국 scale up은 한계가 있으므로, 샤딩으로 가야합니다. )

엄청 많이 사용한다면 Scale Up을 하라 – Scale up if your metrics show heavy use

장비의 load가 65%를 넘는다면, Scaling up을 고려해야 합니다. 평균적으로 동작할 때 load가 , 일관성있게 해당 수치 이하여야 합니다.  복구나, 수직 Scaling 상황에도 영향을 줍니다. instance size를 늘려야 할 필요가 있다면, AWS는 Large, Extra Large, high Memory 4XL 순서로 업그레이드를  추천합니다.  큰 EBS 볼륨에서도 latency가 적습니다.

샤딩에 주의하라 – Be careful when sharding

샤딩을 적용하는 것은 어플리케이션의 액세스 패턴에 대한 깊은 이해가 필요합니다. MongoDB가 어떻게 샤딩을 하고 정말로 샤딩이 필요한지에 대해서 시간을 드려서 고민하시기 바랍니다. 그리고 성능에 영향을 주는 좋은 샤딩 키를 선택하는 것도 중요합니다.(selecting a good sharding key) ( 역자 주: 샤딩의 경우 샤딩키를 제외하고는, Unique 속성을 줄 수 없습니다. 복합 샤딩키는 가능합니다.)

Config 서버는 클러스터 상태에 매우 중요합니다. 실서비스의 샤딩 환경에서는 3 대의 Config 서버가 필요합니다. 자주 Config 서버의 데이터를 백업하고,  그것을 확인하고, 절대로 Config 서버의 데이터를 지우면 안됩니다. 가능하면 /etc/hosts 파일에 서버 이름을 저장해두고 사용하길 바랍니다.( 클러스터를 좀 더 탄력적으로 만들 수 있습니다.)

Config 서버는 경량 프로세스이지만, 역시 64bit 장비에서 동작해야 합니다. 3개의 Config 서버를 한 장비에 몰아넣으면 안됩니다. 만약, 샤드된 설치를 고려한다면 Engine Yard Professional Services 에 컨설팅 스케줄을 잡으실 수 있습니다.

 그래픽적으로 모니터링 하기 위해서 MongoMMS를 사용하라 – Use Mongo MMS to graphically monitor your service

만약 이미 Mongo MMS 를 사용해본 적이 없다면, 10gen 에서 열정적으로 개발하고 있는 제품으로, 클러스터의 상태를 체크해서 최고의 방법으로 표시해 줄것입니다.

 MongoDB resource를 살펴라 – Keep up with MongoDB resources

빨리 바뀌므로, 정보를 항상 최신으로 유지하라. 다음 사이트에서 정보를 찾을 수 있습니다.

뭔가 더 듣고 싶나요? 피드백을 주세요 – Want to hear more? Give us feedback!

피드백은  빠른 릴리즈 프로세스, 블로그 포스팅 계획, 로드맵 우선 순위등 많은 곳에 이용됩니다. 어떤 알파/베타 릴리즈를 시도하는지, 어떤 질문이라도 해주시기 바랍니다. 우리의 데이터베이스가 계속 최적화되고 계속 발전하기를 바랍니다.
(역자 주: 여기에 조금만 더 추가하자면, MongoDB의 경우 보안 기능이 기본적으로 disable 되어 있기 때문에,  이걸 키고 사용하는게 좋습니다. 
http://www.mongodb.org/display/DOCS/Security+and+Authentication
 여기서 보실 수 있습니다.  MongoDB의 소스를 보면 MONGO_SSL을 사용할 수 있도록 들어가 있는 것 같습니다. 전체 데이터에 대한 SSL 지원인지는 좀 더 봐야겠네요 ^^)

최근의 행복에 대한 생각

먼저, 저는 상당히 행복합니다. 돈도 조금이나마 저축이 가능할 정도로 벌고 있고, 꽤 재미있는 일도 하고 있고

그런데, 최근에, 지속적인 행복 상태를 만드는데, 주변 환경도 중요하다라는 생각이 듭니다.

그래서 고민이 되는 것이 자연 환경이 좋은 “제주도” 로 옮긴다든지, 아니면, 외국을 한번 미친듯 하고 나가 본다든지, 부산으로 내려가서, 그냥 조용히, 알바하면서 사는 건 어떨까 라는 생각이 듭니다.

물론 이것들은, 중요한 전제조건이 붙습니다. “먹고 살 돈이 되느냐?” 몇년 안에 분명히 2세도 가질테고, 기본적으로 사용하는 돈들 아무리 생각해도, 어느 정도는 벌어야 가장으로서, 집안 식구들을 먹여 살릴 것 같은데, 컴퓨터 프로그래밍 말고는 재주가 없는 저로서는 지방에서 가족을 부양하한다는 것은 상당히 큰일입니다.

그렇다면, 시골이나, 지방으로 내려가게 되면, 어떻게 먹고 살아야 할 것인지에 대해서, 고민이 스멀스멀 생겨나게 됩니다.  재미난 것은, 제가 일하는 분야의 IT 쪽에서는 사실, 꼭 같은 사무실로 출근할 필요는 없다는 것입니다. 하지만, 함께 없을 때 생기는 커뮤니케이션의 비용에 대한 걱정으로, 사무실로 출근을 해야 하는 것이죠.

뭔가 세상이 바껴서, 전부 재택근무 이런 시기가 온다면 정말 좋겠지만, 아직까지 그러기는 힘들고, 나름의 좋은 방법을 계속 생각해보는 수 밖에 없을 듯 합니다.

별 도움 안되는 Server Modeling with Mysql

A Walk In The Cloud

미흡한 지식으로 Cloud 를 살짝 정리해보았습니다.

과연 Developer/Operator/DBA는 Cloud 에서 어떤 포지션을 가져야 할까요?

Follow

Get every new post delivered to your Inbox.

Join 29 other followers