D duplikasi Kecepatan Warp Sistem File Read -only yang canggih.
Sistem file read-only kompresi tinggi yang cepat untuk Linux dan Windows.
DwarFS adalah sistem file read-only dengan fokus pada pencapaian rasio kompresi yang sangat tinggi khususnya untuk data yang sangat berlebihan.
Ini mungkin kedengarannya tidak terlalu menarik, karena jika berlebihan, maka akan terkompresi dengan baik. Namun, saya menemukan bahwa sistem file terkompresi dan read-only lainnya tidak berfungsi dengan baik dalam memanfaatkan redundansi ini. Lihat di sini untuk perbandingan dengan sistem file terkompresi lainnya.
DwarFS juga tidak berkompromi pada kecepatan dan untuk kasus penggunaan saya, menurut saya DwarFS setara atau berkinerja lebih baik daripada SquashFS. Untuk kasus penggunaan utama saya, kompresi DwarFS jauh lebih baik daripada kompresi SquashFS , 6 kali lebih cepat untuk membangun sistem file , biasanya lebih cepat untuk mengakses file di DwarFS dan menggunakan lebih sedikit sumber daya CPU.
Untuk memberi Anda gambaran tentang kemampuan DwarFS, berikut perbandingan singkat DwarFS dan SquashFS pada kumpulan file video dengan ukuran total 39 GiB. Yang menarik adalah setiap file video unik memiliki dua file saudara dengan kumpulan aliran audio berbeda (ini adalah kasus penggunaan sebenarnya). Jadi, terdapat redundansi pada data video dan audio, namun karena streaming disisipkan dan blok identik biasanya berjauhan, sulit memanfaatkan redundansi tersebut untuk kompresi. SquashFS pada dasarnya gagal mengompresi data sumber sama sekali, sedangkan DwarFS mampu mengurangi ukurannya hampir sebanyak 3 kali lipat, yang mendekati nilai maksimum teoritis:
$ du -hs dwarfs-video-test
39G dwarfs-video-test
$ ls -lh dwarfs-video-test.*fs
-rw-r--r-- 1 mhx users 14G Jul 2 13:01 dwarfs-video-test.dwarfs
-rw-r--r-- 1 mhx users 39G Jul 12 09:41 dwarfs-video-test.squashfs
Selain itu, saat memasang gambar SquashFS dan melakukan uji throughput baca acak menggunakan fio-3.34, squashfuse
dan squashfuse_ll
menghasilkan kecepatan sekitar 230 MiB/s:
$ fio --readonly --rw=randread --name=randread --bs=64k --direct=1
--opendir=mnt --numjobs=4 --ioengine=libaio --iodepth=32
--group_reporting --runtime=60 --time_based
[...]
READ: bw=230MiB/s (241MB/s), 230MiB/s-230MiB/s (241MB/s-241MB/s), io=13.5GiB (14.5GB), run=60004-60004msec
Sebagai perbandingan, DwarFS berhasil mempertahankan kecepatan baca acak sebesar 20 GiB/s :
READ: bw=20.2GiB/s (21.7GB/s), 20.2GiB/s-20.2GiB/s (21.7GB/s-21.7GB/s), io=1212GiB (1301GB), run=60001-60001msec
Fitur khas DwarFS adalah:
Pengelompokan file berdasarkan kesamaan menggunakan fungsi hash kesamaan. Hal ini mempermudah eksploitasi redundansi melintasi batas file.
Analisis segmentasi di seluruh blok sistem file untuk mengurangi ukuran sistem file yang tidak terkompresi. Hal ini menghemat memori ketika menggunakan sistem file terkompresi dan dengan demikian berpotensi memungkinkan tingkat cache hit yang lebih tinggi karena lebih banyak data dapat disimpan dalam cache.
Kerangka kerja kategorisasi untuk mengkategorikan file atau bahkan fragmen file dan kemudian memproses masing-masing kategori secara berbeda. Misalnya, ini memungkinkan Anda tidak membuang waktu untuk mencoba mengompresi file yang tidak dapat dikompresi atau mengompresi data audio PCM menggunakan kompresi FLAC.
Implementasi yang sangat multi-thread. Baik alat pembuatan sistem file maupun driver FUSE mampu memanfaatkan banyak inti sistem Anda dengan baik.
Saya mulai mengerjakan DwarFS pada tahun 2013 dan kasus penggunaan utama serta motivasi utama saya adalah saya memiliki beberapa ratus versi Perl berbeda yang menghabiskan sekitar 30 gigabyte ruang disk, dan saya tidak mau menghabiskan lebih dari 10% hard disk saya. berkendara untuk menyimpannya saat saya membutuhkannya.
Sampai saat itu, saya telah menggunakan Cromfs untuk memerasnya ke ukuran yang bisa diatur. Namun, saya menjadi semakin jengkel dengan waktu yang dibutuhkan untuk membangun image sistem file dan, yang lebih buruk lagi, sering kali crash terjadi setelah sekitar satu jam atau lebih.
Saya jelas juga telah melihat SquashFS, tetapi tidak pernah mendekati tingkat kompresi Cromfs.
Ini saja tidak akan cukup untuk membuat saya menulis DwarFS, tetapi pada saat yang sama, saya cukup terobsesi dengan perkembangan terkini dan fitur standar C++ yang lebih baru dan sangat ingin proyek hobi C++ dapat dikerjakan. Selain itu, saya sudah lama ingin melakukan sesuatu dengan FUSE. Terakhir, saya telah memikirkan sedikit tentang masalah sistem file terkompresi dan memiliki beberapa ide yang pasti ingin saya coba.
Mayoritas kodenya ditulis pada tahun 2013, lalu saya melakukan beberapa pembersihan, perbaikan bug, dan pemfaktoran ulang sesekali, namun saya tidak pernah benar-benar mencapai kondisi di mana saya akan merasa senang melepaskannya. Terlalu canggung untuk membangun dengan ketergantungannya pada perpustakaan kebodohan Facebook (yang cukup mengagumkan) dan tidak memiliki dokumentasi apa pun.
Menggali proyek itu lagi tahun ini, segalanya tidak tampak suram seperti dulu. Kebodohan sekarang dibangun dengan CMake jadi saya menariknya sebagai submodul. Sebagian besar dependensi lain dapat dipenuhi dari paket-paket yang seharusnya tersedia secara luas. Dan saya juga telah menulis beberapa dokumen dasar.
DwarFS biasanya dibangun dengan baik dengan sedikit perubahan. Jika tidak, silakan ajukan masalah. Saya telah menyiapkan pekerjaan CI menggunakan image Docker untuk Ubuntu (22.04 dan 24.04), Fedora Rawhide, dan Arch yang dapat membantu menentukan rangkaian dependensi terkini. Perhatikan bahwa membangun dari tarball rilis memerlukan lebih sedikit ketergantungan daripada membangun dari repositori git, terutama alat ronn
serta Python dan modul mistletoe
Python tidak diperlukan saat membangun dari tarball rilis.
Ada beberapa hal yang perlu diperhatikan:
Ada kecenderungan untuk mencoba dan memisahkan perpustakaan kebodohan dan fbthrift yang disertakan sebagai submodul dan dibangun bersama dengan DwarFS. Meskipun saya setuju dengan sentimen tersebut, sayangnya itu adalah ide yang buruk. Selain fakta bahwa folly tidak membuat klaim apa pun tentang stabilitas ABI (yaitu Anda tidak bisa secara dinamis menghubungkan biner yang dibuat dengan satu versi folly dengan versi lain), bahkan tidak mungkin untuk menautkan dengan aman ke pustaka folly yang dibuat dengan kompilasi berbeda pilihan. Bahkan perbedaan kecil sekalipun, seperti versi standar C++, dapat menyebabkan kesalahan run-time. Lihat masalah ini untuk detailnya. Saat ini, bahkan tidak mungkin untuk menggunakan versi eksternal dari folly/fbthrift karena DwarFS sedang membangun subset minimal dari kedua perpustakaan; ini dibundel dalam perpustakaan dwarfs_common
dan digunakan secara ketat secara internal, yaitu tidak ada header kebodohan atau fbthrift yang diperlukan untuk dibangun di perpustakaan DwarFS.
Masalah serupa dapat muncul saat menggunakan GoogleTest versi yang diinstal sistem. GoogleTest sendiri merekomendasikan agar diunduh sebagai bagian dari build. Namun, Anda dapat menggunakan versi yang diinstal sistem dengan meneruskan -DPREFER_SYSTEM_GTEST=ON
ke panggilan cmake
. Gunakan dengan risiko Anda sendiri.
Untuk pustaka paket lainnya (yaitu fmt
, parallel-hashmap
, range-v3
), versi yang diinstal sistem akan digunakan selama memenuhi versi minimum yang diperlukan. Jika tidak, versi pilihan akan diambil selama pembuatan.
Setiap rilis memiliki binari yang dibuat sebelumnya dan ditautkan secara statis untuk Linux-x86_64
, Linux-aarch64
dan Windows-AMD64
yang tersedia untuk diunduh. Ini harus berjalan tanpa ketergantungan apa pun dan dapat berguna terutama pada distribusi lama di mana Anda tidak dapat dengan mudah membuat alat dari sumbernya.
Selain tarball biner, ada biner universal yang tersedia untuk setiap arsitektur. Biner universal ini berisi semua alat ( mkdwarfs
, dwarfsck
, dwarfsextract
dan driver dwarfs
FUSE) dalam satu executable. Eksekusi ini dikompresi menggunakan upx, sehingga ukurannya jauh lebih kecil dibandingkan gabungan masing-masing alat. Namun, ini juga berarti biner harus didekompresi setiap kali dijalankan, yang dapat menimbulkan overhead yang signifikan. Jika itu masalahnya, Anda dapat tetap menggunakan biner individual "klasik" atau Anda dapat mendekompresi biner universal, misalnya:
upx -d dwarfs-universal-0.7.0-Linux-aarch64
Biner universal dapat dijalankan melalui tautan simbolik yang diberi nama sesuai alat yang tepat. misalnya:
$ ln -s dwarfs-universal-0.7.0-Linux-aarch64 mkdwarfs
$ ./mkdwarfs --help
Ini juga berfungsi pada Windows jika sistem file mendukung tautan simbolis:
> mklink mkdwarfs.exe dwarfs-universal-0.7.0-Windows-AMD64.exe
> .mkdwarfs.exe --help
Alternatifnya, Anda dapat memilih alat dengan meneruskan --tool=<name>
sebagai argumen pertama pada baris perintah:
> .dwarfs-universal-0.7.0-Windows-AMD64.exe --tool=mkdwarfs --help
Perhatikan bahwa sama seperti biner Windows dwarfs.exe
, biner Windows universal bergantung pada winfsp-x64.dll
dari proyek WinFsp. Namun, untuk biner universal, DLL dimuat dengan lambat, sehingga Anda masih dapat menggunakan semua alat lain tanpa DLL. Lihat bagian Dukungan Windows untuk rincian lebih lanjut.
DwarFS menggunakan CMake sebagai alat pembuatan.
Ia menggunakan Boost dan Folly, meskipun Folly disertakan sebagai submodul karena sangat sedikit distribusi yang benar-benar menawarkan paket untuk itu. Folly sendiri memiliki sejumlah ketergantungan, jadi silakan periksa di sini untuk daftar terbaru.
Ia juga menggunakan Facebook Thrift, khususnya perpustakaan frozen
, untuk menyimpan metadata dalam format yang sangat hemat ruang, dapat dipetakan dalam memori, dan terdefinisi dengan baik. Ini juga disertakan sebagai submodul, dan kami hanya membangun kompiler dan perpustakaan yang sangat sedikit yang berisi cukup agar DwarFS dapat berfungsi.
Selain itu, DwarFS sebenarnya hanya bergantung pada FUSE3 dan sekumpulan pustaka kompresi yang sudah diandalkan oleh Folly (yaitu lz4, zstd, dan liblzma).
Ketergantungan pada googletest akan otomatis teratasi jika Anda membangun dengan pengujian.
Titik awal yang baik untuk sistem berbasis apt mungkin adalah:
$ apt install
gcc
g++
clang
git
ccache
ninja-build
cmake
make
bison
flex
fuse3
pkg-config
binutils-dev
libacl1-dev
libarchive-dev
libbenchmark-dev
libboost-chrono-dev
libboost-context-dev
libboost-filesystem-dev
libboost-iostreams-dev
libboost-program-options-dev
libboost-regex-dev
libboost-system-dev
libboost-thread-dev
libbrotli-dev
libevent-dev
libhowardhinnant-date-dev
libjemalloc-dev
libdouble-conversion-dev
libiberty-dev
liblz4-dev
liblzma-dev
libzstd-dev
libxxhash-dev
libmagic-dev
libparallel-hashmap-dev
librange-v3-dev
libssl-dev
libunwind-dev
libdwarf-dev
libelf-dev
libfmt-dev
libfuse3-dev
libgoogle-glog-dev
libutfcpp-dev
libflac++-dev
nlohmann-json3-dev
Perhatikan bahwa saat membuat dengan gcc
, tingkat pengoptimalan akan disetel ke -O2
bukan default CMake -O3
untuk versi rilis. Setidaknya dengan versi hingga gcc-10
, build -O3
lebih lambat hingga 70% dibandingkan build dengan -O2
.
Pertama, buka paket arsip rilis:
$ tar xvf dwarfs-x.y.z.tar.xz
$ cd dwarfs-x.y.z
Alternatifnya, Anda juga dapat mengkloning repositori git, namun perlu diingat bahwa repositori ini memiliki lebih banyak ketergantungan dan pembangunan kemungkinan akan memakan waktu lebih lama karena arsip rilis dikirimkan bersama sebagian besar file yang dihasilkan secara otomatis yang harus dihasilkan ketika membangun dari repositori:
$ git clone --recurse-submodules https://github.com/mhx/dwarfs
$ cd dwarfs
Setelah semua dependensi terinstal, Anda dapat membangun DwarFS menggunakan:
$ mkdir build
$ cd build
$ cmake .. -GNinja -DWITH_TESTS=ON
$ ninja
Anda kemudian dapat menjalankan tes dengan:
$ ctest -j
Semua biner menggunakan jemalloc sebagai pengalokasi memori secara default, karena biasanya menggunakan lebih sedikit memori sistem dibandingkan dengan pengalokasi glibc
atau tcmalloc
. Untuk menonaktifkan penggunaan jemalloc
, berikan -DUSE_JEMALLOC=0
pada baris perintah cmake
.
Dimungkinkan juga untuk membangun/menginstal perpustakaan, alat, dan driver FUSE DwarFS secara mandiri. Hal ini paling menarik ketika mengemas DwarFS. Perhatikan bahwa alat dan driver FUSE memerlukan perpustakaan yang sudah dibangun atau sudah diinstal. Untuk membangun perpustakaan saja, gunakan:
$ cmake .. -GNinja -DWITH_TESTS=ON -DWITH_LIBDWARFS=ON -DWITH_TOOLS=OFF -DWITH_FUSE_DRIVER=OFF
Setelah perpustakaan diuji dan diinstal, Anda dapat membuat alat (yaitu mkdwarfs
, dwarfsck
, dwarfsextract
) menggunakan:
$ cmake .. -GNinja -DWITH_TESTS=ON -DWITH_LIBDWARFS=OFF -DWITH_TOOLS=ON -DWITH_FUSE_DRIVER=OFF
Untuk membuat driver FUSE, gunakan:
$ cmake .. -GNinja -DWITH_TESTS=ON -DWITH_LIBDWARFS=OFF -DWITH_TOOLS=OFF -DWITH_FUSE_DRIVER=ON
Menginstalnya semudah:
$ sudo ninja install
Meskipun Anda tidak perlu menginstal alat untuk memainkannya.
Mencoba membangun biner yang terhubung secara statis sangat tidak disarankan dan tidak didukung secara resmi. Oleh karena itu, berikut ini cara menyiapkan lingkungan tempat Anda dapat membuat biner statis.
Ini telah diuji dengan ubuntu-22.04-live-server-amd64.iso
. Pertama, instal semua paket yang terdaftar sebagai dependensi di atas. Instal juga:
$ apt install ccache ninja libacl1-dev
ccache
dan ninja
bersifat opsional, tetapi membantu dengan kompilasi yang cepat.
Bergantung pada distribusi Anda, Anda perlu membuat dan menginstal versi statis beberapa perpustakaan, misalnya libarchive
dan libmagic
untuk Ubuntu:
$ wget https://github.com/libarchive/libarchive/releases/download/v3.6.2/libarchive-3.6.2.tar.xz
$ tar xf libarchive-3.6.2.tar.xz && cd libarchive-3.6.2
$ ./configure --prefix=/opt/static-libs --without-iconv --without-xml2 --without-expat
$ make && sudo make install
$ wget ftp://ftp.astron.com/pub/file/file-5.44.tar.gz
$ tar xf file-5.44.tar.gz && cd file-5.44
$ ./configure --prefix=/opt/static-libs --enable-static=yes --enable-shared=no
$ make && make install
Itu saja! Sekarang Anda dapat mencoba membuat binari statis untuk DwarFS:
$ git clone --recurse-submodules https://github.com/mhx/dwarfs
$ cd dwarfs && mkdir build && cd build
$ cmake .. -GNinja -DWITH_TESTS=ON -DSTATIC_BUILD_DO_NOT_USE=ON
-DSTATIC_BUILD_EXTRA_PREFIX=/opt/static-libs
$ ninja
$ ninja test
Silakan periksa halaman manual untuk mkdwarfs, dwarfs, dwarfsck, dan dwarfsextract. Anda juga dapat mengakses halaman manual menggunakan opsi --man
pada setiap biner, misalnya:
$ mkdwarfs --man
Halaman manual kurcaci juga menunjukkan contoh untuk menyiapkan DwarFS dengan overlayfs untuk membuat sistem file yang dapat ditulis dipasang di atas gambar DwarFS yang hanya bisa dibaca.
Deskripsi format sistem file DwarFS dapat ditemukan dalam format dwarfs.
Gambaran umum tingkat tinggi tentang operasi internal mkdwarfs
ditunjukkan dalam diagram urutan ini.
Menggunakan perpustakaan DwarFS seharusnya cukup mudah jika Anda menggunakan CMake untuk membangun proyek Anda. Untuk memulai dengan cepat, lihat contoh kode yang menggunakan perpustakaan untuk mencetak informasi tentang gambar DwarFS (seperti dwarfsck
) atau mengekstraknya (seperti dwarfsextract
).
Ada lima perpustakaan individu:
dwarfs_common
berisi kode umum yang dibutuhkan oleh semua perpustakaan lainnya. Antarmuka didefinisikan dalam dwarfs/
.
dwarfs_reader
berisi semua kode yang diperlukan untuk membaca data dari gambar DwarFS. Antarmuka didefinisikan dalam dwarfs/reader/
.
dwarfs_extractor
berisi kode yang diperlukan untuk mengekstrak gambar DwarFS menggunakan libarchive
. Antarmuka didefinisikan dalam dwarfs/utility/filesystem_extractor.h
.
dwarfs_writer
berisi kode yang diperlukan untuk membuat gambar DwarFS. Antarmuka didefinisikan dalam dwarfs/writer/
.
dwarfs_rewrite
berisi kode untuk menulis ulang gambar DwarFS. Antarmuka didefinisikan dalam dwarfs/utility/rewrite_filesystem.h
.
Header di subfolder internal
hanya dapat diakses pada waktu pembuatan dan tidak akan dipasang. Hal yang sama berlaku untuk subfolder tool
.
API pembaca dan ekstraktor harus cukup stabil. API penulis kemungkinan besar akan berubah. Namun perlu diperhatikan bahwa tidak ada jaminan terhadap stabilitas API sebelum proyek ini mencapai versi 1.0.0.
Dukungan untuk sistem operasi Windows saat ini masih bersifat eksperimental. Setelah bekerja secara eksklusif di dunia Unix selama dua dekade terakhir, pengalaman saya dengan pengembangan Windows agak terbatas dan saya berharap pasti ada bug dan sisi kasar dalam kode Windows.
Versi Windows dari driver sistem file DwarFS bergantung pada proyek WinFsp yang mengagumkan dan winfsp-x64.dll
-nya harus dapat ditemukan oleh driver dwarfs.exe
.
Alat-alat yang berbeda akan berperilaku hampir sama baik Anda menggunakannya di Linux atau Windows. Gambar sistem file dapat disalin antara Linux dan Windows dan gambar yang dibuat pada satu OS akan berfungsi dengan baik pada OS lainnya.
Namun ada beberapa hal yang perlu diperhatikan:
DwarFS mendukung hardlink dan symlink di Windows, sama seperti di Linux. Namun, membuat hardlink dan symlink tampaknya memerlukan hak istimewa admin di Windows, jadi jika Anda ingin, misalnya, mengekstrak gambar DwarFS yang berisi semacam tautan, Anda mungkin mengalami kesalahan jika Anda tidak memiliki hak istimewa yang tepat.
Karena masalah di WinFsp, symlink saat ini tidak dapat menunjuk ke luar sistem file yang dipasang. Selain itu, karena masalah lain di WinFsp, symlink dengan huruf drive akan muncul dengan jalur target yang rusak.
Driver DwarFS di Windows dengan benar melaporkan jumlah hardlink melalui API-nya, namun saat ini jumlah tersebut tidak disebarkan dengan benar ke lapisan sistem file Windows. Hal ini mungkin disebabkan oleh masalah di WinFsp.
Saat memasang image DwarFS di Windows, titik pemasangan tidak boleh ada. Berbeda dengan Linux yang titik mountnya harus benar-benar ada. Selain itu, dimungkinkan untuk memasang gambar DwarFS sebagai huruf drive, misalnya
dwarfs.exe gambar.dwarfs Z:
Aturan filter untuk mkdwarfs
selalu memerlukan pemisah jalur Unix, terlepas dari apakah itu berjalan di Windows atau Linux.
Membangun di Windows tidak terlalu rumit berkat vcpkg. Anda harus menginstal:
Visual Studio dan kompiler MSVC C/C++
Git
CMembuat
Ninja
WinFsp
WinFsp
diharapkan diinstal di C:Program Files (x86)WinFsp
; jika tidak, Anda harus menyetel WINFSP_PATH
saat menjalankan CMake melalui cmake/win.bat
.
Sekarang Anda perlu mengkloning vcpkg
dan dwarfs
:
> cd %HOMEPATH%
> mkdir git
> cd git
> git clone https://github.com/Microsoft/vcpkg.git
> git clone https://github.com/mhx/dwarfs
Kemudian, bootstrap vcpkg
:
> .vcpkgbootstrap-vcpkg.bat
Dan buat DwarFS:
> cd dwarfs
> mkdir build
> cd build
> ..cmakewin.bat
> ninja
Setelah selesai, Anda seharusnya dapat menjalankan pengujian. Atur CTEST_PARALLEL_LEVEL
sesuai dengan jumlah inti CPU di mesin Anda.
> set CTEST_PARALLEL_LEVEL=10
> ninja test
Pustaka dan alat DwarFS ( mkdwarfs
, dwarfsck
, dwarfsextract
) kini tersedia dari Homebrew:
$ brew install dwarfs
$ brew test dwarfs
Versi macOS dari driver sistem file DwarFS bergantung pada proyek macFUSE yang mengagumkan. Hingga formula ditambahkan, Anda harus membuat driver DwarFS FUSE secara manual.
Membangun macOS seharusnya relatif mudah:
Instal Homebrew
Gunakan Homebrew untuk menginstal dependensi yang diperlukan:
$ brew install cmake ninja macfuse brotli howard-hinnant-date double-conversion
fmt glog libarchive libevent flac openssl nlohmann-json pkg-config
range-v3 utf8cpp xxhash boost zstd
Saat menginstal macFUSE untuk pertama kalinya, Anda harus mengizinkan perangkat lunak secara eksplisit di System Preferences / Privacy & Security . Kemungkinan besar Anda harus melakukan boot ulang setelah ini.
Unduh tarball rilis dari halaman rilis dan ekstrak:
$ wget https://github.com/mhx/dwarfs/releases/download/v0.10.0/dwarfs-0.10.0.tar.xz
$ tar xf dwarfs-0.10.0.tar.xz
$ cmake --fresh -B dwarfs-build -S dwarfs-0.10.0 -GNinja -DWITH_TESTS=ON
$ cmake --build dwarfs-build
$ ctest --test-dir dwarfs-build -j
macfuse
dari brew install
dan menggunakan perintah berikut ini sebagai pengganti perintah cmake
pertama di atas: $ cmake --fresh -B dwarfs-build -S dwarfs-0.10.0 -GNinja -DWITH_TESTS=ON -DWITH_FUSE_DRIVER=OFF
$ cmake --fresh -B dwarfs-build -S dwarfs-0.10.0 -GNinja -DWITH_TESTS=ON -DWITH_LIBDWARFS=OFF -DWITH_TOOLS=OFF
$ sudo cmake --install dwarfs-build
Itu saja!
Astrofotografi dapat menghasilkan data gambar mentah dalam jumlah besar. Dalam satu malam, kemungkinan besar Anda akan mendapatkan beberapa lusin gigabyte data. Dengan sebagian besar kamera astrofotografi khusus, data ini menghasilkan gambar FITS. Ini biasanya tidak terkompresi, tidak terkompresi dengan baik dengan algoritma kompresi standar, dan meskipun ada format FITS terkompresi tertentu, format ini tidak didukung secara luas.
Salah satu format kompresi (disebut "Beras") dapat dikompres dengan cukup baik dan sangat cepat. Namun, penerapannya untuk FITS terkompresi memiliki beberapa kelemahan. Kelemahan yang paling parah adalah kompresinya tidak sebaik sensor warna dan sensor dengan resolusi kurang dari 16 bit.
DwarFS mendukung kompresi ricepp
(Rice++), yang dibangun berdasarkan ide dasar kompresi Rice, namun membuat beberapa penyempurnaan: DwarFS mengompresi gambar berwarna dan kedalaman bit rendah secara signifikan lebih baik dan selalu mencari solusi optimal selama kompresi daripada mengandalkan heuristik .
Mari kita lihat contoh penggunaan 129 gambar (gelap, datar, dan terang) yang diambil dengan kamera ASI1600MM. Setiap gambar berukuran 32 MiB, jadi totalnya ada 4 GiB data. Mengompresinya dengan alat fpack
standar membutuhkan waktu sekitar 16,6 detik dan menghasilkan total ukuran keluaran 2,2 GiB:
$ time fpack */*.fit */*/*.fit
user 14.992
system 1.592
total 16.616
$ find . -name '*.fz' -print0 | xargs -0 cat | wc -c
2369943360
Namun, hal ini menyisakan file *.fz
yang tidak dapat dibaca oleh semua aplikasi.
Menggunakan DwarFS, inilah yang kami dapatkan:
$ mkdwarfs -i ASI1600 -o asi1600-20.dwarfs -S 20 --categorize
I 08:47:47.459077 scanning "ASI1600"
I 08:47:47.491492 assigning directory and link inodes...
I 08:47:47.491560 waiting for background scanners...
I 08:47:47.675241 scanning CPU time: 1.051s
I 08:47:47.675271 finalizing file inodes...
I 08:47:47.675330 saved 0 B / 3.941 GiB in 0/258 duplicate files
I 08:47:47.675360 assigning device inodes...
I 08:47:47.675371 assigning pipe/socket inodes...
I 08:47:47.675381 building metadata...
I 08:47:47.675393 building blocks...
I 08:47:47.675398 saving names and symlinks...
I 08:47:47.675514 updating name and link indices...
I 08:47:47.675796 waiting for segmenting/blockifying to finish...
I 08:47:50.274285 total ordering CPU time: 616.3us
I 08:47:50.274329 total segmenting CPU time: 1.132s
I 08:47:50.279476 saving chunks...
I 08:47:50.279622 saving directories...
I 08:47:50.279674 saving shared files table...
I 08:47:50.280745 saving names table... [1.047ms]
I 08:47:50.280768 saving symlinks table... [743ns]
I 08:47:50.282031 waiting for compression to finish...
I 08:47:50.823924 compressed 3.941 GiB to 1.201 GiB (ratio=0.304825)
I 08:47:50.824280 compression CPU time: 17.92s
I 08:47:50.824316 filesystem created without errors [3.366s]
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
waiting for block compression to finish
5 dirs, 0/0 soft/hard links, 258/258 files, 0 other
original size: 3.941 GiB, hashed: 315.4 KiB (18 files, 0 B/s)
scanned: 3.941 GiB (258 files, 117.1 GiB/s), categorizing: 0 B/s
saved by deduplication: 0 B (0 files), saved by segmenting: 0 B
filesystem: 3.941 GiB in 4037 blocks (4550 chunks, 516/516 fragments, 258 inodes)
compressed filesystem: 4037 blocks/1.201 GiB written
Dalam waktu kurang dari 3,4 detik, ini memampatkan data hingga 1,2 GiB, hampir setengah ukuran keluaran fpack
.
Selain menghemat banyak ruang disk, ini juga berguna saat data Anda disimpan di NAS. Berikut perbandingan kumpulan data yang sama yang diakses melalui koneksi jaringan 1 Gb/s, pertama-tama menggunakan data mentah yang tidak dikompresi:
find /mnt/ASI1600 -name '*.fit' -print0 | xargs -0 -P4 -n1 cat | dd of=/dev/null status=progress
4229012160 bytes (4.2 GB, 3.9 GiB) copied, 36.0455 s, 117 MB/s
Dan selanjutnya menggunakan gambar DwarFS pada share yang sama:
$ dwarfs /mnt/asi1600-20.dwarfs mnt
$ find mnt -name '*.fit' -print0 | xargs -0 -P4 -n1 cat | dd of=/dev/null status=progress
4229012160 bytes (4.2 GB, 3.9 GiB) copied, 14.3681 s, 294 MB/s
Itu kira-kira 2,5 kali lebih cepat. Kemungkinan besar Anda dapat melihat hasil serupa dengan hard drive eksternal yang lambat.
Saat ini, DwarFS tidak memiliki kemampuan bawaan untuk menambahkan informasi pemulihan ke citra sistem file. Namun, untuk tujuan pengarsipan, ada baiknya untuk memiliki informasi pemulihan agar dapat memperbaiki gambar yang rusak.
Untungnya ini relatif mudah menggunakan sesuatu seperti par2cmdline:
$ par2create -n1 asi1600-20.dwarfs
Ini akan membuat dua file tambahan yang dapat Anda tempatkan di samping gambar (atau di penyimpanan berbeda), karena Anda hanya memerlukannya jika DwarFS mendeteksi masalah dengan gambar sistem file. Jika ada masalah, Anda bisa lari
$ par2repair asi1600-20.dwarfs
yang kemungkinan besar akan dapat memulihkan gambar jika kurang dari 5% (itulah default yang digunakan par2create
) gambar rusak.
Atribut yang diperluas saat ini tidak didukung. Atribut tambahan apa pun yang disimpan dalam sistem file sumber saat ini tidak akan dipertahankan saat membuat image DwarFS menggunakan mkdwarfs
.
Meskipun demikian, inode root dari image DwarFS yang terpasang saat ini menampilkan satu atau dua atribut yang diperluas di Linux:
$ attr -l mnt
Attribute "dwarfs.driver.pid" has a 4 byte value for mnt
Attribute "dwarfs.driver.perfmon" has a 4849 byte value for mnt
Atribut dwarfs.driver.pid
hanya berisi PID driver DwarFS FUSE. Atribut dwarfs.driver.perfmon
berisi hasil monitor kinerja saat ini.
Selanjutnya, setiap file biasa memperlihatkan atribut dwarfs.inodeinfo
dengan informasi tentang inode yang mendasarinya:
$ attr -l "05 Disappear.caf"
Attribute "dwarfs.inodeinfo" has a 448 byte value for 05 Disappear.caf
Atribut tersebut berisi objek JSON dengan informasi tentang inode yang mendasarinya:
$ attr -qg dwarfs.inodeinfo "05 Disappear.caf"
{
"chunks": [
{
"block": 2,
"category": "pcmaudio/metadata",
"offset": 270976,
"size": 4096
},
{
"block": 414,
"category": "pcmaudio/waveform",
"offset": 37594368,
"size": 29514492
},
{
"block": 419,
"category": "pcmaudio/waveform",
"offset": 0,
"size": 29385468
}
],
"gid": 100,
"mode": 33188,
"modestring": "----rw-r--r--",
"uid": 1000
}
Hal ini berguna, misalnya, untuk memeriksa bagaimana file tertentu tersebar di beberapa blok atau kategori mana yang telah ditetapkan ke file tersebut.
Tes SquashFS, xz
, lrzip
, zpaq
dan wimlib
semuanya dilakukan pada CPU Intel(R) Xeon(R) E-2286M 8 inti @ 2.40GHz dengan RAM 64 GiB.
Pengujian Cromfs dilakukan dengan DwarFS versi lama pada CPU Intel(R) Xeon(R) 6 inti D-1528 @ 1,90GHz dengan RAM 64 GiB.
Pengujian EROFS dilakukan menggunakan DwarFS v0.9.8 dan EROFS v1.7.1 pada Intel(R) Core(TM) i9-13900K dengan RAM 64 GiB.
Sistem sebagian besar menganggur selama seluruh pengujian.
Direktori sumber berisi 1.139 instalasi Perl berbeda dari 284 rilis berbeda, total 47,65 GiB data dalam 1.927.501 file dan 330.733 direktori. Direktori sumber baru saja dibuka dari arsip tar ke partisi XFS pada drive NVME 970 EVO Plus 2TB, sehingga sebagian besar isinya kemungkinan besar disimpan dalam cache.
Saya menggunakan jenis kompresi dan tingkat kompresi yang sama untuk SquashFS yang merupakan pengaturan default untuk DwarFS:
$ time mksquashfs install perl-install.squashfs -comp zstd -Xcompression-level 22
Parallel mksquashfs: Using 16 processors
Creating 4.0 filesystem on perl-install-zstd.squashfs, block size 131072.
[=========================================================/] 2107401/2107401 100%
Exportable Squashfs 4.0 filesystem, zstd compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,
compressed xattrs, compressed ids
duplicates are removed
Filesystem size 4637597.63 Kbytes (4528.90 Mbytes)
9.29% of uncompressed filesystem size (49922299.04 Kbytes)
Inode table size 19100802 bytes (18653.13 Kbytes)
26.06% of uncompressed inode table size (73307702 bytes)
Directory table size 19128340 bytes (18680.02 Kbytes)
46.28% of uncompressed directory table size (41335540 bytes)
Number of duplicate files found 1780387
Number of inodes 2255794
Number of files 1925061
Number of fragments 28713
Number of symbolic links 0
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 330733
Number of ids (unique uids + gids) 2
Number of uids 1
mhx (1000)
Number of gids 1
users (100)
real 32m54.713s
user 501m46.382s
sys 0m58.528s
Untuk DwarFS, saya tetap menggunakan default:
$ time mkdwarfs -i install -o perl-install.dwarfs
I 11:33:33.310931 scanning install
I 11:33:39.026712 waiting for background scanners...
I 11:33:50.681305 assigning directory and link inodes...
I 11:33:50.888441 finding duplicate files...
I 11:34:01.120800 saved 28.2 GiB / 47.65 GiB in 1782826/1927501 duplicate files
I 11:34:01.122608 waiting for inode scanners...
I 11:34:12.839065 assigning device inodes...
I 11:34:12.875520 assigning pipe/socket inodes...
I 11:34:12.910431 building metadata...
I 11:34:12.910524 building blocks...
I 11:34:12.910594 saving names and links...
I 11:34:12.910691 bloom filter size: 32 KiB
I 11:34:12.910760 ordering 144675 inodes using nilsimsa similarity...
I 11:34:12.915555 nilsimsa: depth=20000 (1000), limit=255
I 11:34:13.052525 updating name and link indices...
I 11:34:13.276233 pre-sorted index (660176 name, 366179 path lookups) [360.6ms]
I 11:35:44.039375 144675 inodes ordered [91.13s]
I 11:35:44.041427 waiting for segmenting/blockifying to finish...
I 11:37:38.823902 bloom filter reject rate: 96.017% (TPR=0.244%, lookups=4740563665)
I 11:37:38.823963 segmentation matches: good=454708, bad=6819, total=464247
I 11:37:38.824005 segmentation collisions: L1=0.008%, L2=0.000% [2233254 hashes]
I 11:37:38.824038 saving chunks...
I 11:37:38.860939 saving directories...
I 11:37:41.318747 waiting for compression to finish...
I 11:38:56.046809 compressed 47.65 GiB to 430.9 MiB (ratio=0.00883101)
I 11:38:56.304922 filesystem created without errors [323s]
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
waiting for block compression to finish
330733 dirs, 0/2440 soft/hard links, 1927501/1927501 files, 0 other
original size: 47.65 GiB, dedupe: 28.2 GiB (1782826 files), segment: 15.19 GiB
filesystem: 4.261 GiB in 273 blocks (319178 chunks, 144675/144675 inodes)
compressed filesystem: 273 blocks/430.9 MiB written [depth: 20000]
█████████████████████████████████████████████████████████████████████████████▏100% |
real 5m23.030s
user 78m7.554s
sys 1m47.968s
Jadi dalam perbandingan ini, mkdwarfs
6 kali lebih cepat dibandingkan mksquashfs
, baik dari segi waktu CPU maupun waktu jam dinding.
$ ll perl-install.*fs
-rw-r--r-- 1 mhx users 447230618 Mar 3 20:28 perl-install.dwarfs
-rw-r--r-- 1 mhx users 4748902400 Mar 3 20:10 perl-install.squashfs
Dalam hal rasio kompresi, sistem file DwarFS 10 kali lebih kecil dibandingkan sistem file SquashFS . Dengan DwarFS, konten telah dikompresi hingga kurang dari 0,9% (!) dari ukuran aslinya . Rasio kompresi ini hanya mempertimbangkan data yang disimpan dalam file individual, bukan ruang disk sebenarnya yang digunakan. Pada sistem file XFS asli, menurut du
, folder sumber menggunakan 52 GiB, sehingga gambar DwarFS sebenarnya hanya menggunakan 0,8% dari ruang aslinya .
Berikut perbandingan lain yang menggunakan kompresi lzma
alih-alih zstd
:
$ time mksquashfs install perl-install-lzma.squashfs -comp lzma
real 13m42.825s
user 205m40.851s
sys 3m29.088s
$ time mkdwarfs -i install -o perl-install-lzma.dwarfs -l9
real 3m43.937s
user 49m45.295s
sys 1m44.550s
$ ll perl-install-lzma.*fs
-rw-r--r-- 1 mhx users 315482627 Mar 3 21:23 perl-install-lzma.dwarfs
-rw-r--r-- 1 mhx users 3838406656 Mar 3 20:50 perl-install-lzma.squashfs
Jelas sekali bahwa prosesnya jauh lebih cepat dan gambar yang dihasilkan jauh lebih kecil. Namun, mkdwarfs
sekitar 4 kali lebih cepat dan menghasilkan gambar 12 kali lebih kecil dari gambar SquashFS. Gambar DwarFS hanya 0,6% dari ukuran file aslinya.
Jadi, mengapa tidak menggunakan lzma
daripada zstd
secara default? Alasannya adalah lzma
memiliki urutan besarnya lebih lambat untuk didekompresi dibandingkan zstd
. Jika Anda hanya sesekali mengakses data pada sistem file terkompresi, ini mungkin bukan masalah besar, namun jika Anda menggunakannya secara ekstensif, zstd
akan menghasilkan kinerja yang lebih baik.
Perbandingan di atas tidak sepenuhnya adil. mksquashfs
secara default menggunakan ukuran blok 128KiB, sedangkan mkdwarfs
menggunakan blok 16MiB secara default, atau bahkan blok 64MiB dengan -l9
. Saat menggunakan ukuran blok yang sama untuk kedua sistem file, perbedaannya, seperti yang diharapkan, menjadi tidak terlalu dramatis:
$ time mksquashfs install perl-install-lzma-1M.squashfs -comp lzma -b 1M
real 15m43.319s
user 139m24.533s
sys 0m45.132s
$ time mkdwarfs -i install -o perl-install-lzma-1M.dwarfs -l9 -S20 -B3
real 4m25.973s
user 52m15.100s
sys 7m41.889s
$ ll perl-install*.*fs
-rw-r--r-- 1 mhx users 935953866 Mar 13 12:12 perl-install-lzma-1M.dwarfs
-rw-r--r-- 1 mhx users 3407474688 Mar 3 21:54 perl-install-lzma-1M.squashfs
Bahkan hal ini masih belum sepenuhnya adil, karena menggunakan fitur ( -B3
) yang memungkinkan DwarFS mereferensikan potongan file hingga dua blok sistem file sebelumnya.
Namun intinya adalah ini adalah keunggulan SquashFS, karena ia tidak mendukung ukuran blok atau referensi balik yang lebih besar. Dan seperti yang akan Anda lihat di bawah, blok lebih besar yang digunakan DwarFS secara default tidak serta merta berdampak negatif terhadap kinerja.
DwarFS juga dilengkapi opsi untuk mengompresi ulang sistem file yang ada dengan algoritma kompresi berbeda. Hal ini dapat berguna karena memungkinkan eksperimen yang relatif cepat dengan algoritma dan pilihan yang berbeda tanpa memerlukan pembangunan kembali sistem file secara penuh. Misalnya, mengompresi ulang sistem file di atas dengan kompresi terbaik ( -l 9
):
$ time mkdwarfs --recompress -i perl-install.dwarfs -o perl-lzma-re.dwarfs -l9
I 20:28:03.246534 filesystem rewrittenwithout errors [148.3s]
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
filesystem: 4.261 GiB in 273 blocks (0 chunks, 0 inodes)
compressed filesystem: 273/273 blocks/372.7 MiB written
████████████████████████████████████████████████████████████████████▏100%
real 2m28.279s
user 37m8.825s
sys 0m43.256s