Sort

GNU sort –compress-program 只壓縮第一個臨時的

  • September 20, 2018

我正在對大文件(>100Go)進行排序,為了減少磁碟寫入所花費的時間,我正在嘗試使用 GNU sort 的--compress-program參數。(相關:如何對大文件進行排序?

但是,在某些情況下,似乎只有第一個臨時文件被壓縮。我想知道為什麼,以及我可以做些什麼來壓縮所有臨時人員。

我在用:

  • sort (GNU coreutils) 8.25
  • lzop 1.03/LZO library 2.09

重現問題的步驟:

您將需要 ~15Go 可用空間,~10Go ram,一些時間

首先,使用以下 C 程式碼創建一個 10Go 文件:

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

int main(void) {
   unsigned long n;
   unsigned char i;
   srand(42);
   for(n = 0; n < 1000000000; n++) {
       for(i = 0; i < 3; i++) {
           printf("%03d", rand() % 1000);
       }
       printf("\n");
   }
   fflush(stdout);
   return 0;
}

並執行它:

$ gcc -Wall -O3 -o generate generate.c
$ ./generate > test.input  # takes a few minutes
$ head -n 4 test.input
166740881
241012758
021940535
743874143

然後,開始排序過程:

$ LC_ALL=C sort -T . -S 9G --compress-program=lzop test.input -o test.output

一段時間後,暫停該程序,並列出在同一文件夾中創建的臨時文件(由於-T .):

$ ls -s sort*
890308 sortc1JZsR
890308 sorte7O878
378136 sortrK37RZ
$ file sort*
sortc1JZsR: ASCII text
sorte7O878: ASCII text
sortrK37RZ: lzop compressed data - version 1.030, LZO1X-1, os: Unix

似乎只有sortrK37RZ(第一個臨時創建的)被壓縮了。

$$ Edit $$在存在問題時,使用set to執行相同sort的命令很好(即所有臨時文件都被壓縮)。-S``7G``8G $$ Edit $$lzop 不要求其他臨時

我嘗試並使用以下腳本作為包裝器lzop

#!/bin/bash
set -e
echo "$$: start at $(date)" >> log
lzop $@
echo "$$: end at $(date)" >> log

這是log文件的內容,當幾個臨時文件寫入磁碟時:

11109: start at Sun Apr 10 22:56:51 CEST 2016
11109: end at Sun Apr 10 22:57:17 CEST 2016

所以我的猜測是根本沒有呼叫壓縮程序。

這裡沒有轉載?

$ shuf -i1-10000000 > t.in
$ sort -S50M -T. t.in --compress-program=lzop  # ^z
$ file sort* | tee >(wc -l) > >(grep -v lzop)
7
$ fg   # ^c
$ sort --version | head -n1
sort (GNU coreutils) 8.25

我猜這個問題是由於大記憶體大小導致無法 fork() 壓縮過程,然後回退到標準寫入。IE sort(1) 在理想情況下使用 fork()/exec() 應該使用 posix_spawn() 來更有效地分叉壓縮過程。現在 fork() 是 CoW,但是為如此大的流程準備相關的會計結構仍然存在成本。在 sort(1) 的未來版本中,我們將使用 posix_spawn() 來避免這種成本(從 2.23 版開始,glibc 剛剛獲得了 posix_spawn() 的可用實現)。

與此同時,我建議使用小得多的 -S。也許-S1G 及以下。

引用自:https://unix.stackexchange.com/questions/275501