【问题标题】:Fast Creation of a very large File in Debian Linux在 Debian Linux 中快速创建一个非常大的文件
【发布时间】:2013-05-27 10:58:28
【问题描述】:

我目前正在从事一个项目,该项目涉及将一个非常大的文件(大约 6GB)从一台 Linux 服务器传输到另一台。这些服务器在 Debian Squeeze 上运行。 为了实现我的主要目标,我最初将文件的名称和大小发送到目标机器,然后创建一个空文件来存储从源机器逐步接收的数据块。 我的问题是在我的服务器上创建一个 6GB 的文件需要很长时间。为了更清楚,我使用以下 C 例程来创建新文件:

void create_file(char* f_name, long long f_size) {
    char* bs, *of, *s_f_size, *count;
    if((pid = fork()) < 0) {
            perror("fork() failed.");
            return;
    }
    if(pid == 0) {
        //Call execl
        of = (char*) malloc(sizeof(char)*(strlen("of=") + strlen(f_name) + 1));
        s_f_size = (char*) malloc(sizeof(char)*32);
        sprintf(s_f_size, "%lld", file_size);
        count = (char*) malloc(sizeof(char)*(strlen("count=") + strlen(s_f_size) + 1));
        strcpy(of, "of=");
        strcat(of, f_name);
        strcpy(count, "count=");
        strcat(count, s_f_size);
        ret = execl("/bin/dd", "dd", "if=/dev/zero", of, "bs=1", count, (char*) 0);
        if(ret < 0) {
            perror("execl() failed");
            free(s_f_size);
            free(of);
            free(count);
            return;
        }else {
            free(s_f_size);
            free(of);
            free(count);
            return;
        }
    }else {
        status = 0;
        wpid = wait(&status);

    }
}

我使用 Linux dd 命令是因为我认为它是创建空 6GB 文件的最快方法。但是,大约需要 15 分钟才能完成。有没有办法更快地创建空文件?我做错了什么?

感谢您的宝贵时间。

真诚地, 尼克

【问题讨论】:

  • 如果直接从命令行运行dd,需要这么长时间吗?
  • 为什么要创建文件?如果您按顺序发送数据,只需继续附加到文件。
  • @Oli 我不能直接从命令行运行 dd,因为上面的例程是从我实现的 C 服务器调用的。
  • 即使它不是连续的,只要你收到一个块,你所要做的就是打开文件,寻找块的位置,然后把它写在那里。它会根据需要稀疏地增长,当你拥有所有的块时,它就不会再稀疏了。
  • 哦,bs=1 是您要求最差性能的方式,一次从用户空间向内核发送一个字节!

标签: c linux debian


【解决方案1】:

除了 Joachim Pileborg 的建议外,您还可以使用 posix_fallocate() 为您的文件预先分配空间。

【讨论】:

  • 我会记住这一点@Hasturkun。感谢您的宝贵帮助。我很感激。
【解决方案2】:

首先creat 文件,然后lseek 到想要的结尾,write 一个虚拟字节。创建任意大但sparse 文件的快速方法。


如果您不希望文件稀疏,则找出驱动器的块大小(可以在大多数 POSIX 平台上使用stat 找到)。创建该大小的缓冲区,并将其写入文件直到所需大小。

如果stat 结构没有st_blksize 成员,那么大多数文件系统的块大小为4 或8 kB。您可能可以使此缓冲区更大,但不能太大。实验和基准测试!

【讨论】:

  • Bu 不会预先预留磁盘空间,因为它是稀疏的。也许 OP 想要保留磁盘空间以避免在传输内容期间空间不足。
  • 为什么要专门创建而不打开系统调用?
  • @popanik 因为您提到了创建,所以打开文件进行创建是自然的系统调用。 open 带有正确的标志当然也可以。
  • 感谢您的帮助@JoachimPileborg。我将在我的系统中使用您的答案。非常感谢您快速准确的回复。
【解决方案3】:

如果您使用的是内核 v2.6.31+ 并且文件系统支持它,请考虑使用fallocate

fallocate -l 6GB hugefile

It 将块预分配给文件。

【讨论】:

  • 是的,但是它比 dd 快得多吗?
  • 是的。随着文件大小的增加,差异将更加显着。 time两人图。
  • 刚看到,速度还挺快的。非常感谢你们的帮助。我真的很感激。
【解决方案4】:

创建大文件需要很长时间,因为操作系统必须在文件系统上做很多事情。只有在文件稀疏的情况下才能跳过(请参阅 Joachim Pileborg 的答案)。稀疏文件是包含“漏洞”(零字节的大块)的文件。这样的文件不会使用很大的空间。预先创建这样的文件将很快生成正确大小的文件。

如果您想保留磁盘空间以避免在传输完成之前用完它,稀疏文件将无法做到。您必须在每个块中写入至少一个字节,然后才能避免稀疏文件的漏洞。我不确定这会比简单地将零转储到文件中直到它具有所需的大小(就像您已经做的那样)更快。

【讨论】:

  • 稀疏文件和预分配磁盘空间文件的底层区别是什么?除了在文件传输过程中磁盘空间不足的危险之外,我还会遇到使用稀疏文件和预分配文件之间的任何其他差异吗?
  • 我能想到的唯一其他区别是每个查看该稀疏文件的磁盘使用情况的人都会发现它并没有真正使用 6GB 空间。
  • 好吧,由于我正在开发的系统是一个原型,我并不关心(此时)。所以,我想我会选择稀疏文件解决方案。感谢您的帮助。
【解决方案5】:

我记得,我使用 open 系统调用来创建一个空文件。然后将数据转储到文件中。 在部分数据写入的情况下,继续寻找位置并从那里转储。如果文件存在,则使用该文件将数据覆盖到其中。

就性能而言,这种方法相当不错。

【讨论】:

    猜你喜欢
    • 2010-09-20
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多