Oberon space
General Category => Общий раздел => Тема начата: 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 либой). Впрочем, со сборщиком мусора там все равно проблемы начинаются на миллионе соединений, приходится немного иначе работать.
-
А разве JS имеет прямой доступ к настоящим сокетам? Подозреваю, что на стороне JS там только милионный массив и только.
-
А разве JS имеет прямой доступ к настоящим сокетам? Подозреваю, что на стороне JS там только милионный массив и только.
Это же Node.js. Не браузер.
Если говорят что там 1M соединений, то там таки реально должен быть миллион соединений, иначе смысл в сказанном теряется полностью.
-
Так не важно, что серверный вариант. Я не пытаюсь опровергнуть факт, что они открыли миллион сокетов. Однако, просто миллион открытых сокетов - это достоинство скорее ОС, а не ПО.
-
Так не важно, что серверный вариант. Я не пытаюсь опровергнуть факт, что они открыли миллион сокетов. Однако, просто миллион открытых сокетов - это достоинство скорее ОС, а не ПО.
Ну оно не только открыло, но еще и обслуживало их всех :-) То есть отдавало страничку всему миллиону.
-
Пардон, а как такое возможно? Может быть, я этот момент неправильно понимаю... Ведь для входящего соединения также выделяется порт, из верхнего диапазона. А порты-то 1...65535?
-
Т.е. количество логических сессий - запросто, но количество TCP-соединений? Чтобы пришёл пакет по TCP-соединению, в нём должен быть указан номер порта. Ну, с учётом "виртуализации" через NAT, допустим. Но в итоге должен быть выделенный под это соединение порт.
-
Пардон, а как такое возможно? Может быть, я этот момент неправильно понимаю... Ведь для входящего соединения также выделяется порт, из верхнего диапазона. А порты-то 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, как было описано здесь, но это сложно когда машинка стоит у хостера.
-
Спасибо за пояснение, Алексей.
Т.е. некий процесс, в принципе, может принимать входящие соединения вообще через 1 порт?
-
Спасибо за пояснение, Алексей.
Т.е. некий процесс, в принципе, может принимать входящие соединения вообще через 1 порт?
Да. Теоретически может.
-
Т.е. количество логических сессий - запросто, но количество TCP-соединений? Чтобы пришёл пакет по TCP-соединению, в нём должен быть указан номер порта. Ну, с учётом "виртуализации" через NAT, допустим. Но в итоге должен быть выделенный под это соединение порт.
Там же написано было -- клиенты были запущены на 40 машинах, с каждой шло по 25к соединений, итого 1 млн соединений.
Кроме того, на сервере в настройках линупса указали -- максимум 1М TCP-соединений.
-
Т.е. количество логических сессий - запросто, но количество TCP-соединений? Чтобы пришёл пакет по TCP-соединению, в нём должен быть указан номер порта. Ну, с учётом "виртуализации" через NAT, допустим. Но в итоге должен быть выделенный под это соединение порт.
Там же написано было -- клиенты были запущены на 40 машинах, с каждой шло по 25к соединений, итого 1 млн соединений.
Кроме того, на сервере в настройках линупса указали -- максимум 1М TCP-соединений.
Там все же основная настройка - максимальное число файловых дескрипторов, а это не только tcp-соедиенения, но и, например открытые другие файлы. :-) А что-то имеющее отношение к tcp/ip нужно крутить только если используешь netfilter/iptables.
-
Кстати, вот тут (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 серверу.
-
Почему он пустил такую маленькую нагрузку и что конкретно это были за сообщения не уточняется.
Там имеется ссылка на гитхаб. Сервер состоит, грубо говоря из двух файлов JS. Один из них worker. Я с JS особо не знаком, поэтому могу что-то попутать, но сложилось впечатление, что сервер принимает запрос, выставляет код ответа 200 и отправляет в теле ответа "Welcome". Всё. То есть, получается, что тестируется именно возможность держать открытыми такое кол-во сокетов.
-
Кстати, вот тут (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 должен умереть, таки да. Причем не только на сервере но и на клиенте.
-
Таким образом одно tcp-соединение может жить часами
Да, аналогия у меня кривая получилась. Чуток более прямая аналогия заключается в сопоставлении его tcp соединений+разъединений с нашей воипной регистрацией+разрегистрацией телефоных аппаратов. Регистрация телефона может жить часами. Сейчас под 32 разрядной Mono у нас Логика может постоянно (т.е. регистраций+разрегистраций) держать примерно до 12'000 RPS. Перед моим уходом в отпуск как раз тестировщики намерили 6'000 RPS (у них просто стенд большую скорость не выдаёт), а судя по профайлеру там ещё есть двухкратный запас.
Короче, я что хотел сказать. Количество одновременных "соединений" должно зависеть от максимально поддерживаемого RPS так, чтобы в случае чего система могла упасть и переподнятся примерно за минуту хотя бы.