-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Feature Request: Target number of blocks/chunks for read performance #142
Comments
Actually... I have a better idea. Does the dwarfs database record how many times each block/chunk is referenced? It would be awesome if dwarfs had a feature to precache the most frequently referenced blocks, up to a desired cache size. Precaching could be done with IDLE priority, to not interfere with immediate user read requests. What I'm doing now is precaching the whole thing after mounting it, but that burns time on blocks that don't need caching. On a side note, I've been running gnome-disks to benchmark a loop mounted image inside dwarfs. For some reason, read performance drops rapidly whenever it is reading blocks that are empty. This is a performance graph of a 1TB drive with windows 10 and stock software from an MSI laptop. Only ~120GB of the beginning of the drive is used, and the rest is all zeros. In the graph, dwarfs has great read performance on the data parts, but there are odd dips to ~90mb/s. The more concerning issue is that it reads the zero parts quite slowly. Shouldn't reading out sparse zeros be fast? The benchmark was done with 1000 samples and 10mb sample size. The system is a dual Xeon E5-2697 v2 (24 cores/48 with hyper threading) and 256GB of RAM. |
Hi, thanks for your input! I'm currently travelling with only sporadic internet connectivity. I'll take a closer look when I'm back mid June. |
Hi @xcfmc, I'm just getting back to this. Curiously, I made a related observation only last week while working on the next release and running some benchmarks against fuse-archive. One of the benchmarks was compressing a 1 GiB file of only zeroes, and I was surprised that fuse-archive could actually have higher throughput than DwarFS when reading that file. So I dug into it and was reminded that random accesses into files are O(n) in DwarFS. That's simply because all chunks have to be traversed from the beginning of the file until the read offset. Unfortunately, that means that even when reading a huge fragmented file sequentially, you get O(n**2) performance as for each What I did to improve this was to implement an "offset cache" that would cache both the offset and index of the last chunk read for the most recently accessed inodes. The cache is tiny (64 inodes) and is only used if an inode has more than 64 chunks. However, sequential reads from fragmented files are now no longer quadratic complexity and throughput improved dramatically. To give you an idea, I tried to reproduce your use case and built a DwarFS image from a single 64 GiB EXT4 file system image. The inode of the EXT4 image consists of just over 3 million chunks. Just copying the EXT4 image to
I interrupted this after a minute because it was getting slower and slower. Now, with the 0.7.0-RC5 DwarFS release from today, things look very different:
Throughput is pretty much constant across the whole image. However, that's obviously not a typical workload for a file system, so let's measure building a
And now with the "new" 0.7.0-RC5 release including the offset cache:
That's definitely better, but still a far cry from what I'd want the performance to be. Now, the good news is that I actually thought about random access into large, fragmented files when implementing the offset cache and have a theoretical solution that I only dismissed because of the added complexity and because it didn't see this being a real use case. So watch this space, it shouldn't be too hard to implement this. With all that being said, I'm a bit irritated by the fact that you're storing file system images inside DwarFS images. Because DwarFS would most certainly perform a lot better when used directly on the data stored in those file systems; compression would very likely be much faster and better, and file access would also be much faster. Is there a reason why you're doing it that way? |
Thanks for the update! I agree that storing files instead of images would be infinitely better. Unfortunately I have several use cases where that is not possible. Even though dwarfs isn't made for these cases, it still works absolute magic on them, compared to other solutions, like Opendedup and Borg backup. Your use of efficient multithreading blows them away on throughput. Here's the list:
There's no pressure to work on these use cases. As I said, Dwarfs is already performing magic on them, compared to other solutions. They may be helpful as stress tests / benchmarks though, as the code evolves. |
That's a super interesting set of use cases, thanks for the clarification! I've built and tested a more elaborate version of the offset cache today and I'm pretty happy with the results. Performing random reads with 32 concurrent processes from the mounted EXT4 image inside the DwarFS image, I'm getting an average read speed of around 250 MB/s:
That's more than 100 times faster than the version you've been using. And the best thing it that this is going to work with all the DwarFS images you already have. :) Sequential reads of the EXT4 image itself are still at around 1.8 GB/s. |
I just tested it, and the performance is awesome! 100x performance increase for my test case as well. Thank you! |
Oh, you can only have tested the "old" cache from 0.7.0-RC5 :) The new cache has only been pushed a few minutes ago, but it's very likely not going to matter much in your case. I'm judging from the screenshot that you built with If you're interested, you can check the number of chunks in your image with
So this 64 GB image has an order of magnitude more chunks than your 1 TB image due to the much smaller match window size. I'm closing this issue, but feel free to let me know if there's anything else. |
Can we add a feature that attempts to target a final number of blocks/chunks?
Reason:
I'm using this to compress hard drive images. I mount the drawrfs archive though fuse, and then mount the drive image inside that. Read performance can get really bad if the final number of blocks is high (especially on a drive image that is fragmented). I've been playing with the -B -S -W and -w parameters, to find a decent compression/performance balance, but it takes a long time to compress and recompress a 1TB image.
Possible Solutions:
One last wishlist feature... Can you add the ability to directly compress a drive (/dev/sda) to a dwarfs image? Maybe it defaults to a single file inside called sda.img?
Thanks again for this awesome program!
The text was updated successfully, but these errors were encountered: