DevOps

미디어 업로드 서버의 성능 튜닝 - 디스크 I/O 튜닝

검정비니 2023. 10. 14. 21:31
728x90
반응형

최근 회사 업무로 인해 영상 Flask를 사용해서 "영상 분할 업로드" 및 영상 처리 API 등의 기능을 가지는 서버를 구현하게 되었다.

이 중, 영상 업로드 관련해서 디스크 I/O에 대한 많은 실험을 하게 되었고, 이에 대한 내용을 정리해 놓고자 이렇게 글을 쓰게 되었다.

Disk I/O 성능 측정하기

이 프로젝트의 주요 기능 중 하나인 영상 업로드의 경우 높은 disk I/O 기능을 사용해야 하기 때문에 Disk 입출력의 성능을 파악하는 것이 주요할 것으로 생각이 되어졌다. 사실 디스크 I/O의 성능의 경우, 기본적으로 Linux에서는 디스크 입출력 성능 체크를 위한 툴로써 dd라는 명령어를 제공한다. dd 커멘드는 파일을 복사하고 변환하는데 사용하는 CLI로, 입출력에 대한 성능 측정을 가능하게 해준다.

 

디스크 쓰기 성능 테스트

우선, 다음 명령어를 통해서 기본적인 파일 쓰기 성능을 테스트해 보았다.

# /dev/zero는 리눅스에서 제공하는 특수파일로, 사용자가 원하는만큼 0x00 바이트로 채워준다.
# bs는 블록 크기, count는 입출력 수행 횟수이다.
$ dd if=/dev/zero bs=1024 count=10000 of=/home/ubuntu/test_file oflag=direct

위에서 볼 수 있듯이, bs는 블록 크기이고 coutn는 입출력 수행 횟수이다. 즉, dd 커멘드를 통해서 생성되는 파일의 크기는 bs * count 만큼이 된다. 또한, oflag=direct는 파일 출력을 위해 write() 호출을 할 때 O_DIRECT 플래그를 활성화시킨다. 이 플래그는 파일시스템의 캐시 영역을 사용하지 않고 바로 디스크로 출력을 하도록 강제한다. 따라서 디스크 입출력 성능을 측정할 때 반드시 사용해야 하는 옵션이다.

 

아래는 위의 명령어의 실행 결과이다:

10000+0 records in
10000+0 records out
10240000 bytes (10 MB, 9.8 MiB) copied, 6.00774 s, 1.7 MB/s

 

즉, 이 서버의 디스크 출력 속도는 1.7 MB/s 정도로 볼수 있다.

 

이제 실제 서비스에서 영상 데이터를 임시로 저장할 때 사용하는 /tmp에 대해서 디스크 출력 테스트를 진행해 보았다.

dd if=/dev/zero bs=1024 count=2000 of=/tmp/test oflag=direct

 

결과는 아래와 같다:

2000+0 records in
2000+0 records out
2048000 bytes (2.0 MB, 2.0 MiB) copied, 1.20932 s, 1.7 MB/s

이번에도 출력 속도는 약 1.7 MB/s가 나왔다. 사실 이 크기는 기대했던 것보다 너무 낮은 성능이었다. 기본적으로 dropzone.js를 통해 chunked 업로드를 구현한 API의 경우, 단일 요청에 대해 최대 20MB의 데이터를 받도록 설정해 놓았기 때문에, 1.7MB/s라면 단일 요청에 대해 거의 10초 이상을 소모해야 한다.

 

혹시 한번에 쓰는 크기가 너무 작아서 성능이 잘 안나오는 것이 아닌가 하는 생각이 들었고, 이 가설을 검증하기 위해 bs 크기를 늘려보았다.

 

우선 한번에 쓰는 크기를 영상 chunk 크기인 20MB와 동일하게 설정해 보았다:

$ dd if=/dev/zero bs=20480000 count=10 of=/tmp/test oflag=direct

그 결과, 확실히 이전과는 다른 결과가 나왔다:

10+0 records in
10+0 records out
204800000 bytes (205 MB, 195 MiB) copied, 0.567581 s, 361 MB/s

361 MB/s라면 20MB짜리 데이터 블록을 초당 18개 정도 쓸 수 있는 정도이다. 이 정도 성능이면 현재 상황에서는 충분히 만족할만한 성능이라고 판단이 되었다. 만에 하나 디스크 성능 테스트 결과가 너무 낮다면 EC2 인스턴스를 한단계 높이는 방안에 대해서 고민했어야 했을텐데, 다행히도 가장 낮은 티어인 t3-micro에서도 기대한 수준의 성능이 나왔다.

 

디스크 읽기 성능 테스트

디스크 출력 성능에 대해서 테스트를 진행했으니, 이제 디스크 읽기 성능에 대해서 테스트를 진행해보았다.

$ dd if=/tmp/test of=/dev/null bs=1024

이번에는 조금전에 썼던 파일에 대해서 read를 한 뒤 /dev/null (리눅스에서 제공하는 특수한 파일로 NULL을 의미한다)에 쓰는 방식으로 read 성능을 테스트해보았다:

400000+0 records in
400000+0 records out
409600000 bytes (410 MB, 391 MiB) copied, 2.06458 s, 198 MB/s

한번에 읽는 크기를 1024로 했음에도 확실히 쓰기에 비해서 높은 속도를 보였다. 그렇다면 이번에는 bs 크기를 늘려보기로 했다:

$ dd if=/tmp/test of=/dev/null bs=10240000

한번에 약 10MB씩 읽도록 설정하고 실험을 진행해 보았다.

결과는 다음과 같다:

40+0 records in
40+0 records out
409600000 bytes (410 MB, 391 MiB) copied, 1.25891 s, 325 MB/s

읽기 성능의 경우 325 MB/s 정도가 나왔다. 사실 처음에는 막연히 read 성능이 write에 비해 월등히 빠르지 않을까 생각을 했으나, 실험 결과 생각보다 별 차이가 없었으며, 오히려 bs 크기에 따라서는 write가 더 빠른 경우도 있었다.

 

어찌되었든, 325 MB/s는 기대한 값보다 더 높은 성능이었기 때문에 만족스러운 상태로 실험을 끝마칠 수 있었다.

반응형