Pull to refresh

GlusterFS, NFS — заметки о скорости и крохотном хранилище

Reading time6 min
Views9K

В нашем проекте есть немного (~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 сервер и расшариваем папку /mnt/nfs *(rw,sync,no_subtree_check,no_root_squash,no_all_squash)

2

На client монтируем расшаренную nfs-папку через mount -t nfs4 srv1: и замеряем скорость.

eth0 на srv1 показывает rx: 940.61 Mbit/s tx: 7.95 Mbit/s

109

На srv1 выключаем обычный NFS сервер, создаем GlusterFS том (далее glusterfs-том) gv0 из одного кирпичика на srv1. Тип glusterfs-тома получится Distribute. Затем расшариваем glusterfs-том gv0 через nfs-ganesha.

далее тип glusterfs-тома Distribute

3

На srv1 монтируем gv0 том через mount -t glusterfs localhost: и замеряем скорость.

eth0 на srv1 показывает rx: 1.94 kbit/s tx: 3.00 kbit/s

170

4

На client монтируем gv0 том через mount -t glusterfs srv1: и замеряем скорость.

eth0 на srv1 показывает rx: 961.47 Mbit/s tx: 6.45 Mbit/s

119

5

На client монтируем gv0 том через mount -t nfs4 srv1: и замеряем скорость.

eth0 на srv1 показывает rx: 921.94 Mbit/s tx: 2.67 Mbit/s

111

К glusterfs-тому gv0 подключаем srv2 с фактором репликации 2, тип которого становится Replicate.

далее тип glusterfs-тома Replicate

6

На srv1 монтируем gv0 том через mount -t glusterfs localhost: и замеряем скорость.

eth0 на srv1 показывает rx: 4.57 Mbit/s tx: 968.52 Mbit/s

119

7

На client монтируем gv0 том через mount -t glusterfs srv1: и замеряем скорость.

eth0 на srv1 показывает rx: 422.84 Mbit/s tx: 2.44 Mbit/s

54

8

На client монтируем gv0 том через mount -t nfs4 srv1: и замеряем скорость.

eth0 на srv1 показывает rx: 604.81 Mbit/s tx: 682.26 Mbit/s

84

Выводы по испытаниям

  1. Удивляет то, что у glusterfs-тома с типом Distribute скорость записи по всем случаям монтирования чуток выше, чем у локального диска и обычного nfs соответсвенно. Замеры делались несколько раз и каждый раз наблюдалась такая картина. Казалось бы, должно быть наоборот. Главный вывод из этого такой: на одном сервере смело можно использовать glusterfs-том типа Distribute, не теряя в скорости. Только вот зачем, спросите вы. Ну хотя бы для того, чтобы изначально заложить вариант расширения хранилища.

  2. Когда 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.

  3. Теоретически можно предположить, что если на 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. Т.е. надо будет думать над тем, как и где увелиичить "толщину" сети.

Tags:
Hubs:
Total votes 4: ↑4 and ↓0+4
Comments23

Articles