Apache featherApache 서버를 운용하면서 점점 늘어나는 동적인 내용의 웹 페이지들 탓에 한계에 부딪히는 상황까지 가게 되면, 결국 값비싼 새로운 장비를 투자해서 서버의 용량을 몇 배 정도 끌어 올릴 수도 있지만, 추가 장비의 도움 없이도 Apache의 성능을 개선하는 방법들을 간략하게나마 소개해 드리겠습니다.

서버에 부담을 주는 요인들 이해하기

서버에 부담을 주는 수천 가지도 넘는 다양한 요인 중에서도 몇 가지 공통되는 부분들이 있습니다. 그 중 가장 큰 세 가지의 요인들을 살펴보면:

  • 많은 수의 작업들이 사용하는 너무나 많은 RAM 사용으로 인한 Drive Swapping.
  • 형편없이 짜인 DB queries, 최적화되지 못한 코드, 그리고 급등하는 작업량으로 인한 CPU의 부담.
  • 하드웨어의 한계 혹은 악의적인 공격에 의한 Network 체증.

Apache의 RAM 사용량 관리하기

Apache의 실행 작업들은 원래 엄청난 양의 RAM을 사용하게 됩니다. 이런 문제는 각각의 작업들이 맡은 일을 마치고 나서도, 다음의 더 크고 중요한 작업들로 넘어가는 대신 이 부풀려진 작업이 RAM에 상주하면서 client에게 자료를 아주 찔끔찔끔 전달하게 된다는 것을 깨닫게 되는 순간부터는 커다란 문제로 다가옵니다. 실제로 이러한 문제는 더 널리 알려졌어야 할 상식적이고도 중요한 정보에 의해 풀이될 수 있습니다:

만약 Apache가 100% 정적인 파일들로만 운용된다면, 각각의 httpd 작업은 2-3 megs 정도의 RAM을 사용하게 됩니다.

그렇다면, 만약 Apache가 99%의 정적인 파일들과 1%의 동적인 파일들로 운용된다면, 각각의 httpd 작업은 가장 복잡한 동적 페이지를 가지고 가정해 볼 경우, 약 3-20 megs 정도의 RAM을 사용하게 됩니다.

이 같은 현상은 작업이 무엇이 되었든 간에 작업을 소화하기 위해 작업량이 증가하기만 할 뿐, 그 작업을 다 끝마치기 전까지는 절대 감소하지 않기 때문입니다. 그래서, 아주 작은 양의 동적 페이지가 존재하거나 통신량의 변동이 없는 한은, 대부분의 httpd 작업들은 금세 시스템에서 가장 큰 동적 스크립트의 크기에 해당하는 RAM을 잡아먹게 됩니다. 아주 똑똑한 웹 서버라면 이런 상황을 알아서 자동으로 잘 대처할 능력이 있겠지만, 서버 운용자에게도 RAM의 사용 효율을 직접 개선하기 위한 몇 가지의 선택수단은 있습니다.

» KeepAlive를 적당히 조절해서 낭비되는 작업들을 줄여라

이것은 장단점이 있습니다. KeepAliveTimeout 설정은 작업이 아무런 일도 하지 않은 채로 접속을 유지하면서 얼마 동안을 대기하고 있을 지를 결정합니다. 여기서의 몇 초는 나중에는 쌓여서 커다란 부담이 될 수도 있습니다.
KeepAlive를 사용하면 서버와 client 모두에게 속도의 향상을 가져다 줄 수 있습니다. 그래서 만약, 이것을 꺼놓은 채로 그림과 같은 정적 파일들을 전달하는 작업의 경우에는 무척이나 더딜 것입니다. 대체적으로 KeepAlive을 켜놓은 상태에서 KeepAliveTimeout을 1-2초 정도로 아주 낮게 설정해 놓는 것이 좋습니다.

» MaxClients의 전체 작업수를 적당한 값으로 제한

동적인 내용을 전달하기 위해 Apache를 운용한다면, 순간 동시 접속량은 무척이나 제한될 수 밖에 없을 것입니다. 일단 특정 양을 넘어가기만 하면, 순식간에 메모리를 잡아먹으면서 점점 느려지다가 결국은 동작은 멈추게 됩니다. 개인적으로는 시스템이나 웹 서버는 이런 결과를 미리 방지하기 위한 조치를 자동적으로 취해주어야 한다고 믿지만, 현실에서는 기본적으로 서버가 자신을 잠식할 수도 있게 내버려 두도록 되어 있는 상황입니다. 결국은 사용자가 여러번의 시도와 시행착오에서 나온 경험을 근거로 자신의 서버가 얼마나 많은 Apache 작업들을 동시에 수행할 수 있는 지를 유추하고, 여기서 얻은 값을 MaxClients로 설정해야 합니다.

주의: Apache의 문서에는 여기에 관해서 오해의 소지가 있습니다 – 만약 Apache가 MaxClients의 한계에 도달하게 되면, client들은 “접속 불능”의 상태가 되는 것이 아니고, 그냥 대기상태로 단지 접속이 느려질 뿐입니다. MaxClients의 값을 기준으로 나머지, StartServers, MinSpareServers, 그리고 MaxSpareServers를 위해 필요한 값들도 같이 어림잡아 결정될 수 있습니다.

» MaxRequestsPerChild를 가지고 작업들이 재설정될 수 있도록 하라

일정 시간 후에는 진행 작업들을 죽이고 처음부터 다시 시작되게 하면 작업들의 RAM 사용량을 낮출 수 있습니다. 이것은 많은 상황들에서 총 메모리 사용량을 줄이는 효과를 나타냅니다. 그리고 동적인 내용을 적게 가지고 있을 경우에는 더 큰 효과를 얻을 수도 있습니다. 이것은 가령 따라잡기 게임과 비슷해서 동적 파일들이 총 RAM 사용량을 점진적으로 늘리게 되면, 작업들을 재시동 시켜서 RAM의 사용량을 점진적으로 줄여주게 됩니다. 여러가지의 MaxRequestsPerChild 값들을 가지고 실험해 보시기 바랍니다만 (20 정도의 낮은 값을 주어도 좋은 효과를 보실 수 있을 겁니다),
너무 낮은 값으로 설정하지는 마시기 바랍니다. 왜냐하면 매번 다시 새로운 작업들을 생성해 내는 일도 Apache에게는 부담이 될 수 있기 때문입니다.

작업량에 따른 가장 적절한 값은 ps axu --sort:rss를 확인해 보시면서 결정하실 수 있을 겁니다. 주의: 여기서의 결과만을 놓고 보면 무척이나 인상적인 효과를 확인하실 수도 있겠지만, 이것이 “항상 일정한 것은 아니라는 것”을 알아두십시오. 여기서 얻을 결과로만 MaxRequestsPerChild의 값을 조절해서 서버의 다른 요인들을 골려하지 않는다면, 결국은 또 다른 문제에 직면하게 되실 겁니다.
이 점을 명심하고, MaxRequestsPerChild 값을 적당히만 조절한다면 MaxClients의 값은 최대 50% 정도 늘리실 수 있을 겁니다.

마지막으로, Apache를 대체 혹은 지원하는 상자 밖의 도구들도 살펴보겠습니다.

» 제 2의 서버를 운용

정적인 문서들이나 그림들의 처리를 위해서는 가볍고 빠른 서버를 사용하고, 동시에 더 복잡한 작업들은 같이 설치된 Apache에 맡기실 수도 있습니다. 이렇게 하면 간단하면서도 적은 양의 자료들을 처리하는 데 Apache의 수 메가바이트 짜리 작업 처리 기능을 묶어둘 필요가 없어집니다. 그리고 예를 들어, PHP 스크립트를 실행할 경우에만 Apache의 작업을 끌어들일 수도 있습니다. 이런 용도로 고를 수 있는 것들은 다음에 몇 가지가 있습니다:

» Lingerd와 작업을 분배

Lingerd는 Apache가 문서를 끌어다 주면 client에게 자료를 전달하는 작업을 떠맡습니다. 하지만 이것은 커널(kernel)의 수정을 요합니다.

» Proxy Cache 사용

Proxy cache는 Apache로부터 전달받은 것들에 대한 복사본을 따로 저장해 놓습니다. 그래서, Apache의 개입 없이도 같은 자료의 경우에는 복사본을 송출하는 것이 가능합니다. 이것은 또한 약간의 더 추가된 메모리를 사용, 동적으로 생성된 웹 페이지들을 따로 저장해 놓음으로 해서 작업의 반응 속도를 빠르게 할 수도 있습니다.

» Apache 다시 컴파일하기

개인적인 작업 환경에 맞게 필요없는 부분들을 제외한 최적의 설정으로 Apache를 다시 컴파일할 수도 있습니다. 하지만 처음하는 사람들에게는 약간 까다로운 작업이 될 수도 있습니다.

» Apache를 완전히 다른 것으로 대체

만약 Apache가 가지고 있는 모든 기능들을 필요로 한 것이 아니라면, 자신의 작업환경에 더 어울리는 다른 대체 서버를 생각해 볼 수도 있습니다. 현재는 가장 적합한 선택가능 서버들로 nonblocking I/O 기술을 사용하면서 같은 작업 안에서 모든 client들한테 한꺼번에 접속할 수 있는 기능을 가진 다음과 같은 것들을 살펴보실 수 있습니다:

» Apache 담금질 참고 문서들

PHP의 CPU와 RAM 사용량 관리하기

» 가속기를 사용

일반적으로 PHP 스크립트들을 컴파일하는 것은 실제 실행시키는 것보다 작업에 더 큰 부담을 줍니다. 그래서 이런 문제점을 해결하기 위해 미리 컴파일 될 수 있도록 하는 간단한 도구들이 있습니다. 이런 도구들에는 (빠르고 무료이지만 약간은 불안정한)Turck MMCache, PHP Accelerator, APC, 그리고 Zend Accelerator가 있습니다. 이런 도구들을 사용하면 보통은 평균적으로 속도가 2-10 배정도의 속도 증가와 PHP의 RAM 사용량의 50%~85% 감소의 효과를 보실 수 있습니다.

더 자세한 글은 PHP 최적화하기를 보십시오.

MySQL의 CPU와 RAM 사용량 관리하기

» 사용하는 Query들을 최적화

이것에 관해서는 다른 많은 곳에서 이미 자세하게 설명되어 있으므로, 여기서는 단지 몇 가지 중요한 점들만 집어 보겠습니다.
하나의 잘 못된 query 문장이 자주 실행된다면 결국은 사이트에는 무릎을 꿇게 할 수도 있습니다. 또한, 두셋의 잘 못된 query때문에 실행의 성능도 하나가 잘 못 되었을 때와 별반 다르지는 않습니다. 이 말은, 하나의 잘 못된 query를 고친다고 해서 서버 전반에 걸친 속도의 향상은 얻을 수 없다는 얘기입니다. 하지만 만약에 최적화되어 있지 않은 query들을 “모두” 찾아서 수정해 준다면, 다섯 배 정도의 급격한 서버 속도의 향상을 보실 수 있을 겁니다. 여기서 지체되는 query들을 잡는데 MySQL의 log-slow-queries 기능은 많은 도움이 될 겁니다.

» 변하기 쉬운 일시적인 자료들은 다른 곳에 저장해 놓으십시오

관계형 데이터베이스의 모든 잡다한 기능들을 필요로 한 것이 아니라면, 자료들을 MySQL 대신에 다른 방법을 사용해서 저장해 놓는 것이 몇 배는 효과적일 것입니다. 임시로 저장될 자료들은 사용자의 세션에 저장해 놓거나 혹은 (Turck MMCache에 포함된 것처럼) 전체적으로 공유된 메모리의 라이브러리에 저장해 놓으십시오.
더욱 중요한 자료들은 파일이나 개인의 flat-file 데이터베이스 시스템에 저장해 놓을 수도 있을 것입니다. 두 경우를 복합적으로 잘 사용한다면 아주 강력한 효과를 얻을 수 있습니다 – 개인의 flat-file 데이터베이스와 복사본이 메모리에 저장된 상태라면, 기록을 위한 작업에서만 디스크로 접근할 필요가 생길 것입니다.

» MySQL 담금질 참고 문서들

기타 참고사항

여기서는 몇 가지 도움이 될 만한 간단한 것들을 알려 드리겠습니다.

너무나 많은 CPU와 RAM을 차지하고 있는 작업들을 확인하기 위해서는 topps axu 명령을 사용하십시오. 하지만 여기서 알아두셔야 할 것은, 이것들의 결과는 실제로는 꼭 믿을 만한 것이 못 될 수도 있습니다. 여기에서 총 RAM 사용량은 항상 정확하지는 않습니다 – 애플리케이션의 thread들은 같은 메모리 page들을 함께 사용하고 있을 경우도 있으며, 이것이 올바로 결과에 반영되지는 않습니다.

네트워크상의 문제들을 확인하기 위해서는 netstat -anp | sort -u 명령을 사용해 보십시오.

Apache의 성능측정 도구인 ab의 사용 결과를 분석해 보십시오 – 주의할 것은 이 도구로는 실제 사용 환경을 정확하게 흉내 낼 수 없다는 것이고, 실제로 예상치에 영향을 주는 가장 두드러진 효과로는 느린 전화모뎀 사용자들에 의한 예상보다 더 길게 접속상태를 열어놓게 돼서 생기는 영향이 있습니다.

» 참고문서들

마무리

만약에, 20M를 처리할 수 있는 작업이 겨우 2k 짜리 JPEG 파일을 보내주고 나서 KeepAlive에 설정된 15초 동안 아무것도 안 하고 대기하고 있어야만 하는 상황이 너무 낭비라고 생각하신다면, 물론 이것에 동의하는 사람은 당신 혼자만은 아닐 겁니다! 기가바이트의 RAM을 장착한 기가 Hz의 기계가 순간 동시 접속 수 200에 머물러야만 한다는 생각은, 아직도 거대 기업들이 소비자에게 그냥 믿어주십사 내놓은 가설이 생각보다 더 깊게 퍼져있는 것이리라 짐작되는 점입니다. 소프트웨어에 대한 약간의 기초적인 지식과 여기에 소개된 몇 가지 요령들과 함께면, 추가 하드웨어의 투자 없이도 부풀려진 문제점들을 줄이고 적어도 원래의 설계되었던 합당한 범위 안에서 서버를 효율적으로 운용하실 수 있으실 것입니다.

따옴: ONLamp.com

관련된 주제의 글

댓글을 남겨 주세요