In danh sách tệp lưu trữ ngay lập tức (không giải nén toàn bộ kho lưu trữ)


10

Một vấn đề với .tar.gztài liệu lưu trữ là, khi tôi cố gắng liệt kê nội dung của một kho lưu trữ, máy tính thực sự giải nén nó, sẽ mất một thời gian rất dài nếu tệp lớn.

Định dạng file khác như .7z, .rar, .zipkhông có vấn đề này. Liệt kê nội dung của họ chỉ mất một lúc.

Theo ý kiến ​​ngây thơ của tôi, đây là một nhược điểm rất lớn của .tar.gzđịnh dạng lưu trữ.

Vì vậy, tôi thực sự có 2 câu hỏi:

  1. Tại sao mọi người sử dụng .tar.gzrất nhiều, mặc dù nhược điểm này?
  2. Tôi có những lựa chọn nào (ý tôi là phần mềm hoặc công cụ khác) nếu tôi muốn khả năng "liệt kê nội dung tức thời"?

Bản sao có thể có của [ superuser.com/questions/565883/ .
agc

Gunzip nó đầu tiên?
Jeff Schaller

Câu trả lời:


18

Điều quan trọng là phải hiểu rằng có một sự đánh đổi ở đây.

tarcó nghĩa là băng lưu trữ . Trên một băng, bạn chủ yếu đọc và viết tuần tự. Băng ngày nay hiếm khi được sử dụng, nhưng tarvẫn được sử dụng cho khả năng đọc và ghi dữ liệu của nó dưới dạng luồng.

Bạn có thể làm:

tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'

Bạn không thể làm điều đó với ziphoặc tương tự.

Bạn thậm chí không thể liệt kê nội dung của một zipkho lưu trữ mà không lưu trữ cục bộ trong một tệp có thể tìm kiếm trước tiên. Suy nghĩ như:

curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin

sẽ không làm việc

Để đạt được việc đọc nhanh nội dung đó, ziphoặc tương tự cần phải xây dựng một chỉ mục. Chỉ mục đó có thể được lưu trữ ở phần đầu của tệp (trong trường hợp đó chỉ có thể được ghi vào các tệp thông thường, không phải luồng) hoặc ở cuối, điều đó có nghĩa là người lưu trữ cần phải nhớ tất cả các thành viên lưu trữ trước khi in cuối và có nghĩa là một kho lưu trữ bị cắt ngắn có thể không thể phục hồi.

Điều đó cũng có nghĩa là các thành viên lưu trữ cần phải được nén riêng lẻ, điều đó có nghĩa là tỷ lệ nén thấp hơn nhiều, đặc biệt là nếu có nhiều tệp nhỏ.

Một nhược điểm khác với các định dạng như ziplà lưu trữ được liên kết với nén, bạn không thể chọn thuật toán nén. Xem cách tarlưu trữ được sử dụng để nén với compress( tar.Z), sau đó gzip, sau đó bzip2, xzkhi các thuật toán nén hiệu suất mới được phát minh. Mã hóa cũng vậy. Ai sẽ tin tưởng zipmã hóa ngày nay?

Bây giờ, vấn đề với tar.gztài liệu lưu trữ không nhiều đến mức bạn cần giải nén chúng. Việc giải nén thường nhanh hơn đọc hết đĩa (có thể bạn sẽ thấy rằng việc liệt kê nội dung của kho lưu trữ tgz lớn sẽ nhanh hơn khi liệt kê cùng một tệp không bị nén khi không lưu vào bộ nhớ), nhưng bạn cần đọc toàn bộ kho lưu trữ.

Không thể đọc chỉ mục một cách nhanh chóng không thực sự là một vấn đề. Nếu bạn thấy trước cần phải đọc nội dung bảng của một kho lưu trữ thường xuyên, bạn chỉ có thể lưu trữ danh sách đó trong một tệp riêng biệt. Chẳng hạn, tại thời điểm tạo, bạn có thể làm:

tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz

Một vấn đề lớn hơn IMO là do khía cạnh tuần tự của kho lưu trữ, bạn không thể trích xuất các tệp riêng lẻ mà không đọc toàn bộ phần đầu của kho lưu trữ dẫn đến nó. IOW, bạn không thể đọc ngẫu nhiên trong kho lưu trữ.

Bây giờ, đối với các tệp có thể tìm kiếm, nó không phải theo cách đó.

Nếu bạn nén toàn bộ tarkho lưu trữ của mình gzip, nó nén toàn bộ, thuật toán nén sử dụng dữ liệu nhìn thấy lúc đầu để nén, do đó bạn phải bắt đầu từ đầu để giải nén.

Nhưng xzđịnh dạng có thể được cấu hình để nén dữ liệu theo từng phần riêng biệt (đủ lớn để quá trình nén có hiệu quả), điều đó có nghĩa là miễn là bạn giữ một chỉ mục ở cuối các đoạn được nén đó, đối với các tệp có thể tìm kiếm, bạn truy cập vào dữ liệu không nén ngẫu nhiên (ít nhất là trong khối).

pixz(song song xz) sử dụng khả năng đó khi nén tartài liệu lưu trữ để thêm chỉ mục bắt đầu của từng thành viên của kho lưu trữ ở cuối xztệp.

Vì vậy, đối với các tệp có thể tìm kiếm, bạn không chỉ có thể nhận được danh sách nội dung của kho lưu trữ tar ngay lập tức (không có siêu dữ liệu) nếu chúng đã được nén bằng pixz:

pixz -l file.tar.xz

Nhưng bạn cũng có thể trích xuất các yếu tố riêng lẻ mà không cần phải đọc toàn bộ kho lưu trữ:

pixz -x archive/member.txt < file.tar.xz | tar xpf -

Bây giờ, về lý do tại sao những thứ như 7zhoặc ziphiếm khi được sử dụng trên Unix chủ yếu là vì chúng không thể lưu trữ các tệp Unix. Chúng đã được thiết kế cho các hệ điều hành khác. Bạn không thể thực hiện sao lưu dữ liệu trung thực bằng cách sử dụng dữ liệu đó. Họ không thể lưu trữ siêu dữ liệu như chủ sở hữu (id và tên), quyền, họ không thể lưu trữ liên kết tượng trưng, ​​thiết bị, fifos ..., họ không thể lưu trữ thông tin về các liên kết cứng và thông tin siêu dữ liệu khác như thuộc tính mở rộng hoặc ACL.

Một số trong số họ thậm chí không thể lưu trữ các thành viên có tên tùy ý (một số sẽ bị nghẹt lại dấu gạch chéo ngược hoặc dòng mới hoặc dấu hai chấm hoặc tên tệp không phải mã ascii) (một số tarđịnh dạng cũng có những hạn chế).

Không bao giờ giải nén tệp tgz / tar.xz vào đĩa!

Trong trường hợp không rõ ràng, người ta không sử dụng tgzhoặc tar.bz2, tar.xz... lưu trữ dưới dạng:

unxz file.tar.xz
tar tvf file.tar
xz file.tar

Nếu bạn có một .tartệp không nén nằm trên hệ thống tệp của mình, thì đó là bạn đã làm sai điều gì đó.

Toàn bộ điểm của những xz/ bzip2/ gziplà máy nén dòng là chúng có thể được sử dụng khi đang bay, trong các đường ống như trong

unxz < file.tar.xz | tar tvf -

Mặc dù các tartriển khai hiện đại biết cách tự gọi unxz/ gunzip/ bzip2, vì vậy:

tar tvf file.tar.xz

nhìn chung cũng sẽ hoạt động (và một lần nữa giải nén dữ liệu một cách nhanh chóng và không lưu trữ phiên bản không nén của kho lưu trữ trên đĩa).

Thí dụ

Đây là một cây nguồn Linux được nén với nhiều định dạng khác nhau.

$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.zip
 97038336 linux-4.6.7z
 89468928 linux-4.6.tar.xz

Đầu tiên, như đã lưu ý ở trên, 7z và zip hơi khác nhau vì chúng không thể lưu trữ một vài liên kết tượng trưng trong đó và thiếu hầu hết các siêu dữ liệu.

Bây giờ một vài thời gian để liệt kê nội dung sau khi đã xóa bộ đệm hệ thống:

$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null  0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null  8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.zip > /dev/null
unzip -v linux-4.6.zip > /dev/null  0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null  0.51s user 0.15s system 89% cpu 0.739 total

Bạn sẽ nhận thấy việc liệt kê tar.xztệp nhanh hơn tệp .tarthậm chí trên PC 7 tuổi này vì việc đọc thêm megabyte từ đĩa mất nhiều thời gian hơn đọc và giải nén tệp nhỏ hơn.

Sau đó, OK, liệt kê các tài liệu lưu trữ với 7z hoặc zip thì nhanh hơn nhưng đó không phải là vấn đề như tôi đã nói, nó dễ dàng được xử lý bằng cách lưu trữ danh sách tệp cùng với kho lưu trữ:

$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null  0.05s user 0.00s system 99% cpu 0.051 total

Thậm chí nhanh hơn 7z hoặc zip ngay cả sau khi thả cache. Bạn cũng sẽ nhận thấy rằng kích thước tích lũy của kho lưu trữ và chỉ mục của nó vẫn nhỏ hơn lưu trữ zip hoặc 7z.

Hoặc sử dụng pixzđịnh dạng được lập chỉ mục:

$ xzcat linux-4.6.tar.xz | pixz -9  > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null  0.04s user 0.01s system 57% cpu 0.087 total

Bây giờ, để trích xuất các phần tử riêng lẻ của kho lưu trữ, trường hợp xấu nhất cho kho lưu trữ tar là khi truy cập vào phần tử cuối cùng:

$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root      5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
    257     638    5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c  7.27s user 1.13s system 115% cpu 7.279 total
wc  0.00s user 0.00s system 0% cpu 7.279 total

Điều đó khá tệ vì nó cần phải đọc (và giải nén) toàn bộ kho lưu trữ. So sánh với:

$ time unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c | wc
    257     638    5976
unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c  0.02s user 0.01s system 19% cpu 0.119 total
wc  0.00s user 0.00s system 1% cpu 0.119 total

Phiên bản 7z của tôi dường như không thể truy cập ngẫu nhiên, vì vậy nó dường như còn tồi tệ hơn tar.xz:

$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
    257     638    5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null  7.28s user 0.12s system 89% cpu 8.300 total
wc  0.00s user 0.00s system 0% cpu 8.299 total

Bây giờ vì chúng tôi đã pixztạo một cái từ trước đó:

$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c  | tar xOf - | wc
    257     638    5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz  1.37s user 0.06s system 84% cpu 1.687 total
tar xOf -  0.00s user 0.01s system 0% cpu 1.693 total
wc  0.00s user 0.00s system 0% cpu 1.688 total

Nó nhanh hơn nhưng vẫn tương đối chậm vì kho lưu trữ chứa một vài khối lớn:

$ pixz -tl linux-4.6.tar.pixz
 17648865 / 134217728
 15407945 / 134217728
 18275381 / 134217728
 19674475 / 134217728
 18493914 / 129333248
   336945 /   2958887

Vì vậy, pixzvẫn cần phải đọc và giải nén một khối dữ liệu lớn (tối đa a) ~ 19MB.

Chúng tôi có thể thực hiện truy cập ngẫu nhiên nhanh hơn bằng cách lưu trữ các khối nhỏ hơn (và hy sinh một chút dung lượng đĩa):

$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c  | tar xOf - | wc
    257     638    5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2  0.17s user 0.02s system 98% cpu 0.189 total
tar xOf -  0.00s user 0.00s system 1% cpu 0.188 total
wc  0.00s user 0.00s system 0% cpu 0.187 total

"Không thể đọc chỉ mục nhanh chóng không thực sự là một vấn đề." Ngược lại, đó là một công cụ chặn hiển thị khi không có đủ không gian hoặc thời gian để giải nén tệp. Đề xuất: 's / Không / Đôi khi không /'
agc

1
@agc, xem chỉnh sửa với một vài phần bổ sung. Hy vọng nó làm rõ nó. Bạn chắc chắn không cần thêm dung lượng đĩa để liệt kê nội dung của kho lưu trữ.
Stéphane Chazelas

1
Xin vui lòng tha thứ cho tôi SC, các bổ sung của bạn được thực hiện tốt, (đặc biệt là về dung lượng đĩa và danh sách lưu trữ), nhưng tôi chủ yếu có nghĩa là một gợi ý hoặc bao gồm "hoặc" ở đây: "không đủ không gian hoặc thời gian" - tức là bộ bao gồm cả hai , cái này hay cái kia Đôi khi các tình huống bắt người dùng không chuẩn bị, và không có sự chuẩn bị trước mà bạn mô tả, một việc lớn .tar.gzcó thể mất quá nhiều thời gian. Đặc biệt nếu phương tiện chậm. Sau đó, định dạng của một kho lưu trữ trở thành sự khác biệt giữa không thể và thực tế.
agc

@ StéphaneChazelas: câu trả lời của bạn rất hay và toàn diện, nhưng tôi nghĩ bạn nên chỉnh sửa phần về pixz - có vẻ như dự án hiếm khi được duy trì và có nhiều vấn đề, vì vậy tốt hơn tôi không nên sử dụng để sao lưu dữ liệu quan trọng ý kiến.
Tối đa

3
  1. Tại sao mọi người sử dụng nó rất nhiều mặc dù nhược điểm này?

Quản trị viên doanh nghiệp và học thuật thường được chú ý nhiều hơn khi mọi thứ bị phá vỡ, được đánh giá cao hơn khi mọi thứ hoạt động hiệu quả. Những môi trường như vậy gây sợ hãi cho thử nghiệm, và khinh miệt cho sự mới lạ .

  1. Tôi có lựa chọn nào (ý tôi là phần mềm / công cụ khác) nếu tôi muốn khả năng "liệt kê nội dung tức thời"?

dar ( D isk Ar chiver) có một loạt cáctính năng giống như tar , cộng với các cải tiến như truy cập ngẫu nhiên nhanh chóng cho lưu trữ nén, lập danh mục AKA, lập chỉ mục AKA, "liệt kê nội dung tức thời" của AKA ...

Xem thêm: Định dạng nén với sự hỗ trợ tốt để truy cập ngẫu nhiên trong kho lưu trữ?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.