성능 향상을 위한 인프라 구조

응답과 처리량

시스템 성능 지표에는 응답(Response)과 처리량(Throughput)있다. 응답은 처리 하나당 소요 시간을 의미하며, 처리량은 단위 시간당 처리하는 양을 의미한다.

이 두 가지를 혼동하지 않고 명확히 구별하는 것이 중요하다.

응답시간 : 검색 엔진에서 검색 버튼을 누른 후 결과가 표시되기까지 걸리는 시간 처리량 : 검색 엔진이 초당 받아들이는 사용자 수

주의사항

웹시스템의 경우에는 웹 서버의 응답뿐만 아니라 AP 서버의 DB 서버의 응답시간도 포함한다

시스템 성능을 측정할때는 퍼센타일(Percentile) 개념을 이용하여 극단적으로 응답 시간이 긴 사용자는 다른 문제를 내포하고 있을 수 있기 때문에 오차라고 생각하고 평균값에 포함하지 않는다

응답 문제

로그나 테스트 등을 통해 어떤 계층(웹/AP/DB 등)에서 응답 지연이 발생하고 있는지 파악해야 한다

실제로 브라우저 렌더링 속도나 네트워크 문제가 포함되어 있을 수도 있다

처리량 문제

대량의 데이터를 교환하고 싶은데 영역이 부족한 경우에 처리량 문제가 발생한다 물리적으로 데이터를 통과시킬 수 없을 때 처리량 관점의 병목 현상이 발생하게 된다

일반적으로 CPU나 메모리 주변 처리량이 많지만 디스크나 네트워크 동신 대역은 낮아서 병목현상이 발생하기 쉽다.

혹은 CPU가 처리를 감당하지 못하는 처리가 올 때 '대기 행렬' 발생해서 처리량 한계를 초과할 수도 있다 여기서 중요한 점은 응답과 처리량은 밀접한 관계가 있다는 것이다.

병목 현상

처리 속도의 제한 요소가 되는 병목 현상

인프라 기술자가 병목 현상(Bottleneck)에 대해 이해하지 않고 성능을 개선할 수는 없다

인프라 아키텍처 용어로서 병목 현상이란, 처리량을 제한하고 있는 요인을 가리킨다

명칭 그대로 '병(Bottle)'의 '목(Neck)' 부분을 생각하면 된다

병목 현상은 어떻게 해결하는가?

성능 분석의 시작은 병목 현상이 발생하고 있는 위치를 정확히 파악하는 것이다

이를 위해 각 서버의 처리량이나 응답 상황 로그를 취득해서 어느 서버가 병목 지점인지 찾는 것 부터 시작한다

병목 현상 해결 방법

병목 지점을 찾았다면 해결하기 위한 두가지 접근법이 있다

1. 병목 위치를 파악해서 어떻게든 해결하는 것이다

이것을 튜닝이라고 한다 병목 위치를 작은 단위로 세분화해서 병목 영역을 더 집중적으로 파헤치는 접근법이 유효하다

2. 시스템 이용자 수를 제한하는 것이다

가능한 방법이냐고 생각할 수 있지만, 이것은 유량 제어라는 이름이 붙은 매우 직관적인 방법이다

대부분의 병목 현상은 당초 예상했던 부하보다 많은 부하가 걸려서 발생하게 된다 유량 제어는 적절한 계층에서 이용자 수를 제한하는 접근법이다

웹 시스템에서 '해당 사이트는 트래픽 초과로 차단되었습니다' 라고 표시되는 것도 유량 제어에 해당한다.

서버의 경우 리소스 최대치가 넘어서면 에러라는 형태로 제어 결과를 표시하게 된다 단, 유량 제어에서는 근본적인 해결책은 되지 못한다. 수평 분할을 통해 서버를 증섬함으로써 시스템 전체 허용량을 늘리는 접근법을 병용할 필요가 있다

병목 지점은 반드시 존재한다

병목 지점은 시스템상에 반드시 존재한다 모든 서버, 소프트웨어, 물리 장비가 균등하게 처리량을 분배하는 것은 이론상 불가능하기 때문이다

하나의 계층에서 병목 현상이 해결되면 반드시 다른 위치에서 병목 현상이 발생된다

따라서, 성능 개선 시에는 반드시 '특정 응답을 몇 퍼센트 개선시킨다', '100명이 추가로 접속해도 문제가 없도록 처리량을 개선한다' 등 인프라뿐만 아니라 시스템 전체 관점에서 목표를 만드는 것이 중요하다

시스템을 통해 본 병목 현상

3계층형 시스템에서 발생할 수 있는 병목 현상은 다섯 가지로 분류해볼 수 있다.

CPU 병목현상 예

CPU 사용률이 높으면 나쁘고 낮으면 좋은 것이 아니다. CPU 사용률은 처리 효율성을 나타내는 것이다

이것은 시스템 관점에서 비효율적인 상태가 아니라 오히려 그 반대다. 다른 계층의 처리량이 매우 좋아서 최종적으로는 CPU에서 병목 현상이 발생한다는 것을 의미하기 때문이다

CPU 사용률이 급증해서 문제가 있는지 없는지를 판단하려면 사용자 관점의 응답 속도나 시스템 전체 처리량을 확인해야 한다

CPU 성능 문제의 두 가지 원인은 아래와 같다.

대기 행렬의 병목 현상

CPU가 100% 가동률로 일하고 있음에도 대기 행렬이 줄어들지 않는 상태라면 대기 행렬에 대한 병목 지점이 되어 처리량 측면의 문제가 발생한다

CPU를 코어 수가 많은 것으로 변경하거나, 서브를 추가해서 병렬 처리하면 처리량이 증가한다. 또한, 처리 자체를 짧게 만드는 방법도 유효하다

대규모 웹 서비스 시스템에서는 사용자 증가에 맞추어 서버를 추가해서 스케일아웃하는 아키텍처를 도입하는 것이 필수다

스케일 아웃 : CPU 코어 수를 늘리거나 수평 분할에 따른 서버 수를 늘리는 튜닝 (= 규모를 크게 만든다)

응답의 병목 현상

대기 행렬을 튜닝하면 처리량 문제는 해결된다. 하지만 처리량 문제를 해결해도 반드시 응답 문제가 해결되는 것은 아니다.

처리 시간 자체가 느리면 병행 처리가 아무리 늘어난다고 해도 응답 시간에는 큰 차이가 없다. 응답 시간을 개선하는데는 처리 능력을 향상시키는 방법과 병렬 처리하는 방법이 있다

처리 능력을 향상시키는 방법

이것을 스케일업(Scale-up)이라고 한다. CPU의 성능(클럭)을 높이는 것이다 단, 스케일업으로 성능을 향상시키는 것은 한계가 있다

최근의 CPU는 클럭 차이가 크지 않아서 이를 통한 극적인 개선 효과는 기대하기 어렵다

병렬로 처리하는 방법

처리를 분할해서 다수의 CPU 코어에게 동시 처리를 시키는 것이다

멀티 프로세스화, 멀티 스레드화해서 복수의 CPU 코어를 이용함으로써 전체적인 처리 응답 시간을 향상시킬 수 있다

처리를 병령화할 수 있는가가 중요하다. 처리에 따라서는 병렬화하는 것이 매우 어려운 경우도 있다 병렬화 검토는 인프라만으로 한계가 있기 때문에 애플리케이션 개발자의 협조가 필요하다

CPU 사용률이 오르지 않는다

  • 보통 CPU 사용률이 100%에 도달하는 경우가 거의 없다. 그 전에 디스크, 네트워크 I/O 에서 막히는 경우가 많기 때문이다

  • 이런 경우 CPU 사용률이 낮아도 I/O 대기 큐에서 대기하는 프로세스 수가 증가한다

  • 이 상태는 CPU 병목 현상보다는 I/O 병목 현상에 가깝다

  • 특히, 데이터베이스는 I/O가 많아서 발생 빈도가 높다. 이런 상태를 개선할 수 있는 방법이 몇가지 있다 처리 다중화

  • 앞의 응답 개선 방법에서도 소개한 처리 병렬화와 기본적으로 같은 개념이다

  • 스레드를 여러 개 가동해서 동기 I/O 명령을 스레드 단위로 병행해서 실행하면 CPU 사용률도, I/O 부하도 증가한다

  • 이를 통해 서버 전체의 리소스 사용 상태를 개선할 수 있다 I/O 비동기화

  • 비동기 I/O를 이용하면 프로세스는 I/O처리 완료를 기다리지 않고 다음으로 넘어 갈 수 있다

  • CPU 처리와 I/O 처리를 동시에 진행할 수 있기 때문에 리소스 사용 상태가 개선된다 3.2 메모리 병목 현상 예 메모리 영역의 병목 현상은 크게 두 가지로 나눌 수 있다. 영역 부족에 의한 병목 현상

  • 프로세스가 가동하려면 반드시 전용 메모리 영역이 필요하지만 서버상의 메모리 영역은 유한하다

  • 메모리 영역이 부족하지 않도록 OS 커널 측에서 페이징 또는 스와핑이라는 처리를 해서 빈 메모리를 확보하는 구조가 있다. 부족한 부분은 디스크 영역으로 보완해서 가상적인 큰 메모리가 있다는 것을 보여주는 기술로 이를 가상 메모리(Virtual Memory)라고 한다

  • 하지만, 메모리와 디스크에는 압도적인 성능 차이가 있으므로 성능 저하가 발생한다 동일 데이터에 대한 병목 현상

  • 캐시는 만능 기술처럼 느껴질 수 있다. 전부 캐시하면 문제를 해결할 수 있는 것 아닌가? 라고 생각할수도 있다

  • 하지만, 메모리에서 경합이 발생하는 경우도 있다. 특정 영역을 복수의 프로세스가 공유하는 경우, 메모리 영역을 참조 또는 갱신할 때 누군가가 그 영역을 관리할 필요가 생긴다

  • 이런 문제를 해결하려면 애초에 경합이 발생하지 않도록 복수의 프로세스나 스레드가 같은 메모리 영역을 참조하지 않도록 만들면 된다 3.3 디스크 I/O 병목 현상 예 외부 저장소

  • 기업형 환경에서는 데이터베이스의 저장 위치로 외부 저장소를 사용하는 경우가 있다. SAN 을 경유하는 SAN 저장소나 네트워크를 경유하는 Network Attached Storage(NAS) 저장소가 있다

  • 단일 응답은 로컬 디스크가 가장 빠르다

  • 처리량 관점에서는 수십 대에서 수백 대 단위의 디스크를 배치하고, 거기에 전용 캐시 전용 메모리 영역까지 갖춘 외부 저장소가 유리하다. 디스크 수에 따라 처리량이 증가하기 때문이다 순차 I/O와 랜덤 I/O

  • 디스크 I/O에는 순차 액세스와 랜덤 액세스가 있다

  • 순차 I/O : 단일 디스크가 기록 위치인 경우, 큰 파일에 액세스 하는 경우에 빠르다

  • 랜덤 I/O : 작은 파일에 액세스 하는 경우, 데이터가 분산된 경우에 빠르다 3.4 네트워크 I/O 병목 현상 네트워크를 경유한 I/O 는 응답 시간 오버헤드가 크다. 이 때문에 응답을 근본적으로 개선하는 것은 어려우며, 처리량을 개선하는 접근법이나 네트워크 I/O 자체가 발생하지 않도록 하는 방법이 효과가 있다. 통신 프로세스의 병목 현상

  • 대역이 크면 고속 통신이라고 착각하기 쉽지만 하나의 프로세스로 처리하는 경우 높은 처리량을 실현하기는 어렵다

  • 이유는 통신에는 반드시 '데이터 전송', '통신 결과 확인' 같은 처리가 포함되므로 항상 풀 파워로 송수신이 이루어지지 않기 때문이다. 또한, 통신이 고속화되면 CPU에서 병목 현상이 발생할 수도 있다

  • 통신에서 대역을 모두 사용하려면 처리를 다중화해서 병렬화할 필요가 있다

  • 압축을 이용해서 전송량을 줄이는 방법도 있으나 압축 및 해제 시 발생하는 CPU 오버헤드를 감안해야 한다 네트워크 경로의 병목 현상

  • 네트워크에서는 눈에 보이지 않는 부분이 병목 지점이 되기 쉽다

  • 예를 들어, DB 에 많은 비용을 투입하였으나 예상한것보다 응답 속도가 느린 경우, 비교적 리소스를 많이 사용하는 AP 서버를 증성했지만, 성능에는 전혀 변화가 없을 수 있다. 이럴때는 기본 게이트웨이가 원인인 경우도 있다

  • 게이트웨이인 특정 라우터가 여러 시스템과 클라이언트 사이의 큰 트랜잭션을 소화하느라 처리 한계에 다다른 경우다

  • 이런 경우는 특정 구간의 전용 네트워크를 증설해서 트래픽을 분할하여 해결할 수 있다

  • 시스템을 신규 구축할 때는 경로와 트래픽 증감에 대해서도 검토해야 한다 3.5 애플리케이션 병목 현상 예 인프라 측은 지금까지 언급했던 스케일업, 스케일아웃 등의 개념을 통해 개선이 가능하다. 하지만 애플리케이션 자체가 병목 지점이 되는 경우가 있다. 알고리즘의 문제라면 인프라 측 리소스를 아무리 늘려도 어플리케이션 처리량이 높아지지 않거나 응답 속도를 개선할 수 없다. 데이터 갱신의 병목 현상

  • 자주 발생하는 것이 특정 데이터에 의존하는 처리가 병목 지점이 되는 것이다

  • 재고 확인을 실시간으로 해야 하고 엄격하게 해야 하는 경우에는 이 형태가 필수이지만, 개선할 수 있는 방법도 있다 다음 두 가지 개선안이 있다 값의 캐시화

  • 서버에 질의를 던지는 것이 병목 지점이 된다면, 더 가까운 장소에 캐시화하는 것이 일반적인 방법이다

  • 단, 네트워크를 경유하는 질의가 없어지므로 처리 효율이 개선될 수 있지만, 병목에 대한 근본적인 해결책은 되지 못한다 병목 지점의 분할

  • 재고 확인을 엄밀하게 처리하지 않고 레코드를 두 개로 나누는 형태도 있다

  • 예를 들어, 재고가 200개가 있다고 하면 100개씩 레코드를 분할하여 처리를 다중화 하는것이 가능하다

  • 결과적으로는 재고가 몇 개 있는지 확인하는 데이터 일치성 문제와 한쪽이 먼저 고갈된 경우 데이터 최신성 문제가 새롭게 발생한다 외부 질의의 병목 현상

  • 대부분의 시스템은 다른 시스템과 데이터 연계가 필요하다. 이 부분이 병목 지점이 되는 경우도 많다

  • 예를 들어, 기반 시스템의 사용자 관리를 일원화하는 프로젝트를 진행 후 일괄 처리에서 큰 폭의 처리 지연이 발생해서 처리가 예정 시간 내에 끝나지 않는 경우 원인은 무엇일까?

  • 원인은 1트랜잭션을 실행 시마다 사용자 정보를 확인하는 처리가 있었기 때문이다. 로컬에서는 질의 시간이 짧지만 분리된 시스템을 조회할 경우에는 I/O 병목 현상이 발생하게 된다- 이 경우 1회 질의로 1 일괄 처리 내의 사용자 정보를 취득하고, 애플리케이션 측에서 일차 파일을 캐시로 저장해서 차이만 확인하는 방법으로 해결할 수 있다 출처: https://slog2.tistory.com/29 [이재원의 티스토리:티스토리]

Last updated