Home

메모리 overcommit

overcommit_memory

Linux의 메모리 관리에서는 메모리 오버커밋이라는 메커니즘이 적용되어 있어 실제 메모리 이상의 공간을 확보할 수 있다. 이는 어떤 문제를 야기시킬 수 있는가 하면 Linux 가상 메모리 시스템은 프로세스가 메모리를 확보할 때는 많게 보이게 하고 실제로 프로세스가 메모리에 접근을 하게되면 실제 메모리를 할당하는데 이때 실제 메모리가 부족하게 되면 OS내부적으로 프로세스를 마음대로 kill을 해버린다. 이른바 OOM-killer(out of memory killer)라고도 한다.

OOM Killer(Out of Memory Killer)는 시스템이 실제 메모리와 가상 메모리 공간(스왑)을 다 사용해, 필요한 메모리 공간을 새로 확보 할 수 없는 경우 프로세스를 종료시켜 여유 메모리를 확보하는 Linux 커널의 메커니즘 중에 하나이다.

그래서 kill된 프로세스가 자기가 왜 죽어버리는지 알수 없는 인터럽트가 발생해서 자신이 인터럽트가 발생했을 때 예외처리를 수행하지 못하는 문제가 발생한다. 이런 현상이 데이터를 관리하는 DB 서버에서 발생한다면 Linux의 좋은 매커니즘이라도 고객의 인지 정보가 실제 데이터에는 저장되지 않는 데이터 유실을 유발시킬 수 있다. DB 자체가 메모리 부족을 인지하고 예외처리하는 로직을 테우게 OS환경을 만들어줄 필요가 있다.
사소하지만 고민해야할 부분인 것이다.

관련 커널 메개변수 정보를 설명하면..

*. vm.overcommit_memory
  • 0 : heuristic에 따라 overcommit 할 수 있고, 하지 않을 수도 있다.(디폴트) 메모리 요구가 있을 때 여유 공간이 없는 경우 실행중인 프로세스를 강제 종료 메모리를 억지로 확보함.
  • 1 : 항상 overcommit 함. 메모리를 다 사용했는데도 충분한 메모리가있는 것처럼 처리 됨. 그 외에는 0과 같음.
  • 2 : overcommit하지 않음. 메모리가 부족할 경우 메모리 확보시 에러 발생시킴. [Swap size] + ([RAM size] * vm.overcommit_ratio/100).
*. vm.overcommit_ratio
  • 사용 가능한 메모리의 백분율로 정의. overcommit_ratio의 디폴트는 50.

vm.overcommit_memory = 0 or 1 일 경우 현재 환경에서 메모리 확보 테스트해 보면

현재의 메모리 정보는 아래와 같다.
[root@mimul01 ~]# free
             total       used       free     shared    buffers     cached
Mem:       1019680     457172     562508          0      25384     159084
-/+ buffers/cache:     272704     746976
Swap:            0          0          0

Physical Memory는 1G정도 된다고 볼 수 있다. CommitLimit(상한)과 Committed_AS(사용량) 정보는 아래와 같다.
[root@mimul01 ~]# cat /proc/meminfo |grep Comm
CommitLimit:     1009480 kB
Committed_AS:     518468 kB

그런 다음 아래 소스를 가지고 malloc 테스트를 실행 해 보았다. 이 경우 오버커밋이 허용되어 있어서 malloc_test 프로그램이 구동되는 동안 계속 메모리 확보를 하고 오버커밋된 범위까지도 메모리 할당을 시도한다. 즉 malloc에서 에러 리턴을 하지 않는 구조이다.
> cat malloc_test.c
#include <stdio.h>
#include <stdlib.h>

#define KB  1024
#define MB  (1024*KB)

int main()
{
  int i = 0;
  char *ptr = NULL;
  for (i=0; ;i++) {
    ptr = (char *)malloc(MB);
    if(ptr == NULL){
      break;
    }
  }
  printf("MALLOC SIZE=%dMB\n",i);
  return(0);
}
[mimul01]/home/k2/Downloads/alloctest> gcc -o malloc_test malloc_test.c
[mimul01]/home/k2/Downloads/alloctest> ./malloc_test 
죽었음

오버커밋 처리되어 malloc_test에서 인터럽트되어 제어가 되지 않고 OOM-killer에 의해 프로세스가 죽게 된다. 이럴 경우 malloc_test 프로세스는 내부의 예외처리가 무시되어 중요한 문제에 봉착될 수 있다. 아래는 프로세스가 죽었을 때 로그이다.
May  8 11:18:50 mimul01 kernel: Out of memory: Kill process 3121 
 (malloc_test) score 884 or sacrifice child

vm.overcommit_memory = 2, vm.overcommit_ratio = 99 일 경우 테스트 사례는

CommitLimit(상한)과 Committed_AS(사용량) 정보는 아래와 같다.
[mimul01]/home/k2/Downloads/alloctest> cat /proc/meminfo  |grep Comm
CommitLimit:     1009480 kB
Committed_AS:     520128 kB

이경우에는 아래처럼 정보를 보면 알겠지만 malloc시 널로 리턴되어 거기까지 메모리를 할당하고 빠져나오는 프로그램 프로세스를 그대로 탔다. 이처럼 제어가 프로그램으로 넘어거 예외 처리를 할 수 있는 구조가 된다.
[mimul01]/home/k2/Downloads/alloctest> ./malloc_test 
MALLOC SIZE=433MB

특히나 대상 서버가 데이터 베이스 서버일 경우에는 데이터의 무결성이 중요함으로 MySQL 데몬에 의해 예외 프로세스를 타게 해주는 것이 유효해 보인다.
더 중요한건 서버의 자원 모니터링을 해서 부족하지 않도록 Scale Up을 잘 해 주는 것이 필요하다.

결론은..

데이터 베이스 서버(MySQL, PostGreSQL, Redis 등)일 경우에는 커널 정보에 아래 설정을 해 두는 것이 데이터 무결성 보호에 도움을 받을 것이다.
vm.overcommit_memory = 2
vm.overcommit_ratio = 99

그리고 데이터 베이스 서버는 스왑 사용도 비용이 크므로 vm.swappiness = 0로 운영하는 것도 괜찮다.

변수와 메소드 네이밍에 관한 15가지 모범 사례

코딩 스타일을 좋게 하는 방법 중에 하나가 네이밍을 일관되게 사용하는 것이다. 그래서 관련된 좋은 아티클, "15 Best Practices of Variable & Method Naming"에 대해서 소개한다.

간략하게 정리해 보면..

1. 범위별로 충분히 짧게, 혹은 충분히 긴 변수 이름을 사용한다. 일반적으로 루프 카운터에는 하나의 문자로, 조건이나 루프 변수는 한 단어로, 메소드는 한/두단어로, 클래스에는 두/세 단어로, 전역 변수는 서/너 단어를 사용한다.

2. 구체적인 변수 이름을 사용한다. 예를 들어, "value", "equals", "data" 같은 변수 이름은 어떠한 경우에도 유효하지 않다.

3. 의미있는 변수 이름을 사용한다. 변수 이름은 저장되는 값을 정확하게 설명할 수 있어야 한다.

4. 변수 이름은 "o_", "obj_", "m_"등으로 시작하지 않는다. 변수 이름에 자신이 변수라고 자기 자신을 언급하는 태그는 필요 없다.

5. 변수에 관련된 회사의 네이밍 규칙을 따르고, 어플리케이션 내에서도 일관된 변수 이름에 쓴다. 예를 들어, txtUserName, lblUserName, cmbSchoolType 등과 같이. 그렇지 않으면, 가독성이 떨어지고 검색/바꾸기 툴 사용 측면에서 사용할 수 없게 된다.

6. 프로그래밍 언어의 표준을 따르자. 그리고 대/소문자 문자들을 일관되지 않게 사용하지 않는다. 예를 들어, userName, UserName, USER_NAME, m_userName, username 등에서 처럼 비 일관되게 사용하지 않는다.
  - Java의 예로 올바른 네이밍은.
  • Camel Case(aka Upper Camel Case)를 클래스에 사용한다. VelocityResponseWriter
  • Lower Case(Lower Camel Case)를 패키지에 사용한다. com.company.project.ui
  • Mixed Case(aka Lower Camel Case)을 변수 로 사용한다. studentName
  • Upper Case를 상수로 사용한다. MAX_PARAMETER_COUNT = 100
  • Camel Case를 enum클래스에 사용하고 Upper Case를 enum 값으로 사용한다.
  • '_'는 상수와 enum값 이외의 어떠한 곳에서도 사용하지 않는다.(이들은 상수이다.)
7. 다른 컨텍스트에서는 동일 클래스내에서 동일 변수를 사용하지 않는다. 예를 들어, 메소드및 생성자, 클래스 등이다. 이렇게 하면 더 간단하게 이해하기 쉽고 관리하기 용이하게 할 수 있다.

8. 메소드및 조건 등에서 다른 목적이라면 동일 변수를 사용하지 않는다. 대신 새로 다른 이름의 변수를 준비한다. 이것은 이해하기 쉬움과 유지 보수의 용이성도 중요하다.

9. 변수 이름에 ASCII가 아닌 문자를 사용하지 않는다. 그들은 당신의 플랫폼에서 작동 할지도 모르지만, 다른 플랫폼에서 작동하지 않을 수 있다.

10. 너무 긴 변수 이름을 사용하지(예로, 50자 길이). 너무 긴 이름은 추잡하고, 읽기 어려운 코드이다. 게다가, 어떤 컴파일러는 최대 길이(character limit)에 의해 작동되지 않는다.

11. 네이밍을 위해 자연 언어를 하나로 정하고 그것을 사용한다. 예를 들어, 영어와 독일어가 혼합 된 이름은 비 일관적이고 읽기 힘들 것이다.

12. 메소드를 위해서도 의미 있는 네이밍을 사용한다. 이름은 메소드의 정확한 동작(action)을 구체적으로 나타내고, 대부분의 경우 동사로 시작(createPasswordHash 등)한다.

13. 메소드에 대해서도 회사의 네이밍 규칙에 따르고, 어플리케이션 내에서 일관되게 메소드 이름을 쓴다. 예를 들어, getTxtUserName(), getLblUserName(), isStudentApproved() 등이다. 그렇지 않으면, 가독성이 떨어지고, 검색/바꾸기 툴의 사용 측면에서 유효하지 않게 된다.

14. 프로그래밍 언어의 표준에 따라 대/소문자 문자열을 일되관하지 않는 상태로 사용하지 않는다. 예를 들어, getUserName, GetUserName, getusername 등의 혼합 말이다.
- Java 의 예로 올바른 경우는.
  • Mixed Case를 메소드 이름으로 사용한다. getStudentSchoolType
  • Mixed Case를 메소드 매개 변수에 사용한다. setSchoolName (String schoolName)
15. 의미있는 이름을 메소드의 매개 변수로 사용한다. 그렇게 되면, 문서가 없는 경우에도 코드 자체가 문서 역할을 하게 된다.

기계가 세상을 통제한다면..

우연히 검색을 하다가 "Algorithms Take Control of Wall Street" 기사를 봤는데 내용이 재미 있어서 소개 및 제 생각을 몇자 적어본다.

내용은 월스트리트는 알고리즘에 의해 접수되었다. 정도...

[Lexicon]은 구독자인 알고리즘이 이해하는 데이터를 전송한다. 즉, 로봇 프로그램(클라이언트)이 이해할 수 있는 방식으로 뉴스를 보낸다. 다우 존스의 모든 기사를 실시간으로 검색하고 주식에 대한 투자자의 기대를 예측할 수 있는 단서를 찾는다. 그리고 그 정보를 컴퓨터가 읽을 수 있는 형태로 해 알고리즘의 구독자에게 전달하는 것이다. 알고리즘은 그것을 더 깊이 분석해 얻어진 데이터를 바탕으로 투자 결정을 내린다.

[Lexicon]은 뉴스를 읽고 시황을 전망, 그 정보를 바탕으로 주식을 매매하는 일련의 프로세스 자동화를 촉진한다. 컴퓨터는 더 이상 계산하는 것만은 아니다. 의사 결정을하게 된 것이다. 금융 시스템 전체가 점점 그렇게 되어 가고 있다.

[Lexicon]을 구독하는 투자자의 대부분은 인간이 아니다. 알고리즘. 즉, 세계에서로 날마다 일어나는 거래를 지배하는 무수한 코드들인 것이다. 그들은 인간처럼 뉴스를 읽거나 하지 않는다. 기사도, 문장조차도 필요 없다. 우리가 알고리즘을 위해 디자인된 세상에 살고 있으며, 또한 우리는 점점 더 알고리즘에 의해 컨트롤 받고 있다.

"시장은 기계가 접수했다. 인간은 단지 그 안에서 거래를 하고 있는 것에 지나지 않는다." 인지 능력을 초월한 속도와 처리 능력의 월스트리트를을 담당하는 컴퓨터 시스템이 폭주 할 때, 사람은 금융 시장의 붕괴(Flash Crash 등)를 방지 할 수 있을까?

빅데이터 뒤에는 빅 브라더가 도사리고 있다. 기계에 의해 제시되는 추론엔진에 의해 소비자들이 조정되는 환경이 되었다. 우리들은 그럴듯함과 익숙함으로 인해 생각의 종말이 올 수도 있지 않을까? 컴퓨터가 세상을 접수한다.

그리고 제어할 수 없는 카오스적 폭주는 원전에서도 도사리고 있다. 우리의 인생은 우리에 의해 결정되지 않는 날이 멀지 않은 것 같처럼 느껴진다.많은 생각이 나는 새벽이다.
Tags :

서브루틴(subroutine) vs 코루틴(co-routine)

서브루틴(subroutine)
폰노이만이 컴퓨터 아키텍처의 발명에 큰 영향을 준 것중에 하나가 서브루틴 개념의 발명이다. 그러다보니 그 지대한 영향력 때문인지 몰라도 사람들의 프로그래밍 스타일까지 파고들어 오늘날에 이르기까지 한다.

서브루틴은 부모와 자식의 주종 관계가 성립하고, 서브루틴의 호출은 부모에 의해서 호출된다. 결국 서브루틴은 처리 후 리턴에 의해 부모로 돌아가는데 그 때 Context정보는 두고 돌아간다.
세상에는 서브루틴처럼 순차적인 문제만 있는 것이 아니다. 문제 자체가 병렬적인게 많다. 대게의 경우 게임이 그러하다. 각각의 플레이어를 계층화할 수 없다는 말이다. 둘 이상이 병렬적으로 Context를 가지고 게임을 하게 된다.
서브루틴은 결과를 리턴할 때마다 Context가 초기화되어 개별 플레이어들의 런타임 Context는 서브루틴 밖으로 리턴시에 가져갈 수 없게 된다.
이런 문제를 해결한 것이 Conway가 생각해 낸 코루틴(co-routine)이다.

코루틴(co-routine)
주종관계가 없는 프로그램 단위가 병렬적으로 진행된다. 자신의 실행을 중단하고 다른 코루틴으로 제어권을 전달할 수도 있다.
서브루틴의 컨텍스트는 종료와 함께 사라지지만, 코루틴의 컨텍스트는 그대로 존재한다. 같은 코루틴에서 멈췄던 곳에서 다시 진행할 수도 있다.

Apache event_mpm vs Nginx 성능 비교

Aapache 2.4 정식 버전의 event_mpm이 어떤 성능을 발휘하며 성능을 최대치로 올리기 위한 튜닝 정보 및 Nginx와 설정 및 성능 비교를 통해 본 Apache의 현재에 대해서 살펴보고자 한다.
과거 Apache와 Nginx의 성능 비교 자료들을 보면 대부분 Nginx의 성능이 월등하게 나온다는 것을 안다. 하지만, 여기서는 두가지 비교를 통해 최적의 사용 포인트를 개인적으로 짚어보는 의도가 강하다. 한마디로 잘 사용해 보고 싶다.
혹시 많이 사용해 보신분들이 이 글을 보시게되면 좋은 조언 부탁드립니다. 혹시 잘못 표기된 정보가 있으면 댓글로 첨언 부탁드립니다.

성능 테스트를 위한 설정 정보들

Event방식의 NonBlocking 이 좋은 건 Apache prefork모듈처럼 하나의 프로세스에서 하나의 클라이언트를 처리하는 방식보다 적은 쓰레드로, 메모리 자원도 적게 사용해 클라이언트의 요청을 처리할 수 있게 해준다.
그만큼 웹 서버에서 DB단과의 클라이언트 요청 처리 lifecycle(데이터 읽고 가공해서 클라이언트로 전달하는 과정)에서의 I/O문제로 블럭킹 시간을 줄일 수 있어서 쓰레드가 많이 필요하지 않게 되는 구조이다. 물론 다중 쓰레드기반에서 전체 쓰레드에 영향을 주지 않고 개별 쓰레드단에서 리스크를 만들게 하는 리스크 해지 기능도 된다.
그리고 event_mpm, Nginx의 설정방법에 대한 정보는 다양한 스트레스 테스트를 통해서 정리해 둘 필요가 있다. 참고로 여기 있는 설정들은 보편적인 부분이어서 각 사이트에 맞는 커스터마이징은 필수라는 것을 잊지 마시길...

1. Apache
Apache는 2.4.4, apr-1.4.6, apr-util-1.5.2, 컴파일은 atomic API: --enable-nonportable-atomics=yes 추가해 줌.
EnableMMAP off
EnableSendfile on
Timeout 10
KeepAlive Off
MaxKeepAliveRequests 100
KeepAliveTimeout 2
UseCanonicalName Off
ServerTokens Prod
ServerSignature Off

<IfModule mpm_event_module>
    ServerLimit            32
    MaxRequestWorkers      8192
    ThreadLimit            256
    StartServers           2048
    MinSpareThreads        2048
    MaxSpareThreads        2048
    ThreadsPerChild        256
    MaxConnectionsPerChild 0
</IfModule>

2. Nginx
Nginx는 싱글 쓰레드방식으로 Master/Worker구조로 되어 있다. Master는 Workder의 모니터, 시그널 핸들링, Worker에 노티 등을 해서 종료, 재설정(Reconfig), 업데이트(Master Upgrade) 등을 진행하고 Worker는 클라이언트의 요청을 처리하고, Master로부터 커맨드를 처리한다.
설정 정보는 아래와 같다.
worker_processes  2;
worker_rlimit_nofile 20000;

error_log /logs/nginx/error.log;
pid /etc/nginx/nginx.pid;

events {
    worker_connections  8192;
    multi_accept on;
    accept_mutex_delay  100ms;
    use epoll;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile on;
    tcp_nopush on;

    keepalive_timeout  5;
    keepalive_requests 100000;
    reset_timedout_connection on;
    client_body_timeout 15;
    client_header_timeout 15;
    send_timeout 2;

    tcp_nodelay on;
    server_tokens off;
    server_name_in_redirect off;

    gzip  on;
    gzip_min_length 10240;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css text/xml text/javascript 
     application/x-javascript application/xml;
    gzip_disable "MSIE [1-6]\.";
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   /www;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

성능 테스트 결과

1, 테스트 정보
메모리 4G, CPU는 Intel(R) Core(TM)2 Quad CPU Q8400 @ 2.66GHz
테스트 도구는 ab로 진행했으며 테스트 페이지 사이즈는 50K. 테스트 스크립트는 아래에 기술해 둔다.
./abtest.sh http://192.168.2.28:8080/index.html 500 10000 500

abtest.sh의 테스트 스크립트는 아래와 같다.
#!/bin/sh

if [ $# -lt 4 ]; then
  echo "abtest.sh <url> <start> <max> <inc>"
  echo ""
  exit 1
fi

url=$1
start=$2
max=$3
inc=$4

num=$start

while true
do
  /home/k2/server/httpd-2.4.4/bin/ab -n 100000 -c $num $url 2>/dev/null > $$

  tps=`cat $$ | grep Requests\ per\ second: | awk '{print $4;exit;}'`
  echo "$num $tps"
  num=`expr $num + $inc`
  if [ $num -gt $max ];then
    exit;
  fi
  sleep 10
done
2. 테스트 결과
위의 설정 정보는 성능 테스트를 여러 번 한 가운데 최적의 성능을 보여주는 것을 기술한 것이다. 그 기준은 동시 가입자가 늘어도 지속적인 성능을 유지하는 것을 목표로 삼았다. 위 최적의 설정 정보로 각 성능을 테스트한 결과는 아래 차트이다.

g

요약해 보자면 동일 기준으로 정적인 페이지 테스트에서 아직은 Nginx의 성능이 많이 앞선다. 나름 Apache의 성능 저하 원인으로는 아마도 strace를 살펴본 결과 futex에서의 waiting이 자주 발생하는 것으로 보아서 아직 성숙단계가 아닌 것처럼 보인다. 그래서 Nginx만큼 성능이 못나온 것으로 보인다.
> strace -fFp 8433
[pid  8625] futex(0x1831d5c, FUTEX_WAIT_PRIVATE, 1756, NULL 
[pid  8624] futex(0x1831d5c, FUTEX_WAIT_PRIVATE, 1756, NULL 
[pid  8623] futex(0x1831d5c, FUTEX_WAIT_PRIVATE, 1756, NULL 
[pid  8622] futex(0x1831d5c, FUTEX_WAIT_PRIVATE, 1756, NULL 

하지만, 용도에 맞추다보니 굳이 Apache를 사용하기를 고집한다면 prefork나 worker보다는 event 방식도 사용해 볼 가치가 있다. ^^

튜닝 포인트들

1. 커널 튜닝
*. /etc/security/limits.conf
* soft nproc 999999
* hard nproc 999999
* soft nofile 999999
* hard nofile 999999

*. /etc/sysctl.conf
fs.file-max = 999999
net.ipv4.tcp_fin_timeout = 5
net.ipv4.tcp_keepalive_time = 10
net.ipv4.tcp_tw_recycle = 1
# increase system IP port limits to allow for more connections
net.ipv4.ip_local_port_range = 1024 65535

# increase TCP buffer sizes
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_mem = 786432 1048576 26777216

# number of packets to keep in backlog before the kernel starts dropping them 
net.ipv4.tcp_max_syn_backlog = 3240000

# increase socket listen backlog
net.core.somaxconn = 3240000
net.ipv4.tcp_max_tw_buckets = 360000
net.core.netdev_max_backlog = 2500
vm.min_free_kbytes = 65536
vm.swappiness = 0
net.core.somaxconn = 65535

2. Apache 에서 StartServers (Min|Max) SpareServers, MaxClients 같게 해 봤다.
트래픽이 많은 곳에서 참고할만한 것 같다. 아래는 Apache의 운영시의 라이프사이클을 설정 정보와 함께 이해하기 쉽도록 매핑해 봤다.


StartServers (Min| Max) SpareServers, MaxClients가 같은 값의 경우 프로세스 수가 고정되므로, MinSpareServers을 위해서만 필요 이상으로 fork할 것도 없고, MaxSpareServers에 의해 남은 프로세스를 KILL 할 필요도 없다. 특히 EC2(Xen)와 같은 클라우드에서 서버를 운영한다면 fork비용이 바싸서 성능 저하요인을 줄일 수 있을거같다.
그리고 CPU는 사용하지 않지만, IDLE 프로세스가 많아지면 메모리가 증가할 것이라고 생각할 수 있지만, CoW(Copy On Write)가 있기 때문에 메모리가 많이 소요되는 건 아니다.

*. Copy On Write 개념
Linux는 fork로 자식 프로세스를 생성한 경우, 부모의 가상 메모리 공간의 내용을 자식에 복사해야 한다. 그러나 제대로 한다고 전체 공간을 복사하는 것은 fork의 비용이 높아지고, 자식이 부모와 같은 프로세스로 실행이 계속되면 내용이 중복된 페이지가 많아져 효율이 좋지 않아진다.
그래서 Linux의 가상 메모리는 메모리 공간 전체를 복사하는 것이 아니라, 처음에는 부모와 자식으로 메모리 공간을 공유하고 있고 쓰기가 일어나는 시점에 쓰기가 일어난 페이지만 새로운 페이지에 복사해서 개별적으로 가져가는 구조로 이 문제를 해결한다. 이것이 Copy-On-Write(CoW)라는 전략이다.

*. 메모리 공유 확인
> cat /proc/16015/smaps | head
00400000-004b2000 r-xp 00000000 08:02 65434  /bin/bash
Size:               712 kB
Rss:                372 kB
Shared_Clean:       372 kB
Shared_Dirty:         0 kB
Private_Clean:        0 kB
Private_Dirty:        0 kB
Swap:                 0 kB
Pss:                186 kB
006b2000-006bc000 rw-p 000b2000 08:02 65434   /bin/bash

*. CoW 공유하는 공간 Shared_Dirty
공유되지 않은 개인 데이터는 Private_Dirty

3. 그 외 설정
- Apache의 경우 MaxClients = ServerLimit(프로세스 수) × ThreadsPerChild. 위 설정의 경우 : 8192 = 32 × 256.

- Nginx 같은 경우 위의 설정 정보를 참고 한다. 간단히 원리를 말하자면 worker_processes는 2 × number of cpus, worker_connections은 가능한 부하테스트 해서 임계치 지정, worker_rlimit_nofile 파일핸들 제약없도록 넉넉히, multi_accept on, accept_mutex_delay 100ms, keepalive_timeout 조정으로 대부분 정리된다.

추가적으로 더 옵션들을 가지고 서비스 특성에 맞체 조정이 필요하지만 여기서는 생략함.
Tags : ,

크리에이터가 되기 위한 레시피

- 아이디어는 무의식과 의식의 경계에서 올라오는 것. 자기만의 시간을 가지고 그 시간에 이것 저것 해(만들고, 메모하고 등)보라. 그것이 잉여력으로 돌아온다.

- 연상을 해보자.
     . 언뜻과 관련이 없을 것 같은, 다른 분야에서의 질문, 문제, 아이디어를 연관/연상시키는 것은 혁신 DNA의 중심이다.

- 질문 안에 솔루션이 있다. 계속 물음을 가지고 현실과의 차이에서 오는 자신의 잘못된 지식을 부정하고 개선하는 노력을 해보자. 질문을 정리하면서 새로운 아이디어가 생길 수 있다.

- 다른 사람, 현상 등의 관찰을 통해 나중의 삶에 대한 부가가치를 발견하는 것이다.
    . 게임의 아이디어를 얻으려거든 어린 아이들의 행태를 지켜보는 것처럼.

- 시행착오를 하더라도 계속 시도해서 더 나은/작은 실패를 지속적으로 해보자.
    . 윈스턴 처칠은 열정을 잃지 않고 다른 실패를 거듭하는 것이 능력이라고 말했다.

- 인연의 기회를 살려보자.
     . Facebook 등의 관계에서 오는 사람들을 만나서 새로운 아이디어를 얻을 수 있을지도 모르겠다. 롱테일의 사람들에게서 다른 냄새를 맡을 수 있다.

- 인위적으로 다른 생각을 해보자.
     . 기존의 가설을 넘어설 수 있는 좋은 방법이 아닐까? "Think different", "Act different"란 구호가 있지 않은가?
Tags : ,

Freemium 전략에 대한 고민

이 포스트는 "When Freemium Fails" 월스트리트 저널의 내용을 읽으면서 아무 생각없이 Freemium 전략을 추구하기보다는 조금 더 생각의 깊이를 가지기 위해 정리해 봅니다.

최근 들어 새로운 비즈니스 영역에 고객을 유입하기 위해서 무료로 서비스와 제품을 제공해서 성공한 기업들(Dropbox와 LinkedIn , Skype 등)이 나타나 그 전철을 밟는 업체가 많다.

이런 Freemium 전략은 긴 시간동안 수익없이 비즈니스를 유지해야 하고 또 성공이 어려울 경우가 훨씬 더 많다. 여전히 몇가지 이유에서 Freemium 전략은 높은 운용 비용과 많은 무료 사용자들을 떠안게 되어 경영 입장에서 비용 함정으로 인식되고 있다.

Harvard Business School의 Vineet Kumar 교수의 말을 빌리자면.
스타트업들은 Freemium 모델에 이끌리는 이유는 사용자들이 현혹될 정도로 단순하고 쉬운 전략이기 때문일 것이다. 무료 서비스에 매료될때까지 사용자들을 유인하고 이후 초과하는 부분을 유효화한다.
문제는 유료 부분과 무료 부분의 경계가 명확하지 않고, 무료 부분의 많은 기능을 제공해 유료 이용자의 이점이 없어져 버린다는 것이다. 무료와 유료의 경계를 명확히 하고 유료이후의 비즈니스에 대한 심도있는 고민이 필요하고 그것을 명확히 하고 난 다음 비즈니스 런칭을 해야겠다.

Freemium 접근은 수백만의 사용자에 도달하지 못하는 비즈니스는 이득이 되지 못한다. 일반적으로 1%, 2% 사용자만이 유료 제품으로 업그레이드를 할 것이라고 Techstarsdml CEO David Cohen이 말한다. Techstars에 참여하는 연간 약 50개의 기업 중 1/4이 Freemium 전략을 사용하고 있다라고 그는 덧붙였다.

이 전략의 특징은 제품의 적용 범위가 한정적인 경우 효율적인 비즈니스 영역이 될 수 없는 상황이 종종 발생하게 된다. 왜냐하면 이미 무료로 제공하고 있는 것을 보고 비교해 유료 사용자는 더 나은, 다른 버전을 요구하기 때문이다. 또, 대기업을 위해 제품이나 서비스를 제공하는 기업도 좋아 보이진 않는다. 일반적인 엔터프라이즈 클라이언트들은 이미 제품이나 서비스를 구매할 수 있는 충분한 예산을 갖고 있기 때문에 무료 제품에 끌리지는 않는다.

그러면 살아남을 Freemium 전략 시나리오는...
  1. 무료 사용자의 지원범위를 유료 사용자의 혜택을 박탈하지 않는 범위내에서 설정한다. free-to-paid 전환율을 5%이내가 되게 한다.
  2. 유료 사용자 유입에만 집중할 것이 아니라, 유료, 무료 사용자 동시에 프로모션을 제공해야 한다.
  3. 무료 사용자들의 친구들에게 자사의 제품과 서비스를 유도하게 한 사용자들은 인센티브를 제공한다.
  4. 유료/무료의 차별화를 명확히 해 유료 서비스의 가치를 명확하게 전달한다.
  5. 무료에서 유료로 자연스럽게 넘어가도록 경로 설계를 잘한다. 예를 들면, 클라우드 스토리지에 무료 공간이 부족해지면 자연 유료 공간을 사게하는 옵션과 같은 것들.
그리고 개인적으로 제품(서비스) 라이프 사이클이 짧은 경우는 Freemium 모델은 필요악일지도 모르겠다.
예를 들어, 소셜 게임은 게임 라이프 사이클이 짧기(1-2개월) 때문에, 우선 출시 후 인기를 끌면 유료화에 들어간다는 생각은 접어야 할 듯 하다. 이미 유료화 시기가 되면 고객은 실증을 느끼고 떠날테니깐....
그래서 로그를 통해 Activity 분석으로 거의 실시간으로 유저의 행동을 파악해, 서비스 런칭과 함께 유료화 마케팅을 준비해야할 듯.