我在具有 48GB 内存的服务器上使用 sort 命令对一个大文件进行排序(解压后101MB
大约 - 700MB
)。这是当时它唯一要做的繁重工作。但是我注意到 sort 创建了大量临时文件。这是否意味着它缺少 RAM 内存?
还是 sort 总是会创建文件?我可以通过-T
命令传递 RAM 中挂载的文件夹文件系统来加快排序过程吗?我试过了,但没有注意到速度明显加快,我想知道我是否构建了错误的测试,或者我只是没有正确理解发生了什么。
这是我发出的命令:
zcat file0.nq.gz | sort
大约 20 秒后,我得到了以下文件/tmp
nuoritoveri@nubis:/tmp[127]$ ls
sortecuGwN sorteKeowj sortGn7dCr sortkdk5Ws sortNb9Khh sortPGTQ6b sortQearCg sortvBB5eS sortZW2mWj
sort1UsQla sortEGauDb sortFMn7bW sortiUDJYd sortlaGUgo sortpEmGb5 sortPQUNQx sortqlb7jh sortxcjjuM
sortaVKeEN sortejgptJ sortgAJJ9l sortJRq2GB sortmQf888 sortpFfWdy sortpv9kO8 sortT52TVQ sortxq8r80
命令完成后,文件就会消失。我还检查了当我不使用管道,而只是对解压后的文件进行排序时会发生什么:
sort file0.nq
文件/tmp
也出现了,但速度不是那么快(可能是因为它必须自己读取文件)。
答案1
一般来说,“一直使用内存直到用完”是一个糟糕的策略,你可能会给其他用户带来麻烦,你最终可能会使用看起来像内存但性能特性更差的交换,或者(因为 Linux 默认过度使用内存)你可能最终被 OOM 杀手杀死。
当对大量数据进行排序时,一种常见的策略是“批量合并”,将数据拆分成批,在内存中排序并写入临时文件。然后有一个合并过程,读取这些批并将它们合并在一起。如果数据集非常大,可能会有多层合并。
我快速浏览了一下 sort 的代码https://sources.debian.org/src/coreutils/8.30-3/src/sort.c/
看起来排序决定使用的缓冲区大小取决于许多因素,包括 ulimit 值、可用内存、-S 参数(如果指定)以及输入文件的大小。
似乎在输入大小未知(例如来自管道的输入)、没有特定的内存压力并且没有指定特定的排序大小的情况下,排序使用由“INPUT_FILE_SIZE_GUESS”确定的缓冲区大小,根据注释,该缓冲区大约有 17 兆字节(请注意,所述缓冲区不仅存储原始行文本,因此可能不适合 17 兆字节的输入)。