Приятно иметь в поездке надежный и быстрый интернет, особенно когда ехать придется не один час! Если путь пролегает в густонаселенном районе — на любом современном телефоне с поддержкой сетей 4G, обычно всё просто работает, мы продолжаем пользоваться интернетом, как привыкли. Естественно, всё меняется, когда выезжаешь за пределы населенных пунктов.


В движущийся транспорт интернет можно подать только двумя путями:


  1. «С неба». Спутник, стратостаты и прочие технологии, которые ретранслируют канал передачи данных «сверху».
  2. С помощью наземной инфраструктуры. Любые способы передачи радиосигнала через базовые станции, установленные на земле. Это может быть инфраструктура сотовых операторов, Wi-Fi-инфраструктура, дедушка радио Ethernet и т. д.

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


Суть агрегации каналов передачи данных можно выразить коротко: суммировать емкость, предоставленную разными физическими линиями. Условно, если у нас есть четыре канала емкостью 1 Мбит/с каждый, на выходе мы должны получить один канал емкостью 4 Мбит/с. В нашем случае есть четыре оператора сотовой связи, через каждый из них в пределе можно выжать до 70 Мбит/с, а в сумме, если звезды сойдутся правильно, — 280 Мбит/с.


Кто-то скажет, что 280 Мбит/с никак не хватит на всех пассажиров поезда, коих в среднем 700 человек, и что получить такую скорость за пределами населенных пунктов нельзя. Более того, там, где связи нет совсем, никакой магии не произойдет: в транспорте также связи не будет. Конечно, этот кто-то совершенно прав. Поэтому мы решаем задачу не комфортного канала для всех, а хоть какого-то — там, где обычные смартфоны физически не в состоянии установить связь.


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


Суть проекта


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


Каждый тип агрегации достоин отдельной статьи, но у нас конкретная задача: насколько возможно, обеспечить надежным и максимально «широким» каналом ПД транспортные средства.


image


Инфраструктура операторов сотовой связи дает основу для задачи:


  1. Конвергентная среда. Передача данных происходит через открытый интернет и разных операторов связи. Это значит, что EtherChannel и другие аппаратно поддерживаемые протоколы работать, естественно, не будут.
  2. Высокая энтропия каналов ПД при движении транспорта. Емкость и задержка в каждом канале непредсказуемо и быстро изменяется, поскольку сильно зависит от расстояния до БС оператора, ее загрузки, помех и т. д.

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


Со стороны клиентского оборудования:


  1. Настройка сети. Через независимые каналы передачи данных устанавливаются L3-тоннели до единой точки агрегации (любой внешний сервер с настроенным NAT). Один канал — один тоннель. Поднимается интерфейс, который будет шлюзом по умолчанию для всей сети.
  2. Специальное ПО. Делает всего две вещи: мониторит целевые метрики качества каналов и тоннелей, потом на основе метрик распределяет NAT-трафик по тоннелям.

Необходимость самостоятельно анализировать каналы через разных операторов сотовой связи с мониторингом уровня сигнала оператора, типа связи, информации о загрузке базовой станции, ошибок в сети передачи данных оператора (не путать с L3-тоннелем) и на основе этих метрик распределять поток данных разрешает Google сообщить нам, что придется писать решение самостоятельно.


К слову, есть решения разного уровня приемлемости, в которых агрегация работает. Например, стандартный bonding интерфейсов в Linux. Поднимаем L3-тоннель через любой доступный инструментарий, хоть через VPN-сервер или SSH-тоннель, настраиваем вручную маршрутизацию и добавляем в бондинг виртуальные интерфейсы тоннелей. Всё будет нормально, пока емкость тоннелей в каждый момент времени одинакова. Дело в том, что при такой топологии сети работает только режим агрегации balance-rr, т. е. в каждый тоннель попадает равное количество байтов по очереди. Это значит, что если у нас будет три канала емкостью (Мбит/с) 100, 100 и 1, то результирующая емкость окажется 3 Мбит/с. То есть минимальная ширина канала умножается на количество каналов. Если емкость — 100, 100, 100, то результирующая будет 300.


Есть другое решение: прекрасный opensource-проект Vtrunkd, который после долгого забвения был реанимирован в 2016 году. Там уже есть почти всё, что нужно. Мы честно написали создателям, что готовы заплатить за доработку решения в части мониторинга метрик качества связи сотовых операторов и включить эти метрики в механизм распределения трафика, но ответа, к сожалению, так и не получили, поэтому решили написать свой вариант с нуля.


Qedr Train


Начали с мониторинга метрик операторов сотовой связи (уровень сигнала, тип сети, ошибки сети и т. д.) Нужно отметить, что модемы выбирались как раз исходя из того, как хорошо они могут отдавать метрики операторов. Мы выбрали модем SIM7100 производства компании Simcom. Все интересующие нас метрики отдаются через обращение в последовательный порт. Этот же модем также отдает GPS/ГЛОНАСС-координаты с хорошей точностью. Также необходимо отслеживать статус метрик компьютера (температуру CPU, SSD, свободное количество оперативной памяти и дискового пространства, S.M.A.R.T. показатели SSD). Отдельно модуль мониторит статистику сетевых интерфейсов (наличие ошибок на прием и отправку, длина очереди на отправку, количество переданных байтов). Поскольку производительность устройства крайне ограничена и пакет передаваемых данных должен быть минимален, а также учитывая простоту мониторинга этих метрик под Linux через /proc/sys, вся подсистема мониторинга также была разработана с нуля.


После того как модуль мониторинга метрик был готов, приступили к сетевой части: программной агрегации каналов. К сожалению, детальный алгоритм — коммерческая тайна, опубликовать его я не могу. Всё же опишу в общих чертах, как работает модуль агрегации, установленный в транспорте:


  1. При запуске читает конфиг в формате JSON, в котором описаны настройки виртуальных интерфейсов. Адреса серверов агрегации подтягиваются из центральной системы динамически. Это обеспечивает балансинг нагрузки на серверную часть и условно бесшовный хендовер при сбое любого сервера агрегации.
  2. На основе прочитанных данных создает L3-тоннели до серверов агрегации. Настраивает маршрутизацию. Тоннель опционально может иметь сжатие данных и шифрование.
  3. На основе данных от модуля мониторинга присваивает каждому тоннелю свой «вес». Чем больше вес, тем больше трафика пойдет именно через этот тоннель. Вес каждого тоннеля актуализируется каждую секунду
  4. Статистика работы устройства, геопозиция и метрики бизнес-логики накапливаются в течение 10 минут, формируется транзакция. Транзакции хранятся в локальной базе Tarantool и отправляются в «голову» нативным механизмом репликации данных СУБД «Тarantool», за что отдельное спасибо разработчикам и активному комьюнити этой СУБД.

Серверная часть агрегации работает радикально проще. При старте модуль агрегации обращается к серверу настроек, получает конфигурацию в JSON-формате и на ее основе запускает L3-интерфейсы. В целом всё тривиально.


Отдельно стоит описать систему сбора и визуализации всех метрик проекта. Она поделена на две большие части. Первая часть — мониторинг систем жизнеобеспечения клиентского и серверного оборудования. Вторая — мониторинг бизнес-метрик работы проекта.


Стек технологий проекта стандартный. Визуализация: Grafana, OpenStreetMap, сервер приложений на клиентской и серверной стороне: Go, СУБД Tarantool.


image


Tarantool


История эволюции СУБД в наших проектах начинается с PostgreSQL в 2009 году. Мы успешно хранили в нем геоданные от бортовых устройств, установленных на спецтранспорте. Модуль PostGIS вполне справлялся с задачами. Со временем очень сильно стало не хватать производительности в обработке данных без схемы хранения. Экспериментировали с MongoDB c версии 2.4 до версии 3.2. Пару раз не смогли восстановить данные после аварийного отключения (полностью дублировать данные не позволял бюджет). Далее обратили внимание на ArangoDB. Если учесть, что бэкенд в то время мы писали на JavaScript, стек технологий выглядел очень приятно. Однако и эта базейка, побыв с нами добрые два года, ушла в прошлое: мы не смогли контролировать потребление оперативной памяти на больших объемах данных. В этом проекте обратили внимание на Tarantool. Ключевым для нас было следующее:


  1. Встроенный механизм транзакций.
  2. Хранение нереляционных данных.
  3. Система хранения данных InMemory и Vinyl (на диске).
  4. Механизм мастер-слейв репликации.
  5. Эффективная работа на мощном железе в ЦОДе и на очень ограниченном оборудовании в транспортном средстве.

На первый взгляд, всё в ней хорошо, за исключением того, что работает она только на одном ядре процессора. Ради науки провели ряд экспериментов, чтобы понять, будет ли это препятствием. После тестов на целевом железе убедились, что для этого проекта СУБД справляется с обязанностями прекрасно.


У нас всего три основных профиля данных: это финансовые операции, временные ряды (т. е. журналы работы систем) и геоданные.


Финансовые операции — это информация о движении денег по лицевому счету каждого устройства. Любое устройство имеет как минимум три SIM-карты от разных операторов связи, поэтому нужно контролировать баланс лицевого счета у каждого оператора связи и, чтобы не допустить отключения, заранее знать, когда пополнить баланс для каждого оператора каждого устройства.


Временные ряды — просто журналы мониторинга от всех подсистем, включая журнал совокупной пропускной полосы для каждого устройства в транспорте. Это дает нам возможность знать, в какой точке пути какой был канал по каждому оператору. Эти данные используются для аналитики покрытия сетью, что, в свою очередь, нужно для упреждающего переключения и развесовки каналов по операторам связи. Если мы заранее знаем, что в конкретной точке у такого-то оператора худшее качество, мы заранее отключаем этот канал из агрегации.


Геоданные — простой трек транспортного средства по пути следования. Каждую секунду мы опрашиваем GPS-датчик, встроенный в модем, и получаем координаты и высоту над уровнем моря. Трек длительностью 10 минут собирается в пакет и отправляется в ЦОД. По требованию заказчика эти данные должны храниться вечно, что при возрастающем количестве транспортных средств заставляет заранее очень серьезно планировать инфраструктуру. Однако в Tarantool шардинг сделан очень просто, и ломать голову над масштабированием хранилища под самые быстрорастущие данные никакой необходимости нет. Резервная копия данных не пишется, поскольку исторической ценности сейчас в этих данных нет.


Для всех типов данных мы использовали движок Vinyl (хранение данных на диске). Финансовых операций не так много, и нет смысла всегда хранить их в памяти, как и журналы, естественно, и геоданные, пока по ним не будет производиться аналитика. Когда аналитика потребуется, в зависимости от требований к быстродействию, возможно, будет иметь смысл подготовить уже агрегированные данные и хранить их на движке InMemory, а далее анализировать эти данные. Но всё это начнется, когда заказчик сформирует свои требования.


Важно отметить, что Tarantool прекрасно справился с нашей задачей. Он одинаково комфортно себя чувствует на ограниченном в ресурсах устройстве и в ЦОДе на десять шардов. Спецификация устройств, которые стоят в транспорте:


CPU: ARMv8, 4Core, 1.1 Ghz
RAM: 2 Gb
Storage: 32 GB SSD
Спецификация сервера ЦОДа:
СPU x64 Intel Corei7, 8Core, 3.2 Ghz
RAM: 32 Gb
Storage: 2 ? 512 Gb (Soft Raid 0)


Как я уже говорил, репликация данных из транспорта в ЦОД налажена средствами самой СУБД. Шардинг данных между десятью шардами — также функционал «из коробки». Вся информация присутствует на сайте Tarantool, и описывать это тут, думаю, не нужно. В настоящий момент система обслуживает всего 866 транспортных средств. Заказчик планирует расширение до 8 тысяч.


Александр Родин, CIO и основной разработчик (да, такое случается не только в стартапах) проекта Qedr Train компании «Региональные телематические системы». Если возникнут вопросы, пишите в комменты или на a.rodin@r-t-s.ru. Постараюсь по возможности ответить всем.

Поделиться с друзьями
-->

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


  1. amarao
    13.07.2017 15:06
    +1

    Часть с «подняли туннели — распихиваем трафик, на сервере собираем» — понятна, всё последующее — какой-то оверкилл.

    Локального демона, который бы динамически дёргал метрики для route'ов в зависимости от загруженности tx queue у сетевого адаптера (или туннеля) — мне кажется, было бы достаточно. Частично нужно было бы ещё как-то учитывать разные flow, чтобы одна флоу попадала только в один канал в один момент времени…

    Вообще, задача с админской точки зрения интересная.


    1. r1alex
      13.07.2017 23:22

      Локального демона, который бы динамически дёргал метрики для route'ов в зависимости от загруженности tx queue у сетевого адаптера (или туннеля) — мне кажется, было бы достаточно

      Накопление очереди, и вообще любые локальные метрики интерфейсов — это уже последствия. В нашем случае, если будем смотреть только на них, то словим системные проблемы потери пакетов, ведь если очередь начала расти — со связью что-то не так.
      Поэтому, первичными метриками являются показатели качества связи самого оператора, а локальные метрики используются только как обратная связь от автоматической развесовки каналов.


      1. amarao
        14.07.2017 13:53
        +1

        А как вы определяете качество связи без отправики реальных пакетов?


        1. r1alex
          17.07.2017 11:26

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


          1. amarao
            17.07.2017 15:22

            Эм… Я понял, что меня смущает.

            Что это за волшебные метрики оператора сотовой связи, которые позволяют оценить качество канала без передачи данных?

            Я бы в качестве признака «фигни в канале» использовал бы ещё метрики vpn-сервера. Например, сранивая rx и tx на приёмнике и отправителе. Если дельта начинает расти — канал плохеет.

            А что такого интересного про канал может рассказать сотовый оператор?


  1. dmitry_ch
    13.07.2017 18:13

    От какого-нибудь Крока ожидал бы такое прочесть, а от Mail.ru… Это в рамках покрытия инетом поездов, чтобы сервисы mail.ru имели большее проникновение (хотя — куда уж больше-то)?


    1. danikin
      13.07.2017 22:30

      А вы статью точно читали? До конца?


      1. dmitry_ch
        13.07.2017 22:33

        Это сарказм был, если что. Для сетевиков как такое сотворить — данность, частая задача, и самый интерес в алгоритмах. А вы как-то его-то и пропустили. Остается спрашивать о том, что я и озвучил.


        1. danikin
          13.07.2017 23:16

          Не, я к тому, что статья не от мейла совсем :) Она в нашем блоге, но внешняя. Там и подпись автора имеется.


          1. dmitry_ch
            13.07.2017 23:17

            Прямо как в анекдоте: «А что, можно было и так?»


            1. danikin
              13.07.2017 23:27

              Мы наивно ранее полагали, что подпись автора с должностью и компанией внизу кабэ намекает на авторство статьи. Теперь, вот, призадумались.


  1. trublast
    13.07.2017 18:50
    +1

    На мой взгляд статья в стиле «как нарисовать сову». Во всей этой воде заинтересовало то, как именно распределялся трафик по априори нестабильным каналам. И тут на тебе — вместо этого рассказали в какой базе данные хранятся.


    1. serg_p
      13.07.2017 20:45
      +1

      Да


    1. r1alex
      13.07.2017 23:31

      Поскольку это заказная разработка, мы серьезно ограничены NDA и детали публиковать не имеем никакой возможности. Если заметили, даже не привели название заказчика. Логика алгоритма достаточно проста, но потребовалось почти полтора года экспериментов, чтобы опытным путем выстроить правильную модель принятия решения.
      Главной задачей было суммирование емкости доступных каналов и при этом избежать потери пакетов.
      Потерю пакетов удалось свести к минимуму только за счет упреждающих решений. В результате самое простое решение оказалось самым надежным. Устройство составляет карту покрытия сотовиков на пути следования. При приближении транспорта к зоне отсутствия или неуверенного приема, идет упреждающее переключение на более стабильные каналы.
      Чем больше ездим — тем точнее карта покрытия. В нашем случае все маршруты статичны и меняются очень редко.


  1. enamchuk
    13.07.2017 23:31

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


    1. r1alex
      13.07.2017 23:32
      +5

      Если интересно, могу написать про это большую отдельную статью. Какое железо было выбрано, как оно было смонтировано, какие сложности и проблемы удалось решить, а какие не удалось. Если этот пост наберет хотя-бы два десятка плюсов — сделаю отдельную статью.


      1. Envek
        13.07.2017 23:49

        Уже набрал, пишите ;-)


        1. r1alex
          14.07.2017 09:57

          Имелось в виду плюсы к комментарию, а не статье.


          1. enamchuk
            14.07.2017 20:31

            я не могу ставить «плюсы», но мне интересно!


  1. boskh
    16.07.2017 19:23
    +1

    Спасибо за статью. Есть вопрос.
    1.Позволил ли Вам сбор метрик операторов связи получить стабильную инфу о перфомансе каждого линка? Дело в том, что метрики волотильны и имеют высокую дисперсию, так же сильно подвержены влиянию стохастической компаненты (проехал грузовик, пролетела стая птиц), дополнительно влияние оказывает загрузка БС.
    2.Ваше решение работает на уровне пакетов или сессий?


    1. r1alex
      16.07.2017 19:25

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


      1. boskh
        17.07.2017 10:40
        +1

        А какова эффективность объединения? доля накладных расходов?


        1. r1alex
          17.07.2017 11:06

          Накладные расходы составляют дополнительные 2 байта для каждого пакета, поскольку в каждый пересылаемый пакет включается информация об его очередности и принадлежности к туннелю


  1. archimed7592
    17.07.2017 09:37
    +1

    Возможно я сейчас глупость спрошу, но тем не менее: как вы исходящий трафик балансируете более-менее ясно. А как вы решаете проблему с балансировкой обратного трафика, который возвращается от сервера к клиенту?


    1. r1alex
      17.07.2017 11:13

      Это хороший вопрос.
      Решается эта задача достаточно просто.
      Демон-агрегатор, который обслуживает передачу трафика по разным туннелям, работает следующим образом.
      1. Каждый тоннель обслуживается собственным потоком. Чтение и запись идут последовательно — это основы IP сетей.
      2. Соединение части пакетов пришедших по разным туннелям, идут в другом потоке, в который они попадают через промежуточный буфер.

      Отвечая на ваш вопрос, программист не заботится о том кто отвечает и кто посылает. он просто последовательно читает и пишет в поток.


      1. archimed7592
        17.07.2017 11:40
        +1

        Как работает туннель — понятно. Как работает IP-маршрутизация поверх 3-х туннелей — не понятно.
        Если серверов аггрегации столько же сколько туннелей — тогда тоже понятно.
        Если сервер аггрегации один, то не понятно.
        Классический пример: BGP с двумя провайдерами… Вы можете выбрать через какого провайдера отправить пакет, но через какого он вернётся — повлиять достаточно проблематично.


        1. r1alex
          17.07.2017 12:12

          Классический пример: BGP с двумя провайдерами… Вы можете выбрать через какого провайдера отправить пакет, но через какого он вернётся

          В нашем случае все гораздо проще. Ответ пишется в тот-же туннель всегда.

          Чтобы один сервер агрегации мог обслуживать множество транспортных устройств, каждый туннель на сервере биндится на свой порт.

          Для того чтобы маршрутизация работала правильно, есть небольшая хитрость.
          Сначала пакеты идущие на определенный порт маркируются средствами iptables
          далее уже средствами ip route формируется таблица маршрутизации в зависимости от меток

          Автор vtrunkd очень подробно описывает этот момент
          смотрите сразу шаг 2