System Compleat.

'YZCerberos'에 해당되는 글 231건

  1. 휴식
  2. 시스템 관리자의 실패, 그리고 서비스.
  3. NginX on Ubuntu-9.0.4-server
  4. Sunfreeware, NexentaOS
  5. Nonpaged Pool

휴식

Stories
( 정윤진, bluebird_dba@naver.com )


사용자 삽입 이미지

Bass Fishing





짙은 피로는
숨구멍이 입 위에 있는지 귀 옆에 있는지
월요일인지 금요일인지

수십년간 학습의 감각을 잊게 할 만큼
강하게 다가와

그 속에 맞이 하는 환희란 고작
높은 하늘 아래 베란다에서의
니코틴 강한 빨간 네모갑 속 담배 한 개피.

폐부를 찢어내는 고통의 쾌락이겠지만

울적한 답답함의 격벽 만큼이나
먹먹해 지는 숨통만이

콧구멍의 존재를 되새겨 준다.

어제보다 텁텁한 오늘의 삶이
내일보다 행복한 모레를 맞이하게 할까 하는
고민인지 화두인지 모를 애매함이 깊이를 더해
멍때림으로 비추어지고

분명 어제보다 더해진 오늘의 잔고 숫자 만큼이나
단축된 수명.

이 짙은 피로에게
구명 조끼라도 입혀 주고 싶다.

이제 그만
밝고 기쁨에 가득한 세상으로 떠올라
깊고, 맑은 큰 숨 들이키라고.


Who got the Excavator




( 정윤진, bluebird_dba@naver.com )

시스템 관리자의 실패, 그리고 서비스.

Techs
( 정윤진, bluebird_dba@naver.com )


웹 서비스를 하는 많은 시스템에서, 사업의 성공과 함께 고객이 증가함에 따라 발생하는 많은 문제들이 있다.  보다 많은 고객에게 무정지 서비스를 하기위한 각 서비스 구성 요소의 이중화 부터, 서버의 추가에 따른 네트워크 장치의 추가, 대역폭의 확장 등 비용 들어가는 요소가 한두가지가 아니게 된다.

물론 이런 비용의 문제가 있다면 자연히 저렴하고 성능좋은 오픈소스 솔루션으로 눈을 돌리게 마련인데, 이 오픈소스 솔루션이라는게 그 좋은 성능만큼 손도 많이가고, 기본적으로 설치되는 패키지 들이 감당 해 낼 수 없는 어떤 한계 상황에 이르게 되면 소소한 튜닝 하나에 서비스의 명암이 엇갈리기도 한다.

여기 블로그에 내가 직접 설치해 보고, 또  그 성능을 온몸으로 확인했던 여러가지 툴 및 어플리케이션들이 '당연하게'  '잘' 동작 한다는 믿음에는 변함이 없지만, 이들과 맞물리는 요소에 따라 실패하게 될 수도 있다는 사실을 최근 뼈저리게 깨닫게 되었다.

사용자 삽입 이미지

BOTTLENECK a image from finsolinc.com





문제의 발단은 고객 서비스 규모의 증가에 따라 상거래 사이트의 특징상 수많은 이미지를 서비스하게 되는데, 이 감당하기 힘든 이미지의 규모 때문에 nginx 를 사용한 이미지 분리를 시도 하였는데, 결과는 참패였다.  참패의 원인은 몇가지가 있는데, 그중에서도 가장 주요한 부분이 바로 아파치의 mod_expire 였다.

HTTP 의 헤더를 조작하는 것이 많은 비용이 들어가는 일이라는 것은 평소에도 잘 알고있었지만, 이 헤더의 조작이 NFS 의 getattr() 호출의 빈번함과 함께 아파치의 Sending Reply 를 지연시켜 결국 사용 가능한 모든 소켓을 불태워 버림에 따라 nginx 는 nginx 대로, 아파치는 아파치 대로 부하상황에 사이트가 정상동작 하지 않게 되어버렸다.  스레드 기반에서의 ( mpm이 워커였다. 물론 prefork 도 동일한 설정에 상황은 마찬가지. ) locking 및 pending 의 무서움을 절실히 깨달았달까.

결국 문제는 찾아 내게 되었지만, 그 주범이 mod_expire 라는 사실에 허무하기 그지 없다. 고객의 사용 패턴에 따라 mod_expire 는 득이 될 수도, 실이 될 수도 있다.


아무리 간단한 서비스 구성에도 많은 요소들이 존재한다.  부하가 없을때에는 당연히 동작해 주는 그것들.  하지만 극한 상황이 되면 아주 작은 파라메터 하나, config 하나, sql 문장 하나가 서버를 멈추게 하고, DB를 멈추게 하는 무서운 적이 될 수 있음을 항상 기억해야 한다.

구성에 관한한 어지간해서는 실패한 경험이 별로 없는데, 이번건은 나에게 매우 큰 정신적 충격이었고,  역시 항상 장애에 대해 트레이닝 하지 않으면 당황하게 되는걸 보니 아직 많이 부족하다 싶다.  그렇게 당연한 인과 관계를 찾아내지 못했던게 참 ... 씁쓸하다고만 하기에는 부족한.


결국, 아파치의 체중조절에 들어갔다.  꼭 필요한 모듈만 올려서 경량화, ServerLimit 조절 같은 기본 구성부터  이미지 서버의 이벤트 폴링,  aio 및 sendfile 의 적용 등.

이제, 쓴맛을 볼만큼 봤으니 단맛을 찾아 내야 겠다.
2만 세션을 커버했다면, 이제 빡시게 준비해서 5만 세션 이상은 버티게 해야지.

대역폭을 병목구간으로 만들어 버리는, 그런 구조를 향하여.



( 정윤진,  bluebird_dba@naver.com )

P.S.

1.
nfs 의 마운트 옵션은 기억해 둘 만 하다.  getattr 비율이 40 또는 60% 이상이라면 서버의 로컬 캐시 타임을 늘리는 방법을 강구해 보도록 하자.

nfsstat -c
nfsstat -m


2.
apache2 구동중인 시스템에서 비교적 성능이 출중한 서버인경우에 위와 같은 상황에서
iowait 나 vmstat 에서 특이할 만한 값은 떨어지지 않는다.
server-status 를 적극 사용 하도록 하고, 리눅스라면 ps -eo wchan 을 참고 하도록 하자.

3.
nginx 는 꼬진 서버가 아니다.
다만 nginx 를 꼭 써야한다면, 기존의 웹서버 설정을 매우 디테일하게 살펴야 할 것이다.

NginX on Ubuntu-9.0.4-server

Techs
( 정윤진, bluebird_dba@naver.com )


오늘은, nginx 의 우분투 설치에 대해 한번 전체 과정을 쭈욱 적어 보려 한다.
우분투에서의 설치 과정은 대체로 다음과 같다.

1. OS 설치.
2. 필요 package 설치
3. nginx source download
4. Additional Module download
5. configure / make / make install
6. Setup
7. Run!!

물론,  2 ~ 5번을 건너 뛰고  apt-get install nginx 해도 된다.  ㅋ
어쨌든 우분투 인스톨이 끝나로 root 계정 세팅을 완료 하였다면 필요한 패키지 인스톨을 시작한다.

Package Install

apt-get update
apt-get dist-upgrade
apt-get install build-essential libpthread-stubs0 libpthread-stubs0-dev libgd2-xpm libgd2-xpm-dev libgeoip-dev libgeoip1 sysvinit openssl libssl-dev libpcre3-dev  libgcrypt11-dev


nginx download

NginX 는, 아직 메이저 버전 넘버가 1 이 채 못되었다.  그렇다고 unstable 한 것은 아니지만, 다음의 버전 넘버링을 참고 하도록 한다.

0.6  -> Legacy 버전  ( 통상 apt-get 으로 install 되는 버전. 3rd party 모듈이 잘 설치되며, 안정적으로 동작한다 )

0.7  -> Stable 버전.

0.8  -> Develop 버전  ( 3rd party 모듈은 포기하는게 좋다.  다만, 기존 3rd party 로 제공되던 모듈이 nginx 에 포함되어  --with 옵션으로 설치 되는 모듈이 많아졌다. )

wget http://sysoev.ru/nginx/nginx-0.6.38.tar.gz
바빠서 그런건지, sysoev.ru 사이트가 종종 먹통일 때가 있다.

google 에서 해당 버전의 파일명을 검색하면 서비스 하는 사이트가 많으니 신뢰할 만한 페이지에서 받아서 사용하도록 한다.

openssl 소스 다운로드
nginx 의 compile 시에 openssl 의 소스코드를 요구한다.

wget http://www.openssl.org/source/openssl-0.9.8k.tar.gz
사이즈에 비해 제법 느리니 커피한잔 마셔 준다. ㅋ



additional module download

http://wiki.nginx.org 의 Module 페이지에 가면 기본적으로 nginx 에서 제공하는 모듈 이외에 3rd party 모듈들의 링크를 제공한다.  필요한게 있다면 추가 하도록 한다.

GeoIP Extension
wget http://wiki.nginx.org/images/9/99/Nginx-geoip-0.1.tar.gz

NCache
wget http://ncache.googlecode.com/files/ncache-2.3_release.tar.gz

다른건 잘 안되서 추적하기도 귀찮고 해서 올리지 않았다.
통상 Upload Module 도 많이 사용 하는듯.

다운로드 받은 모듈은 configure 시에 옵션으로 써 주기 편한 디렉토리에 압축을 풀어 놓도록 한다.  난  $SRCDIR/nginx-0.6.38/modules  에 압축을 풀었다.


Configure && make && make install

일반적인 xNix 어플리케이션의 compile 과 비슷하다.

./configure --add-module=./modules/ncache-2.3 --add-module=./modules/nginx-geoip-0.1/  --with-google_perftools_module --with-poll_module --with-http_ssl_module  --with-http_realip_module  --with-http_gzip_static_module  --with-http_stub_status_module --prefix=/opt/nginx --with-openssl=/usr/src/binaries/openssl-0.9.8k

더 필요한게 있다면 붙여도 된다.

위의 apt-get install 만으로는 빠져있는 것들이 있을 것이다.  configure 과정에서 뭔가 누락된게 있다고 징징대면  apt-cache search 다음에 apt-get 으로 인스톨 해 주면 된다.

configure 가 끝나면 make , make install

configure 는 이상없이 끝났는데,  make 과정에서 error 를 토해내면서 중지하면,  error 부분을 조치해 주고 다시 make 를 시도한다.  통상 openssl 소스를 추가적으로 --with 옵션에 넣어준 경우,  make clean 시에 rm -f 로 디렉토리를 지우려는 멍청한 짓을 가끔 해서 make 파일을 수정하는 세련된 짓은 하지 않고, 그냥 rm -fR ../openssl-0.9.8k 해서 지웠다.
당연히, 지운다음에 다시 압축을 풀어줘야지.


nginx.conf &&  RUN!!!!

 정상적으로 설치가 완료 되었다면,  --prefix 로 지정한 디렉토리에 nginx 가 이쁘게 컴파일되어 설치된 모습을 볼 수 있다.  실행 바이너리는 ./sbin 에 , conf 는 ./conf 디렉토리 안에 있다.

nginx.conf 에서는, 다음의 몇가지가 기본적인 설정이다.  뭐 wiki 참조하시면 엄청 잘 나와있으므로, 모자란 부분은 거기서 추가 하시도록 한다.

몇몇 주요한 conf 는,

worker_process
sendfile

upstream  httpservice {
    ip_hash;
    server x.x.x.x:80;
}

location / {
      set $memcached_key $uri;
      memcached_pass     x.x.x.x:11211;
      ....
      ..
      Default nginx.conf 참조
}

rewrite 및 기타 virtual host 설정등도 함께 제공하므로, wiki.nginx.org 에서 참조 하도록 한다.

nginx 를 구동하기 위해서는, 적절한 계정이 있어야 한다.
groupadd -g 81 apache
useradd -g 81 apache

난 apache 로 돌렸다.  ( 사실 이건 예전에 AJ 가 쓰던거지만. )


어쨌든, 다 설정 되었으면 구동한다.

./sbin/nginx  ( & 안해도 된다  알아서 한다 )

지정한 process 만큼 떠 있는 모습이 확인 가능하다.



음.. 뭐 이런 매뉴얼 스러운 글은 원래 잘 쓰지 않는 편이지만,  나도 돌머리라 자주 잃어버려서 정리 겸 해서 쓴다.  뭐 사실 잃어버려도 다시 삽질 하면 되지만, 점점 삽질 하는 시간이 웬지 아까워 진다고 할까나...


그냥 wiki.nginx.org 를 번역하는게 나을지도..  그러고 보니 한글 페이지를 봤던것 같은 기억도;;;  varnish 가 더 희소성이 높으려나.. ㅋㅋㅋ


( 정윤진, bluebird_dba@naver.com )



Sunfreeware, NexentaOS

Techs
( 정윤진, bluebird_dba@naver.com )

친구네 시스템이 SunOS 5.9 로 되어있어서 간혹 장애가 나면 지원겸 해서 보아주는 경우가 있는데, 아무리 솔라리스라고 해도 리눅스의 유용한 툴들이 가끔 그리워 지게 마련이다.
더군다나 솔라리스에 오픈 소스의 솔루션을 설치할라 치면, automake 나 gcc 같은 툴들이 몸서리 쳐지게 필요해 지는데, 이때 유용한 것이 제목과 같은 Sunfreeware 다.

sunfreeware 에는 리눅스 세상에서 유용했던 또는 필수적인 여러가지 오픈소스들을 지원하는데, 다운로드 및 설치가 간단해서 많은 이들이 사용하고 있는것으로 안다.

가장 대표적인 예가 아파치, php 와 같은 범 unix 솔루션들을 그냥 바이너리/패키지 형태로 받아 쓰기에는 문제가 있는 경우가 많아서, 해당 시스템에서 직접 컴파일 해서 사용하거나 또는 일반 리눅스 머신에서 크로스 컴파일하여 타겟 시스템에 올리거나, 어쨌든 컴파일 해서 각종 튜닝을 시도해야 하는 것이 맞기 때문에 sunfreeware 에서 제공하는 여러 패키지를 반드시 설치해야 한다.


패키지를 구하는 방법은 간단해서, sunfreeware.com 에 접근하여 원하는 패키지를 다운로드 받으면 된다.

ftp ftp.sunfreeware.com 에 anonymous 로 접근
pub/freeware
원하는 패키지 다운로드!

압축 대강 해제해 주고
pkg-add -d [$PKGFILE]

좌르륵 설치 된다.


이와 같은 상용유닉스에서는 일반 리눅스에서는 별로 신경쓰지 않았던 여러 어플리케이션 별 튜닝 차이점에 대해 잘 살펴 보아야 한다.
잘 알려진 apache2.x 버전의 솔라리스 구동에는 많은 옵션들이 있으며, 이 솔라리스라 하더라도 SPARC 인지 아니면 다른 프로세서인지에 따라 시스템적 튜닝 요소들이 존재한다.

말이 좋아 튜닝이지, 사용자가 많아지는 환경이 되면 스왑을 잔뜩 잡수셔서 뻗거나, pthread 관련 문제로 인해 아파치가 다이 하시는등 그거 꽤 번잡스럽지만 신경써 주지 않으면 서비스 자체가 불가능 한 경우도 많으니 이기종 플랫폼에서 유의하는 것은 뭐 당연하달까.

자세한 정보는 여기서.
http://www.sunfreeware.com/


한가지 더,  세상이 좋아져서 opensolaris.org 라는게 생겼다.
opensolaris 자체를 사용해 보는 것도 좋지만, NexentaOS 라는거를 시스템 하면 꼭 한번쯤은 써보는게 좋지 않나 하는 생각이다.

왜?

이 NexentaOS 는 솔라리스 커널 기반에 Debian ( 또는 Ubuntu ) 식의 APT 를 사용한 패키지 관리 툴이 포함된 멋진놈이라는 거다.
리눅스 진영에서 솔라리스에 항상 군침 흘리는것이 바로 이  ZFS 인데, 세상에 현존하는 파일시스템 가운데 군계일학 같은 이놈을 우분투와 같이 아트한 패키징 시스템과 함께 리눅스처럼 편하게 사용 할 수 있다는것은 축복인거다.  게다가 지원하는 패키지도 13000개 이상이라는 홈페이지의 소개만큼이나 여러 툴을 쉽게 사용할 수 있다.

뭐, sunfreeware 만 쓰기엔 좀 거시기 해서 NexentaOS 도 곁다리로 소개하긴 하지만,
적어도 뭔가 공유 스토리지가 필요한 시스템 군을 구성하는데 있어서 성능적 측면에서는
이 NexentaOS 를 백단의 NFS 메인으로 두고 프론트 군 구성에 적절한 웹서버들을 포진하는 것은 대단히 매력적인 방법이 아닌가 싶다.


오늘은 원래 nginx.conf 에 대해서 대강 설명을 해볼까 했는데, 피곤하기도 하고 해서 그건 다음번 포스팅에 하기로 하고,  Nexenta에 대해서도 시간을 내어 한번 퍼포먼스 테스트를 해 봤으면 좋겠다. 


nexentaos 는 다음의 링크들에서 구하실 수 있겠다.

http://www.nexenta.org/os
http://www.opensolaris.org/os/downloads/


( 정윤진, bluebird_dba@naver.com )

Nonpaged Pool

Techs
( 정윤진, bluebird_dba@naver.com )

---------
시작하기 전에, 본 내용은 2010/03/18일에 포스팅한 내용을 보는것이 Nonpaged 및 Paged Pool 영역에 대한 추적에 용이함을 미리 말씀 드린다.

해당 내용은 여기 를 참조 하시면 되며, 아래의 내용은 경험담 정도로 보아주시면 좋겠다.
---------


일전에 윈도우 서버에서 nonpaged pool 영역에 문제가 생기면서 추적을 하다 하다가 포기한 적이 있다.  그 당시의 장애는 프로그램의 코드 문제로 나중에 밝혀 졌지만  이러한 유형의 장애 추적이 윈도우에서는 매우 어렵다 라고 느꼈던 개인적으로는 큰 사건중의 하나였다.

나의 경우에는 장애 상황에 장애 해결을 위한 실마리를 찾지 못하면 빠르게 원복하는게 항상 답이라고 생각한다.  이 원복의 의미에는, 최근에 변경한 ( 업데이트한 ) 서비스의 구성요소 일 수도 있고 일부 정말 모르겠는 경우 메모리의 문제가 발생하면 재부팅을 하거나 하는 것.

다만, 장애 상황에서 단 하나의 연관 가능성 있는 실마리라도 발견하면 추적하게 되는데, 적당한 시간만 있다면 이러한 잠깐의 추적이 완전한 문제 해결로의 지름길이 되곤한다.
따라서 장애 발생 시간에 ( 서비스에 문제가 되고 있는 시간에 ) 빨리 원복을 할지 이 장애의 원인을 추적할 지는 숱한 번민의 대상이 되고,  당황하거나 이런 부분을 조금이라도 소흘히 하게 되면 서비스 재개는 늦어지고, 장애 원인은 찾지 못해 매번 동일한 장애를 맞이하게 되는 슬픈 현실에 빠지게 될 수도 있다.

서론이 길었지만,  뭐 어쨌든 이번 이야기는 IIS를 동작시키는 윈도우 서버에서의 Non paged pool 의 부족  상황에 대해 어떠한 드라이버가 문제가 되는지를 추적하는 방법에 대해서다. 


윈도우 2003에서는 ( 다른 버전의 윈도 서버에서도 비슷한 방법을 제공하리라 생각한다 ) Windows Support Tools 에서  poolmon.exe 라는 툴을 제공한다.
일단 이 툴을 시스템에 미리 설치 해 두고, 정상 동작 상황에서도 한번 쯤 사용법을 익히는 것도 좋은 공부가 될 것으로 생각한다. ( 윈도 커널에 대한 )
조금 더 개발쪽으로 치우친 시스템 엔지니어라면, windbg.exe 같은 툴을 병행해서 사용하면 더 좋을 듯 싶다.


일단, IIS 구동중인 서버에서 Non-paged pool 영역의 메모리 부족사태가 발생하면 다음과 같은 IIS Error 로그가 발생하게 된다.

2009-xx-xx 02:06:22 - - - - - - - - - 1_Connections_Refused -
2009-xx-xx 02:06:32 - - - - - - - - - 1_Connections_Refused -
2009-xx-xx 02:07:37 - - - - - - - - - 1_Connections_Refused -
2009-xx-xx 02:11:02 - - - - - - - - - 2_Connections_Refused -

당연히 정상적인 서비스가 되고 있지 않은 상황이다.

윈도우 서버의 non-paged pool 은 다들 잘 아시다 시피 커널의 메모리 영역이며, 통상 윈도우에서는 최대 256M 의 메모리를 이 영역에 할당한다.  문제는, IIS 의 http.sys 가 이 영역에서 동작하기 때문에 시스템의 다른 드라이버 또는 커널 메모리 영역에서 동작하는 '그 무언가'가 메모리를 많이 잡수시면 정상적인 IIS 의 동작을 방해한다는데 있다.

유닉스 시스템을 기반으로 유추해 보건데, 이는 IIS 에서 응답 처리를 하기 위해 새로운 thread 의 할당 및 클라이언트 응답에 대한 정상적인 프로세스를 진행하는데 있어 할당 되어야할  커널 메모리 영역이 부족하기 때문에 '난 지금 처리 불가' 라는 메세지를 토해 내는 것 쯤으로 이해한다.

문제는, '그래서 어떤 드라이버인데?'  를 알아야 이 문제가 풀릴 테지만, 이게 쉽지 않다.

poolmon.exe 를 사용하면,  paged pool 과 non-paged pool 에 대한 정보를 알 수 있다.
이 정보에 나타나는 드라이버의 이름은 아래의 스크린샷에서 처럼 당최 뭔 드라이버인지 그 이름을 유추해 내기 힘든 ( 또는 명명규칙을 내가 모르니까 ) 구조로 되어있어, poolmon 자체에서 일종의 translate 를 제공하기도 한다.  ( poolmon.exe -C 하면 .txt 를 뱉어낸다.  )

사용자 삽입 이미지

poolmon.exe



그런데, 이 정보에도 나타나지 않거나 또는 이 정보로도 어떤 드라이버인지 알아낼 수 있는 여지가 많지 않다는게 참 큰일이다.  분명히 시스템에서는 이러한 이름으로 할당된 정보가 어디엔가에서는 참조되고 있을터인데, 각 영역의 Addressing 번지 수 라도 알면 어떻게 좀 해보겠는데  이 non-paged pool table(?) 비슷한 정보를 찾아 내는데 나는 결국 실패했다.

IIS 에서 구동하는 프로세스 자체가 문제인가? 라는 증거만 나와도 그 다음은 참 쉬웠을 텐데.

iisdiag.msi 를 사용하여 IIS 프로세스에 대한 덤프를 떠서 MS 에서 제공하는 Analyze 툴을 써도 신뢰할 만한 정보는 딱 부러지게 나오는게 없었던 기억이다.

결국, 윈도 시스템에 대한 이해 부족이 문제여서 'Windows 커널의 구조와 원리' 에 대한 책을 구입해서 파 보고 있는 중이다.


non-paged pool 영역이 꽉 차면, IIS 재시작은 답이 아니다.  서버 재부팅으로 아예 비워야 한다.  .NET 의 GC 동작도 의심해 보고 perfmon 으로 GC의 Level 별 카운트 증가에 대해 파 보기도 했지만, 결국 원하는 답은 나오지 않아  주기적으로 서버를 재부팅 해야 했던 아픈 기억이 있다.  이런 경우, 커널 덤프를 MS에 보내면 뭔가 답을 알려 주려나?


어쨌든, 좀 지난 일이긴 하지만 이러한 문제는 언제든 재발 될 수 있고, 또 어떤 서비스를 구성하건간에 사전에 신경쓰지는 않아도 발생했을때 한가지 더의 실마리를 알아내기 위해 평소에 이것 저것 많이 봐야 하는 직업임에는 분명한 듯.


결국은 또 신세타령 -ㅁ-;;


( 정윤진, bluebird_dba@naver.com )