Примечание переводчика: На Хабре и в нашем блоге о корпоративном IaaS мы много пишем об облачных технологиях, и рассматриваем интересные инфраструктурные проекты различных компаний. Ранее мы рассказывали о масштабировании Apache Storm в Spotify, а сегодня представляем вашему вниманию адаптированный перевод заметки инженера проекта 45 Drives о создании 20- и 30-гигабитных соединений в сетях Ethernet.



Стоимость создания 10-гигабитного Ethernet подключения сильно упала за последние два года. Плюс, сам процесс подключения тоже стал проще, так как аппаратное обеспечение и драйверы стали совершеннее. Это я веду к тому, что любой, кто настраивал гигабитный Ethernet, сможет настроить и 10-гигабитный.

Если вы имели возможность пользоваться гигабитным Ethernet, то вам определенно понравится большая ширина канала более молодого 10-гигабитного стандарта. Думаю, что это сродни покупке нового «Мустанга» с пятилитровым двигателем… ну, не то чтобы у меня был такой…

Но если вы похожи на меня, то знаете, что быстрее – не означает достаточно быстро. Хорошей новостью для нас, скоростных наркоманов, станет то, что из 10-гигабитного соединения можно с легкостью выжать гораздо больше. Все, что вам нужно для этого сделать – это подключить второй (и более) порт и связать их вместе.

Я проделал это в 45 Drives, с целью протестировать наши ячейки хранения Storinator (их скорость записи и чтения более 2 Гбайт/с, что сильно превышает возможности одного, или даже двух, 10-гигабитных соединений). В моем сегодняшнем посте я поделюсь своим опытом в связывании портов и расскажу, как я создаю 20-гигабитные и 30-гигабитные соединения.

Установка в исследовательской лаборатории 45 Drives


Сердцем нашей 10-гигабитной сети является неуправляемый восьмипортовый коммутатор Netgear XS708E, стоимость которого составляет $819, что равняется примерно $100 за порт. Это довольно дешево, по сравнению с остальными 10-гигабитными Ethernet коммутаторами от других поставщиков, таких как Cisco, Arista, Dell – цены на их продукцию могут варьироваться от $400 до $1000 за порт. Коммутатор Netgear хорошо справляется с передачей данных при заявленной пропускной способности и идеально подходит для работы в лаборатории.

Каждый блок Storinator, который мы используем в нашей сети, оборудован сетевым адаптером Intel X540-T2 по цене $500 за штуку. Однако есть гораздо менее дорогие карты, например, Supermicro AOC-STG-i2T, которой мы тоже пользовались и сочли её вполне достойной.

Наконец, чтобы соединить все железо вместе, мы использовали сетевые кабели Cat 6. За короткий промежуток времени их эксплуатации в нашей лаборатории мы не заметили никаких проблем с производительностью, однако для рабочих установок советуем использовать Cat 6a или Cat7.

Настроить сеть очень просто, так как процесс идентичен настройке стандартной гигабитной сети. Нужно просто подключить необходимые машины к коммутатору с помощью предпочитаемых вами кабелей. Любая ОС, которой мы предлагаем воспользоваться, автоматически «подхватит» 10-гигабитную сетевую карту и отобразит подключенный интерфейс.

Для простоты я подключил DHCP сервер к 10-гигабитному коммутатору, так что коммутатор автоматически назначит IP-адреса всем подключенным интерфейсам. Ниже представлена схема моей установки.



Схема установки 45 Drives

Теперь, когда моя сеть подключена, а мои серверы и клиенты могут «разговаривать» друг с другом по 10-гигабитной магистрали, давайте перейдем к интересной части… Тестированию пропускной способности новой сети!

Тестирование пропускной способности


Впервые мне объясняли, что такое пропускная способность сети, на примере автомагистрали. Чем больше полос на дороге, тем большее количество автомобилей способно быстро по ней ехать. Все аналогично в случае с серверами и клиентами, обменивающимися файлами. Чем выше пропускная способность сети, тем большее количество пользователей способны обмениваться файлами на высокой скорости.

Во всех тестах я использовал инструмент iperf – широко известную программу для тестирования пропускной способности сети. С помощью iperf, определяющего качество сетевого соединения, мы можем убедиться, что у нас настроена 10-гигабитная сеть Ethernet. Мне нравится этот инструмент, потому что он безукоризненно работает на любой ОС.



Показания iperf при проверке 10-гигабитного соединения между клиентом №3 и сервером хранения Storinator

Расширение 10-гигабитной сети


Технология 10-гигабитного Ethernet обеспечивает очень большую скорость передачи данных, но наши ячейки хранения Stroinator все равно быстрее. У нас есть клиенты, которые регулярно ведут чтение и запись на скоростях больше 2 Гбайт/с, и мы достигли этих скоростей у себя в лаборатории. Чтобы передать данные в ячейку или забрать их оттуда, требуется подключение, которое в два или три раза превышает возможности, предлагаемые 10-гигабитным Ethernet.

Я хотел расширить возможности 10-гигабитной сети, поэкспериментировав со связыванием портов. Этот процесс имеет и другие названия, такие как NIC teaming или агрегация каналов. Суть связывания портов вот в чем: вы настраиваете несколько 10-гигабитных соединений между машиной и коммутатором, а затем объединяете их. Результаты могут быть разными, включая пропускную способность равную сумме всех соединений.

Linux упростил процесс агрегации каналов, предлагая встроенный в ядро модуль и несколько режимов связывания: их всего семь, каждый из которых обладает своей уникальной особенностью. Разные режимы могут или обеспечивать отказоустойчивость, или балансировать нагрузку, или и то, и другое. Каждый режим имеет свои недостатки, поэтому очень важно выбрать тот из них, который лучше всего подходит для решения вашей задачи.

Мой интерес пробудил тот факт, что, теоретически, с помощью метода распределения нагрузки round-robin (режим 0 в Linux) мы можем удвоить пропускную способность соединения, настроенного между нашими машинами, не прибегая к установке дополнительного аппаратного обеспечения, а просто добавив несколько кабелей.

Как связывать порты


Поскольку драйвер для связывания каналов предустановлен в ядро Linux, нет нужды устанавливать какие-либо другие пакеты. Для работы в режиме round-robin коммутатор также не требует дополнительной настройки, что удобно.

Чтобы связать каналы в CentOS, первое, что нужно сделать – это создать конфигурационный файл в директории для хранения конфигураций сетевых интерфейсов и скриптов (/etc/sysconfig/network-scripts/ifcfg-bond0). В этом конфигурационном файле указаны имя устройства, IP-адрес, подсеть, режим связывания и так далее. Большинство параметров прописывает пользователь. Важно отметить, что я использовал режим 0 (round-robin). Для более подробной информации об агрегации каналов на CentOS, пожалуйста, посмотрите информационную страничку.

Далее, нам нужно модифицировать существующие индивидуальные сетевые соединения, чтобы сделать их частью связанного интерфейса. Развязанные сетевые интерфейсы «подхватываются» при загрузке, поэтому, все, что нужно сделать, это внести несколько изменений в конфигурационные файлы интерфейсов. Пожалуйста, посмотрите созданный мной информационный пост, в котором описано, что нужно прописать в этих файлах.

Операционная система FreeNAS гораздо более прямолинейная, в отличие от CentOS. Перед загрузкой FreeNAS предоставит вам список опций в порядке от 1 до 14:

  • Выберите пункт 2 «Агрегация связей»;
  • Далее выберите «Создать агрегацию связей»;
  • Выберите протокол связывания (1-6). В ОС FreeNAS метод round-robin находится под номером 5, но вы можете выбрать какой угодно, в зависимости от ваших нужд;
  • Далее система попросит вас выбрать те интерфейсы, которые будут связаны. Выберите те, которые вы хотите агрегировать;
  • Чтобы изменения вступили в силу, потребуется перезагрузка;
  • После перезагрузки, выбрав пункт 1, вы сможете настроить новый связанный интерфейс, как если бы вы настраивали обычный.

Кроме того, агрегирование каналов в FreeNAS упрощается наличием webGUI. Весь процесс также описан на нашем информационном портале, в секции, посвящённой NAS.

Теперь, когда я связал сетевые интерфейсы, установив режим round-robin в надежде удвоить пропускную способность, давайте посмотрим, что из этого вышло!

Результаты и оптимизация


Результирующую пропускную способность, получившуюся после связывания портов, я проверил на примере хоста Storinator и клиента Storinator №1. Обе машины работают под управлением CentOS 7, в каждой установлена одна сетевая карта Intel X540-T2, подключенная к коммутатору Netgear XS708E.

Затем я запустил iperf и увидел, что результирующая пропускная способность составила 11,3 Гбит/с.



Вывод iperf после связывания двух интерфейсов. Без настройки

Я был озадачен этим, поскольку ожидал получить цифру близкую к 20 Гбит/с, поэтому мне пришлось потратить некоторое время на настройку нашей сети. В какой-то литературе я вычитал, что стандартные размеры окна TCP ведут к плохой производительности, при использовании более новой инфраструктуры 10-гигабитного Ethernet. Я попробовал использовать различные размеры окон, но увидел только дальнейшее снижение пропускной способности.

Дальнейшее исследование показало, что оптимальный размер окна TCP напрямую связан с задержкой передачи, которая, в свою очередь, зависит от скорости сети (биты в секунду) и времени двухсторонней задержки (в секундах). Когда впервые был придуман TCP (в 1974 году), то оптимальный размер окна был выбран на основании существующих тогда скоростей сети. С тех пор, однако, мы значительно увеличили скорости передачи данных, поэтому нужно было пересмотреть оптимальный размер окна TCP. К счастью, оказалось, что Linux (и большинство других ОС) расширяют размер окна TCP в зависимости от настроенной сети. Выходит, что настраивать ничего не нужно, так как ядро ОС самостоятельно определило оптимальный размер окна.

Моей следующей мыслью было воспользоваться джамбо-кадрами, вместо стандартных кадров размером 1500 байт. Другими словами, я выяснял, каков размер пакета данных, передаваемого по сети. Это называется MTU (Maximum Transmission Unit). Как в случае с окном TCP: скорости увеличились и небольшие MTU стали неэффективны.

Переключившись на джамбо-кадры, я заметил улучшение: пропускная способность выросла с 11,3 Гбит/с до 13,9 Гбит/с. Теперь я всегда устанавливаю размер MTU равным 9000 байт в 10-гигабитных сетях. (Важно помнить: если вы вносите подобные изменения самостоятельно, то убедитесь, что все используемые вами компоненты поддерживают джамбо-кадры. Сегодня большинство современного оборудования их поддерживает).



Вывод iperf с джамбо-кадрами

Все еще озадаченный тем, почему я не могу получить скорость 20 Гбит/с, я решил разместить по две сетевые карты в каждой машине и связать два интерфейса (по одному на каждую карту) с коммутатором.

В результате успех – 20-гигабитное соединение!



Iperf показывает 20-гигабитное соединение с двумя сетевыми картами

Оказалось, что хотя сетевые карты Intel и 10-гигабитные, они не могут выдавать 10 гигабит на оба порта одновременно – максимум 14 гигабит на два порта. (Проблема должна лежать где-то внутри архитектуры карты или в PCI-соединении).

Три сетевые карты с тремя интерфейсами дадут вам пропускную способность, равную «скромным» 30 Гбит/с. Это очень большая магистраль!



Ipref показывает 30-гигабитное соединение с тремя сетевыми картами

Однако я уверен, что если вы хотите получить пропускную способность 30 Гбит/с, то лучше использовать две сетевые карты, имеющие по два интерфейса – то есть по 14 Гбит/с на карту.

В этом случае вам удастся добиться большей избыточности и сократить свои затраты: не придётся покупать три сетевые карты.

Заключение


Этот пост затронул тему того, как легко и дешево настроить 10-гигабитную сеть Ethernet. Моей основной задачей было поделиться своим опытом настройки 20-гигабитной сети с помощью агрегации каналов.

За время опытов я понял несколько вещей:

  • Легко расширить 10-гигабитную сеть и обеспечить избыточность связей с помощью агрегирования каналов. Посмотрите нашу информационную страничку, где подробно расписан процесс связывания интерфейсов на ОС CentOS и FreeNAS.
  • Не все сетевые карты одинаковы – те, которые я использовал, не могли выдавать скорость в 10 Гбит/с на порт. Все чего я смог добиться – это 14 Гбит/с на одну карту.
  • Джабмо-кадры способны дать серьезный прирост к пропускной способности. Однако лучше не трогать размер окна TCP, так как ОС автоматически установит нужный, в зависимости от вашего сетевого подключения.

Комментарии (10)


  1. inkvizitor68sl
    24.09.2015 16:17
    +5

    То есть вся статья ради того, чтобы сказать, что у вас сетевые карты на 14 гбит, а не на 20?
    Щиорт побери.

    А где куда более важная инфа про irq, про то, что одна сессия всё равно будет в 10G?


    1. Ad3pt
      24.09.2015 21:43

      Насколько я знаю, round-robin — единственный из механизмов port bonding, позволяющий увеличивать скорость одной сессии. Жалко, работает не везде и как попало (очень сильно зависит от конкретного свитча)


      1. blind_oracle
        24.09.2015 22:08
        +1

        Да, увеличивает, только резко возрастает количество TCP out of order пакетов, даже при crossover подключении без свичей вовсе. Поэтому нужно задирать параметр net.ipv4.tcp_reordering.


  1. DoMoVoY
    24.09.2015 21:44

    Узкое место: PCI-E, а точнее серверный мост, который является посредником между CPU и PCI-E устройствами. Начиная с чипсета intel c202/c602 PCI-E линии подключены напрямую к CPU. По сравнению с intel 5500/5520 ускорение на порядок! Возможно Ваша платформа не имеет прямых линий на CPU.


  1. blind_oracle
    24.09.2015 22:11
    +1

    Статья — много воды и немножко цитат из bonding.txt.
    Вы открыли миру аггрегацию линков!


  1. lexore
    24.09.2015 23:06

    Мне казалось, для аггрегирования обычно используют mode=4 (IEEE 802.3ad) (LACP).
    Автору статьи нужно было запустить, например, htop, чтобы посмотреть, как дела с прерываниями.
    Если видно, что загружено только одно ядро процессора загрузкой ядра linux (в htop красненький цвет), то драйвер упирался прерываниями в CPU.
    У интелового драйвера можно выставить 4 или 8 векторов прерываний, которые могут висеть каждое на своем ядре.
    Тогда драйвер сетевухи будет размазывать нагрузку на 4-8 ядер, а не на одно.
    Вполне возможно, тогда автор получил бы 20 Гб сразу.


    1. blind_oracle
      26.09.2015 22:26

      Через iperf автор ни с каким режимом кроме round-robin никогда бы не получил больше 10Гбит.

      Ибо все эти режимы используют хеш от (srcip | dstip | srcport | dstport | srcmac | dstmac) в разных режимах и комбинациях для выбора интерфейса для передачи данных.

      В таком виде единственный TCP поток пойдет всегда по одному интерфейсу.


      1. lexore
        26.09.2015 22:45

        Ну, не совсем. Iperf поддерживает работу в несколько потоков.
        Каждый поток открывает свое соединение.
        Я получил вот такую картину:

        22:42:09.093381 IP 127.0.0.1.51086 > 127.0.0.1.5001: tcp 65483
        22:42:09.093446 IP 127.0.0.1.51090 > 127.0.0.1.5001: tcp 106
        22:42:09.093463 IP 127.0.0.1.5001 > 127.0.0.1.51090: tcp 0
        22:42:09.093479 IP 127.0.0.1.51090 > 127.0.0.1.5001: tcp 65483
        22:42:09.093562 IP 127.0.0.1.51088 > 127.0.0.1.5001: tcp 65483
        22:42:09.093590 IP 127.0.0.1.5001 > 127.0.0.1.51088: tcp 0
        22:42:09.093642 IP 127.0.0.1.51086 > 127.0.0.1.5001: tcp 65483
        22:42:09.093670 IP 127.0.0.1.5001 > 127.0.0.1.51086: tcp 0
        22:42:09.093719 IP 127.0.0.1.51089 > 127.0.0.1.5001: tcp 106
        22:42:09.093735 IP 127.0.0.1.5001 > 127.0.0.1.51089: tcp 0
        22:42:09.093750 IP 127.0.0.1.51091 > 127.0.0.1.5001: tcp 65483
        22:42:09.093774 IP 127.0.0.1.5001 > 127.0.0.1.51091: tcp 0
        22:42:09.093843 IP 127.0.0.1.51087 > 127.0.0.1.5001: tcp 65483
        


        Автору статьи нужно было просто указать -P 2, или -P 4.


        1. blind_oracle
          27.09.2015 09:23

          Это понятно, но, как я понял, целью его был разгон именно одного потока.
          Да и никто не гарантирует, что та комбинация IP:PORT, которая будет получена приведёт к использованию двух разных интерфейсов.


          1. lexore
            27.09.2015 11:49

            > Это понятно, но, как я понял, целью его был разгон именно одного потока.
            Мне кажется, автор просто не подумал об этом.
            Как говорится, не ищите хитрый план там…
            Я не знаю примеров реальной нагрузки, где нужно отдавать 10Г в одну TCP сессию.