chapter11. Performance Tuning1 - CPU

  • 학습목표
    • CPU성능과 용량의 측정 및 평가 방법
    • CPU성능을 최적화하는 방법
    • CPU 자원 요구사항 계획하기
    • 시스템 저장장치의 중요 개념
    • 저장장치의 성능과 용량 계측하기
    • 디스크와 파일 시스템의 성능을 최적화 하는 방법
    • 저장장치 요구를 만족시키기 위한 계획에서의 가이드라인
    • 메모리 성능과 용량을 평가하는 방법
    • 메모리 성능과 스왑성능 튜닝 기법
    • 메모리 용량과 스왑 용량 계획하기
    • 네트워크 오류의 발생과 오류 측정 방법
    • 네트워크 성능을 최적화하는 방법
    • 네트워크 수용력 요구를 만족시키기 위한 프로젝트 방법
  1. CPU성능과 수용력 측정
    1. 평균 분석하기: 부하 평균은 일정 기간의 시간동안 시스템 상에서 실행 가능한 상태로 있는 프로세스의 평균 숫자이다.(실행 중인 프로세스 + 실행 큐에 있는 프로세스) ssh host@ip uptime하면 1분 5분 15분 부하 평균을 알 수 있다. 원칙 첫번째는 부하평균은 컴퓨터에 설치되어 있는 프로세서의 수에 연관되어 해석되어야 분명해진다. 일반적으로 설치된 프로세서의 숫자에 조금 못 미치는 부하 평균은 시스템이 프로세서의 파워를 적절하게 사용하고 있다는 것을 의미한다. 4개의 프로세서를 가진 컴퓨터의 부하평균이 3.5라면 이것은 자원을 최대한 이용하고 있다는 것이다. 원칙 두번째는 실행큐의 크기가 프로세스 숫자의 4배나 그 이상이 지속적으로 유지되는 경우라면 컴퓨터에 더 많은 프로세서를 추가해야 한다는 것이다. 명령어는 vmstat [옵션] [인터벌] [횟수]이며 가상메모리 사용량, 페이지 사용량, cpu사용량과 같은 다양한 성능 통계를 얻는다. 실행 큐의 크기는 r칼럼에 표시된다.
    2. 사용자 프로세스 대 시스템 프로세스 트레킹
      1. 프로세스 뿐만 아니라 커널 또한 cpu자원을 요구하며, 커널에 의해 cpu자원을 소모하는 작업은 다음과 같다. vmstat의 출력에서 us와 sy 항목이 각각 사용자 공간에서 소비되는 시간의 비율과 시스템 공간에서의 소비 시간의 비율을 출력하게 된다. id는 유휴 시간 비율임.
        1. 과도한 페이징과 스왑핑 작업
        2. 소프트웨어 방식의 RAID에서 페리티 연산 작업
        3. 대용량의 메모리 할당과 해제 작업
        4. 네트워크 트래픽의 필터링
      2. context switch(cs): 사용자레벨에서 커널 레벨의 진입이다 그 반대경우이다. 컨텍스트 스위치가 일어날때 시스템에 현저한 성능 불이익을 가져오기 때문에 중요하다. 일반적으로 시스템 콜과 인터럽트 이벤트때 대표적으로 컨텍스트 스위치를 일으킨다. 사용자 공간과 커널 공간의 스위치 전환은 CPU에 부하를 주게 되므로, 시스템의 기능이 둔해진 것 같은데 가시적인 부하가 보이지 않을 경우 컨텍스트 스위치를 원인으로 의심해야할 것이다. 커텍스트 스위치는 변화량이 급격하게 올려간다면 시스템에 문제가 있다고 볼 수 있다.
        1. 시스템 콜: 시스템 콜은 사용자 공간으로부터 커널 공간으로 들어가는 엔트리 포인트이다. 프로세스가 파일을 열거나, 데이터를 쓰거나 시스템을 재부팅하려면 프로세스는 커널에게 이러한 작업을 수행하도록 하기위해 시스템 콜을 사용하게 된다. 커널에 의해 해당 작업이 성공했건 실패했건 완료된 후에는 제어권이 사용자 공간의 프로세스로 다시 넘어오게 된다.
        2. 인터럽트: 인터럽트는 네트워크 인터페이스로 트래픽이 도착하거나 키보드에서 키가 눌려지거나, 타이머가 만료되거나 하는 경우 시스템은 인터럽트를 발생한다. 인터럽트는 시스템을 강제적으로 커널 상태로 들어가게 하여 인터럽트를 처리한다. 인터럽트는 인터럽트가 발생한 시간에 시스템에서 실행 중인 모든 프로세스의 실행을 선점하는데, 실행 중이었던 프로세스가 무엇이었던지 상관하지 않고 바꾸어 넣음으로써 커널이 인터럽트를 발생시킨 이벤트를 처리할 수 있게 된다.
      3. ps를 이용한 프로세스의 cpu사용량 모니터
        1. ps의 TIME은 프로세스가 구동하는데 사용한 cpu시간량을 리포트해준다. ps를 여러번 사용하여 cpu사용량이 얼마나 증가되었는 지를 확인 할 수 있다.
      4. top를 이용한 프로세스의 cpu사용량 모니터
        1. top는 5초의 인터벌로 15개의 프로세스를 cpu사용량 순으로 출력해주며 인터벌 간격마다 갱신하여 결과를 계속 출력해준다.
      5. time을 이용한 프로세스의 cpu 사용량 모니터
        1. time 명령어는 명령행에서 명령어를 지정하여 해당 명령이 수행하는데 사용한 실제시간, 사용자시간, 시스템 시간을 알려준다. time명령어는 이미 실행 중인 프로세스의 사용량을 측정하는 데 도움이 되지 않지만, 프로그램을 실행하기에 앞서 해당 프로세스가 얼마나 cpu를 사용할지 테스트하는데 유용하다.
    3. CPU성능 히스토리 분석
      1. cpu사용량의 히스토리는 실시간적으로 분석 데이터를 보는 것만큼이나 유용하다. 왜냐하면 성능문제가 일어났을 때 그 원인을 밝힐 수 있기 때문이다. 명령어는 sar이고 sar -u를 통해 그날 cpu 활용도를 보고해준다.
  2. CPU성능 튜닝
    • 프로세스서 대부분의 시간이 애플리케이션 코드를 실행하는데 사용된다. 이말은 향상된 성능을 내기 위해선 애플리케이션 개발자들이 코드를 최적화하고 튜닝해야 한다는 것을 의미한다. 시스템 관리자 차원에서도 시스템 자원이 최대한 성능을 발휘하도록 cpu를 튜닝함으로써 성능 향상을 꾀할 수 있다. 다음 방법으로 cpu튜닝을 효과적으로 할 수 있다.
      1. 적절한 컴파일러 옵션 선택: 패키지를 빌드할 때 컴파일러의 최적화 옵션을 이용하는 것이다.
      1. 범용 GNU C 컴파일러(GCC) 최적화 옵션 이용하기
        1. 레지스터(register) 변수 이용: 변수를 메로리 대신에 프로세서 내에 직접 저장할 수 있게 해준다.
        2. 루프 전개(loop unrolling): 이것은 루프의 내부에 있는 코드 행을 루프 코드가 아닌 연속적인 일반 코드로 펼쳐버리는 방법으로 루프 반복에 드는 비용을 줄인다.
        3. 함수 인라인(inlining): 호출되는 단순한 함수의 소스를 호출하는 코드에 직접 펼쳐버림으로써 함수 호출에 드는 오버헤드를 제거해 준다.
      2. GCC를 이용하여 시스템 종속적으로 최적화하기
        1. GCC는 또한 애플리케이션을 실행할 특정 컴퓨터에만 이용할 수 있도록 최적화하는 기능을 제공한다. 예를들어 펜티엄 프로세서에서 실행할 애플리케이션을 컴파일할 때 -mcpu=686 플래그를 사용하면 해당 프로세서에 특화된 지시어를 이용할 수 있게 해줌으로써 속도를 향상시킬 수 있다.
        2. 프로세스 우선순위 결정
      3. 성능 튜닝에 있어 가장 오래된 방법 중의 하나가 프로세스의 우선순위를 스케줄링에서 조정하는 것이다. 우선순위는 전통적으로 nice값으로 알려져있으며, 만일 하나의 프로세스가 시스템의 cpu시간을 독차지함으로써 시스템을 둔하게 만드는 원인이 되고 있다면 nice값을 -20~19까지 조정하여 우선순위를 변화시킬 수 있다. 기본값은 0 낮을 수록 높은 우선순위이다. find명령어로 임시 디렉토리에 있는 오래된 파일을 삭제하는 경우의 사용 예이다. nice -n 10 find 10 /tmp /var/tmp -mtime +14 -type f -exec rm -rf {} \; & renice -n 5 16165를 통해서 실행중인 프로세스의 우선순위를 변경할 수 있다.
        1. 프로세서 업그레이드
      4. cpu를 주로 필요로 하는 프로그램을 cpu바운드 프로세스라고 부르는데 이런 프로세스에 cpu를 업그레이드하면 성능향상에 이점을 가져올 수 있다.
        1. 다중 프로세서 활용
      5. 다중 프로세서 시스템에서 단일 애플리케이션의 성능을 얻어내는데 가장 중요한 요소는 두개 이상의 작업을 동시에 실행할 수 있는 시스템의 능력이다. 이렇게 하기 위해선 애플리케이션이 대중 스레드 기능을 지원해야 한다.
        1. 단일 스레드 프로그램
        2. 다중 프로세스 프로그램: 다중 프로세스 프로그램은 여러 개의 작업을 동시에 처리하기 위해서 자식 프로세스를 스판한다(낳는다). 예로들면 Apache가 시작되면 여러 개의 httpd 프로세스들이 포크되며, 원래의 부모 프로세스는 들어오는 각 접속을 자식 프로세스들에게 인계하게 된다.자식 프로세스 각각은 단일 스레드 프로세스이며 한 시각에 하나의 http요청만을 처리할 수 있다. 그러나 모든 httpd프로세스가 동시에 요청들을 처리하게 됨으로써 단일 프로세서 시스템이라 할지라도 웹서버에 확장성을 제공해 준다.
        3. 진정한 다중 스레드 프로그램: 다중 스레드 프로그램은 하나의 단일 프로세스 내에 여러 개의 실행 스레드를 가질 수 있다. 스레드는 프로세스와 달리 스레드를 생성하는 작업의 오버헤드가 매우 적다. 그리고 각각의 스레드가 독립적으로 실행된다 할지라도 프로세스 내의 전역 데이터에 모든 스레드가 접근할 수 있게된다. 가장 중요한 것은 동일 프로세스 내의 다중 스레드는 하나의 프로세서 내에서만이 아니라 다른 프로세서에서도 동시에 실행될 수 있다는 것이며, 이것이 단일 프로세스에서 다중 프로세싱을 할 수 있게 해주는 이점을 준다.
        4. 프로세스 트레이스
      6. 많은 유닉스 커널이 실행 중인 프로세스의 시스템 콜을 추적(trace)할 수 있는 기능을 지원한다. 트레이스는 특정 프로세스가 잘못되었을 때 정확하게 어떤 프로세스가 잘못된 시도를 하고 있는지 확인하는데 유용하다.예를 들어 솔라리스 운영체제의 oracle서버의 15분 부하 평균이 1.30이라고 한다면, 다음과 같이 truss 명령어를 사용하여 cpu의 30%를 차지하고 있는 한 개의 oracle프로세스에서 일어난 시스템 콜을 추적할 수 있을 것이다. truss -d -f -p 260 리눅스에서는 strace이다.
  3. CPU 자원 계획
    • 프로세스 자원을 계획하는 일은 cpu 성능에 영향을 미치는 변수가 너무 다양하기 때문에 어려운 작업이 될 것이다.고려해야 할 요소는 다음과 같다.
      1. 각 애플리케이션에 필요한 최소 cpu 요구사항
      2. 각 애플리케이션에서의 동시작업 기능 지원 여부
      3. 최대한도(peak) 사용 시의 부하 평균
      4. 최대한도 사용 시의 성능
        1. cpu 이용 경향 분석 * sa와 같은 툴을 이용하여 cpu의 사용량에 관한 데이터를 수집할 수 있으며 이용 경향을 찾아낼 수 있다. 예를 들어 매일 오후 7시에서 오후 9시까지 cpu의 유휴 시간이 2%로 갑자기 떨어지는 서버라면, 바로 이 시간대가 최대한도의 사용량을 보이는 시간임이 분명할 것이다. 이 최대한도를 참고하여 추가하거나 감소시키거나 한다.
        2. 확장성 있는 하드웨어 사용 * 현재의 프로세싱 요구사항에만 맞추는 것이 아닌 장래의 사용량 증가에 맞추어 확장할 수 있는 하드웨어를 사용하도록 해야한다.
        3. 부분 적재된 하드웨어를 사용: 4개 cpu지원하는 서버 구매하고 2개의 cpu만 구매하여 장착한다.
        4. 수평적으로 확장 가능하도록 서비스를 설계: 단순히 서비스를 제공해주는 노드의 수를 늘림으로써 서비스의 용량과 성능이 늘어날 수 있는 서비스를 말한다.
        5. 강력한 확장성의 하드웨어 사용