Linux 시스템에서 큰 파일을 빠르게 생성


438

Linux ( Red Hat Linux ) 시스템 에서 대용량 파일을 빠르게 만들 수 있습니까?

dd 는 작업을 수행하지만 /dev/zero테스트를 위해 수백 GB 크기의 파일이 필요한 경우 드라이브 에서 읽고 쓰는 데 시간이 오래 걸릴 수 있습니다 ... 반복적으로 수행해야하는 경우 시간이 실제로 더해집니다.

파일의 내용에 신경 쓰지 않고 신속하게 파일을 만들고 싶습니다. 어떻게 할 수 있습니까?

스파 스 파일을 사용하면 작동하지 않습니다. 파일에 디스크 공간을 할당해야합니다.


1
Ext4는 파일 할당 성능이 훨씬 뛰어납니다. 최대 100MB의 전체 블록을 한 번에 할당 할 수 있기 때문입니다.
martinus

5
'truncate'명령은 희소 파일을 만듭니다. 예 : en.wikipedia.org/wiki/Sparse_file
Jason Drew

2
사람들은 아래에서 자르고 dd를 사용하여 "스파 스 파일이 작동하지 않습니다"를 심각하게 무시하는 것 같습니다.
hpavc

1
"테스트 용"의 의미를 정의해야합니다. 하드 디스크의 쓰기 속도를 테스트하십니까? 무엇 df을보고 할 것인가? 특정 작업을 수행하는 앱 테스트 대답은 테스트하려는 대상에 따라 다릅니다. 어쨌든 나는 조금 늦었다-나는 당신의 질문 이후 몇 년이 지난 것을 본다 :-)
ndemou

1
만약 당신이 나처럼 전체 파티션을 시뮬레이트하는 방법을 찾고 있다면 / dev / full을
Julian

답변:


509

dd다른 답변에서 좋은 해결책이지만이 목적을 위해서는 느립니다. Linux (및 기타 POSIX 시스템)에는 fallocate실제로 쓰지 않고 원하는 공간을 사용하는 최신 디스크 기반 파일 시스템과 매우 빠르게 작동합니다.

예를 들면 다음과 같습니다.

fallocate -l 10G gentoo_root.img

5
dd가 이미 내부적으로 사용하고 있습니까? 3.0.0 커널에서 'dd if = / dev / zero of = zerofile bs = 1G count = 1'을 수행하면 초당 500MB 이상의 쓰기 데이터 속도로 2 초 안에 쓰기가 완료됩니다. 2.5 인치 노트북 하드 드라이브에서는 불가능합니다.
lxgr

21
fallocate내가 찾던 것입니다.
AB

7
이 ( fallocate)는 Linux ZFS 파일 시스템에서도 작동하지 않습니다 -github.com/zfsonlinux/zfs/issues/326
Joe

5
fallocate는 ext3에서도 지원되지 않습니다. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie

3
데비안에서 GNU / Linux fallocateutil-linux패키지의 일부입니다 . 이 도구는 RedHat의 Karel Zak이 작성했으며 소스 코드는 여기에서 찾을 수 있습니다. kernel.org/pub/linux/utils/util-linux
Franta

295

이것은 오늘날의 가상 환경 환경에서 일반적인 질문입니다. 불행히도 그 대답은 생각만큼 간단하지 않습니다.

dd는 명백한 첫 번째 선택이지만, dd는 본질적으로 사본이며 모든 데이터 블록을 작성하도록 강제합니다 (따라서 파일 내용 초기화). 그리고 초기화는 너무 많은 I / O 시간을 차지합니다. (더 오래 걸리고 싶습니까? / dev / zero 대신 / dev / random을 사용하십시오 ! 그러면 CPU와 I / O 시간을 사용하게됩니다!) 결국 dd는 좋지 않은 선택입니다. VM "create"GUI에서 사용되는 기본값). 예 :

dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G

잘라내 기는 또 다른 선택이며 아마도 가장 빠를 것입니다. 그러나 "스파 스 파일"을 생성하기 때문입니다. 기본적으로 스파 스 파일은 동일한 데이터가 많은 디스크 섹션이며 기본 파일 시스템은 실제로 모든 데이터를 저장하는 것이 아니라 모든 것이 존재하는 것처럼 "척하는"방식으로 "속임수"입니다. 따라서 truncate를 사용하여 VM에 20GB 드라이브를 만들면 파일 시스템은 실제로 20GB를 할당하지 않지만 디스크에서 트랙 하나만으로도 20GB의 제로가 있다고 속임수로 표시합니다. 실제로 (실제로) 사용 중일 수 있습니다. 예 :

 truncate -s 10G gentoo_root.img

fallocate은이다 와 - 마지막 최고 - 선택 . 그것은 본질적으로 "보유"(또는 공간 당신이있는 거 추구하는 모든 "할당은"하지만, 그래서 쓰기 아무것도 귀찮게하지 않기 때문에, VM의 디스크 할당에 사용 fallocate를 사용하여 20GB 가상 드라이브 공간을 만들면 실제로는 "스파 스 파일"이 아닌 20GB 파일을 얻게되며 아무것도 쓰지 않아도됩니다. 새로운 디스크와 같은 종류!) 예 :

fallocate -l 10G gentoo_root.img

4
+1 truncate은 JFS에서 작동합니다. fallocate별로. 한 가지 점 : 숫자에 소수점을 포함 할 수 없으므로 1536G, not 을 지정해야했습니다 1.5T.
Calrion

1
내에 따르면 fallocate매뉴얼 페이지이 만 지원됩니다 btrfs, ext4, ocfs2, 및 xfs파일 시스템
나단 S. 왓슨 헤이그

참고 swapon불행하게도 미리 할당 된 범위에 대한 작업을하지 않는, 마지막으로 내가 확인. XFS 메일 링리스트에서 오래된 여유 공간 데이터를 대신 노출하고 사전 할당 된 것으로 표시된 범위를 갖지 않는 대체 옵션을 갖는 것에 대한 논의가 있었으므로 스왑이 작동합니다. 그러나 나는 아무것도 한 적이 없다고 생각합니다.
Peter Cordes

1
참고로,에서 너무 많은 데이터를 읽으려고 /dev/random임의의 데이터 부족을 초래할 수 있으며, "환경과 노이즈가 수집 될 때까지 엔트로피 풀이 비어있는 경우,는 / dev / 임의의 의지 블록에서 읽어" 그것은 아주 아주 취할 수 있도록 매우를 오랜 시간
Xen2050

154

리눅스 및 모든 파일 시스템

xfs_mkfile 10240m 10Gigfile

Linux 및 일부 파일 시스템 (ext4, xfs, btrfs 및 ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS 및 아마도 다른 UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

설명

mkfile <size>대신 myfile을 사용해보십시오 dd. 이 -n옵션을 사용하면 크기가 표시되지만 데이터가 기록 될 때까지 디스크 블록이 할당되지 않습니다. -n옵션이 없으면 공간이 0으로 채워져 디스크에 쓰기를 의미하므로 시간이 걸립니다.

mkfile 은 SunOS에서 파생되었으며 모든 곳에서 사용할 수 없습니다. 대부분의 Linux 시스템은 xfs_mkfile이름에도 불구하고 XFS 파일 시스템뿐만 아니라 정확히 동일한 방식으로 작동합니다. 그것은에 포함 xfsprogs (데비안 / 우분투) 또는 이와 유사한라는 이름의 패키지.

대부분의 Linux 시스템에는 fallocate특정 파일 시스템 (예 : btrfs, ext4, ocfs2 및 xfs)에서만 작동하지만 모든 파일 공간을 할당하지만 (홀리 파일이 아닌 파일을 생성 함) 가장 빠르지 않습니다. 그것의.


5
이 mkfile은 어디에 있습니까, 낯선가? 기본 RHEL 설치에 없습니다.
paxdiablo 2013

2
솔라리스 유틸리티입니다. gpl mkfile을 검색하면 몇 가지 소스 코드 예제가 있습니다.
Martin Beckett

5
OS X에서 매력으로 작동합니다 :mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfile우분투의 xfsprogs 에 포함되어 있으며 내 ext3 fs의 매력처럼 작동합니다. :)
Greg Dubicki

97
truncate -s 10M output.file

10M 파일을 즉시 생성합니다 (M은 1024 * 1024 바이트, MB는 1000 * 1000, K, KB, G, GB와 동일).

편집 : 많은 사람들이 지적했듯이 실제로 파일을 장치에 할당하지는 않습니다. 이를 통해 장치에서 사용 가능한 공간에 관계없이 "스파 스"파일을 생성하므로 실제로 임의의 큰 파일을 생성 할 수 있습니다.

따라서이 작업을 수행 할 때 파일에 액세스 할 때까지 물리적 할당이 지연됩니다. 이 파일을 메모리에 매핑하는 경우 예상 성능이 없을 수 있습니다.

그러나 이것은 여전히 ​​유용한 명령입니다.


1
이것을 시도했지만 사용 가능한 디스크 공간에 영향을 미치지 않습니다. 이전에 설명한대로 드문 파일이기 때문에 필수입니다.
Gringo Suave

7
이것은 문제를 해결하지 못하기 때문에 최고의 대답이 아니어야합니다 fallocate. 아래 대답은 그렇지 않습니다.
Gringo Suave

4
@GringoSuave 그러나 이것은 유사하지만 약간 다른 문제가있는 일부 사람들에게 여전히 유용합니다.
AJMansfield 2016 년

@GringoSuave : 요청에 따라 큰 파일을 만드는 것 같습니다. 왜 문제가 해결되지 않습니까? 또한 잘못된 답변 아래에 대부분의 경우 작동하지 않는다는 메모가 있습니다.
Pavel Šimerda 5

1
작동하지 않을 것이라고 스파 스 파일을 만드는 것이 좋습니다.
hpavc

44

여기서 seek는 원하는 파일 크기 (바이트)입니다.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575

6
이 접근 방식이 마음에 들지만 주석 작성자는 어떤 이유로 스파 스 파일을 원하지 않습니다. :(
ephemient

3
dd if = / dev / zero of 1GBfile bs = 1000 count = 1000000
Damien

7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret

1
스파 스 파일의 truncate경우 훨씬 더 나은 것 같습니다.
Pavel Šimerda

36

seek가 원하는 파일의 크기 (바이트) 인 예

#kilobytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200K

#megabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200M

#gigabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200G

#terabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200T


dd 맨 페이지에서 :

블록 및 바이트 뒤에는 다음과 같은 곱셈 접미사가 올 수 있습니다 : c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * T, P, E, Z, Y의 경우 1000, G = 1024 * 1024 * 1024 등입니다.


이것은 n-1 방식 보다 훨씬 나아 보이 므로 기본적으로와 같습니다 truncate.
Pavel Šimerda

19

1GB 파일을 만들려면

dd if=/dev/zero of=filename bs=1G count=1

7
카운트가 1이어야한다고 생각합니다. (centos에서 테스트)
SvennD

dd if=/dev/zero of=filename bs=20G count=12GB 파일 만 생성합니다! 20GB가 아닙니다.
Maulik Gangani

18

나는 리눅스에 대해 많이 알지 못하지만 몇 년 전에 DC Share에서 거대한 파일을 가짜로 작성하기 위해 작성한 C 코드가 있습니다.

#include < stdio.h >
#include < stdlib.h >

int main() {
    int i;
    FILE *fp;

    fp=fopen("bigfakefile.txt","w");

    for(i=0;i<(1024*1024);i++) {
        fseek(fp,(1024*1024),SEEK_CUR);
        fprintf(fp,"C");
    }
}

C에는 더 나은 방법이 있어야합니다. 또한 파일을 닫아야합니다. 한 번에 1 문자 씩 백만 쓰기 반복하기
ACV

10

"yes"명령을 사용할 수도 있습니다. 구문은 매우 간단합니다.

#yes >> myfile

이것을 중지하려면 "Ctrl + C"를 누르십시오. 그렇지 않으면 사용 가능한 공간이 모두 소모됩니다.

이 파일을 정리하려면 다음을 실행하십시오.

#>myfile

이 파일을 정리합니다.


7

나는 당신이 dd보다 훨씬 빠를 것이라고 생각하지 않습니다. 병목 현상은 디스크입니다. 수백 GB의 데이터를 쓰는 데는 시간이 많이 걸립니다.

그러나 다음은 응용 프로그램에서 작동 할 수있는 가능성입니다. 파일의 내용에 신경 쓰지 않는다면, 내용이 프로그램의 동적 출력 인 "가상"파일을 만드는 것은 어떻습니까? 파일을 open ()하는 대신 popen ()을 사용하여 외부 프로그램에 대한 파이프를 엽니 다. 외부 프로그램은 필요할 때마다 데이터를 생성합니다. 파이프가 열리면 파이프를 연 프로그램이 fseek (), rewind () 등이 될 수 있다는 점에서 일반 파일처럼 작동합니다. 닫을 때 pclose () 대신 close ()를 사용해야합니다. 파이프로 완성되었습니다.

응용 프로그램에서 파일이 특정 크기 여야하는 경우 "파일"의 위치를 ​​추적하고 "종료"에 도달하면 eof를 보내는 것은 외부 프로그램에 달려 있습니다.


4

한 가지 접근 방식 : 관련없는 응용 프로그램이 충돌하는 방식으로 파일을 사용하지 않도록하려면 특정 디렉토리에 다양한 크기의 파일 풀을 만든 다음 필요할 때 해당 파일에 대한 링크를 만드십시오.

예를 들어 다음과 같은 파일 풀이 있습니다.

  • / home / bigfiles / 512M-A
  • / home / bigfiles / 512M-B
  • / home / bigfiles / 1024M-A
  • / home / bigfiles / 1024M-B

그런 다음 / home / oracle / logfile이라는 1G 파일이 필요한 응용 프로그램이있는 경우 "ln /home/bigfiles/1024M-A /home/oracle/logfile "를 .

별도의 파일 시스템에있는 경우 심볼릭 링크를 사용해야합니다.

A / B / etc 파일을 사용하여 관련없는 응용 프로그램간에 충돌이 발생하지 않도록 할 수 있습니다.

링크 작업은 최대한 빨리 이루어집니다.


작은 수영장이나 큰 수영장을 가질 수 있습니다. 어쨌든 질문자가 요청한 것이므로 적어도 하나 이상의 파일이 필요했습니다. 풀이 하나의 파일로 구성되어 있으면 아무것도 잃지 않습니다. 디스크의 버킷로드가 있고 저렴한 가격으로 제공 해야하는 경우 문제가 없습니다.
paxdiablo 2013

3

GPL mkfile은 dd 주위의 (ba) sh 스크립트 래퍼입니다. BSD의 mkfile은 0이 아닌 버퍼를 memets하고 반복적으로 씁니다. 나는 전자가 dd를 능가하는 것을 기대하지 않을 것입니다. 후자는 읽기를 생략하기 때문에 약간 dd if = / dev / zero로 끝날 수 있지만, 훨씬 더 나은 것은 스파 스 파일을 만드는 것입니다.

실제로 데이터를 쓰지 않고 파일에 공간을 할당하는 시스템 호출이없는 경우 (그리고 Linux 및 BSD에는 아마도 Solaris도 부족) ftrunc (2) / truncate (1)를 사용하여 파일을 확장하면 성능이 약간 향상 될 수 있습니다 원하는 크기로 파일을 메모리에 mmap 한 다음 모든 디스크 블록의 첫 바이트에 0이 아닌 데이터를 씁니다 (fgetconf를 사용하여 디스크 블록 크기 찾기).


4
BSD와 Linux는 실제로 오류가 있습니다 (편집 : POSIX로 널리 사용 가능함).
Tobu


3

이것은 다음 제약 조건으로 내가 할 수있는 가장 빠릅니다 ( 빠르지 않습니다 ).

  • 큰 파일의 목표는 디스크를 채우는 것이므로 압축 할 수 없습니다.
  • ext3 파일 시스템 사용 ( fallocate불가)

이것은 그것의 요지입니다 ...

// include stdlib.h, stdio.h, and stdint.h
int32_t buf[256]; // Block size.
for (int i = 0; i < 256; ++i)
{
    buf[i] = rand(); // random to be non-compressible.
}
FILE* file = fopen("/file/on/your/system", "wb");
int blocksToWrite = 1024 * 1024; // 1 GB
for (int i = 0; i < blocksToWrite; ++i)
{
   fwrite(buf, sizeof(int32_t), 256, file);
}

우리의 경우 이것은 임베디드 리눅스 시스템을위한 것이며 이것은 잘 작동하지만 더 빠른 것을 선호합니다.

참고로이 명령 dd if=/dev/urandom of=outputfile bs=1024 count = XX은 사용할 수 없을 정도로 느 렸습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.