Oberon space

General Category => Общий раздел => Тема начата: valexey от Август 15, 2012, 03:46:22 pm

Название: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 03:46:22 pm
Смысл в proof of concept (на базе составного документа фейс для изначально чисто вебного форума). А технического совершенства добиваться уже потом, возможно посредством других инструментов.
У меня мозги как-то иначе резонируют на подобную задачку. В первую очередь когда я думаю о программе "Форум", то возникает схема из нескольких модулей (смотри вложение), а уж чего там в гуе будет, как-то не интересно.

Во вложении набросок системы типа "Форум" а-ля микро-одноклассники или нано-фэйсбук. На полноценный фэйсбук (сто миллионов соединений) не потянет, а на 100-200 тысяч одновременных соединений -- запросто.

Кстати, вот тут (http://habrahabr.ru/post/123154/) пишут что node.js тянет до миллиона одновременных соединений. Без балансеров и прочего. На одной машине. И это, черт возьми, голимый js! (хотя, справедливости ради, этот голимый js в подобном тесте является тонкой надстройкой над pure low level C либой). Впрочем, со сборщиком мусора там все равно проблемы начинаются на миллионе соединений, приходится немного иначе работать.
Название: Re: Высоконагруженный веб.
Отправлено: Valery Solovey от Август 15, 2012, 04:20:39 pm
А разве JS имеет прямой доступ к настоящим сокетам? Подозреваю, что на стороне JS там только милионный массив и только.
Название: Re: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 04:30:34 pm
А разве JS имеет прямой доступ к настоящим сокетам? Подозреваю, что на стороне JS там только милионный массив и только.
Это же Node.js. Не браузер.
Если говорят что там 1M соединений, то там таки реально должен быть миллион соединений, иначе смысл в сказанном теряется полностью.
Название: Re: Высоконагруженный веб.
Отправлено: Valery Solovey от Август 15, 2012, 05:47:26 pm
Так не важно, что серверный вариант. Я не пытаюсь опровергнуть факт, что они открыли миллион сокетов. Однако, просто миллион открытых сокетов - это достоинство скорее ОС, а не ПО.
Название: Re: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 05:56:19 pm
Так не важно, что серверный вариант. Я не пытаюсь опровергнуть факт, что они открыли миллион сокетов. Однако, просто миллион открытых сокетов - это достоинство скорее ОС, а не ПО.
Ну оно не только открыло, но еще и обслуживало их всех :-) То есть отдавало страничку всему миллиону.
Название: Re: Высоконагруженный веб.
Отправлено: Илья Ермаков от Август 15, 2012, 06:10:10 pm
Пардон, а как такое возможно? Может быть, я этот момент неправильно понимаю... Ведь для входящего соединения также выделяется порт, из верхнего диапазона. А порты-то 1...65535?
Название: Re: Высоконагруженный веб.
Отправлено: Илья Ермаков от Август 15, 2012, 06:12:46 pm
Т.е. количество логических сессий - запросто, но количество TCP-соединений? Чтобы пришёл пакет по TCP-соединению, в нём должен быть указан номер порта. Ну, с учётом "виртуализации" через NAT, допустим. Но в итоге должен быть выделенный под это соединение порт.
Название: Re: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 06:25:52 pm
Пардон, а как такое возможно? Может быть, я этот момент неправильно понимаю... Ведь для входящего соединения также выделяется порт, из верхнего диапазона. А порты-то 1...65535?
Во-первых я это уже описывал: http://oberspace.dyndns.org/index.php/topic,292.msg7416.html#msg7416
Во-вторых это также описано и в статье.

Так что в общем ограничение на 64K соединений это миф рожденный неграмотными в сетевых делах товарищами ("профессионалами", ога). Более подробно: конкретное tcp-соединение идентифицируется четверкой чисел: src ip, src port, dst ip, dst port. Так что если тебе на порт 1234 приеходят ip-пакеты с разных пар ip+port, то все ок, это будет РАЗНЫЕ tcp соединения. Количество их, как понимаешь, может быть число_разных_ip x число_разных_портов. С учетом IPv6 можно считать что бесконечность :-)

Кстати, я в предыдущем обзаце обманул - IP не оперирует портами, порт это понятие следующего уровня (tcp, udp). :-) Но смысл от этого не меняется.

Так что реальное ограничение на колличество одновременных tcp-соединений сервера это максимальное число файловых дескрипторов (то есть сколько там в базовый int влезет) + ограничение по памяти.

На всякий случай статью процитирую:
Цитировать
Как это ни странно, обеспечить необходимую нагрузку было сложнее, чем создать сервер. Дело в том, что TCP-соединение уникально определяется четверкой [source ip, source port, dest ip, dest port], таким образом с одной машины на 1 порт сервера можно создать не более 64 тыс одновременных соединений (по количеству source ports). Можно было бы создать 16 сетевых интерфейсов с разными IP, как было описано здесь, но это сложно когда машинка стоит у хостера.
Название: Re: Высоконагруженный веб.
Отправлено: Илья Ермаков от Август 15, 2012, 07:02:35 pm
Спасибо за пояснение, Алексей.
Т.е. некий процесс, в принципе, может принимать входящие соединения вообще через 1 порт?
Название: Re: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 07:04:24 pm
Спасибо за пояснение, Алексей.
Т.е. некий процесс, в принципе, может принимать входящие соединения вообще через 1 порт?
Да. Теоретически может.
Название: Re: Высоконагруженный веб.
Отправлено: Geniepro от Август 15, 2012, 08:33:13 pm
Т.е. количество логических сессий - запросто, но количество TCP-соединений? Чтобы пришёл пакет по TCP-соединению, в нём должен быть указан номер порта. Ну, с учётом "виртуализации" через NAT, допустим. Но в итоге должен быть выделенный под это соединение порт.
Там же написано было -- клиенты были запущены на 40 машинах, с каждой шло по 25к соединений, итого 1 млн соединений.
Кроме того, на сервере в настройках линупса указали -- максимум 1М TCP-соединений.
Название: Re: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 08:38:57 pm
Т.е. количество логических сессий - запросто, но количество TCP-соединений? Чтобы пришёл пакет по TCP-соединению, в нём должен быть указан номер порта. Ну, с учётом "виртуализации" через NAT, допустим. Но в итоге должен быть выделенный под это соединение порт.
Там же написано было -- клиенты были запущены на 40 машинах, с каждой шло по 25к соединений, итого 1 млн соединений.
Кроме того, на сервере в настройках линупса указали -- максимум 1М TCP-соединений.
Там все же основная настройка - максимальное число файловых дескрипторов, а это не только tcp-соедиенения, но и, например открытые другие файлы. :-) А что-то имеющее отношение к tcp/ip нужно крутить только если используешь netfilter/iptables.
Название: Re: Высоконагруженный веб.
Отправлено: Губанов Сергей Юрьевич от Август 15, 2012, 08:42:35 pm
Кстати, вот тут (http://habrahabr.ru/post/123154/) пишут что node.js тянет до миллиона одновременных соединений. Без балансеров и прочего. На одной машине. И это, черт возьми, голимый js! (хотя, справедливости ради, этот голимый js в подобном тесте является тонкой надстройкой над pure low level C либой). Впрочем, со сборщиком мусора там все равно проблемы начинаются на миллионе соединений, приходится немного иначе работать.
Сами по себе соединения процессора особо-то не жрут. Если тот мужик раздобудет компьютер в котором в десять раз больше оперативки, то может громко закричать, что он теперь держит десять миллионов соединений. Но это лохотрон.

Процессор жрут: установление соединения, разрыв соединения, обработка сообщений.

Скорость установления соединений у него получилась как он пишет 5000-7000 в секунду (для определённости пусть будет 5000), скорость завершения соединений 400'000 за 3 минуты, то есть 2200 в секунду.

Пусть x -- количество устанавливаемых соединений, а y -- количество разрываемых соединений за одну секунду, тогда при максимальной нагрузке будет:

x/5000 + y/2200 = 1

В стационарном режиме количество устанавливаемых соединений за одну секунду равно количеству разрываемых. Из предыдущего уравнения находим его корень при x=y:

x = 1527 соединений в секунду (устанавливается и разрывается).

Жалкие полторы тысячи соединений в секунду. И это без полезной нагрузки: просто на установление и на разрыв соединения.

Установив миллион соединений он пустил по ним жалкие 50'000 сообщений в секунду израсходовав на них 2-3 ядра из 8. Почему он пустил такую маленькую нагрузку и что конкретно это были за сообщения не уточняется. Предположим, что при полной загрузке его серверок может обработать 150'000 сообщений в секунду.

Пусть p количество "звонков" в секунду (установлений соединения + разрыв соединения), а q -- количество сообщений в секунду. Тогда при максимальной нагрузке справедлива формула:

p/1527 + q/150000 = 1

Из этой формулы получаем следующее.

Сценарий 1.
Установили соединение, послали 1 сообщение (q = p), разорвали соединение.
Максимальная нагрузка: p = 1511 "звонков" в секунду.

Сценарий 2.
Установили соединение, послали 10 сообщений (q = 10*p), разорвали соединение.
Максимальная нагрузка: p = 1385 "звонков" в секунду.

Сценарий 3.
Установили соединение, послали 100 сообщений (q = 100*p), разорвали соединение.
Максимальная нагрузка: p = 756 "звонков" в секунду.

Сценарий 4.
Установили соединение, послали 1000 сообщений (q = 1000*p), разорвали соединение.
Максимальная нагрузка: p = 136 "звонков" в секунду.

Короче, лохотрон. При такой низкой скорости обслуживания миллион одновременных "звонков" не нужны.

Для сравнения, на работе у нас балансеры держут 500-1000 звонков в секунду каждый. Далее балансеры перенаправляют звонки в мою программу на C#. Она запущенная под 64 разрядной Windows 7 на 2600K может обслуживать до 7000 звонков в секунду если отключить запись CDR в базу данных и акаунтинг по RADIUS серверу.
Название: Re: Высоконагруженный веб.
Отправлено: Valery Solovey от Август 15, 2012, 08:58:23 pm
Почему он пустил такую маленькую нагрузку и что конкретно это были за сообщения не уточняется.
Там имеется ссылка на гитхаб. Сервер состоит, грубо говоря из двух файлов JS. Один из них worker. Я с JS особо не знаком, поэтому могу что-то попутать, но сложилось впечатление, что сервер принимает запрос, выставляет код ответа 200 и отправляет в теле ответа "Welcome". Всё. То есть, получается, что тестируется именно возможность держать открытыми такое кол-во сокетов.
Название: Re: Высоконагруженный веб.
Отправлено: valexey от Август 15, 2012, 09:00:50 pm
Кстати, вот тут (http://habrahabr.ru/post/123154/) пишут что node.js тянет до миллиона одновременных соединений. Без балансеров и прочего. На одной машине. И это, черт возьми, голимый js! (хотя, справедливости ради, этот голимый js в подобном тесте является тонкой надстройкой над pure low level C либой). Впрочем, со сборщиком мусора там все равно проблемы начинаются на миллионе соединений, приходится немного иначе работать.
Сами по себе соединения процессора особо-то не жрут. Если тот мужик раздобудет компьютер в котором в десять раз больше оперативки, то может громко закричать, что он теперь держит десять миллионов соединений. Но это лохотрон.

Процессор жрут: установление соединения, разрыв соединения, обработка сообщений.

Скорость установления соединений у него получилась как он пишет 5000-7000 в секунду (для определённости пусть будет 5000), скорость завершения соединений 400'000 за 3 минуты, то есть 2200 в секунду.

Пусть x -- количество устанавливаемых соединений, а y -- количество разрываемых соединений за одну секунду, тогда при максимальной нагрузке будет:

x/5000 + y/2200 = 1

В стационарном режиме количество устанавливаемых соединений за одну секунду равно количеству разрываемых. Из предыдущего уравнения находим его корень при x=y:

x = 1527 соединений в секунду (устанавливается и разрывается).

Жалкие полторы тысячи соединений в секунду. И это без полезной нагрузки: просто на установление и на разрыв соединения.

Установив миллион соединений он пустил по ним жалкие 50'000 сообщений в секунду израсходовав на них 2-3 ядра из 8. Почему он пустил такую маленькую нагрузку и что конкретно это были за сообщения не уточняется. Предположим, что при полной загрузке его серверок может обработать 150'000 сообщений в секунду.
Какие именно были сообщения посмотреть можно. Все исходники же опубликованы чтобы народ мог повторить и перепроверить. Равно как и опровергнуть лохотрон. Результаты эксперимента должны быть повторяемыми.

Да, на счет "числа звонков":
1) Насколько я помню, наш замечательный РТУ до сих пор не умеет sip over tcp, так что tcp там не ходит и понятия собственно "соединение" в терминах tcp там просто нет.
2) Сценарий работы sip/rtp-звонка и http-сессии сильно разный. Современный http обычно имеет замечательный хедер keep-alive, благодаря которому http соединение не рвется до тех пор пока человек не уйдет с сайта. Таким образом одно tcp-соединение может жить часами (один и тот же пользователь не плодит tcp-соединения). И по этому самому соединению ходят туда-сюда реквесты с респонзами. Таким образом скорость подключения/отключения tcp-соединений роли тащемто не играет (кроме того, я сильно подозреваю, что львиную долю времени на подключение/отключение tcp жрет таки ядро а не прикладная программа в виде Node.js). Играет роль скорость отдачи данных при уже установленном миллионе соединений. Ну и латентность респонза на реквест.

Я подозреваю что так мало данных он передал по двум причинам:
1) Трафик реально стоит денег. (тестирование, как видишь проводилось не в уютной серверной одной конторы).
2) Физически (территориально) сервер и клиенты были сильно разнесены (они были в разных странах как минимум, возможно на разных континентах). Кроме того хостер где сидел сервак просто мог ограничить ширину входящего канала (обычно там канал сильно уже чем заявлен в рекламе).

Я не то чтобы его или Node.js оправдываю, просто привожу соображения.

PS. А JavaScript должен умереть, таки да. Причем не только на сервере но и на клиенте.
Название: Re: Высоконагруженный веб.
Отправлено: Губанов Сергей Юрьевич от Август 16, 2012, 01:05:01 pm
Таким образом одно tcp-соединение может жить часами
Да, аналогия у меня кривая получилась. Чуток более прямая аналогия заключается в сопоставлении его tcp соединений+разъединений с нашей воипной регистрацией+разрегистрацией телефоных аппаратов. Регистрация телефона может жить часами. Сейчас под 32 разрядной Mono у нас Логика может постоянно (т.е. регистраций+разрегистраций) держать примерно до 12'000 RPS. Перед моим уходом в отпуск как раз тестировщики намерили 6'000 RPS (у них просто стенд большую скорость не выдаёт), а судя по профайлеру там ещё есть двухкратный запас.

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