-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slow performance writing compared to bazil.org/fuse #55
Comments
Interesting. As cgofuse is really a thin shim over libfuse, this must be a misconfiguration of libfuse. Configuration of the FUSE "connection" for the Since you are trying this on Linux my recommendation would be to test different values for conn->max_write = 128 * 1024; There is also the possibility that libfuse2 (that cgofuse uses) does not have optimizations in libfuse3, in which case we may have to finally move cgofuse to support libfuse3. This is a much larger undertaking, because we would not want to break compatibility with systems that only have the FUSE2 API. |
@ncw Adding |
direct_io sounds like the wrong thing to add with my reading of the docs. https://libfuse.github.io/doxygen/structfuse__config.html#ae335bab50dfddef49b0ed81671066fa8 If you set the block size of the dd to 4k then it will change the write block size I think. I'll try this tomorrow. However it shows that the block size is the problem. |
It actually seems correct based on my usage of it in mergerfs too across multiple servers to get the best performance. The moment we introduce kernel caching (by not adding Without
With
|
I did a bit of experimenting with They appear to behave the same so if you which is odd because I don't think I'm setting direct_io in Anyway I've always been lead to believe that direct_io is slow not fast - the kernel page cache is there for a reason so I'm still puzzled. |
There may be some changes because of the used FUSE protocol version too. cgofuse, from my testing, uses version 7.19 of the fuse protocol (7.19) whereas bazil/fuse uses 7.12 with mergerfs using 7.31 (which is the latest). Edit: Corrected the versions. |
Adding |
I think that is it @darthShadow Interestingly I found this in the fuse changelog for v3.0.0 (and that was the only reference in the entire git repo!)
So that probably explains why I can't find Setting So I guess the solution for this is for rclone to set Longer term migrating cgofuse to libfuse v3 will also fix the problem as it enables big writes by default apparently. |
Ideally, cgofuse should be doing it instead since I can't see any downside to it and bazil/fuse also has it enabled by default. There is one other large improvement that came recently in fuse with kernels > 4.20 that should probably also be enabled by default which is the max_pages. It defaults to 32 by default and after 4.20, allows for an increase up to 256, making the max_write change from 128k to 1M. However, I am not sure how to go about implementing it in cgofuse due to not knowing C and not having the time to learn it right now. If someone wants to take it up, these are the reference PR(s) in bazil/fuse (for Go) & mergerfs (for C): |
Arguments for adding
Arguments against adding
In any case if we wanted to do this, we could scope it to those platforms that use libfuse:
|
Based on the testing from here, looks like osxfuse doesn't respect |
@darthShadow thanks for doing all this research. We can use your information to enable "big" writes across all supported systems (either implicitly or perhaps via a new |
Do we want to set blocksize for macOS too? I am not sure if there are any downsides to it since there is almost 0 documentation about it apart from a mention in macfuse/macfuse#507 (comment) Any thoughts on adding max-pages support too? |
Got this from @trapexit for when we want to bump up the fuse version and need the fuse API changes: https://github.com/trapexit/mergerfs/blob/master/libfuse/include/fuse_kernel.h#L123 |
The OSXFUSE mount options document mentions
I am not opposed to add more options, but we must do so with a risk vs reward consideration. Every time we change something there is a risk that we will break an existing user. Our reward is of course that we fix a functionality or performance problem. Unfortunately a lot of these options are not well described. Reading the source sometimes answers questions, but often real-world effects are missed. For example, does Having said this I think there is a lot of value in what you are doing @darthShadow. If you or someone else compiles a comprehensive list of options/configurations/etc. that positively affect performance, I would certainly be interested to incorporate them into cgofuse in some form. |
max_pages impacts the max size of a fuse message. Practically speaking it impacts reads and writes the most (as getdent/readdir is currently limited to 4k messages by the kernel unfortunately.) Besides needing larger buffers to handle the size change there is no other effect. |
@billziss-gh wrote:
I don't think the sources for v4 are available -( The sources for v3 are though.
It is easy enough for rclone to set However with I don't think |
@ncw max_pages is available in libfuse3 v3.6+ I believe. The default kernel in 20.04.1 should be fine. The feature was added to 4.20. |
Both If we do decide not to enable either of the above flags, then we should at least consider bumping up the supported fuse version to 7.31 so we can at least make use of those on the client (rclone).
A performance section of some obvious flags to try sounds like a good idea.
It should be supported as long as you have a kernel greater than 4.20, which is the case by default in 20.04.
I am not sure if that is the correct test for it. I don't even have any libfuse*.so files (probably because I don't have the For the default 32 pages (pre kernel 4.20 & fuse 7.28):
For the increased value of 256 pages (post kernel 4.20 & fuse 7.28):
|
It's not useful to use mergerfs as an example here wrt anything libfuse as it uses a custom fork of libfuse2 which I maintain for the project. That said it would show the kernel supports the feature. |
Using However with kernel 5.4 on ubuntu 20.04 fuse complains about both the flags
This is with libfuse 2.9.9-3 |
libfuse2 is deprecated and does not support the feature. It's only in libfuse3. And "fuse_msg_size" is a mergerfs thing. Not a libfuse thing. |
Different fuse library but still relevant: distr1/distri#59 |
I just retested rclone...
But
So this issue is still relevant. That's for Linux - how does this perform on macOS @darthShadow with the correct We should put these workarounds in somewhere either in cgofuse or in rclone! |
I just returned from a trip and catching up. What are the workarounds that need to be added into cgofuse and/or rclone. Was it just |
I hope it was a good one :-)
I think I can put it in rclone easily enough if you don't want to add it to cgofuse. |
Thank you. It was quite nice actually!
I think it may make more sense to add such an option to rclone as it might break compatibility for other file systems. |
Ok sounds good to me :-) Are you thinking about supporting fuse3 on Linux? That seems to be standard everywhere now. |
It looks like it is something that has to be done sooner or later, although I am rather busy at the moment. |
It's the same 16k with or without the flag, so no difference. Setting |
Hi!
I'm trying to track down a performance issue with cgofuse vs bazil.org/fuse in rclone.
Here is cgofuse mounting a local disk on Linux.
And here is the mount command. Note the 4k writes
And here is bazil.org/fuse
And its mount command - note the 128k blocks
I'd say this difference is entirely down to the different sized write blocks, but I haven't been able to change it. I've tried loads of fuse parameters (
max_write
,auto_cache
) and I haven't been able to budge cgofuse from its 4k blocks for write.Fuse mysteriously says this in the docs for
max_write
This was originally noted with macOS on the rclone forum but it replicated with linux for me very easily.
Any help much appreciated - running short of hair to pull out ;-)
(Testing done with rclone master (built with
go build -tags cmount
to include cgofuse support on Linux, and use--debug-fuse
to see the fuse debug).)The text was updated successfully, but these errors were encountered: