Skip to content

OlegSchwann/vpn-provider-load-calculation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 

Repository files navigation

Расчёт высоконагруженного сервиса

Задание курса Highload третьего семестра основной программы Технопарка Mail.ru. Требовалость создать архитектуру сервиса и вычислить количество оборудования, необходимое для создания сервиса, покрывающего 30% выбранного рынка.

1 Тема

VPN provider.

2 Определение возможного диапазона нагрузок подобного проекта.

3 Выбор планируемой нагрузки как 30% рынка в России.

количество пользователей интернета в России = 90000000
количество пользователей VPN в России = 24%
средний трафик на мобильное устройство в месяц = 8 Gb
моделируемая для рынка в России = 30%
Получаем нагрузку в 20 Gb/s

4 Логическая схема базы данных (без выбора СУБД)

Особенности хорошего VPN провайдера:

Поэтому в базе хранится только чувствительная и важная информация: Логин, пароль пользователя, его текущий тариф в Kb/s.

5 Физическая системы хранения (конкретные СУБД, шардинг, расчет нагрузки, обоснование реализуемости на основе результатов нагрузочного тестирования)

Расчёт нагрузки на базу данных: VPN сервера делают 1 select в момент подключения клиента, Billing cистема делает update раз в месяц.
среднее время посещения pikabu.ru = 9 мин.
Рассматрим этот развлекательный сайт как типичный случай использования. Пользователь будет переподключаться к VPN, генерируя 1 запрос в базу, раз в 9 минут.
Получается, что наши потенциальные 6480000 пользователей, используя сервис единовременно, будут генерировать нагрузку 12000 rps select по индексу для проверки авторизации.

6 Выбор прочих технологий: языки программирования, фреймфорки, протоколы взаимодействия, веб-сервера и т.д. (с обоcнованием выбора)

Части, из которых состоит сервис:

  • Сервис обеспечивает VPN. В качестве сервера выберем openvpn, он свободный и является стандартом. Используя его, мы получаем совместимость с официальным мобильным приложением, а пользователи получают большое количество обзоров.
  • Сервис проверяет, заплатил ли пользователь за услугу. Нужна база данных с логинами / паролями / тарифами. Выберем Postgres как надёжное хранилище данных.
  • OpenVPN должен ходить в сторонний сервис для авторизации. Для этого нужен плагин на C. См обоснование необходимости в 6.1.
  • Так как писать логику шардирования и походов в базу данных на C сложно, нужен отдельный сервис. Он должен выдерживать 12000 rps. Golang способен справиться с такой нагрузкой и изменяется в след за бизнес требованиями гораздо легче С. Для устойчивости используем 2 таких сервера на соседних серверах.
  • Сервис должен масштабироваться самостоятельно. Мы хотим экономить на персонале, дешевле сразу сделать хорошо. Упаковываем сервера с бизнес логикой в docker. Для openvpn серверов, где производительность сети является ключевым элементом, отключаем виртуализацию сети c помощью docker run --network=host. Для самой первой версии продукта используем Ansible, потом переходим на kubernets, как только будут решены проблемы бизнес логики.
  • Так как пользователи изначально используют VPN частично для защиты личных данных и анонимного доступа, то нормальный сервис не должен собирать данные о соединениях. Нужен мониторинг только нагрузки оборудования и сети. Для сбора данных используем ClickHouse. Для отображения используем grafana и официальный плагин для доступа к clickhouse. Настраиваем себе оповещения через в telegram.
  • Сервису нужна точка входа. Собираем landing c кратким описанием возможностей, ценой для разных скоростей. Экономим на начальном этапе, собираем визитку на tilda.
  • Сервис должет предоставлять небольшой личный кабинет. Пользователь будет заходить туда несколько раз в месяц. При моделируемом количестве пользователей получаем 400 rps. Необходимые функции: просмотр статуса пользователя, тарифа. Кнопка "попробовать" или "продлить" или "оплатить". Нужен безпроблемно расширяющийся с бизнес логикой монолит, выберем Django. Судя по тестам производительности, 2-x серверов хватит. В начале и конце месяца нужно иметь возможность увеличить производительность, kubernets уже запланирован.
  • Сервис должен принимать оплату c как можно большего количества систем. По опыту одного успешного студенческого startup'а интегрируемся с robokassa.ru , который снимает с разработчиков проблемы других множественных интеграций.

6.1 Выбор системы авторизации для OpenVPN

OpenVPN поддерживает авторизацию, для этого используются плагины. На данный момент не существует готового решения для подключения к PostgreSQL. Интерфейс плагинов авторизации - набор функций на С. Он хорошо задокументирован. Есть официальный легковесный плагин, позволяющий запускать внешний исполняемый файл или скрипт. Он делает exec при каджой попытке авторизации, передавая описание пользователя через переменные окружения. Мы считаем, что пользователи равномерно переподключаются к 30 серверам, создавая на одном сервере 400 событий авторизации в секунду.

Примитивный замер производительности exec:

time bash -c ' \
    for ((i = 0; i < 400; i++)); do \
        python3 -c \
            "import os; print(os.environ);" \
        > "/dev/null"; \
    done \
';
real  8.429s  
user  7.095s  
sys   1.346s  

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

time bash -c ' \
    for ((i = 0; i < 400; i++)); do \
        "/usr/bin/env" > "/dev/null"; \
    done \
';
real  0.361s  
user  0.270s  
sys   0.109s  

доказыает, что возможно запускать простой бинарник, хотя это и занимает от 20% до 50% 1 ядра. Так как всё равно придётся писать на компилируемом языке, то лучше всего написать свой плагин на C, используя плагин для запуска скриптов как пример. Так как писать бизнес логику на С довольно долго и дорого, плагин должен:

  • устанавливать постоянное соединение с backend сервером
  • упаковывать передаваемые данные о новом подключении в json
  • отправлять в сервер с логикой
  • асинхронно ожидать ответа
  • закрывать все соединения при выключении

7 Расчет нагрузки и потребного оборудования

  • Расчёт пропускной способности VPN. Возьмём официальные замеры производительности. Требуются сервера с аппаратной реализацией шифрования: с набором инструкций AES-NI. Это увеличивает производительность с 156 Mb/s до 750 Mb/s. Учитывая моделируемую нагрузку 20Gb/s при одновременном подключении всех пользователей, необходимо 30 серверов Intel Xeon X5660 CPU @ 2.80GHz с сетевой картой gigabit ethernet (как в тесте).
  • Расчет базы данных: В базе хранится логин пароль и тариф. Такая база на 90000000 записей будет занимать < 1 gb и помещаться в оперативную память. Потому данные можно не шардировать, только создать несколько реплик для масштабирования нагрузки.

8 Выбор хостинга / облачного провайдера и расположения серверов

По опыту Yandex, стоит выбрать Финляндию для расположения серверов. Преимущества: датацентры стоят дешевле, за счёт охлаждения уличным воздухом напрямую. Терпимый ping для европейской части России.

pingHelsinki
Moscow 28.15ms
Novosibirsk 94.05ms
St Petersburg7.00ms
Vladivostok 120.13ms

Выбираем самый дешёвый способ: свои сервера в арендованных стойках.

9 Схема балансировки нагрузки

Наш сервис ориентируется на множество мобильных пользователей, на множественные медленные длинноживущие соединения. Все сервера VPN одинаковы. Можно использовать DNS балансировку. Вся нагрузка приходится на VPN сервера, доступные по белому ip адресу непосредственно из сети. Также можно использовать балансировку в момент оплаты. В личном кабинете выдаётся ключ и адрес для подключения. Выдавать стоит не все сервера, а небольшое подмножество. Это также позволяет отправлять новых пользователей на новый, только что установленный, сервер, не замедляя соединения старых клиентов. Будем использовать абстракцию: пользователь знает об одном адресе, при этом за ним будет скрываться несколько физических серверов с одним и тем же сертификатом. Позволяет увеличивать мощность конкретного адреса, заменять физические машины без изменения адресов подключения на клиентских устройствах.

10 Обеспечение отказоустойчивости

Для обеспечения отказоустойчивости не должно быть единых точек отказа в критически важной части сервиса.
1 У пользователя есть URL и ключ.
2 При падении физического сервера с OpenVPN клиенты пытаются соединиться заново, ip перемещается на рабочий сервер.
3 При падении go сервера авторизации плагин использует другое соединение.
4 Выше говорилось, что размер базы данных с логином паролем будет около 1 gb. Это позволяет не делать шардирование, и ходить в любой из экземпляров базы данных. При падении базы данных можно просто сходить в соседнюю.
5 Application сервер на Django имеет несколько экземпляров. При падении Nginx балансировщик перестаёт отправлять запросы на упавший сервис.

About

Сalculated explanatory note for building VPN provider.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published