디스크 덤프 (dd)를 사용한 디스크 복제에 적합한 블록 크기


46

가장 간단한 형태의 dd를 사용하여 하드 드라이브를 복제합니다.

dd if=INPUT of=OUTPUT

그러나 맨 페이지에서 dd는 blocksize 매개 변수를 알고 있습니다. 클로닝 절차의 속도를 높이는 blocksize 매개 변수에 최적의 값이 있습니까?


답변:


32

64k는 좋은 선택 인 것 같습니다.

Results:

  no bs=        78s     144584+0 records
  bs=512        78s     144584+0 records
  bs=1k         38s     72292+0 records
  bs=2k         38s     36146+0 records
  bs=4k         38s     18073+0 records
  bs=5k         39s     14458+1 records
  bs=50k        38s     1445+1 records
  bs=500k       39s     144+1 records
  bs=512k       39s     144+1 records
  bs=1M         39s     72+1 records
  bs=5M         39s     14+1 records
  bs=10M        39s     7+1 records

( 여기 에서 찍은 ).

이것은 내가 한 번 @work을 포주했던 io-heavy 컨버터 프로그램의 속도를 높이기위한 읽기 / 쓰기 버퍼링에 관한 나의 발견과 일치합니다.


이 벤치 마크는 회전 드라이브 및 ssd에서 다르게 보일 수 있습니다.
Jiri

3
-1 이것은 거의 완전히 하드 드라이브에 따라 다릅니다. OP가 자신의 하드 드라이브에 대한 최적의 블록 크기를 얻기 위해 단계를 반복 할 수 있도록 이러한 값을 얻는 데 사용되는 절차를 설명하십시오. 또한 결과 목록에 64k를 표시하지 않았으며 1k를 지난 모든 결과는 거의 동일합니다.
Micheal Johnson

@MichealJohnson은이 게시물을 자유롭게 편집하고 제공된 링크에서 해당 테이블이 생성 된 방법에 대해 설명하고 여기에 붙여 넣습니다. 64k는 속도 측면에서 더 이상 개선되지 않는 첫 번째 값이며 자연스러운 정렬입니다. 그리고 측정 된 속도는 사용 된 하드웨어에 전적으로 의존한다는 것이 명백합니다. 이것은 5 년 전에 사실이었으며 지금도 마찬가지입니다.
akira

1
왜 64k입니까? 나에게 2k는 더 이상 개선되지 않으므로 1k가 가장 좋은 가치이며 64k만큼 자연스럽게 정렬됩니다.
Micheal Johnson

블록 크기가 SD 카드의 성능을 변경하거나 dd to sdcard를 사용하여 움직이는 파일의 크기 만 줄입니까?
Trismegistos

22

dd는 원하는대로 BS를 사용하여 행복하게 복사하고 부분 블록 (끝 부분)을 복사합니다.

기본적으로 블록 크기 (bs) 매개 변수는 다른 디스크에 해당 덩어리를 쓰려고 시도하기 전에 한 디스크에서 덩어리에서 읽는 데 사용되는 메모리의 양을 설정하는 것으로 보입니다.

RAM이 많은 경우 BS를 크게 (그러나 전체가 RAM에 포함) 만드는 것은 RAM을 악용하여 대량의 읽기 및 쓰기를 수행하여 I / O 하위 시스템을 최대한 활용한다는 의미입니다. BS를 작게 만든다는 것은 전체 활동의 비율로 I / O 오버 헤드가 증가한다는 것을 의미합니다.

물론 여기에는 수익을 줄이는 법이 있습니다. 대략적인 대략적인 추정은 약 128K ~ 32M 범위의 블록 크기가 일반 I / O에 비해 오버 헤드가 작고 성능이 크게 향상되어 큰 차이가 없다는 것입니다. 하한이 128K ~ 32M 인 이유는 OS, 하드웨어 등에 따라 다릅니다.

그것이 저라면, 128K의 BS를 사용하고 다시 16M을 사용하여 복사 / 복제를 타이밍하는 몇 가지 실험을 수행 할 것입니다. 눈에 띄게 더 빠르면 사용하십시오. 그렇지 않은 경우 두 개의 더 작은 BS를 사용하십시오.


10

이 토론이 조금 오래되었지만 Google을 통해 여기에 온 사람들에게는 ...

dd는 이유가 멍청하다는 점을 명심하십시오.

복잡한 파티션 구성표 (리눅스 시스템에 LVM을 추가로 사용하는 이중 부팅 하드 드라이브 고려)는 Clonezilla와 같은 프로그램의 목공 작업에서 버그를 제거하기 시작합니다. 잘못 마운트 해제 된 파일 시스템은 ntfsclone을 하늘 높이 날릴 수 있습니다.

섹터별로 복제 된 손상된 파일 시스템은 원본보다 나쁘지 않습니다. 실패한 "스마트 카피"후 손상된 파일 시스템은 정말 죄송합니다.

확실하지 않은 경우에는 dd를 사용하고 법의학을 따르십시오. 법의학 이미징에는 섹터 별 사본이 필요합니다 (사실, dd로 시작하는 것보다 더 많은 섹터가 필요할 수 있지만, 그 이야기는 긴 이야기입니다). 느리고 지루하지만 작업이 올바르게 완료됩니다.

또한 "conv = noerror, sync"옵션 을 통해 몇 개월이 걸리지 않고 고장 나기 시작한 드라이브를 복제하거나 긁힌 ( 기침 ) CD 에서 ISO를 만들 수 있습니다.


뭐라고합니까 sync옵션은 무엇입니까? 맨 페이지는 다음과 같이 말합니다 "use synchronized I/O for data and metadata". 우리는 무엇과 동기화하고 있습니까? 그것은 많은 다른 것들이 될 수 있습니다.
sherrellbc

1
@sherrellbc sync는 읽기 오류가있는 경우 입력 블록을 0으로 채우므로 데이터 오프셋이 동기화 상태를 유지합니다.
goetzc

9

다른 사람들이 말했듯이, 보편적으로 정확한 블록 크기는 없습니다. 어떤 상황에 최적이거나 어떤 하드웨어가 다른 상황에있어 비효율적 일 수 있습니다. 또한 디스크의 상태에 따라 "최적의"크기와 다른 블록 크기를 사용하는 것이 좋습니다.

최신 하드웨어에서 매우 신뢰할 수있는 한 가지 방법은 기본 블록 크기 인 512 바이트가보다 최적의 대안보다 거의 10 배 느리다는 것입니다. 의심 스러울 때 64K가 현대적인 기본 설정이라는 것을 알았습니다. 64K는 일반적으로 최적의 블록 크기는 아니지만 내 경험에 따르면 기본값보다 훨씬 효율적인 경향이 있습니다. 64K는 또한 믿을만한 성능을 자랑합니다. 2002 년경 Eug-Lug 메일 링리스트에서 64K의 블록 크기를 권장하는 메시지를 찾을 수 있습니다 : http://www.mail-archive.com/eug- lug@efn.org/msg12073.html

최적의 출력 블록 크기를 결정하기 위해 기본 512 바이트에서 최대 64M까지 다양한 블록 크기 범위에서 dd로 128M 테스트 파일 작성을 테스트하는 다음 스크립트를 작성했습니다. 이 스크립트는 내부적으로 dd를 사용하므로주의해서 사용하십시오.

dd_obs_test.sh :

#!/bin/bash

# Since we're dealing with dd, abort if any errors occur
set -e

TEST_FILE=${1:-dd_obs_testfile}
TEST_FILE_EXISTS=0
if [ -e "$TEST_FILE" ]; then TEST_FILE_EXISTS=1; fi
TEST_FILE_SIZE=134217728

if [ $EUID -ne 0 ]; then
  echo "NOTE: Kernel cache will not be cleared between tests without sudo. This will likely cause inaccurate results." 1>&2
fi

# Header
PRINTF_FORMAT="%8s : %s\n"
printf "$PRINTF_FORMAT" 'block size' 'transfer rate'

# Block sizes of 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M
for BLOCK_SIZE in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
do
  # Calculate number of segments required to copy
  COUNT=$(($TEST_FILE_SIZE / $BLOCK_SIZE))

  if [ $COUNT -le 0 ]; then
    echo "Block size of $BLOCK_SIZE estimated to require $COUNT blocks, aborting further tests."
    break
  fi

  # Clear kernel cache to ensure more accurate test
  [ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] && echo 3 > /proc/sys/vm/drop_caches

  # Create a test file with the specified block size
  DD_RESULT=$(dd if=/dev/zero of=$TEST_FILE bs=$BLOCK_SIZE count=$COUNT conv=fsync 2>&1 1>/dev/null)

  # Extract the transfer rate from dd's STDERR output
  TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')

  # Clean up the test file if we created one
  if [ $TEST_FILE_EXISTS -ne 0 ]; then rm $TEST_FILE; fi

  # Output the result
  printf "$PRINTF_FORMAT" "$BLOCK_SIZE" "$TRANSFER_RATE"
done

GitHub에서보기

이 스크립트를 데비안 (우분투) 시스템과 OSX Yosemite에서만 테스트 했으므로 다른 Unix 버전에서 작업하려면 약간의 조정이 필요할 것입니다.

기본적으로 명령은 현재 디렉토리에 dd_obs_testfile 이라는 테스트 파일을 작성합니다 . 또는 스크립트 이름 뒤에 경로를 제공하여 사용자 정의 테스트 파일의 경로를 제공 할 수 있습니다.

$ ./dd_obs_test.sh /path/to/disk/test_file

스크립트의 출력은 다음과 같이 테스트 된 블록 크기와 해당 전송 속도의 목록입니다.

$ ./dd_obs_test.sh
block size : transfer rate
       512 : 11.3 MB/s
      1024 : 22.1 MB/s
      2048 : 42.3 MB/s
      4096 : 75.2 MB/s
      8192 : 90.7 MB/s
     16384 : 101 MB/s
     32768 : 104 MB/s
     65536 : 108 MB/s
    131072 : 113 MB/s
    262144 : 112 MB/s
    524288 : 133 MB/s
   1048576 : 125 MB/s
   2097152 : 113 MB/s
   4194304 : 106 MB/s
   8388608 : 107 MB/s
  16777216 : 110 MB/s
  33554432 : 119 MB/s
  67108864 : 134 MB/s

(참고 : 전송 속도 단위는 OS에 따라 다릅니다)

최적의 읽기 블록 크기를 테스트하기 위해 거의 동일한 프로세스를 사용할 수 있지만 / dev / zero에서 읽고 디스크에 쓰는 대신 디스크에서 읽고 / dev / null에 씁니다. 이를 수행하는 스크립트는 다음과 같습니다.

dd_ibs_test.sh :

#!/bin/bash

# Since we're dealing with dd, abort if any errors occur
set -e

TEST_FILE=${1:-dd_ibs_testfile}
if [ -e "$TEST_FILE" ]; then TEST_FILE_EXISTS=$?; fi
TEST_FILE_SIZE=134217728

# Exit if file exists
if [ -e $TEST_FILE ]; then
  echo "Test file $TEST_FILE exists, aborting."
  exit 1
fi
TEST_FILE_EXISTS=1

if [ $EUID -ne 0 ]; then
  echo "NOTE: Kernel cache will not be cleared between tests without sudo. This will likely cause inaccurate results." 1>&2
fi

# Create test file
echo 'Generating test file...'
BLOCK_SIZE=65536
COUNT=$(($TEST_FILE_SIZE / $BLOCK_SIZE))
dd if=/dev/urandom of=$TEST_FILE bs=$BLOCK_SIZE count=$COUNT conv=fsync > /dev/null 2>&1

# Header
PRINTF_FORMAT="%8s : %s\n"
printf "$PRINTF_FORMAT" 'block size' 'transfer rate'

# Block sizes of 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M
for BLOCK_SIZE in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
do
  # Clear kernel cache to ensure more accurate test
  [ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] && echo 3 > /proc/sys/vm/drop_caches

  # Read test file out to /dev/null with specified block size
  DD_RESULT=$(dd if=$TEST_FILE of=/dev/null bs=$BLOCK_SIZE 2>&1 1>/dev/null)

  # Extract transfer rate
  TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')

  printf "$PRINTF_FORMAT" "$BLOCK_SIZE" "$TRANSFER_RATE"
done

# Clean up the test file if we created one
if [ $TEST_FILE_EXISTS -ne 0 ]; then rm $TEST_FILE; fi

GitHub에서보기

이 경우 중요한 차이점은 테스트 파일이 스크립트로 작성된 파일이라는 것입니다. 기존 파일에서이 명령을 가리 키지 마십시오. 그렇지 않으면 기존 파일이 임의의 데이터로 덮어 쓰기됩니다!

내 특정 하드웨어의 경우 128K가 HDD에서 가장 최적의 입력 블록 크기이고 32K가 SSD에서 가장 최적이라는 것을 알았습니다.

이 답변은 대부분의 조사 결과를 다루고 있지만 블로그 게시물을 작성하기에 충분한 시간 동안이 상황에 부딪 쳤 습니다. http://blog.tdg5.com/tuning-dd-block-size/ 자세한 내용은 내가 거기에서 수행 한 테스트에.

이 StackOverflow 게시물도 도움이 될 수 있습니다. dd : 최적의 블록 크기를 계산하는 방법?



1

외부 SATA의 새 SSD에 이전 부팅 드라이브 복제 (sss to ssd)

  • 리눅스 우분투 18.04.2 LTS 64bit 사용
  • hp xw4600 (8GB RAM, 인텔 코어 2 쿼드 Q6700 @ 2.66GHz 4c / 4t no-HT)

디스크 사용 (도구)> 포맷> ATA 보안 지우기 (2 분)

$ lsblk -l /dev/sd?
NAME MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda    8:0    0 119,2G  0 disk 
sda1   8:1    0 119,2G  0 part /
sdb    8:16   0   2,7T  0 disk 
sdc    8:32   0   2,7T  0 disk 
sdd    8:48   0  12,8T  0 disk 
sde    8:64   0   2,7T  0 disk
sdf    8:80   1 465,8G  0 disk 

$ sudo fdisk -l /dev/sda
Disk /dev/sda: 119,2 GiB, 128035676160 bytes, 250069680 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

$ sudo fdisk -l /dev/sdf
Disk /dev/sdf: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
  • sda : Kingston SSD (이전 : 디스크는 최고 270MB / s에 가까운 최고 263MB / s의 속도를보고하며 시스템 디스크로 인한 쓰기 테스트는 없음)
  • sdf : Crucial MX500, 500GB, CT500MX500SSD1 (디스크 보고서 : 평균 rd / wr 속도 284 / 262MB / s 및 액세스 시간 0.05ms, 피크는 약 290 / 270MB / s 임)

시운전 :

$ sudo dd if=/dev/sda of=/dev/sdf
250069680+0 records in
250069680+0 records out
128035676160 bytes (128 GB, 119 GiB) copied, 3391,72 s, 37,7 MB/s
#       --vvvvv--                            *********
$ sudo dd bs=1M if=/dev/sda of=/dev/sdf
122104+1 records in
122104+1 records out
128035676160 bytes (128 GB, 119 GiB) copied, 473,186 s, 271 MB/s
#                                            *********  ********

동일한 결과로 보안 지우기 후 두 번째 시도 :

128035676160 bytes (128 GB, 119 GiB) copied, 472,797 s, 271 MB/s

슈퍼 유저에 오신 것을 환영합니다! 답변 해 주셔서 감사합니다 . 요약을 포함하도록 편집 해 보시기 바랍니다 . 인용 된 모든 출력 중에서 실제 답변이 무엇인지 찾기가 까다로 웠습니다! 건배
bertieb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.