Hệ thống tệp chỉ ghi ảo để lưu trữ tệp trong kho lưu trữ


8

Tôi có một quá trình song song lúng túng tạo ra một lượng lớn các tệp gần như (nhưng không hoàn toàn). Có cách nào để lưu trữ các tệp "nhanh chóng" để dữ liệu không tiêu tốn nhiều dung lượng hơn mức cần thiết không?

Quá trình tự chấp nhận các tham số dòng lệnh và in tên của từng tệp được tạo ra thiết bị xuất chuẩn. Tôi đang gọi nó với nhiệm parallel --gnuvụ phân phối đầu vào (xuất phát từ quy trình khác) và thu thập đầu ra:

arg_generating_process | parallel --gnu my_process | magic_otf_compressor

VÍ DỤ SIMPLE cho phần đầu tiên của đường ống trong bash:

for ((f = 0; $f < 100000; f++)); do touch $f; echo $f; done

Làm thế nào có thể magic_otf_compressortrông như thế nào? Bạn nên coi mỗi dòng đầu vào là tên tệp, sao chép từng tệp vào .tarkho lưu trữ nén (cùng một tệp lưu trữ cho tất cả các tệp được xử lý!) Và sau đó xóa nó. (Trên thực tế, nó là đủ để in tên của từng tệp được xử lý, một tệp khác | parallel --gnu rmcó thể đảm nhiệm việc xóa các tệp.)

Có công cụ nào như vậy không? Tôi không xem xét việc nén từng tệp riêng lẻ, điều này sẽ lãng phí quá nhiều dung lượng. Tôi đã xem xét archivemount(sẽ giữ cho hệ thống tệp trong bộ nhớ -> không thể, các tệp của tôi quá lớn và quá nhiều) và avfs(không thể làm cho nó hoạt động cùng với FUSE). Tôi đã bỏ lỡ những gì?

Bản thân tôi chỉ cách một bước để hack một công cụ như vậy, nhưng ai đó phải làm nó trước đây ...

EDIT : Về cơ bản, tôi nghĩ rằng tôi đang tìm kiếm một stdin front-end cho libtar(trái ngược với front-end dòng lệnh tarđọc các đối số từ, tốt, dòng lệnh).


Bạn đã xem xét việc viết các tập tin trong một định dạng có nén riêng? Ví dụ, hdf5 có thể được nén khi chúng được ghi bằng nén gzip hoặc szip. Hdf5 cũng hỗ trợ MPI để nó hoạt động tốt với những vấn đề song song đáng xấu hổ đó.
casey

2
Nếu bạn muốn nén và sao chép, zfs xuất hiện trong tâm trí.
Stéphane Chazelas

@casey: Đó là HTML, nhưng tôi cho rằng tôi có thể sử dụng bộ chứa HDF5.? Chưa xem xét điều này.
krlmlr

@StephaneChazelas: Điều này có thể được thực hiện trong vùng người dùng không?
krlmlr

Câu trả lời:


1

Có vẻ như tarmuốn biết tất cả các tên tập tin trả trước. Vì vậy, nó là ít trên đường bay và nhiều hơn sau khi bay. cpiodường như không có vấn đề đó:

| cpio -vo 2>&1 > >(gzip > /tmp/arc.cpio.gz) | parallel rm

Cảm ơn. Vì vậy, ngay cả RTFM là không đủ ;-) Tôi thậm chí đã xem tarmã của mình để thấy rằng có một hàm trả về tên tệp tiếp theo sẽ được xử lý, khiến tôi đọc lại tài liệu. - Vì vậy, stdoutđược hướng đến gzipquá trình thông qua thay thế quá trình, và stderrđược chuyển hướng đến stdoutđược xử lý bởi bước tiếp theo trong đường ống?
krlmlr

Vâng Cấu trúc >> () không hoạt động trong tất cả các hệ vỏ, nhưng nó hoạt động trong Bash.
Ole Tange

Tôi có thể xác nhận rằng tarđọc danh sách tệp trước, bằng cách sử dụng ví dụ đơn giản mà tôi đã thêm vào câu hỏi của mình. Tuy nhiên, đọc lại tarmã nguồn của tôi , có vẻ như tôi nên đọc danh sách các tệp "đang hoạt động" nếu không tạo ra một kho lưu trữ gia tăng. Thật không may, tôi có lỗi biên dịch tartừ nguồn ... :-(
krlmlr

Tôi đã không tìm thấy một cách để ngăn chặn dòng cuối cùng trong đầu ra cpio, ngoài grep -v 'blocks$'. ( head -n -1sử dụng bộ đệm rất lớn ...) Làm cho giải pháp này có một chút hack, nhưng đừng
bận

@krlmlr đó là số lẻ: Tôi head -n -1chỉ sử dụng 16 MB khi chạy trên một vài GB dữ liệu. Bạn luôn có thể sử dụng perl: perl -ne 'print $ last; $ last = $ _'
Ole Tange

7

Một trường hợp kinh điển của RTFM (tất cả là vậy!) . Các -Ttùy chọn để GNU tarsẽ đọc các tập tin được lưu trữ từ tập tin khác (trong trường hợp của tôi, /dev/stdinbạn cũng có thể sử dụng -), và thậm chí có một --remove-fileslựa chọn:

alias magic_otf_compressor='tar --create -T - --remove-files -O | pixz'

(sử dụng phiên bản song song xzđể nén, nhưng bạn có thể sử dụng máy nén ưa thích của mình thay thế). Được sử dụng như:

arg_generating_process |
  parallel --gnu my_process |
  magic_otf_compressor > file.tar.xz

EDIT : Như Ole chỉ ra, tardường như đọc toàn bộ danh sách các tệp với -Ttùy chọn vì một số lý do. Các thử nghiệm sau đây xác nhận điều này:

for ((f = 0; $f < 1000; f++)); do
    touch $f; echo $f;
done | tar -c -f otf.tar -T - -v

Có một độ trễ một giây trên hệ thống của tôi trước khi tất cả các tệp được in cùng một lúc; ngược lại, nếu tarlệnh được thay thế bởi cat, tất cả các tệp được in khi chúng được tạo. Tôi đã gửi một yêu cầu hỗ trợ với người dân tar, hãy xem.

EDIT ^ 2 : Gần đây nhất tartừ nguồn sửa lỗi này. Nó chưa có trong Ubuntu 13.10, nhưng có thể được bao gồm trong 14.04.


1

Bằng cách nào đó, điều này dường như không phải là một công việc tốt cho một máy nén rắn (lưu trữ dựa trên băng + nén). Chèn từng tệp một trông giống như một công việc cho ziphoặc một số định dạng khác cho phép truy cập tệp ngẫu nhiên trong kho lưu trữ và chèn tăng dần.

Thực tế là các tệp tương tự sẽ không giúp được gì nhiều trong cả hai trường hợp. Trong zip, các tệp được nén riêng và trong máy nén rắn, thường có một cửa sổ trong đó quá trình nén diễn ra.

Nếu các tệp dựa trên văn bản, bạn có thể lưu trữ khác so với một tệp tham chiếu. Đối với nhị phân, nó khó hơn một chút nhưng có thể được thực hiện.

Cũng có một cách chính thức (không chỉ ghi, nhưng hệ thống tập tin thích hợp). Ví dụ, hệ thống tập tin ZFS và BTRFS cung cấp nén trong suốt. Bạn cũng có thể sử dụng http://developer.berlios.de/projects/fusecompress này


Mỗi tập tin của tôi khoảng 100k. Sẽ không đủ để cho phép máy nén sử dụng cửa sổ 1M chứ? xzdường như hoạt động với kích thước từ điển mặc định là 8M (ở mức nén mặc định -6), có vẻ như rất nhiều cho trường hợp sử dụng của tôi. - Khác với tệp tham chiếu là tốt, nhưng yêu cầu phải xây dựng tệp tham chiếu trước. Một hệ thống tập tin nén sẽ phát hiện các tập tin có nội dung gần giống nhau?
krlmlr

Nén hệ thống tệp không nén trên các tệp (cũng không nén), nhưng btrfskhông sao chép khi ghi, vì vậy nếu bạn sao chép tệp và sửa đổi một phần của tệp, nó chỉ lưu các phần mà bạn đã thay đổi. Nếu bạn không tạo tệp theo cách này, có các công cụ chống trùng lặp tồn tại , nhưng btrfschưa phải là một hệ thống tệp trưởng thành và ổn định và sao chép thì đây là giai đoạn phát triển ban đầu. Nhưng bây giờ tôi nghĩ về nó, những gì về lessfs.com/wordpress
orion

Tôi nhận được tỷ lệ nén ấn tượng với máy nén rắn cho trường hợp sử dụng của mình, nhưng, như bạn đã phác thảo, tôi cho rằng kết quả sẽ tệ hơn nếu các tệp lớn hơn kích thước từ điển.
krlmlr

0

Điều này có vẻ không rõ ràng, nhưng tôi cá là squashfssẽ hoàn hảo cho việc này - và thậm chí nó còn được thực hiện trong kernel. Vì phiên bản 4.1 squashfscó thể xử lý các tệp giả như được chỉ định trên mksquashdòng lệnh hoặc thông qua tập lệnh shell và mksquashfssẽ tạo các tệp khi nó tạo tệp lưu trữ.

Nó có thể xử lý các đường ống - ví dụ, bạn có thể chụp một quá trình khác stdoutvào một kho lưu trữ bí đao có thể gắn kết - thậm chí là năm mươi - thật tuyệt vời. Trong trường hợp của bạn, nếu bạn có thể làm việc ra các hậu cần kịch bản của đường ống đầu ra của quá trình của bạn thông qua nó, bạn có thể quấn quá trình của bạn hoàn toàn trong mksquashfsvà gió lên với một kho lưu trữ duy nhất. Đây là một chút từ readmecách nó hoạt động và có thêm ở đây :

Mksquashfs 4.1 thêm hỗ trợ cho "tệp giả động" và thao tác sửa đổi. Các tệp giả động cho phép các tệp được tạo động khi Mksquashfs được chạy, nội dung của chúng là kết quả của việc chạy một lệnh hoặc một đoạn script shell. Hoạt động modifiy cho phép sửa đổi chế độ / uid / gid của một tệp hiện có trong hệ thống tệp nguồn.

Tạo các ví dụ về tệp động

Tạo một tập tin "dmesg" chứa đầu ra từ dmesg.

    dmesg f 444 root root dmesg

Tạo một tệp LIÊN QUAN chứa tên phát hành, ngày tháng, xây dựng máy chủ lưu trữ và số phiên bản tăng dần. Phiên bản tăng dần là hiệu ứng phụ của việc thực thi tập lệnh shell và đảm bảo mỗi khi Mksquashfs chạy một số phiên bản mới được sử dụng mà không yêu cầu bất kỳ tập lệnh shell nào khác.

    RELEASE f 444 root root \
        if [ ! -e /tmp/ver ]; then \
        echo 0 > /tmp/ver; \
        fi; \
        ver=`cat /tmp/ver`; \
            ver=$((ver +1)); \
            echo $ver > /tmp/ver; \
            echo -n "release x.x"; \
            echo "-dev #"$ver `date` "Build host" `hostname`

Sao chép 10K từ thiết bị / dev / sda1 vào đầu vào tệp. Thông thường Mksquashfs được cung cấp một thiết bị, fifo hoặc ổ cắm có tên sẽ đặt tệp đặc biệt đó trong hệ thống tệp Squashfs, điều này cho phép nhập vào các tệp đặc biệt này trong hệ thống tệp Squashfs.

        input f 444 root root dd if=/dev/sda1 bs=1024 count=10

Làm thế nào điều này sẽ làm việc trong cơ sở hạ tầng tôi vạch ra?
krlmlr

Bạn sẽ phải có được quy trình của mình để viết tên tệp của nó vào tập lệnh gọi của mksquash và để nó tiếp tục nối thêm chúng khi nó chạy. Hoặc thậm chí vào một tmpfs mà squash sẽ đọc và nén khi nó chạy. Hoặc, như một đề cập khác, thông qua một cái gì đó khác - gọi cpio giống như ví dụ dd ở trên, nhưng với cpio có thể sử dụng chức năng sao chép của nó. Trong mọi trường hợp - nó chắc chắn đọc, tạo và nén khi đang bay.
mikeerv

Nó sẽ nén trên các tập tin?
krlmlr

Nó nén đầu vào của nó trong một luồng - tất cả các nút, tất cả của nó. Tôi đã sử dụng nó với dd và nó khá tuyệt - Tôi luôn sử dụng kích thước khối 1MB và nén xz.
mikeerv

Điều này trông giống như một tùy chọn, nhưng từ câu trả lời của bạn, tôi không thấy cách tạo, giả sử, một kho lưu trữ squashfs với một thư mục testvà một tệp filetrong thư mục này. Bạn có thể vui lòng cung cấp một ví dụ ngắn gọn?
krlmlr
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.