277 lines
21 KiB
Markdown
277 lines
21 KiB
Markdown
[Документация](../../README-ru.md#документация) → Использование → VitastorFS и псевдо-ФС
|
||
|
||
-----
|
||
|
||
[Read in English](nfs.en.md)
|
||
|
||
# VitastorFS и псевдо-ФС
|
||
|
||
В Vitastor есть две реализации файловой системы. Обе используются через `vitastor-nfs`.
|
||
|
||
Команды:
|
||
- [mount](#mount)
|
||
- [start](#start)
|
||
- [upgrade](#upgrade)
|
||
- [defrag](#defrag)
|
||
|
||
⚠️ Важно: для оптимальной производительности Vitastor NFS в Linux при использовании
|
||
HDD и EC (erasure кодов) выполните инструкции из раздела [Размер записи Linux NFS](#размер-записи-linux-nfs).
|
||
|
||
## Псевдо-ФС
|
||
|
||
Упрощённая реализация псевдо-ФС используется для эмуляции файлового доступа к блочным
|
||
образам Vitastor. Это не полноценная файловая система - в ней отсутствуют многие функции
|
||
POSIX ФС, а метаданные всех файлов (образов) сохраняются в etcd и всё время хранятся в
|
||
оперативной памяти - то есть, псевдо-ФС подходит для сотен или тысяч файлов, но не миллионов.
|
||
|
||
Псевдо-ФС предназначена для доступа к образам виртуальных машин в средах, где другие
|
||
способы невозможны или неудобны - например, в VMWare. Для VMWare это лучшая опция, чем
|
||
iSCSI, так как при использовании iSCSI VMWare размещает все виртуальные машины в одном
|
||
большом блочном образе внутри собственной ФС VMFS, а с NFS VMFS не используется и каждый
|
||
диск ВМ представляется в виде одного файла, то есть, соответствует одному блочному образу
|
||
Vitastor, как это и задумано изначально.
|
||
|
||
Чтобы подключить псевдо-ФС Vitastor, выполните команду `vitastor-nfs mount --block /mnt/vita`.
|
||
|
||
Либо же запустите сетевой вариант сервера:
|
||
|
||
```
|
||
vitastor-nfs start --block --etcd_address 192.168.5.10:2379 --portmap 0 --port 2050 --pool testpool
|
||
```
|
||
|
||
Примонтировать ФС, запущенную с такими опциями, можно следующей командой:
|
||
|
||
```
|
||
mount server:/ /mnt/ -o port=2050,mountport=2050,nfsvers=3,soft,nolock,tcp
|
||
```
|
||
|
||
## VitastorFS
|
||
|
||
VitastorFS - полноценная кластерная (Read-Write-Many) файловая система. Она поддерживает
|
||
большую часть функций POSIX - иерархическую организацию, символические ссылки, жёсткие
|
||
ссылки, быстрые переименования и так далее.
|
||
|
||
Метаданные VitastorFS хранятся в собственной реализации БД формата ключ-значения,
|
||
основанной на Параллельном Оптимистичном Б-дереве поверх обычного блочного образа Vitastor.
|
||
И записи каталогов, и иноды, как обычно в Vitastor, хранятся в простом человекочитаемом
|
||
JSON-формате :-). Для инспекции содержимого БД можно использовать инструмент `vitastor-kv`.
|
||
|
||
Чтобы использовать VitastorFS:
|
||
|
||
1. Создайте пул для данных ФС или выберите существующий пустой пул
|
||
2. Создайте блочный образ для метаданных ФС, желательно, в более быстром пуле (на SSD
|
||
или по крайней мере на HDD, но без EC), но можно и в том же пуле, что данные
|
||
(размер образа значения не имеет):
|
||
`vitastor-cli create -s 10G -p fastpool testfs`
|
||
3. Пометьте пул данных как ФС-пул: `vitastor-cli modify-pool --used-for-app fs:testfs data-pool`
|
||
4. Либо примонтируйте ФС: `vitastor-nfs mount --fs testfs --pool data-pool /mnt/vita`
|
||
5. Либо запустите сетевой NFS-сервер: `vitastor-nfs start --fs testfs --pool data-pool`
|
||
|
||
### Поддерживаемые функции POSIX
|
||
|
||
- Чтение актуальной версии данных сразу после записи
|
||
- Последовательное и произвольное чтение и запись
|
||
- Запись за пределами текущего размера файла
|
||
- Иерархическая организация, мгновенное переименование файлов и каталогов
|
||
- Изменение размера файла (truncate)
|
||
- Права на файлы (chmod/chown)
|
||
- Фиксация данных на диски (когда необходимо) (fsync)
|
||
- Символические ссылки
|
||
- Жёсткие ссылки
|
||
- Специальные файлы (устройства, сокеты, каналы)
|
||
- Отслеживание времён модификации (mtime), изменения атрибутов (ctime)
|
||
- Ручное изменение времён модификации (mtime), последнего доступа (atime)
|
||
- Корректная обработка изменений списка файлов во время листинга
|
||
|
||
### Ограничения
|
||
|
||
Отсутствующие на данный момент в VitastorFS функции POSIX:
|
||
- Блокировки файлов не поддерживаются
|
||
- Фактически занятое файлами место не подсчитывается и не возвращается вызовами
|
||
stat(2), так что `du` всегда показывает сумму размеров файлов, а не фактически занятое место
|
||
- Времена доступа (`atime`) не отслеживаются (как будто ФС смонтирована с `-o noatime`)
|
||
- Времена модификации (`mtime`) отслеживаются асинхронно (как будто ФС смонтирована с `-o lazytime`)
|
||
- Привилегии доступа по умолчанию не проверяются сервером (клиент NFS Linux их также не проверяет).
|
||
Чтобы включить проверки, используйте опцию `--enforce 1`.
|
||
|
||
Другие недостающие функции, которые нужно добавить в будущем:
|
||
- Переиспользование номеров инодов. В текущей реализации номера инодов всё время
|
||
увеличиваются, так что в теории вы можете упереться в лимит, если насоздаёте
|
||
и наудаляете больше, чем 2^48 файлов.
|
||
- Очистка места в Б-дереве метаданных. Текущая реализация никогда не сливает и не
|
||
удаляет блоки Б-дерева, так что в теории дерево может разростись и стать неоптимальным.
|
||
Если вы столкнётесь с такой ситуацией сейчас, вы можете решить её с помощью
|
||
команд `vitastor-kv dumpjson` и `loadjson` (т.е. пересоздав и загрузив обратно все метаданные ФС).
|
||
- Инструмент проверки метаданных файловой системы. У VitastorFS нет журнала, так как
|
||
журнал бы сильно замедлил реализацию, вместо него используются оптимистичные
|
||
транзакции на основе CAS (сравнить-и-записать), и теоретически при нештатном
|
||
завершении сервера ФС в БД также могут оставаться неконсистентные "мусорные"
|
||
записи. ФС устроена так, что на работу они не влияют, но для порядка и их стоит
|
||
уметь подчищать.
|
||
|
||
## Размер записи 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 не поддерживает встроенное масштабирование или отказоустойчивость.
|
||
То есть, вы не можете задать несколько адресов серверов при монтировании ФС.
|
||
|
||
Однако вы можете использовать любые стандартные сетевые балансировщики нагрузки
|
||
или схемы с отказоустойчивостью. Это точно безопасно при настройках `immediate_commit=all` и
|
||
`client_enable_writeback=false`, так как с ними NFS-сервер Vitastor вообще не хранит
|
||
в памяти ещё не зафиксированные на дисках данные; и вполне вероятно безопасно
|
||
даже без `immediate_commit=all`, потому что NFS-клиент ядра Linux повторяет все
|
||
незафиксированные запросы при потере соединения.
|
||
|
||
## RDMA
|
||
|
||
vitastor-nfs поддерживает NFS через RDMA. В теории это также должно позволять использовать
|
||
VitastorFS из GPUDirect.
|
||
|
||
Вы можете протестировать NFS-RDMA, даже если у вас нет RDMA-карты, с помощью SoftROCE:
|
||
|
||
1. Сначала создайте SoftROCE устройства на обоих тестовых серверах: `rdma link add rxe0 type rxe netdev eth0`.
|
||
Утилита `rdma` входит в состав пакета iproute2, а `eth0` вам нужно заменить на имя своей
|
||
сетевой карты.
|
||
|
||
2. Запустите vitastor-nfs с RDMA: `vitastor-nfs start (--fs <NAME> | --block) --pool <POOL> --port 20049 --nfs_rdma 20049 --portmap 0`
|
||
|
||
3. Смонтируйте ФС: `mount 192.168.0.10:/mnt/test/ /mnt/vita/ -o port=20049,mountport=20049,nfsvers=3,soft,nolock,rdma`
|
||
|
||
## Команды
|
||
|
||
### mount
|
||
|
||
`vitastor-nfs (--fs <NAME> | --block) mount [-o <OPT>] <MOUNTPOINT>`
|
||
|
||
Запустить локальный сервер и примонтировать ФС в директорию <MOUNTPOINT>.
|
||
|
||
Чтобы отмонтировать ФС, используйте обычную команду `umount <MOUNTPOINT>`.
|
||
|
||
Сервер автоматически останавливается при отмонтировании ФС.
|
||
|
||
- `-o|--options <OPT>` - Передать дополнительные опции монтирования NFS (пример: -o async).
|
||
|
||
### start
|
||
|
||
`vitastor-nfs (--fs <NAME> | --block) start`
|
||
|
||
Запустить сетевой NFS-сервер. Опции:
|
||
|
||
| <!-- --> | <!-- --> |
|
||
|------------------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||
| `--bind <IP>` | принимать соединения по адресу \<IP> (по умолчанию 0.0.0.0 - на всех) |
|
||
| `--port <PORT>` | использовать порт \<PORT> для NFS-сервисов (по умолчанию 2049). Укажите "auto", чтобы выбрать и напечатать случайный порт |
|
||
| `--portmap 0` | отключить сервис portmap/rpcbind на порту 111 (по умолчанию включён и требует root привилегий) |
|
||
| `--nfs_rdma <PORT>` | включить NFS-RDMA на порту RDMA-CM \<PORT> (попробуйте 20049). Если RDMA включено и указано `--port 0`, TCP будет отключено |
|
||
| `--nfs_rdma_credit 16` | максимальный "кредит", глубина очереди для NFS-клиентов |
|
||
| `--nfs_rdma_send 1024` | максимальное число операций RDMA отправки (должно быть больше nfs_rdma_credit) |
|
||
| `--nfs_rdma_alloc 1M` | округление выделения памяти для RDMA-клиентов |
|
||
| `--nfs_rdma_gc 64M` | максимальный объём неиспользуемой памяти RDMA-клиентом перед освобождением |
|
||
|
||
### upgrade
|
||
|
||
`vitastor-nfs --fs <NAME> upgrade`
|
||
|
||
Обновить метаданные ФС. Можно запускать онлайн (при запущенных серверах NFS), но после выполнения их всё
|
||
же желательно перезапустить.
|
||
|
||
### defrag
|
||
|
||
`vitastor-nfs --fs <NAME> defrag [OPTIONS] [--dry-run]`
|
||
|
||
Дефрагментировать тома, используемые для хранения мелких файлов, в которых более, чем
|
||
<defrag_percent> процентов данных удалено. Можно запускать онлайн.
|
||
|
||
На уровне реализации ФС файлы, меньшие, чем размер объекта пула (block_size умножить на число
|
||
частей данных, если пул EC), упаковываются друг за другом в большие "тома" / "общие иноды".
|
||
Когда такие файлы удаляются или увеличиваются, они перемещаются и оставляют за собой "мусор".
|
||
|
||
При дефрагментации мусор удаляется, а всё ещё используемые данные перемещаются в новые тома.
|
||
|
||
Опции:
|
||
|
||
| <!-- --> | <!-- --> |
|
||
|----------------------------|------------------------------------------------------------------------ |
|
||
| `--volume_untouched 86400` | Дефрагментировать только тома, в которые уже не писали это число секунд |
|
||
| `--defrag_percent 50` | Дефрагментировать только тома, в которых этот % данных удалён |
|
||
| `--defrag_block_count 16` | Читать это количество блоков пула за один раз |
|
||
| `--defrag_iodepth 16` | Перемещать одновременно до этого числа файлов |
|
||
| `--trace` | Печатать детальную статистику дефрагментации |
|
||
| `--dry-run` | Не производить никаких изменений, только описать выполняемые действия |
|
||
| `--recalc-stats` | Пересчитать и сохранить статистику всех томов |
|
||
| `--include-empty` | Дефрагментировать старые и пустые тома; обязательно перезапустите NFS-сервера после использования этой опции |
|
||
| `--no-rm` | Перемещать, но не удалять данные |
|
||
|
||
## Общие опции
|
||
|
||
| <!-- --> | <!-- --> |
|
||
|--------------------|---------------------------------------------------------|
|
||
| `--fs <NAME>` | использовать VitastorFS с метаданными в образе \<NAME> |
|
||
| `--block` | использовать псевдо-ФС для доступа к блочным образам |
|
||
| `--pool <POOL>` | использовать пул \<POOL> для новых файлов (обязательно, если пул в кластере не один) |
|
||
| `--subdir <DIR>` | экспортировать подкаталог \<DIR>, а не корень (только для псевдо-ФС) |
|
||
| `--nfspath <PATH>` | установить путь NFS-экспорта в \<PATH> (по умолчанию /) |
|
||
| `--pidfile <FILE>` | записать ID процесса в заданный файл |
|
||
| `--logfile <FILE>` | записывать логи в заданный файл |
|
||
| `--enforce 1` | проверять права доступа на стороне сервера (по умолчанию нет) |
|
||
| `--foreground 1` | не уходить в фон после запуска |
|