В нашем проекте есть немного (~500GB) статических файлов, которые раздаются через nginx. Лежат они на одном физическом сервере и подключены по NFS к серверу, на котором запущен nginx. Скорость сети между серверами 1GBit/s. И вот мы задумались о том, чтобы как-то обезопасить проект от "потери" сервера, хранящего статические файлы. Сразу отметём вопросы выбора типа хранилища, просто примем тот факт, что мы выбрали GlusterFS, а вот почему и как, вы узнаете в статье.
У нас было только одно требование к GlusterFS - скорость должна быть не сильно ниже текущего NFS, ведь почти в каждой статье пишут, что как раз скорость у GlusterFS хромает.
Общие положения
Для тестирования скорости и "игр" с GlusterFS разворачивались виртуалки (CPU - 1, RAM - 1GB, Disk - 10GB) в облаке openstack у одного из провайдеров. Сеть между виртуалками 1GBit/s.
В качестве серверов GlusterFS используется Ubuntu 22.04 и ее пакеты glusterfs-server, nfs-ganesha-gluster из стандартного репозитория. Хоть мы и стараемся использовать на серверах RedHat base дистрибутивы (Centos, AlmaLinux), но как ни странно, нормально установить GlusterFS на AlmaLinux8 и AlmaLinux9 не вышло. Если будет интересно почему, то могу написать в комментариях.
-
Скорость измерялась с помощью скрипта. Да, тупо записывали на диск/nfs-папку/glusterfs-том 1GB блоками по 1MB. Потом сравнивали показатели. Ведь все познается в сравнении, не правда ли?
#!/usr/bin/env perl $s = 0; for ($i = 1; $i <= 3; $i++) { $rv = `sync; dd if=/dev/zero of=speed_test.img bs=1M count=1024 2>&1; sync`; $rv =~ /\s+(\d+)\.?\d?\s+MB\/s/; $s += $1; print $rv; } printf("speed = %0.0f\n", $s/3);
Самое замечательное в GlusterFS это то, что она очень гибкая в конфигурировании томов, которые могут плавно переходить от Distribute к Replicate и затем к Distributed‑Replicate. Да, кстати, читатель этой статьи должен знать термины GlusterFS, ну или желательно, чтобы знал, ну или не желательно, в общем, как хотите, но в статье будут встречаться термины GlusterFS без особых объяснений.
Скоростные испытания
srv1, srv2 — виртуалки в роли сервера, client — виртуалка в роли клиента, eth0 на srv1 замерялась через vnstat в момент теста скорости.
п/п |
действия |
скорость (MB/s) |
1 |
На srv1 замеряем скорость локального диска. |
165 |
На srv1 запускаем обычный NFS сервер и расшариваем папку | ||
2 |
На client монтируем расшаренную nfs-папку через eth0 на srv1 показывает |
109 |
На srv1 выключаем обычный NFS сервер, создаем GlusterFS том (далее glusterfs-том) gv0 из одного кирпичика на srv1. Тип glusterfs-тома получится Distribute. Затем расшариваем glusterfs-том gv0 через nfs-ganesha. | ||
далее тип glusterfs-тома Distribute | ||
3 |
На srv1 монтируем gv0 том через eth0 на srv1 показывает |
170 |
4 |
На client монтируем gv0 том через eth0 на srv1 показывает |
119 |
5 |
На client монтируем gv0 том через eth0 на srv1 показывает |
111 |
К glusterfs-тому gv0 подключаем srv2 с фактором репликации 2, тип которого становится Replicate. | ||
далее тип glusterfs-тома Replicate | ||
6 |
На srv1 монтируем gv0 том через eth0 на srv1 показывает |
119 |
7 |
На client монтируем gv0 том через eth0 на srv1 показывает |
54 |
8 |
На client монтируем gv0 том через eth0 на srv1 показывает |
84 |
Выводы по испытаниям
Удивляет то, что у glusterfs-тома с типом Distribute скорость записи по всем случаям монтирования чуток выше, чем у локального диска и обычного nfs соответсвенно. Замеры делались несколько раз и каждый раз наблюдалась такая картина. Казалось бы, должно быть наоборот. Главный вывод из этого такой: на одном сервере смело можно использовать glusterfs-том типа Distribute, не теряя в скорости. Только вот зачем, спросите вы. Ну хотя бы для того, чтобы изначально заложить вариант расширения хранилища.
-
Когда glusterfs-том трансформируется в тип Replicate, скорость начинает падать. Что вполне очевидно, т.к. файлы начинают зеркалироваться на двух серверах (как raid1 у mdadm). Падение происходит по разному у разных типов монтирования, что тоже вполне очевидно, если посмотреть на показатели загруженности eth0 на srv1.
При монтировании через
mount-t glusterfs
скорость упала до 54 (в два раза), при этом eth0 на srv1 загружен лишь на половину, т.к. вторая половина трафика ушла на srv2, т.е. client в момент записи пишет сразу на два сервера и eth0 у client при этом загружен на 100%.При монтировании через
mount-t nfs4
скорость упала до 84, при этом eth0 на srv1 загружен на 100%, но трафик уже идет в обоих направлениях. т.к. srv1, получая байты от client, вынужден отправлять их на srv2. Теоретически можно предположить, что если на client сделать две сетевухи и объединить (bonding) их в одну, то при монтировании через
mount-t glusterfs
скорость должна возрасти в два раза, т.е. до 108, что полностью соответствует обычному NFS.
Исходя из вышесказанного, мы решили поэтапно перенести наше хранилище статических файлов с одного сервера на другой с glusterfs-томом типа Distribute с последующим добавлением второго сервера и преобразованием glusterfs-тома в Replicate. Да, скорости в 84 для нашего типа нагрузки вполне хватает. Ну и поскольку в итоге планируется два сервера, то желательно разнести их по разным зонам доступности. Схема получилась вот такой.
+ --- nfs endpoint
/
+------/-------+
| / |
| +--------+ |
| | srv1 | |
| | 900G | | availability
| +--------+ | zone 1
| |
===|==============|==============
| |
| +--------+ | availability
| | srv2 | | zone 2
| | 900G | |
| +--------+ |
| |
| Replicated |
| volume 900G |
+--------------+
Для того чтобы можно было "потерять" один из серверов в такой схеме и продолжить нормально работать, нужно выполнить два условия: точка монтирования nfs должна быть только на одном из серверов; glusterfs-том нужно потюнить вот так:
gluster volume set gv0 network.ping-timeout 5
gluster volume set gv0 cluster.quorum-type fixed
gluster volume set gv0 cluster.quorum-count 1
Подводя общие итоги, хочется сказать
Скорость GlusterFS нифига не медленная, а очень сильно зависит от "толщины" сети и типа тома. Например, сама GlusterFS рекомендует использовать фактор репликации равный 3, но тогда скорость записи упадет не в два раза, а в три, т.к. клиент будет одновременно писать на три сервера вместо двух. И следовательно, чем выше нужна скорость, тем "толще" надо делать сеть. А вот как делать сеть "толще", надо думать - либо ставить 10GBit/s сетевухи, либо пытаться объединять сетевухи. Все очень сильно зависит от требований и финансовых возможностей проекта.
Схема из двух серверов и с монтированием glusterfs-тома по nfs вполне работоспособна. Скорость, конечно, падает по сравнению с обычным nfs, но не в два раза, как с монтированием по glusterfs. Это куда лучше, чем использовать rsync и прочее для возможности "потери" сервера.
Немного фантазий, проверенных на практике
Если нам перестанет хватать места, то можно легко добавить еще пару серверов srv3 и srv4 (добавлять нужно парами), и тогда тип glusterfs-тома станет Distributed-Replicate, а схема будет уже такой:
+-----------------------------------------+
| |
| +- vip for nfs -+ |
| / \ |
| / \ |
| +------/-------+ +-------\------+ |
| | / | | \ | |
| | +--------+ | | +--------+ | |
| | | srv1 | | | | srv3 | | |
| | | 900G | | | | 900G | | | availability
| | +--------+ | | +--------+ | | zone 1
| | | | | |
===|==|==============|=====|==============|==|==============
| | | | | |
| | +--------+ | | +--------+ | | availability
| | | srv2 | | | | srv4 | | | zone 2
| | | 900G | | | | 900G | | |
| | +--------+ | | +--------+ | |
| | | | | |
| | Replicated | | Replicated | |
| | volume 900G | | volume 900G | |
| +--------------+ +--------------+ |
| |
| Distributed volume 1800G |
+-----------------------------------------+
При такой схеме файлы будут распределяться по имени на разные пары серверов. Например, файл с именем speed_test_11.img попадет на сервера srv1 и srv2, а файл с именем speed_test_22.img попадет на сервера srv3 и srv4. Дальше представим, что client монтирует glusterfs-том через mount-t nfs4
, подлючаясь к srv1. В таком случае, если тест скорости будет делаться на файле speed_test_11.img, то скорость будет 84, ну а если на файле speed_test_22.img, то скорость будет 54 (как у монтирования через mount-t glusterfs
), т.к. в этом случае уже сам srv1 будет вынужден по сети отправлять файл на два сервера - на srv3 и srv4. Т.е. надо будет думать над тем, как и где увелиичить "толщину" сети.
Комментарии (21)
Dmitry2019
03.02.2023 14:49Я настраивал Glusterfs для одного проекта, где сервера поочерёдно раз в 5 минут записывали на Glusterfs порядка 10к файлов (MRTG). И скорости сети и диска хватало с запасом, но Gluster периодически терял синхронизацию между нодами. Пришлось откатиться на NFS
krpsh Автор
03.02.2023 14:52Хм... А вот это ценный факт. В описаниях к Glusterfs всегда говорят, что она надежная. Не ожидал такого. А можете чуток по подробней сказать о типе тома(ов) в том проекте?
Dmitry2019
03.02.2023 15:10+1glusterfs 7.9
2 пира симметрично реплицируемые по отдельному интефейсуgluster peer status
Number of Peers: 1Hostname: cfs2
Uuid: 0cf321d6-315b-416c-bdc4-7f9372aecdeb
State: Peer in Cluster (Connected)
Other names:
cfs2-backVolume Name: mrtg
Type: Replicate
Volume ID: e5dff098-c7c6-4f33-baef-ad99f66150e4
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: cfs1:/home/mrtg
Brick2: cfs2:/home/mrtg
Options Reconfigured:
transport.address-family: inet
storage.fips-mode-rchecksum: on
nfs.disable: on
performance.client-io-threads: off
/etc/hosts10.10.20.5 cfs1-back
10.10.20.6 cfs2-back
10.10.22.1 cfs1
10.10.22.2 cfs2krpsh Автор
03.02.2023 15:22Правильно ли я понимаю, что изначально вы монтировали том mrtg как glasterfs, но после потерь синхронизации между нодами вы откатились на обычный nfs, не nfs-ganesha?
Dmitry2019
03.02.2023 16:20Мы настроили NFS на реплицируемых нодах VMWare. И, если одна нода упадёт, то сервис будет недоступен только на время, пока вторая нода не поднимется с тем же IP. А это пара секунд
Dmitry2019
03.02.2023 16:23Мы также рассматривали поставить rsync между двумя нодами NFS и подключаться к ним через HAProxy. Но не дошли руки
Firz
03.02.2023 17:39А вот как делать сеть «толще», надо думать — либо ставить 10GBit/s сетевухи, либо пытаться объединять сетевухи. Все очень сильно зависит от требований и финансовых возможностей проекта.
Просто мысли вслух, к разговору о объединении сетевух:
В свое время изучал как и чем можно «ускорить» сеть для домашнего хранилища и был удивлен случайно узнав что Samba/SMB умеет «multichannel»(включается отдельно в настройках сервера и иногда нужно и у клиентов) — просто подключаешь к сервер несколько сетевух, к клиенту несколько сетевух и все, при копировании файлов он использует все доступные интерфейсы. То есть, к примеру, можно к свичу подключить 2 сетевухи сервера и 2 сетевухи клиента и он сам будет использовать оба интерфейса, при этом что у сервера что у клиента это будут два обычных интерфейса, без всякого агрегирования каналов. Тестировал даже варианты когда только 1 интерфейс сервера и один интерфейс клиента подключен к общей сети(свичу), а остальные сетевые интерфейсы подключены напрямую от клиента к серверу, и при подключении к сетевому ресурсу в общей сети(через свитч) он все равно определяет и использует напрямую подключенные интерфейсы для увеличения скорости передачи данных.select26
03.02.2023 18:31LACP работает на L2 и совершенно прозрачно. Обычно можно собрать до 8 интерфейсов в группу.
krpsh Автор
03.02.2023 20:26Да, я как-то давно слышал о таком режиме у SMB/CIFS, но сам не пробовал, не было необходимости.
Я сегодня попробовал объединить (bonding) две сетевухи в разных местах.
Сначала сделал две сетевухи у client, объединил их в режиме balance-rr и смонтировал glusterfs-том gv0 через
mount-t glusterfs
. Как я и предполагал в статье, скорость увеличилась в два раза - с 54 до 108.Затем я убрал дополнительную сетевуху на client (осталась одна) и добавил по одной на srv1 и srv2, объединил их в режиме balance-rr на каждом из srv. На client cмонтировал glusterfs-том gv0 через
mount-t nfs4
и скорость стала 98.При факторе репликации 2 (как у нас) монтировать лучше через nfs, т.к. в таком случае возникновения split brain менее вероятно, чем при монтировании через glusterfs. Это объясняется тем, что при glusterfs клиент пишет сразу на два сервера, а при nfs только на один сервер.
Firz
03.02.2023 21:07+1Я тоже в свое время баловался всякими LACP и multichannel и в итоге оказалось лучше и проще купить по 40-50$ SFP+ сетевух, за 150$ 4-портовый SPF+ свитч и сделать дома 10-гигабитную сеть.
krpsh Автор
03.02.2023 21:38Хорашая мысль, но у нас весь проект в дата-центре и цены там на 10-гигабитную сеть не особо радуют. А вот вариант с объединением сетевух вполне реален с нашим бюджетом.
VASYL_MELNYK
04.02.2023 14:27Я пробовал, самба работает согласно документации, но оказалось , что скорость реально падает очень сильно и когда в шаре много файлов это очень грустно становится, а когда попробовал монтировать саму шару гластера в папку и уже на самбе расшаривать просто эту шару, то оказалось что в случае такого монтирования для обновления списка файлов в шаре надо обновить через ф5, тогда как если файлы лежат просто локально такого поведения нет.
Но гластер отлично подходит для синхронизации шар между нодами кластера виртуализации, например я в проксмоксе разливаю бекапы на ноды - большие файлы и мало гластер справляется без проблем.
для мелких файлов лучше подходит riak, правда из нюансов надо следить за загрузкой дисков и количеством потоков репликации, мы как то пробовали на одном жестком диске держать две ноды репликации - оно фактически умерло
krpsh Автор
04.02.2023 14:48Про riak не слышал. Бегло сейчас читанул - нам не подходит, т.к. нам нужен доступ к файлам на файловой системе. Да и файлы у нас разные, от 10kb до 100Mb.
VASYL_MELNYK
04.02.2023 15:08мы тоже не хотели уходить с обычной файловой системы, но пришлось - не смогли ничего найти, пришлось переписывать апи хранилища, но там было проще - там был все таки веб-портал.
borovinskiy
03.02.2023 22:39По Ceph были бенчи и переход с 1Г на 10Г увеличивает скорость в Ceph примерно в 2 раза.
В Gluster прирост может будет другой, но в 10 раз он наверняка не будет )krpsh Автор
04.02.2023 08:09Если перевести нашу схему на 10GBit/s, то мы упремся в диски на srv{1,2}, т.е. в 165. Для двух серверов с томом Replicate сеть в 10GBit/s излишне,а вот для фактора репликации 3 и с быстрыми дисками на серверах это уже вполне годится )
borovinskiy
Ну я бы поостерегся тестировать скорость dd. Это тест в лучшем случае только скорости последовательной записи, а вовсе не "много случайного чтения большого количества мелких статических файлов nginx".
Посмотрите на fio. Там много настроек как протестировать и последовательно и случайно и чтение и запись.
А конкретно в вашем случае и тест следует проводить именно на nginx, например сняв логи с реального сервера и запустив по ним бенчмарк JMeter, чтобы повторить реальную нагрузку веб-сервера.
krpsh Автор
Конечно вы правы, что мерить скорость дисков надо именно fio. Но в данном случае мы просто мерием скорости и СРАВНИВАЕМ их, а не пытаемся узнать скорость записи и чтения реальных дисков. И самое главное, что при нашей нагрузки нам с запасом хватает скорости обыного NFS, от этого мы и отталкивались. Поэтому считаю, что в данном случает достаочно dd.
borovinskiy
HDD может быть быстрее SSD для линейной записи кусками по 1М.
Следует ли из этого, что для чтения большого количества мелких файлов стоит выбрать HDD?