본문 바로가기

IT/Linux

파일 쓰기/읽기 속도 측정 스크립트

윈도우는 여러가지 Tool이 있긴 하지만, 리눅스에서 마땅히 쓸만한 방법을 못 찾았다.

원래 테스트 하고자 했던 상황은 NAS 구성과 세팅에 따라 읽기/쓰기 속도가 얼마나 달라지는지를 테스트하고 싶었다.

(SMBv2, SMBv3, NFS 프로토콜 차이, RAID 차이, HDD vs SSD 차이 등)

 

그래서 일단 서칭햇을 때 dd를 사용하여 임시 파일을 쓰는 속도 측정과 이를 null로 읽어오는 방법 등에 대해 확인을 하긴 했고, 아래처럼 한다고 한다.

 

쓰기>

dd if=/dev/zero bs=1M count=2048 of=test_file oflag=direct

읽기>

dd if=test_file of=/dev/null bs=1024

 

물론 잘 되었는데, 문제는 dd의 구조에 따라 차이가 있다.

예를 들면, 나는 대용량 파일을 테스트하고 싶다고 하면 10G 정도라고 가정하자.

그러면 우리가 일반적으로 테스트하는 환경은 10G 파일을 한번에 옮기는 짓을 할때의 구성을 보고싶다.

 

그런데 dd의 경우 한번에 최대 쓸 수 있는 data block size가 2G 정도 이기 때문에, 2G를 5번정도 나누어서 쓰는 형태를 진행해야한다. 그러면 뭔가 우리가 생각하는 실사용과 좀 차이가 있지 않을까? 하는 생각이 들었다. 

(실제 하드 디스크 성능을 테스트하는 알고리즘이 어떻게 되는지는 잘모르겠다.)

 

그래서 생각한 방법은 해당 임시 파일을 만들고, 이 파일을 테스트하고자 하는 destination에 직접 복사하는 걸로 실사용 환경과 유사하게 만들어주는 것이었다.

(다만 이 경우 가장 중요한 건 임시 파일을 읽어오는 로컬 파일이 테스트하고자 하는 대상보다 훨씬 빨라야 어떤 병목현상이 일어나지 않을 것이다.)

 

쓰는건 그렇게 해결하긴 했는데 문제는 읽는걸 어떻게 처리하는게 좋을지 잘 모르겠다. 우선은 단위를 쪼개서 1G 단위로 읽어오는걸로 해봤는데 (왜냐면 10G읽어오는걸 dd 테스트하니까 읽어오긴 하던데.. 일단 비교를 위해 두가지 모두 하는걸로 되어있음..), 좀 차이가 있음.

 

작성한 BASH 스크립트는 아래와 같다. 

주석은 ChatGPT가 달았다.

 

내 경우 NAS를 테스트하는 게 목적이었기 때문에 로컬에 임시파일을 생성하고 NAS 폴더를 마운트해서 테스트했다.

#!/bin/bash

# 테스트에 사용할 임시 로컬 파일 경로
temp_local_file="/home/users/hjang/testfile"
# 테스트에 사용할 임시 파일 경로
temp_file="/home/users/hjang/cobi1/SpeedTest/testfile"
# 시간을 밀리초로 변환하는 함수 정의
milliseconds() {
    echo $(($(date +%s%N) / 1000000))
}

# 함수 정의: 테스트 수행
perform_test() {
    local test_filesize="$1"    # 테스트할 파일 크기
    local num_count=$2          # 반복 횟수

    echo "[$test_filesize * $num_count times Test]"

    # dd 명령어 옵션 설정
    local dd_size
    local dd_count
    local fileunit=${test_filesize: -1}
    local filesizenum=${test_filesize%[GMK]}    

    if [[ "$filesizenum" -ge 2 && "$fileunit" == "G" ]]; then  # 2G 이상이면
        dd_size="1G"          # 최소된위 1G
        dd_count=$filesizenum # 1G 단위로 반복하도록 수정
    else
        dd_size=$test_filesize 
        dd_count=1
    fi

    # Generate Temp File
    write_dd=$(dd if=/dev/zero of=$temp_local_file bs=$dd_size count=$dd_count oflag=direct 2>&1 | tail -n 1)
    file_size=$(stat -c %s "$temp_local_file")

    # Test Write Speed
    local total_time=0
    local total_speed=0
    for (( i=1; i<=$num_count;i++))
    do
        start_time=$(milliseconds)
        cp "$temp_local_file" "$temp_file"
        end_time=$(milliseconds)
        elapsed_ms=$((end_time - start_time))
        
        speed_byte=$(bc <<< "scale=2; ($file_size*1000) / $elapsed_ms")
        speed_MB=$(bc <<< "scale=2; $speed_byte / (1024*1024)")
        total_speed=$(bc <<< "$total_speed + $speed_MB")
        total_time=$(bc <<< "$total_time + $elapsed_ms")
    done
    average_speed=$(bc <<< "scale=2; $total_speed / $num_count")
    total_time_sec=$(bc <<< "scale=2; $total_time / 1000")
    echo "  - Write Speed: $average_speed MB/s ($total_time_sec secs)"

    # Test Read Speed
    local total_time=0
    local total_speed=0
    for (( i=1; i<=$num_count;i++))
    do
        start_time=$(milliseconds)
        read_dd=$(dd of=/dev/null if=$temp_file bs=$dd_size count=$dd_count 2>&1 | tail -n 1)
        end_time=$(milliseconds)
        elapsed_ms=$((end_time - start_time))
        
        speed_byte=$(bc <<< "scale=2; ($file_size*1000) / $elapsed_ms")
        speed_MB=$(bc <<< "scale=2; $speed_byte / (1024*1024)")
        total_speed=$(bc <<< "$total_speed + $speed_MB")
        total_time=$(bc <<< "$total_time + $elapsed_ms")
    done
    average_speed=$(bc <<< "scale=2; $total_speed / $num_count")
    total_time_sec=$(bc <<< "scale=2; $total_time / 1000")
    echo "  - Read Speed: $average_speed MB/s ($total_time_sec secs)"    
    read_dd=$(dd of=/dev/null if=$temp_file bs=$test_filesize count=$num_count 2>&1 | tail -n 1)
    echo "  - Read dd Speed: $read_dd"
}

perform_test "4K" "1000"
perform_test "10M" "100"
# perform_test "100M" "10"
perform_test "1G" "5"
perform_test "10G" "2"
# perform_test "100G" "2"
# perform_test "500G" "2"

# 임시 파일 삭제
rm $temp_file
rm $temp_local_file

echo "Tests complete"

 

 

 

'IT > Linux' 카테고리의 다른 글

Docker에서 GPU 에러 해결  (0) 2024.03.10
Nvidia Driver 재설치 중 모듈 문제  (0) 2024.03.10