GeeseFS
ФС из S3, или Параллелизм гусей в природе
Виталий Филиппов
Зачем?
Мотивация
- S3 есть у всех
- S3 дешевле ФС и кросс-ДЦ
- ФС нужны (HPC и т.п.)
- Логичный вектор развития
- ФС и S3 похожи
- ФС → сетевая ФС ← S3
- Можно ли преодолеть отличия?
Файл
Напильник
"Именованная последовательность байт"
Файловая система
Хранит файлы — ваш К.О.
S3
- Simple Storage Service — S3
Amazon уже у всех
- Объектное хранилище
- Объект ≈ файл
- А в чём разница?..
S3 vs ФС
Нет иерархии префикс + разделитель
Слабая консистентность уже сильная
Нет мутабельности Multipart Copy
Нет атрибутов UserMetadata
- Нет переименования
- Великовата задержка (latency)
- Отличная масштабируемость (МБ/с)
- Для больших файлов — OK!
Конвергентная эволюция*
* или ежиная типизация? :)
Примеры от конкурентов
- Amazon
- AWS Storage Gateway (аж 4: File, FSx, Volume, Tape)
- Безумная прослойка на базе Java + NFS-Ganesha
- Azure (ADLSv2)
- Иерархические NFS-бакеты, дозапись, NFS-Gateway
- Huawei/Сбер
- Иерархические бакеты, дозапись
- Google
- REST API с композицией объектов, gcsfuse
Тоже сделать Storage Gateway?
Юзерам нужен не шлюз хранилища, а само хранилище
Примеры юзкейсов S3-ФС
1
ПО без поддержки S3. createrepo? :)
* бывает нужна частичная перезапись
POSIX-совместимость
- Иерархия
- Частичная перезапись
- Строгая консистентность
- Атомарное переименование
|
- Модификации при readdir
- Атомарная запись?
|
- Символические ссылки
- Права, POSIX ACL
- Специальные файлы
- ctime, atime, mtime; utimes(2)
- xattr
|
- Жёсткие ссылки, stat.st_nlink
- flock и fcntl(F_SETLK)
- Разреженные файлы
- fallocate
- POSIX AIO
|
POSIX ФС и атомарная запись
Видите её?
А её нет
Без fsync данные на диск не попадут
POSIX-совместимость
- Иерархия
- Частичная перезапись
- Строгая консистентность
- Атомарное переименование
|
- Модификации при readdir
Атомарная запись
- fsync, O_SYNC
- truncate
|
- Символические ссылки
- Права, POSIX ACL
- Специальные файлы
- ctime, atime, mtime; utimes(2)
- xattr
|
- Жёсткие ссылки, stat.st_nlink
- flock и fcntl(F_SETLK)
- Разреженные файлы
- fallocate
- POSIX AIO
|
Почему S3-FUSE медленные?
* Если нет конденсаторов ↓
- POSIX ФС используют кэш и асинхронную запись
- Сами диски тоже асинхронны
- SSD: 100000+ iops без fsync,
- Но только 1000 iops* с fsync
- S3FS и т.п. — синхронны
- Проход по иерархии a/b/c — 3 запроса
- Вообще есть странности
Странности
- Полное скачивание обновляемого файла
- N+1 (1000001) запрос при листингах (s3fs)
- Игнор fsync (goofys)
- ≤ 1000 файлов при переименовании директории (goofys)
- Глючная оптимизация листингов (goofys)
- Зависающий кэш (rclone-mount)
Вывод: нужна своя реализация
с гусями и параллелизмом
Интерфейсы ФС
FUSE
- Нет параллельной записи в 1 файл
- 1 "сокет" между ядром и userspace
- ПСП до ~2.5 Гбайт/с
- Просто, много библиотек
|
NFS
- Параллелизм есть
- Протокол простой
- Библиотек нет
- EdenSCM, Vitastor... :)
|
virtio-fs
- Только QEMU
- FUSE через очереди virtio
- Параллелизм есть
- Специфическое решение
|
Модуль ядра
😱
|
План реализации
- Берём goofys
- Отпиливаем рудименты
- Добавляем буферизацию
- Добавляем недостающие POSIX-фичи
- Тестируем
- Бенчим и оптимизируем
- Думаем о доработках сервиса :)
POSIX-совместимость
| GeeseFS | rclone | Goofys | S3FS | gcsfuse |
Иерархия, переименование | + | + | + | + | + |
Частичная перезапись | + | | | | |
Чтение после записи | + | | | + | + |
Truncate, запись за пределы | + | | | + | + |
Переименование каталогов | + | + | | + | + |
Модификации при readdir | + | + | | + | + |
fsync | + | | | + | + |
chmod/chown | | | | + | |
Символические ссылки | | | | + | + |
Файлы сокетов, устройств | | | | | |
Установка mtime | | + | | + | + |
xattr | + | | + | + | |
Жёсткие ссылки, блокировки | нет |
Оптимизации
| GeeseFS | rclone | Goofys | S3FS | gcsfuse |
Параллельное упреждающее чтение | + | | + | + | |
Параллельная отправка частей | + | | + | + | |
Случайное чтение без упреждения | + | | + | | + |
Копирование на сервере при дозаписи | + | | | | + |
Копирование на сервере при перезаписи | + | | | | |
xattr без дополнительных запросов | | | | | + |
Предзагрузка каталогов при поиске файла | + | | | | |
Быстрые рекурсивные листинги | + | | | | + |
Асинхронная запись | + | + | | | |
Асинхронное удаление | + | | | | |
Асинхронное переименование | + | | | | |
Дисковый кэш для чтения | + | | | + | + |
Дисковый кэш для записи | + | | | + | |
Эмуляция перезаписи
Эмуляция перезаписи
- CreateMPU → UploadPart{1,} → CompleteMPU
- Кэш ограничен — мы не rclone 😆
- Ограничения S3:
- Части минимум 5 МБ
- Читать до завершения нельзя
- Обязательно (1..N), N ≤ 10000
- Залил № X — должен залить и (1..X-1)*
Нужен PATCH
- Частичное обновление объекта
- Без "всего вот этого"
- И без лимита размера объекта
- Архитектурных препятствий нет
- Сделаем. Неизбежно :)
Другие доработки сервера?
-
UserMetadata в ListObjects
- PATCH
- Переименование
- Удалённое обновление кэша (SQS?)
- Запатчить Ceph? 🤔
Тестирование ФС
- Производительность
- Стабильность
- xfstests (7, 11 — dirstress, fsstress)
- pjdfstest
- Тесты от goofys и собственные
cp -r, rm -r
Время копирования и удаления 6500 мелких файлов (меньше — лучше)
mdtest
Тест от авторов JuiceFS — FUSE поверх Redis+S3 (оп/с)
Линейные скорости
- Рекорды, с железки с 25 Гбит/с сетью:
- Запись — 1.6 Гбайт/с (32T * 25 Мб)
- Чтение — 2.5 Гбайт/с
-
Amazon: | GeeseFS | Goofys | S3FS |
Запись, блок 1 МБ | 288 МБ/с | 269 МБ/с | 143 МБ/с |
Чтение, блок 1 МБ | 252 МБ/с | 226 МБ/с | 201 МБ/с |
- Как? → Параллелизм, «zerocopy» go-fuse
libfio_fileserver
Чтение с распределением 90:10/10:90
fio -name=test -ioengine=./libfio_fileserver.so -directory=/home/admin/s3/fileserver -chunk_size=128k -size=10G -direct=1 -bs=128k -rw=randread -iodepth=16 -runtime=60 -ramp_time=60 -random_distribution=zoned:90/10:10/90
Диск ВМ* | GeeseFS | Goofys | S3FS |
977 iops | 894 iops | 449 iops | 100 iops |
* Диск ВМ — Amazon GP2 SSD 32 гб
Сборка ядра
|
GeeseFS (Yandex) |
CephFS* (ядро) |
CephFS-FUSE |
GeeseFS (Ceph) |
HDD ntfs-3g |
Распаковка |
3:24 |
2:47 |
5:08 |
10:23 |
0:32 |
make defconfig |
0:52 |
0:34 |
0:20 |
1:13 |
0:31 |
make -j16 |
3:22 |
2:52 |
8:27 |
3:12 |
4:40 |
Удаление |
2:58 |
4:50 |
3:58 |
8:30 |
1:33 |
∑ |
10:36 |
11:03 |
17:53 |
20:06 |
7:10 |
I/O при сборке: 38k r/s (99.8% из кэша), ~200 w/s, ~165k meta/s
* Локальный днищецеф; после каждого шага перемонтирование
Спасибо!
Виталий Филиппов
vfilippov@yandex-team.ru
vitalif@yourcmc.ru
t.me/vitalif