본문 바로가기

서버운영 (TA, ADMIN)/미들웨어

[서버관리] 단일호스트 서버의 부하 튜닝

'부하분산'이라는 말에서 떠오르는 것은 대부분의 경우 복수의 호스트로 처리를 나누어 담당시키는, 문자 그대로의 '분산'입니다. 그러나 원래 한 대에서 처리할 수 있는 부하를 서버 10대로 분산하는 것은 본말이 전도된 것입니다. 단일 서버의 성능을 충분히 끌어낼 수 있는 것을 시작으로 복수 서버에서의 부하분산이 의미를 갖습니다.



추측하지 말라, 계측하라



단일 호스트의 성능을 끌어내는 데에는 서버 리소스의 이용현황을 정확하게 파악할 필요가 있습니다. 즉, 부하가 어느 정도 걸리고 있는지를 조사할 필요가 있습니다. 그리고 이런 계측작업이야말로 단일 호스트의 부하를 줄이는 데 가장 중요한 작업입니다.


"추측하지 말라, 계측하라" - 프로그램 명언입니다.


부하분산의 세계도 예외없이 이에 해당합니다. 계측함으로써 시스템의 병목을 규명하고, 이를 집중적으로 제거함으로써 성능을 끌어낼 수 있습니다.



병목 규명작업의 기본적인 흐름


병목을 규명하기 위한 작업을 크게 나누면 다음과 같습니다.


1. Load Average 확인

2. CPU, I/O 중 병목 원인 조사


1. Load Average 확인

우선, 부하 규명의 시작이 되는 지표로 top이나 uptime 등의 명령으로 Load Average를 확인합니다. 


Load Average는 시스템 전체의 부하상황을 나타내는 지표입니다. 다만, Load Average만으로는 병목의 원인이 어딘지를 판단할 수 없습니다. Load Average 값을 시초로 해서 병목지점에 대한 조사를 시작합니다.


Load Average는 낮은데 시스템의 전송량이 오르지 않을 경우도 가끔 있습니다. 이럴 경우는 소프트웨어의 설정이나 오류, 네트워크, 원격 호스트 측에 원인이 없는지 살펴봅니다.



2. CPU, I/O 중 병목 원인 조사

Load Average가 높은 경우, 다음으로 CPU와 I/O 어느 쪽에 원인이 있는지를 조사합니다. sar나 vmstat으로 시간 경과에 따라 CPU 사용률이나 I/O 대기율의 추이를 확인할 수 있으므로 이를 참고해서 규명합니다.


'CPU 부하'가 높을 경우, 다음과 같은 흐름을 따라 조사해 갑니다.

- 사용자 프로그램의 처리가 병목인지, 시스템 프로그램이 원인인지를 확인합니다. top, sar 이용

- 또한 ps로 볼 수 있는 프로세스의 상태나 CPU 사용시간 등을 보면서 원인이 되고 있는 프로세스를 찾습니다.

- 프로세스를 찾은 후 보다 상세하게 조사할 경우는 strace로 추적하거나 oprofile로 프로파일링을 해서 병목지점을 좁혀갑니다.


일반적으로 CP에 부하가 걸리고 있는 것은 다음 상황중 하나입니다.


- 디스크나 메모리 용량 등 그 밖의 부분에서는 병목이 되지 않는, 말하자면 이상적인 상태

- 프로그램이 폭주해서 CPU에 필요이상의 부하가 걸리는 경우


전자의 상태에다 시스템의 전송량에 문제가 있다면 서버 증설이나 프로그램의 로직이나 알고리즘을 개선해서 대응합니다. 후자의 경우는 오류를 제거해서 프로그램이 폭주하지 않도록 대처합니다.


'I/O 부하'가 높은 경우, 프로그램으로부터 입출력이 많아서 부하가 높거나 스왑이 발생해서 디스크 액세스가 발생하고 있는 상황 중 하나일 경우가 대부분입니다. sar나 vmstat로 스왑의 발생상황을 확인해서 문제를 가려냅니다.


확인한 결과 스왑이 발생하고 있을 경우는 다음과 같은 점을 실마리로 조사합니다.


- 특정 프로세스가 극단적으로 메모리를 소비하고 있지 않은지를 ps로 확인할 수 있습니다.

- 프로그램의 오류로 메모리를 지나치게 사용하고 있는 경우에는 프로그램을 개선합니다.

- 탑재된 메모리가 부족한 경우에는 메모리를 증설합니다. 메모리를 증설할 수 없을 경우는 분산을 검토합니다.


스왑이 발생하지 않고 디스크로의 입출력이 빈번하게 발생하고 있는 상황은 캐시에 필요한 메모리가 부족한 경우를 생각해볼 수 있습니다. 해당 서버가 저장하고 있는 데이터 용량과 증설 가능한 메모리 양을 비교해서 다음과 같이 나눠서 검토합니다.


- 메모리 증설로 캐시영역을 확대시킬 수 있는 경우는 메모리를 증설합니다.

- 메모리 증설로 대응할 수 없는 경우는 데이터 분산이나 캐시서버 도입 등을 검토합니다.

  물론, 프로그램을 개선해서 I/O 빈도를 줄이는 것도 검토합니다.


부하의 원인을 좁혀나가는 기본 전략입니다.



OS 튜닝이란 부하의 원인을 알고 이것을 제기하는 것



사실 튜닝 방법을 굳이 설명할 필요는 없습니다. 튜닝이라는 단어에서, 본래 소프트웨어가 지니고 있는 성능을 2배, 3배 이상으로 키워주기 위한 시책을 떠올리는 사람이 있을지 모르겠으나 튜닝의 본래 의미는 '병목이 발견되면 이를 제거하는' 작업입니다. 애초에 본래 하드웨어나 소프트웨어가 지니고 있는 성능 이상의 성능을 내는 것은 아무리 노력해도 불가능한 것입니다. 할 수 있는 것은 '하드웨어/소프트웨어가 본래 지닌 성능을 충분히 발휘할 수 있도록 문제가 될 만한 부분이 있다면 제거'하는 것입니다.


최근의 OS나 미들웨어는 디폴트 상태에서도 충분한 성능을 발휘할 수 있도록 설정되어 있습니다. 정체되지 않은 고속도로의 차도를 넓혀도 1대의 자동차가 목적지에 도달하기까지 걸리는 시간은 달라지지 않는 것과 마찬가지로, 디폴트 설정이 최적화되어 있다면 아무리 설정을 변경하더라도 대부분의 경우에는 효과가 없습니다.


CPU의 계산시간을 최대한 이용해서 10초 걸리는 처리는 아무리 OS 설정을 만진다고 해도 10초 이하로 줄어들 수 는 없습니다.


한편, 예를 들어 다른 프로그램의 I/O 성능이 영향을 끼치고 있어서 해당 프로그램이 본래 10초에 끝낼 일을 100초 걸려 마친다고 할 경우에는 I/O 성능을 개선할 수 있습니다. 이는 정체하고 있는 고속도로의 예 입니다. I/O 성능을 개선하기 위해서는 다음과 같은 것을 규명할 필요가 있습니다.


- 메모리를 증설해서 캐시 영역을 확보함으로써 대응할 수 있는가

- 원래 데이터량이 너무 많지는 않은가

- 애플리케이션 측의 I/O 알고리즘을 변경할 필요가 있는가


결국 원인을 알면 해당 원인에 대한 대응방법은 자명한 것입니다. 이렇게 자명해진 대응방법을 실천하는 것이 튜닝입니다.