60.Unix2008. 12. 15. 10:20
반응형
[출처] http://maso.zdnet.co.kr/maso/2000/10/11/014004,971241222,178.html

Novice] 진정한 엔터프라이즈급 운영체제, 솔라리스 매력탐구

웹 서버를 위한 솔라리스 튜닝

그동안 웹 서버 최적화라고 하면 아파치 설정 파일의 파리미터 값의 최적화나 컴파일
전에 소스의 HARD_SERVER_LIMIT 값을 변경하는 정도 의 애플리케이션 내에서의 작업이
주류를 이뤘다. 하지만 그동안 이런 애플리케이션 튜닝 외에 운영체제(솔라리스)
레벨에서 웹 서버 최적화를 위해 제공할 수 있는 성능 개선책에 대해서는 튜닝법은
고사하고 실제로 운영체제의 어느 부분을 튜닝해야 성능을 개선할 수 있는지에 대한
것조차도 관련 자료를 구하기 힘들었다. 그래서 이번호에서는 그동안 우리가 웹 서버
환경을 설계할 때 오해하기 쉬운 여러 가지 환경적 요소에 대해 하나씩 짚어가면서,
실제 운영 경험을 토대로 웹 환경에서의 솔라리스의 특징과 튜닝법에 대해 소개하고자
한다.

김민형 한국외대 전산소

연재 순서
1회(2000. 09): 솔라리스엔 뭔가 특별한 것이 있다
2회:(2000. 10): 웹 서버를 위한 솔라리스 튜닝
3회: 엔터프라이즈 환경의 오라클을 위한 솔라리스 튜닝

--------------------------------------------------------------------------------

실제 웹 서버 튜닝에 들어가기 전에 반드시 다시 짚고 넘어가야 할 세 가지가 있다.
먼저 네트워크에 대한 실전 감각을 다져야 한다는 것이다. 제아무리 웹 서버가
최적화돼 있다 하더라도 라우터의 라우팅 경로가 잘못돼 있거나, 자기가 속한
네트워크의 특성을 파악하지 못하고 있다면, 심하게 말하면 웹 서버 튜닝은 헛수고가
되고 만다. 필자의 경험에 비춰볼 때 심지어 복수 회선을 쓰고 있음에도 그에 대한
trunking 에러 등으로 한 회선을 아예 쓰지 못하는 사이트도 있었다. 이 사이트
운영자는 서버가 느리기 때문이라고 생각하고 있었다.

그 다음으로 최적화(튜닝)에 대한 우선 순위의 기초를 정리해야 한다. 일반적으로
시스템 튜닝 과정에서 OS 튜닝은 가장 나중에 하는 영역이다. 예를 들어 초기 CERN 웹
서버를 이용하면 OS 파라미터들이 튜닝돼 있다고 해도 최근에 나온 아파치 웹 서버의
1/10에도 미치지 못하는 성능을 낸다. 또한 최근에 나온 웹 엔진들 역시 퍼포먼스를
고려하지 않은 것을 이용하게 되면 마찬가지 결과를 가져온다. 예를 들어 HP-UX에서
OSDK(Oracle Servlet development kit) 웹 엔진을 이용할 때 원하는 퍼포먼스가
나오지 않는다고 제아무리 전문가들을 불러 OS를 최적화한다 해도 앞서 말한 CERN
서버의 경우처럼 성능 개선의 여지는 좁다.

끝으로 OS 튜닝을 하기 전 염두해 둬야 할 것이 있는데, 우리는 지금 솔라리스8을
이용한다는 것이다. 솔라리스8은 이전의 SunOS 4.X나 솔라리스 2.5.1 이전의 버전처럼
이용자가 반드시 튜닝해야 할 파라미터들이 극히 줄었다. 한 마디로 초기 설정이 점차
최적화돼 나오고 있다는 것이다(퍼포먼스 분석가/튜닝 전문가에게는 상당히 아쉬운
일이 아닐 수 없지만). 그와 더불어 하드웨어 드라이버에 있어서도 최신의 드라이버를
사용함으로써 하드웨어적인 성능 개선을 얻을 수 있을 뿐 아니라 솔라리스8에는
SUNWncar, SUNWncarx, SUNWncau라는 Solaris Network and Cache Accelerator가 포함돼
있어 네트워크와 관련해서는 그 이전의 어떤 버전보다 나은 환경을 제공하고 있다.
기존의 솔라리스를 이용하는 환경에서 퍼포먼스를 생각한다면 반드시 최신의 버전을
이용해야 하며, 필자의 주관적인 견해로는 현재 나온 HP-UX, AIX, 디지털
유닉스(OSF1) 등 상용 유닉스 중에서 웹 환경에 있어서는 솔라리스가 그 자체만으로도
가장 나은 성능을 얻을 수 있다고 생각한다.

대역폭과 속도는 정비례하지 않는다

먼저 http 환경은 무엇보다도 네트워크 같은 환경적인 요소에 가장 큰 영향을 받는다.
그러므로 네트워크에 관련해 오해의 소지가 많은 부분에 대해 설명하면서 웹 환경의
특성을 살펴본 후 튜닝법에 들어가기로 하겠다.

먼저 웹 환경의 컨텐츠는 크게 두 가지로 분류할 수 있다. 그 중 하나는 html
파일같은 작은 조각에서부터 100~200KB 단위까지의 웹 링크를 간단히 하기 위한
이미지맵 gif, jpg 파일이 중심이 되는 부류이고, 다른 하나는 요사이 멀티미디어 웹
컨텐츠라고도 불리는 ASF나 리얼 비디오, mpeg, avi 같은 동영상 자료, 리얼 오디오
같은 음악 자료나 200KB∼1MB 미만의 gif, jpeg 파일 같은 대용량 파일이 중심이 되는
부류이다. 이 두 가지 부류는 단순히 파일 크기만 다른 것이 아니라, http 환경에서
서로 다른 특징을 가지고 있다.

먼저 가장 중요한 것은 대부분의 사이트가 해당되는 작은 크기의 파일이 중심이 되는
http 환경에서 브라우징 속도는 기본적으로 네트워크 대역폭과는 ‘별다른’ 관련이
없다는 점이다. 이에 대해 실제로 간단한 실험을 한 번 해보자. 아파치만 기본 설치한
두 서버를 가진 환경에서 한 서버는 10Mbps 스위치에, 다른 하나는 100Mbps 스위치에
연결한 후 두 서버의 아파치 초기 화면을 띄워보자. 물론 한 서버에 접속하고 나서
로컬 캐시를 삭제한 후 다른 서버에 접속해야 한다는 점을 잊지 말자. 이 두 가지
경우에서 브라우징 속도에 차이가 있을까?

결과를 살펴보면 거의 느낄 수 없다. 이렇게 작은 사이즈 파일 위주의 환경에서는
서비스 제공자 입장에서 볼 때 자신의 네트워크의 부하가 적고 이용자의 네트워크가
일정 수준 이상의 대역폭을 확보하고 있다면, 이용자들의 브라우징 속도를 빠르게
해주기 위해서는 엄청난 규모의 확장이 아니고서는 큰 대역폭의 회선을 얻는 것은 별
도움이 되지 않는다.

아직까지 이에 익숙하지 않기 때문에 상당히 생소하게 들릴 수도 있는데 실제 속도를
계산해보면 쉽게 이해가 갈 것이다. 예를 들어, 우리가 관리하는 곳이 어느 증권회사
지사로 이 곳은 내부 전용선(T1)으로 객장 고객에게 본사의 정보를 웹으로 제공한다고
가정하자.

그런데 주가 정보는 돈을 다루면서 리얼타임으로 변하므로 직접 연결로 접속을 하는데
요새 들어 객장 고객들에게 느리다는 불평을 받아 우리는 대책을 강구해야 한다.
그런데 회선 증설을 하기 전에 얼마나 실효가 있는지 수치를 계산해 보면, 일반적으로
html 웹페이지는 대개 평균 5KB 정도의 크기이므로 한 페이지를 보여줄 때 현재는 5KB
/ 1.5Mbps(T1) = 2.5ms 정도의 시간이 걸린다. 이 수치는 라우터마다 다르지만,
라우터를 거칠 때마다 대략 1.5ms 정도의 지연이 발생하므로 6개 정도를 지난다면 총
11.5ms의 지연이 발생한다. 그런데 이를 T3(45Mbps)로 증설하면 0.83ms + 9ms(라우터)
= 9.83ms로 전체 네트워크 지연시간을 줄일 수 있다.

하지만 이 수치는 T1과 비교해서는 대략 20% 정도 밖에 속도 개선을 가져오지 못한다.
필자가 알기로 국내에서 일반적으로 T3 라인의 연이용료는 대형 통신업체는 정가가
1억을 호가하는 것으로 알고 있다(KREN 자료 인용). 게다가 특별한 경우가 아니면
회선 업체에서 T3를 연결해주지도 않지만 말이다.

이 정도로는 아직 감이 안 오는 독자들도 있을텐데 잠시 필자의 경험을 예로 들면,
필자는 얼마 전 친분이 있는 업체의 썬 장비에 KIDC에서 운영하고 있는 DB 서버를
복제하는 일을 하기 위해 인도네시아에 다녀온 적이 있다. 그 곳 역시 이제 막 웹
서비스를 시작하려고 준비하는 회사여서 전용회선 선정을 놓고 고심하고 있었다.
인도네시아의 경우 한국과 비교해 통신 환경, 특히 인터넷 환경이 극도로 열악해
INDOSAT이라는 최대 회선 제공 업체의 128K 라인 운영료가 국내 E1급의 가격과 맞먹을
정도였다. 낮은 회선 속도를 감수할지, 아니면 코로케이션 서비스를 받을 건지
고민하는 상황에서 갑자기 혜성처럼(?) 등장한 PSN이라는 통신업체가 512k를 약간
비싼 가격에 제공한다고 해 한번 테스트하기로 했다. 테스트 결과 512K의 대역폭은
맞았지만, 우리는 그 업체의 상품을 포기하고 INDOSAT의 256K를 이용하기로 했는데,
왜 그랬을까?

PSN의 경우 연결 방식을 마이크로웨이브를 통해 주변 오피스까지 연결한 다음, 몇
군데 마이크로웨이브 릴레이를 거쳐 중앙과 연결한 다음 인공위성을 통해 인터넷을
이용하는 방식이었는데, 문제는 마이크로웨이브 연결 방식의 특성 때문에 엄청난
네트워크 지연 시간을 감수해야 하는데다, 오히려 회선의 대역폭이 커질수록 지연
시간이 길어졌다. 이로 인해 홈페이지 첫 화면 로딩 시간이 128K와 비교해 오히려
길어지는 결과를 가져왔기 때문에 우리는 과감히 포기한 것이다.

그럼 이에 대한 대안은 무엇일까? 고급 라우터와 인텔리전트 스위칭 장비, 그리고
IDC에 서버 입주 등이 바로 그것이다. 중대형 사이트에서 고급 장비를 쓰는 이유는
비단 돈이 많아서가 아니다. 앞서 본대로 라우터를 거칠 때마다 생겨나는 지연 시간을
최소화하기 위함이고, IDC에 장비를 입주시키는 것은 관리의 편리함이나 네트워크
대역폭의 확보뿐만 아니라 서버를 가장 빠르게 접속할 수 있는 통신사업자의 백본에
바로 붙임으로서 라우팅 홉수를 줄이기 위함이기도 하다.

그렇다고 웹 환경에서는 대역폭을 고려하지 않아도 될까? 물론 그것도 아니다. 최근
새롭게 등장한 멀티미디어 컨텐츠를 가진 웹 환경의 경우와 httpop/s이 높은 사이트의
경우엔 사정이 약간 다르다. 멀티미디어 컨텐츠의 경우 요새는 ASF나 리얼
오디오/비디오처럼 조각화(fragmentation)해 연결 기간 동안 적은 패킷량이
오고가도록 하지만 이용자의 수가 어느 정도에 이를 경우, 더 이상 다른 이용자가
접속하지 못할 뿐만 아니라 이더넷의 특성상 대역폭의 한계에 다다르면 느려져 서비스
품질이 극도로 떨어진다. 이 특성은 이런 멀티미디어 컨텐츠 뿐만 아니라 엄청나게
붐비는 사이트의 경우도 마찬가지이므로 최대한의 대역폭을 확보해줘야 서비스 품질을
일정하게 해준다.

솔라리스 네트워크 튜닝

지금까지 환경적 장애 요인에 대해 충분히 설명했으니 이제 본론인 솔라리스 네트워크
튜닝으로 들어가겠다.

물론 웹 서버 튜닝에는 네트워크 튜닝만이 포함되는 것은 아니다. 모든 시스템 튜닝은
CPU, 메모리, I/O(디스크와 네트워크)가 유기적으로 얽혀 있기 때문에 모든 부분에서
골고루 설명해야 하는데, 지면 관계상 주요 부분만 살펴본다.

하지만 달리 생각하면, 요사이 컴퓨팅 환경에서는 네트워크 튜닝시 네트워크 그
자체의 튜닝 부분을 제외하고는 CPU나 디스크 I/O같은 다른 환경적 요소를 덜 받게
됐다는 점도 간과할 수 없다. CPU의 경우, 예전의 SunOS 4.X 대역에서는 TCP/IP
프로토콜 통신도 커다란 CPU - bound 프로세스였다. 하지만 솔라리스가 날로 발전하고
CPU 성능의 급성장으로 인해 이젠 아무리 바쁜 사이트라도 서버 사이징(Server
Sizing)만 잘해놓으면, CPU가 네트워크에 대해 문제를 일으키지 않는다. 참고로
솔라리스 2.5.1까지만 해도 초당 수백 건의 접속만 감당할 수 있었다가 2.6에
이르면서 초당 수천 건의 접속을 감당하게 됐으며, 이 수치는 날로 늘어나고 있다.
물론 단순 웹 서버가 아닌 자바 서블릿이나, CGI 같은 서버 사이드 프로세싱 요소가
있긴 하지만, 이는 엄밀히 말하지만 웹 서버 자체의 기능이 아니라, 웸 서버와 연동된
다른 애플리케이션의 퍼포먼스와 관련된 문제이다. 참고로 필자가 속한 기관의 웹
전용 시스템은 운영이나 기타 다른 업체의 웹 서버 중, 아직까지 CPU 부하로 인해
지연된 적은 거의 없었다.

또한 메모리 역시 GB 급으로 가고 있고, 웹 컨텐츠 전체를 물리적 메모리나 스왑으로
올릴 정도로 메모리가 커짐에 따라, Disk-bound 프로세스에서도 벗어나게 됐다.
그러므로 우리는 일반적인 웹 서버 환경에서는 이제 네트워크 튜닝에만 전념할 수
있게 됐다.

우선 솔라리스에서 네트워크 튜닝은 기본적으로 거의 모든 플랫폼에서 공통적으로
적용할 수 있다는 특징이 있다. 달리 표현하자면, 그만큼 적다는 말이 된다. 앞서
말한 것처럼 솔라리스가 최신판으로 올라갈수록 OS 자체가 점차 최적화돼가고 있기
때문에 몇 가지 고정된 파라미터 값을 제외하고는 손댈 영역이 점점 없어지고 있는
것이다.

LAN 카드 설정, /dev/hme

스팍 플랫폼에서 솔라리스는 100Mbps 고속 이더넷 인터페이스 카드를 /dev/hme로
정의한다. 그런데 이 인터페이스는 자동으로 10/ 100Mbps를 맞추는 오토
센싱(auto-sensing) 기능을 지원하지만 이것이 잘 안 될 때가 종종 있다. 특히
스위치가 풀 듀플렉스를 지원하는데 하프 듀플렉스로 맞춰지는 일이 비일비재한데
이럴 때는 수동으로 설정해줘야만 한다. hme를 100Mbps 풀 듀플렉스로 설정하는
방법은 ndd 커맨드를 이용하는 방법과 /etc/system에 파라미터 값을 넣어주는 두 가지
방법이 있는데, 그중 ndd를 이용하는 방법은 다음과 같다.

# ndd -set /dev/hme adv_autoneg_cap 0 (오토 센싱 기능 off)
# ndd -set /dev/hme adv_100fdx_cap 1 (100Mbps 풀 듀플렉스 기능 on)
# ndd -set /dev/hme adv_100hdx_cap 0
# ndd -set /dev/hme adv_100T4_cap 0

이는 재부팅시에는 설정 값이 지워진다. 이를 방지하기 위해서는
/etc/init.d/inetsvc에 다음과 같은 명령문을 넣어주면 된다.

/usr/sbin/ndd -set /dev/hme adv_100fdx_cap 1

또 다른 방법은 /etc/system에 커널 파라미터 값을 넣어 주는 것인데, /etc/system
끝에 다음과 같은 줄을 넣어주고 재부팅하면 된다.

set hme:hme_adv_autoneg_cap=0
set hme:hme_adv_100hdx_cap=0
set hme:hme_adv_100fdx_cap=1

웹 환경에 맞는 TCP 튜닝 파라미터

이제 우리는 TCP 튜닝 파라미터 값을 웹 서버 환경의 특성에 맞게 변경해 OS의 TCP
환경을 웹 서버에 최적화하는 작업을 하겠다. 먼저 솔라리스에서는 네트워크
드라이버나 TCP 프로토콜의 파라미터 값을 보여주거나 변경할 때 ndd를 사용한다. ndd
커맨드는 물론 HP-UX 등과 마찬가지로 파라미터를 보는 것은 누구나 이용할 수
있지만(#ndd [-get] /dev/OOO), 파라미터 값 변경은 오직 root만이 할 수 있다(#ndd
-set /dev/OOO OOOO 형태). 영구히 변경할 때는 이 ndd 커맨드를 앞서 LAN 카드
설정에서 말한 대로 /etc/init.d/inetsvc에 다음과 같은 형태로 넣어준다.

/usr/sbin/ndd -set /dev/tcp tcp_time_wait_interval 60000

또는 /etc/system에 약간 변형된 형태(set ip:ip_forwarding =0)로 파라미터 값을
등록하면 된다. 단 /etc/system에 등록할 때 주의할 점은 이 파일을 편집할 때 잘못된
변수 값이나, 잘못된 형식 등으로 인해 부팅이 되지 않는 경우가 종종 있는데, 이럴
때는 스팍 플랫폼의 경우엔 ok prom 프롬프트에서 ‘boot -i’으로 인터페이스 부팅을
한 다음 [/etc/system]을 참조하겠느냐는 부분에 /dev/null을 참조한다고 하면 된다.
이는 출시 설정에는 /etc/ system은 거의 모두 주석 처리돼 있어 이 파일을 참조하지
않으면 OS는 일단 무리 없이 부팅되기 때문이다. 솔라리스 x86 역시 부트 옵션에서
boot -i 하면 가능하다.

그리고 TCP 프로토콜도 hme(100Mbps 인터페이스, 스팍 플랫폼)와 마찬가지로
/dev/tcp이다. 먼저 /dev/tcp에서 튜닝이 가능한 파라미터들의 정보를 확인하는
명령은 다음과 같다.

#ndd [-get] /dev/tcp ?

[ ]안의 내용은 솔라리스에서는 언제나 생략할 수 있는 옵션이다. 이 옵션을 치면
다음과 같은 tcp 튜닝 파라미터들의 리스트가 출력된다.

<리스트 1>에 나온 수많은 TCP 파라미터 중 우리가 주로 이용할 수 있는 것은
몇 가지가 있는데 하나씩 알아보자.

tcp_time_wait_interval(솔라리스 2.6 이전까지는 tcp_close_wait_inter val이었음) :
메모리에서 TCP 연결이 끊어져도 tcp가 쓰던 소켓 정보를 일정 기간 대기 상태로
가지고 있고, 이를 가지고 있는 시간인데 기본값은 240,000ms(4분)이지만, 이는 tcp
소켓을 많이 요구하는 서버, 즉 웹 서버에서는 너무 길게 waiting하는 것이 메모리
낭비이므로 60,000ms(1분)정도로 줄이는 것이 좋다. 그러나 이를 너무 줄일 경우,
커넥션 품질 자체가 불안할 수 있으므로 더 이상 줄이지 않는 것이 바람직하다.
tcp_conn_req_max_q0 : TCP/IP 프로토콜 통신에서 half-open connection 상태, 즉
마지막 ACK를 받지 못한 상태의 커넥션을 몇 개까지 가지고 있을지에 대한 파라미터
값이다. 기본값은 1024인데 이 파리미터는 뒤에 설명할 tcp_conn_req_max_q와 형태가
비슷하다고 무조건 늘리는 경우가 있는데 불필요하며, 이 파라미터는 completed
connection마저도 listen queue에 들어가지 못하는 경우를 제외하고는 변경할 필요가
없다.
tcp_conn_req_max_q : 바로 웹 서버 튜닝에서 가장 많이 사용하는 파라미터이다.
기본값은 128인데, 1024 이하 정도로 늘려주는 것이 바람직하다. 이는 completed
connection이 실제 처리되기까지 받아주는 큐 크기로 너무 부족하면 상당히 바쁜 웹
서버의 경우, 사용자의 요청을 놓치는 경우가 발생할 수 있기 때문이다.
tcp_slow_start_initial : TCP 프로토콜 통신에서 처음에 테스트용으로 보내는 초기화
패킷 수를 말한다. 썬의 기본값은 1인데 다른 벤더들(특히 MS)이 2개를 사용하므로
이를 2로 변경해주는 것이 바람직하다. 솔라리스 8의 경우 가끔 4인 사례를 발견할 수
있었다.
네트워크 모니터링

#netstat -s -Ptcp 커맨드를 이용하면 모든 프로토콜의 정보를 출력하는데 -Ptcp라는
옵션을 추가하면 우리가 TCP 프로토콜의 파라미터를 변경하기 전 TCP와 관련한 정보만
출력해준다.

여기서 우리가 주목해 봐야 할 것은 tcpListenDropQ0와 tcpList enDrop인데,
tcpListenDropQ0는 accept() system call시 drop된 것의 카운트(갯수)이고
tcpListenDrop(Q)은 three-way handsha ke라고도 불리는 처음 두번째 ACK를 받기 전
incompleted connection이 큐에 들어가지 못한 카운트다.

글을 맺으며

지난호의 솔라리스 기사를 보고 격려의 메일을 보내온 독자들께 감사드린다. 사실
국내외에서 엔터프라이즈급 환경이건 중소규모 환경이건 간에 가릴 것 없이 상당히
많은 환경에서 썬 기종을 사용하고 있고, 거의 예외 없이 솔라리스를 기본 운영체제로
사용하고 있음에도 불구하고 이에 대한 자료를 찾기가 힘들었다.

이번 연재가 부족하나마 그동안 솔라리스에 관한 자료에 목말라하던 여러 솔라리스
이용자들에게 조금이나마 보탬이 됐으면 한다.

필자 연락처 : security@hufs.ac.kr, http://security.hufs.ac.kr
정리 : 송우일 wooil@sbmedia.co.kr

김민형
Posted by 1010