5장. 대규모 데이터 처리의 어려운 점 (메모리와 디스크)

5장. 대규모 데이터 처리의 어려운 점 (메모리와 디스크)

(대규모 데이터 처리가 어려운 이유)메모리 내에서 처리(계산)할 수 없다. #

  • 메모리에서 처리할 수 없으면 DISK 를 사용해야 한다.
  • 메모리의 크기는 DISK에 비해 작기 때문에 데이터의 크기가 클 경우 메모리에서 모두 처리할 수 없게 된다.
  • 메모리는 디스크에 비해 10^5(10만) ~ 10^6(100만) 배 빠르다.

메모리는 왜 디스크보다 빠를까? #

1. 물리적인 구조

물리적인 구조가 그렇다. 메모리는 전기적인 부품이다. 데이터를 탐색하는 속도가 빠르다.

반대로 DISK는 동축 상에 원반(disk)로 쌓여 있다. 원반 회전, 헤드의 이동 등의 물리적인 비용이 발생하고 이게 크다.

SSD의 경우 물리적인 회전이 아니므로 탐색 비용이 빠르지만 버스 속도가 병목이 되거나 그 밖에 구조에 기인하는 면이 있어서 메모리에 비해서는 느리다.

2. 전송 속도, 버스 속도

아래는 책에서 나온 hdparm 측정한 전송 속도 예시이다. 약 100배 이상 차이가 난다.

Timing cached reads : 7525.03 MB/sec (7.5 GB/초)
- Memory 에서 읽어 CPU 까지 가는 비용이라고 보면 될 것 같다.

Timing buffered disk reads : 58.37 MB/sec (58 MB/초)
- Disk 에서 읽어 CPU 까지 가는 비용이라고 보면 될 것 같다.



단일 호스트의 부하 #

추측하지 말라, 계측하라 #

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


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

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

  1. Load Average 확인
  2. CPU, I/O 병목 원인 확인/조사

1. 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 부하가 높은 경우1. 사용자 프로그램의 처리가 병목인지, 시스템 프로그램이 원인인지 확인한다. top, sar 등으로 확인할 수 있다.

2. ps로 볼 수 있는 프로세스 상태, CPU 사용 시간 등을 확인할 수 있다.

3. (문제로 보여지는) 프로세스를 찾았고 보다 상세하게 조사할 경우 strace, oprofile 등으로 프로파일링을 해서 병목 지점을 좁혀간다.

일반적으로 CPU에 부하가 걸리고 있는 경우는 다음 상황 중 하나이다.

1. disk, memory 용량 등 그 밖의 부분에서는 병목이 되지 않는, 말하자면 이상적인 상태
2. 프로그램이 폭주해서 CPU에 필요 이상의 부하가 걸리는 경우
1. 서버 증설
2. 프로그램 로직 / 알고리즘 개선
3. 오류 제거
I/O 부하가 높은 경우프로그램으로부터 입출력이 많아서 부하가 높거나 스왑이 발생해서 디스크 액세스가 발생하고 있는 상황 중 하나인 경우가 대부분이다.

sar, vmstat 등으로 스왑의 발생 상황을 확인해서 문제를 가려내 볼 수 있다.

스왑이 발생하고 있는 경우는 다음과 같이 조사해볼 수 있다.

1. 특정 프로세스가 극단적으로 메모리를 많이 사용하고 있는지 ps 등으로 확인한다.
2. 프로그램의 오류로 메모리를 지나치게 사용하고 있는지 확인한다.
3. 탑재된 메모리가 부족한지 확인한다. (메모리를 증설하지 못하는 경우에는 분산을 검토한다.)

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

1. 메모리 증설로 캐시 영역을 확대시킬 수 있는 경우는 메모리를 증설한다.
2. 메모리 증설로 대응할 수 없는 경우는 데이터 분산, 캐시 서버 도입 등을 검토한다.
3. 프로그램을 개선해서 I/O 빈도를 줄이는 것을 검토한다.
1. 프로그램 개선
2. 메모리 증설 or 분산
3. 캐시 서버 도입

OS 튜닝 (= 부하의 원인을 알고 이것을 제거하는 것) #

튜닝이라는 단어를 ‘본래 SW가 지니고 있는 성능을 2배, 3배, x배 이상으로 키워지기 위한 것’으로 이해하고 있을 수 있다. 이게 아니다.

튜닝의 본래 의미는, ‘병목이 발견되면 이를 제거하는 작업’이다. 애초에 HW, SW가 지니고 있는 성능 이상의 성능을 내는 것은 불가능하다.

우리가 할 수 있는 것은 본래 지닌 성능을 충분히 발휘할 수 있도록 문제가 될 만한 부분을 제거하는 것이다.

최근의 OS, 미들웨어는 기본적으로 충분한 성능을 발휘할 수 있도록 설정되어 있다. 이렇게 기본 설정이 최적화 되어 있다면 아무리 설정을 변경하더라도 대부분의 경우에는 효과가 없다. (오히려 역효과가 날 수도 있을 것이다.)

문제가 되는 부분(예를 들어, 10초 걸릴 작업이 100초가 걸리는 등)이 발견되면 아래와 같은 행동들을 통해 튜닝(병목 구간 제거)을 하는 것이다.

  • (메모리 증설 확인) 캐시 영역을 확보함으로써 대응할 수 있는지 확인한다.
  • (데이터 양 확인) 원래 데이터 양이 비정상적으로, 비효율적으로 많지는 않는지 확인한다.
  • (I/O 관련 애플리케이션 알고리즘 확인) 애플리케이션 측의 I/O 알고리즘을 변경할 필요는 없는지 확인한다.

위 내용의 바탕이 되고 있는 ‘(24시간 365일) 서버/인프라를 지탱하는 기술’이라는 책이 있다. OS 내부 구조, 부하 계측 방법에 관한 기본적인 내용을 설명한다.