Add instructions to change NFS_MAX_FILE_IO_SIZE
This commit is contained in:
@@ -14,6 +14,9 @@ Commands:
|
||||
- [upgrade](#upgrade)
|
||||
- [defrag](#defrag)
|
||||
|
||||
⚠️ Important: follow the instructions from [Linux NFS write size](#linux-nfs-write-size)
|
||||
for optimal Vitastor NFS performance if you use EC and HDD and mount your NFS from Linux.
|
||||
|
||||
## Pseudo-FS
|
||||
|
||||
Simplified pseudo-FS proxy is used for file-based image access emulation. It's not
|
||||
@@ -100,6 +103,62 @@ Other notable missing features which should be addressed in the future:
|
||||
in the DB. The FS is implemented is such way that this garbage doesn't affect its
|
||||
function, but having a tool to clean it up still seems a right thing to do.
|
||||
|
||||
## Linux NFS write size
|
||||
|
||||
Linux NFS client (nfs/nfsv3/nfsv4 kernel modules) has a hard-coded maximum I/O size,
|
||||
currently set to 1 MB - see `rsize` and `wsize` in [man 5 nfs](https://linux.die.net/man/5/nfs).
|
||||
|
||||
This means that when you write to a file in an FS mounted over NFS, the maximum write
|
||||
request size is 1 MB, even in the O_DIRECT mode and even if the original write request
|
||||
is larger.
|
||||
|
||||
However, for optimal linear write performance in Vitastor EC (erasure-coded) pools,
|
||||
the size of write requests should be a multiple of [block_size](../config/layout-cluster.en.md#block_size),
|
||||
multiplied by the data chunk count of the pool ([pg_size](../config/pool.en.md#pg_size)-[parity_chunks](../config/pool.en.md#parity_chunks)).
|
||||
When write requests are smaller or not a multiple of this number, Vitastor has to first
|
||||
read paired data blocks from disks, calculate new parity blocks and only then write them
|
||||
back. Obviously this is 2-3 times slower than a simple disk write.
|
||||
|
||||
Vitastor HDD setups use 1 MB block_size by default. So, for optimal performance, if
|
||||
you use EC 2+1 and HDD, you need your NFS client to send 2 MB write requests, if you
|
||||
use EC 4+1 - 4 MB and so on.
|
||||
|
||||
But Linux NFS client only writes in 1 MB chunks. 😢
|
||||
|
||||
The good news is that you can fix it by rebuilding Linux NFS kernel modules 😉 🤩!
|
||||
You need to change NFS_MAX_FILE_IO_SIZE in nfs_xdr.h and then rebuild and reload modules.
|
||||
|
||||
The instruction, using Debian as an example (should be ran under root):
|
||||
|
||||
```
|
||||
# download current Linux kernel headers required to build modules
|
||||
apt-get install linux-headers-`uname -r`
|
||||
|
||||
# replace NFS_MAX_FILE_IO_SIZE with a desired number (here it's 4194304 - 4 MB)
|
||||
sed -i 's/NFS_MAX_FILE_IO_SIZE\s*.*/NFS_MAX_FILE_IO_SIZE\t(4194304U)/' /lib/modules/`uname -r`/source/include/linux/nfs_xdr.h
|
||||
|
||||
# download current Linux kernel source
|
||||
mkdir linux_src
|
||||
cd linux_src
|
||||
apt-get source linux-image-`uname -r`-unsigned
|
||||
|
||||
# build NFS modules
|
||||
cd linux-*/fs/nfs
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD -j8 modules
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD modules_install
|
||||
|
||||
# move default NFS modules away
|
||||
mv /lib/modules/`uname -r`/kernel/fs/nfs ~/nfs_orig_`uname -r`
|
||||
depmod -a
|
||||
|
||||
# unload old modules and load the new ones
|
||||
rmmod nfsv3 nfs
|
||||
modprobe nfsv3
|
||||
```
|
||||
|
||||
After these (not much complicated 🙂) manipulations NFS begins to be mounted
|
||||
with new wsize and rsize by default and it fixes Vitastor-NFS linear write performance.
|
||||
|
||||
## Horizontal scaling
|
||||
|
||||
Linux NFS 3.0 client doesn't support built-in scaling or failover, i.e. you can't
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
- [upgrade](#upgrade)
|
||||
- [defrag](#defrag)
|
||||
|
||||
⚠️ Важно: для оптимальной производительности Vitastor NFS в Linux при использовании
|
||||
HDD и EC (erasure кодов) выполните инструкции из раздела [Размер записи Linux NFS](#размер-записи-linux-nfs).
|
||||
|
||||
## Псевдо-ФС
|
||||
|
||||
Упрощённая реализация псевдо-ФС используется для эмуляции файлового доступа к блочным
|
||||
@@ -104,6 +107,66 @@ JSON-формате :-). Для инспекции содержимого БД
|
||||
записи. ФС устроена так, что на работу они не влияют, но для порядка и их стоит
|
||||
уметь подчищать.
|
||||
|
||||
## Размер записи Linux NFS
|
||||
|
||||
Клиент Linux NFS (модули ядра nfs/nfsv3/nfsv4) имеет фиксированный в коде максимальный
|
||||
размер запроса ввода-вывода, равный 1 МБ - см. `rsize` и `wsize` в [man 5 nfs](https://linux.die.net/man/5/nfs).
|
||||
|
||||
Это означает, что когда вы записываете в файл в примонтированной по NFS файловой системе,
|
||||
максимальный размер запроса записи составляет 1 МБ, даже в режиме O_DIRECT и даже если
|
||||
исходный запрос записи был больше.
|
||||
|
||||
Однако для оптимальной скорости линейной записи в Vitastor при использовании EC-пулов
|
||||
(пулов с кодами коррекции ошибок) запросы записи должны быть по размеру кратны
|
||||
[block_size](../config/layout-cluster.ru.md#block_size), умноженному на число частей
|
||||
данных пула ([pg_size](../config/pool.ru.md#pg_size)-[parity_chunks](../config/pool.ru.md#parity_chunks)).
|
||||
Если запросы записи меньше или не кратны, то Vitastor приходится сначала прочитать
|
||||
с дисков старые версии парных блоков данных, рассчитать новые блоки чётности и только
|
||||
после этого записать их на диски. Естественно, это в 2-3 раза медленнее простой записи
|
||||
на диск.
|
||||
|
||||
При этом block_size на жёстких дисках по умолчанию устанавливается равным 1 МБ.
|
||||
Таким образом, если вы используете EC 2+1 и HDD, для оптимальной скорости записи вам
|
||||
нужно, чтобы NFS-клиент писал по 2 МБ, если EC 4+1 и HDD - то по 4 МБ, и т.п.
|
||||
|
||||
А Linux NFS-клиент пишет только по 1 МБ. 😢
|
||||
|
||||
Но это можно исправить, пересобрав модули ядра Linux NFS 😉 🤩! Для этого нужно
|
||||
поменять значение переменной NFS_MAX_FILE_IO_SIZE в заголовочном файле nfs_xdr.h,
|
||||
после чего пересобрать модули NFS.
|
||||
|
||||
Инструкция по пересборке на примере Debian (выполнять под root):
|
||||
|
||||
```
|
||||
# скачиваем заголовки для сборки модулей для текущего ядра Linux
|
||||
apt-get install linux-headers-`uname -r`
|
||||
|
||||
# заменяем в заголовках NFS_MAX_FILE_IO_SIZE на желаемый (здесь 4194304 - 4 МБ)
|
||||
sed -i 's/NFS_MAX_FILE_IO_SIZE\s*.*/NFS_MAX_FILE_IO_SIZE\t(4194304U)/' /lib/modules/`uname -r`/source/include/linux/nfs_xdr.h
|
||||
|
||||
# скачиваем исходный код текущего ядра
|
||||
mkdir linux_src
|
||||
cd linux_src
|
||||
apt-get source linux-image-`uname -r`-unsigned
|
||||
|
||||
# собираем модули NFS
|
||||
cd linux-*/fs/nfs
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD -j8 modules
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD modules_install
|
||||
|
||||
# убираем в сторону штатные модули NFS
|
||||
mv /lib/modules/`uname -r`/kernel/fs/nfs ~/nfs_orig_`uname -r`
|
||||
depmod -a
|
||||
|
||||
# выгружаем старые модули и загружаем новые
|
||||
rmmod nfsv3 nfs
|
||||
modprobe nfsv3
|
||||
```
|
||||
|
||||
После такой (относительно нехитрой 🙂) манипуляции NFS начинает по умолчанию
|
||||
монтироваться с новыми wsize и rsize, и производительность линейной записи в Vitastor-NFS
|
||||
исправляется.
|
||||
|
||||
## Горизонтальное масштабирование
|
||||
|
||||
Клиент Linux NFS 3.0 не поддерживает встроенное масштабирование или отказоустойчивость.
|
||||
|
||||
@@ -162,10 +162,12 @@ apt-get install linux-headers-`uname -r`
|
||||
apt-get build-dep linux-image-`uname -r`-unsigned
|
||||
apt-get source linux-image-`uname -r`-unsigned
|
||||
cd linux*/drivers/vdpa
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules modules_install
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m modules_install
|
||||
cat Module.symvers >> /lib/modules/`uname -r`/build/Module.symvers
|
||||
cd ../virtio
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules modules_install
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m modules_install
|
||||
depmod -a
|
||||
```
|
||||
|
||||
|
||||
@@ -165,10 +165,12 @@ apt-get install linux-headers-`uname -r`
|
||||
apt-get build-dep linux-image-`uname -r`-unsigned
|
||||
apt-get source linux-image-`uname -r`-unsigned
|
||||
cd linux*/drivers/vdpa
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules modules_install
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m modules_install
|
||||
cat Module.symvers >> /lib/modules/`uname -r`/build/Module.symvers
|
||||
cd ../virtio
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules modules_install
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m -j8 modules
|
||||
make -C /lib/modules/`uname -r`/build M=$PWD CONFIG_VDPA=m CONFIG_VDPA_USER=m CONFIG_VIRTIO_VDPA=m modules_install
|
||||
depmod -a
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user