Skip to content
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

on btrfs, gocryptfs is significantly slower than encfs #63

Closed
tyrak opened this issue Nov 19, 2016 · 9 comments
Closed

on btrfs, gocryptfs is significantly slower than encfs #63

tyrak opened this issue Nov 19, 2016 · 9 comments

Comments

@tyrak
Copy link

tyrak commented Nov 19, 2016

Hi,

I just discovered this project and I am considering to use it to replace encfs, but it's write performance is significantly worse than encfs on my laptop. This is a sandy bridge laptop with a 5400 rpm (spinning) hard drive running 64-bit linux. I tried the provided precompiled binary for debian as well as compiling it myself (both with and without openssl support) and the results are very similar.

Here are some benchmarks:

$ ./benchmark.bash 
Testing gocryptfs at /tmp/benchmark.bash.5r4.mnt
WRITE: 131072000 bytes (131 MB) copied, 89.1114 s, 1.5 MB/s
UNTAR: 914.49
LS:    2.05
RM:    9.34

and

$ ./benchmark.bash -encfs
Testing EncFS at /tmp/benchmark.bash.QZU.mnt
WRITE: 131072000 bytes (131 MB) copied, 3.32415 s, 39.4 MB/s
UNTAR: 20.68
LS:    3.54
RM:    4.99
@rfjakob
Copy link
Owner

rfjakob commented Nov 20, 2016 via email

@tyrak
Copy link
Author

tyrak commented Nov 20, 2016

Thanks for the quick reply. I did some further tests. As it turns out, the culprit is not the fact that I am using a (spinning) hard drive, but rather the file system I am using, namely btrfs. I ran the exact same tests as above, on a ext4 volume this time, in the same disk as before. Here are the results:

$ ./benchmark.bash
Testing gocryptfs at /mnt/ext4/benchmark.bash.jSH.mnt
WRITE: 131072000 bytes (131 MB) copied, 1.01945 s, 129 MB/s
UNTAR: 12.59
LS:    1.24
RM:    4.48

$ ./benchmark.bash -encfs
Testing EncFS at /mnt/ext4/benchmark.bash.Kqv.mnt
WRITE: 131072000 bytes (131 MB) copied, 1.65637 s, 79.1 MB/s
UNTAR: 14.90
LS:    3.89
RM:    3.37

As you can see, gocryptfs is substantially faster than encfs in this case. So there is an issue with btrfs. Maybe you are using fsync excessively or some other operation that is slow under btrfs?

@rfjakob rfjakob changed the title gocryptfs is significantly slower than encfs on btrfs, gocryptfs is significantly slower than encfs Nov 23, 2016
rfjakob added a commit that referenced this issue Nov 23, 2016
This improves performance on hdds running ext4, and improves
streaming write performance on hdds running btrfs. Tar extract
slows down on btrfs for some reason.

See #63
@rfjakob
Copy link
Owner

rfjakob commented Nov 23, 2016

@tyrak I have pushed a change that coalesces small writes into bigger blocks now. If you get to it, please check out the "btrfs" branch and post the benchmark results. BTW benchmark.bash now takes a path argument :)

@rfjakob
Copy link
Owner

rfjakob commented Nov 23, 2016

@tyrak
Copy link
Author

tyrak commented Nov 24, 2016

Thanks for the patch. I tried it and the numbers have improved, but the UNTAR benchmark is still slow:

$ ./benchmark.bash
Testing gocryptfs at /tmp/benchmark.bash.NGy
WRITE: 131072000 bytes (131 MB) copied, 7.05766 s, 18.6 MB/s
UNTAR: 454.42
LS:    1.29
RM:    10.73

@rfjakob
Copy link
Owner

rfjakob commented Nov 24, 2016

What gocrypts is doing differently than EncFS is that it preallocates the space before writing a block. This makes sure it does not run out of space in the middle of a write. I have timed how long that takes on ext4 and btrfs during the tar extract benchmark:

ext4:

Prealloc: 18.754µs, Write: 7.532µs
Prealloc: 24.04µs, Write: 9.322µs
Prealloc: 8.466µs, Write: 8.58µs
Prealloc: 9.16µs, Write: 4.739µs
Prealloc: 7.912µs, Write: 9.016µs
Prealloc: 9.738µs, Write: 8.068µs
Prealloc: 8.781µs, Write: 7.374µs
Prealloc: 8.044µs, Write: 8.27µs
Prealloc: 10.62µs, Write: 11.295µs
Prealloc: 8.545µs, Write: 7.474µs
Prealloc: 9.952µs, Write: 10.287µs
Prealloc: 8.943µs, Write: 7.319µs
[...]

btrfs generally looks like this:

Prealloc: 204.07µs, Write: 10.428µs
Prealloc: 189.509µs, Write: 11.735µs
Prealloc: 1.148818ms, Write: 15.123µs
Prealloc: 6.53432ms, Write: 11.962µs
Prealloc: 224.249µs, Write: 12.288µs
Prealloc: 402.438µs, Write: 15.157µs
Prealloc: 265.148µs, Write: 14.551µs
Prealloc: 328.26µs, Write: 11.468µs
Prealloc: 290.392µs, Write: 16.553µs
Prealloc: 233.991µs, Write: 10.779µs
Prealloc: 177.823µs, Write: 12.756µs
Prealloc: 1.158379ms, Write: 10.462µs
Prealloc: 298.516µs, Write: 16.475µs
Prealloc: 259.497µs, Write: 15.527µs
Prealloc: 1.818556ms, Write: 45.656µs
Prealloc: 3.098858ms, Write: 17.108µs
Prealloc: 307.257µs, Write: 18.329µs
Prealloc: 233.511µs, Write: 10.417µs
[...]

and every now and then I see sequences of this:

Prealloc: 34.118642ms, Write: 89.893µs
Prealloc: 46.081966ms, Write: 18.067µs
Prealloc: 60.740359ms, Write: 16.502µs
Prealloc: 48.189781ms, Write: 20.414µs

In summary, preallocation on btrfs is much slower than on ext4. And this is the reason gocryptfs is slow on btrfs.

rfjakob added a commit that referenced this issue Nov 24, 2016
Preallocation is very slow on hdds that run btrfs. Give the
user the option to disable it. This greatly speeds up small file
operations but reduces the robustness against out-of-space errors.

More info: #63
@rfjakob
Copy link
Owner

rfjakob commented Nov 24, 2016

@tyrak I have just pushed another commit to the btrfs branch. It adds the -noprealloc option, which disables preallocation. When this is on, the last 4kB block of a file may become unreadable when you run out of space in the middle of a write. But this can happen on EncFS as well, and I have never seen a complaint about it. Or on ext3, which does not support preallocation, and causes gocryptfs to disable it automatically.

Anyway, if you want to benchmark this, pull the btrfs branch and add -noprealloc to line 50 in benchmark.bash: https://github.com/rfjakob/gocryptfs/blob/btrfs/benchmark.bash#L50

In my testing, this gives a massive speedup.

@tyrak
Copy link
Author

tyrak commented Nov 25, 2016

Awesome! I just tested it, and it makes gocryptfs faster than encfs. I am ready to test it thoroughly now. Thanks!

rfjakob added a commit that referenced this issue Nov 25, 2016
This improves performance on hdds running ext4, and improves
streaming write performance on hdds running btrfs. Tar extract
slows down on btrfs for some reason.

See #63

Benchmarks:

encfs v1.9.1
============

$ ./benchmark.bash -encfs /mnt/hdd-ext4
Testing EncFS at /mnt/hdd-ext4/benchmark.bash.u0g
WRITE: 131072000 bytes (131 MB, 125 MiB) copied, 1,48354 s, 88,4 MB/s
UNTAR: 20.79
LS:    3.04
RM:    6.62

$ ./benchmark.bash -encfs /mnt/hdd-btrfs
Testing EncFS at /mnt/hdd-btrfs/benchmark.bash.h40
WRITE: 131072000 bytes (131 MB, 125 MiB) copied, 1,52552 s, 85,9 MB/s
UNTAR: 24.51
LS:    2.73
RM:    5.32

gocryptfs v1.1.1-26-g4a7f8ef
============================

$ ./benchmark.bash /mnt/hdd-ext4
Testing gocryptfs at /mnt/hdd-ext4/benchmark.bash.1KG
WRITE: 131072000 bytes (131 MB, 125 MiB) copied, 1,55782 s, 84,1 MB/s
UNTAR: 22.23
LS:    1.47
RM:    4.17

$ ./benchmark.bash /mnt/hdd-btrfs
Testing gocryptfs at /mnt/hdd-btrfs/benchmark.bash.2t8
WRITE: 131072000 bytes (131 MB, 125 MiB) copied, 6,87206 s, 19,1 MB/s
UNTAR: 69.87
LS:    1.52
RM:    5.33

gocryptfs v1.1.1-32
===================

$ ./benchmark.bash /mnt/hdd-ext4
Testing gocryptfs at /mnt/hdd-ext4/benchmark.bash.Qt3
WRITE: 131072000 bytes (131 MB, 125 MiB) copied, 1,22577 s, 107 MB/s
UNTAR: 23.46
LS:    1.46
RM:    4.67

$ ./benchmark.bash /mnt/hdd-btrfs/
Testing gocryptfs at /mnt/hdd-btrfs//benchmark.bash.XVk
WRITE: 131072000 bytes (131 MB, 125 MiB) copied, 3,68735 s, 35,5 MB/s
UNTAR: 116.87
LS:    1.84
RM:    6.34
rfjakob added a commit that referenced this issue Nov 25, 2016
Preallocation is very slow on hdds that run btrfs. Give the
user the option to disable it. This greatly speeds up small file
operations but reduces the robustness against out-of-space errors.

Also add the option to the man page.

More info: #63
@rfjakob
Copy link
Owner

rfjakob commented Nov 25, 2016

Ok good. I have merged the changes to master and dropped the "btrfs" branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants