C10k (Проблема 10000 соединений) на разных языках/платформах



    UPD. Вторая версия бенчмарка тут: eric.themoritzfamily.com/websocket-demo-results-v2.html


    Предупреждение: если у вас есть претензии к бенчмарку и/или к коду, бенчмарк выложен на Гитхабе, что позволяет вам править баги самим или сообщить о багах автору.

    Подробнее о проблеме 10000 соединений: ru.wikipedia.org/wiki/Проблема_10000_соединений

    Как с проблемой 10000 соединений через вебсокеты справятся Erlang, Go, Haskell (Snap), Java (Webbit), Node.js (websocket) и Python (ws4py)?



    Во время бенчмарка каждую миллисекунду запускается новый клиент. Раз в секунду каждый клиент отсылает сообщение с текущим временем на сервер, а сервер отсылает это сообщение назад.

    Реализация Время на подсоединение (среднее) Задержка (средняя) Сообщений Соединений Таймаутов соединения
    Erlang 865ms 17ms 2849294 10000 0
    Haskell (Snap) 168ms 227ms 1187413 4996 108
    Java (Webbit) 567ms 835ms 1028390 4637 157
    Go 284ms 18503ms 2398180 9775 225
    Node.js (websocket) 768ms 42580ms 1170847 5701 4299
    Python (ws4py) 1561ms 34889ms 1052996 4792 5208


    Реализации на Питоне и Node.js падали на примерно половине соединений.

    Несмотря на то, что ожидалось, что Go порвет Erlang по производительности, задержка была намного выше и на 225 соединениях сервер запрос не обработал.

    Java Webbit была темной лошадкой, но в итоге показала результаты лучше, чем Go (157 необработанных подсоединений).

    Самое удивительное, что gevent (Python) и node.js перестали работать после 5001 и 4792 соединений соответсвенно, несмотря на то, что и тот и другой были реализованы специально для решения проблемы C10k.

    Более детальное описание, код и сырые данные — на GitHub'е: github.com/ericmoritz/wsdemo/blob/master/results.md

    UPD. В сравнения включается все больше и больше людей, появились тесты для Tornado (Python)



    UPD. Вторая версия бенчмарка тут: eric.themoritzfamily.com/websocket-demo-results-v2.html

    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 258
    • +9
      Тег порадовал «смешались в кучу кони люди». Коль таки дела, спрошу и я. Вот на винде, я понимаю, в WinAPI функция мультиплексирования select — не масштабируемая, и на прикладном уровне дает сложность o(n), что в принципе может создавать проблемы для 10 000 и больше соединений (или все-же справляется?), ну а у linux в чём беда?
      • +2
        Я так понимаю, проблема не столько ОСи, сколько самих веб-серверов, которые могут просто не уметь обрабатывать такое количество соединений :)
        • +1
          Не совсем верно. Например в Java NIO базируется на разных технологиях в разных ОС и соответственно по разному себя ведет.
          • +3
            Название должно быть «проблема 10000 WebSocket соединений», судя по исходникам.
          • +4
            Кто-то ещё пользуется селектом на винде? IOCP же.
            • +1
              Я пользуюсь, но судя по всему, больше не буду.
              • 0
                Посмотрите в сторону htts://github.com/joyent/libuv :)
                • 0
                  Что это? И зачем мне на него смотреть? :)
                  • +1
                    Библиотека асинхронного ввода и вывода, сочинённая специально для внедрения в Node.js.
              • +1
                Кто-то еще пользуется виндой как серверной платформой?
                • 0
                  • 0
                    не знаю к счастью или к сожалению, но у нас в конторе так исторически сложилось, что всё на MS. Я бы рад предложить перейти местами на nix (почтовик бесплатный на iredmail и прокся очень вписываются), но как только с шефом начинаем обсуждать, видим что пока проблем больше чем плюсов…
                    Так что коли вся сетка на Win, выбирать особенно не приходится… Хотя может время изменится для нас =)
                • +3
                  Select никто и не использует. На винде есть IOCP, на линуксе epoll, на FreeBSD и ее производных — kqueue. Это если рассматривать уровень системных вызовов.
                  • +1
                    и есть несколько различных либ, скрывающих детали конкретной ОС.
                    • +3
                      например, сказочный boost.asio для с++. С приходом лямбд он стал очень удобным.
                    • +5
                      Если не требуется адового количества соединений, то можно и select.
                      • +3
                        Та ладно! Половина open source софта, весьма известных названий с которым я имел дело, вообще не знает каким именно чудом оно компилируется под винду. IOCP для них — черная магия. Пишут в лоб да как по-проще. И это еще в лучшем случае.
                      • 0
                        Под вынью не пробовал, но поговаривают 10к не тянет.
                        • +4
                          Вот на винде, я понимаю, в WinAPI функция мультиплексирования select — не масштабируемая, и на прикладном уровне дает сложность o(n), что в принципе может создавать проблемы для 10 000 и больше соединений (или все-же справляется?), ну а у linux в чём беда?


                          При всем моем уважении, select() была функцией мультиплексирования на винде лет двадцать назад. Последние лет… много используется GetQueuedCompletionStatus() которая волне себе способна держать до миллиона входящих TCP подключений, из них одновременно передающих данные ~ 10k.
                          • 0
                            Ну, наверное я немножко устарел. Года 2 назад писал веб-сервер, не помню что курил и читал, но альтернативы тогда не нашел. Сейчас сеть у меня сводится к QNetworkAccessManager, как бы печально это не звучало.
                            • +4
                              При всем моем уважении и любви к Qt, QNetworkAccessManager не предназначен для создания чего-нибудь сложнее нескольких соединений. По этому поводу есть много материалов в гугле, но если есть желание можете посмотреть в код — он там простой и страшный.
                              • +1
                                Для винды он там cводиться к WaitForОлолоОbjectОлоло, смотрел. Да знаю я, просто как факт, там где нужна высокая производительность, я так и не делаю, а Qt для клиентский приложений — awesome.
                          • +2
                            А при чем здесь винда? Это select сам по себе такой. Более того, оригинально он еще и битмаски использовал, что мешало ему работать с дескрипторами имеющими номер выше определенного (насколько я знаю apache делает кучу dup2 для перемещения несокетных дескрипторов «вверх» и сокетных — «вниз»). Вообще, история c10k в юниксах (включая wannabe — типа линукса) — это леденящий душу триллер.
                          • 0
                            А почему ожидалось, что Go порвет Erlang?
                            • 0
                              Нативно-компилируемы потому что, наверное
                              • +3
                                А при тестировании Erlang использовался HIPE или нет?

                                Еще, я смотрю есть код для Ruby, как он себя показал?
                          • +3
                            Во-первых, «C10k», почти наверняка, — проблема 10 тысяч соединений, а не тысячи.
                            Интересней было бы добавить сюда реализацию на каком-нибудь С (или хотя бы с использованием либы на С). Так, чисто для сравнения. Ну и перл с haskell'ом, чтоли.
                            • 0
                              Да, уже исправил на 10 000 :)

                              Хаскель в бенчмарке есть, а С и Перл можно добавить (Гитхаб же :) )
                              • 0
                                да, хаскел «не заметил»: задумался на середине ответа и дописал хаскелл уже позже ;)
                                Пойду попробую изобразить что-нибудь на перле аналогичное…
                                • 0
                                  Я исходники не смотрел, но судя по описанию действительно тест 1000 подключений происходит, так как при создании подлючения каждую миллисекунду = 10 секунд по 1000 подключений в секунду.
                              • +8
                                s/Латентность/Задержка/
                                • +1
                                  Ох уж эта политкорректность! :) Сейчас исправлю :)
                                • 0
                                  довольно интересно. обязательно попробую у себя на сервере.
                                  какая версия nodejs у вас использовалась?
                                  • –1
                                    Что говорится, мопед не мой, так что не знаю :)
                                    • +2
                                      Стоп, а если мопед не ваш, то где ссылка на автора? Я до последнего комментария был уверен, что это ваше исследование и вы провели позитивную работу и сделали вклад. Черт побери!
                                      • –2
                                        :) Ссылка на автора — ссылка на Гитхаб :)
                                    • 0
                                      С Go в этом случае причина, насколько я понимаю, состоит в том, что по умолчанию «goroutine», которые используются в Go для реализации многопоточности, являются легковесными только до тех пор, пока им не понадобится делать какие-нибудь блокирующие операции, например чтение-запись в сокеты. Когда же goroutine требуется прочитать что-то из сокета, она превращается в обычный thread операционной системы, что должно весьма плохо сказываться на производительности, хотя коннект может действительно при этом идти быстро.
                                      • +2
                                        Все операции ввода-вывода и прочие системные вызовы в Go асинхронны хоть и имееют api который выглядит, как блокирующий. Единственный способ написать блокирующий код в Go — это долгие вычесления, которые обычно достаточно быстры благодаря компилируемой природе языка.
                                        • +1
                                          Кроме того горотуны не превращаються в обычные потоки в класическом понимании. Планировщик (scheduler) выполняет их в зависимости от того ждут ли они на результат асинхронной операции (любые системные вызовы или ожидание на ответ из канала), или же готовы к исполнению, на одном из реальных thread-ов, которые есть у него в пуле (на данный момент количесто таких потоков зависит от переменной среды GOMAXPROCS).
                                          • 0
                                            Так почему он себя так плохо показал? Выходит го не подходит для высоконагруженных проектов?
                                            • 0
                                              Ну конкретно у реализации вебсокетов модель немного другая, насколько я понимаю — они больше заточены под более-менее тяжелую обработку запросов, нежели на замену nginx. Ещё может быть вариант, что автор что-то не так намерял, ибо он, видимо, в 32-битной системе это тестировал.
                                              • 0
                                                То есть если поставить перед го приложением nginx то будет всё ок?
                                                • 0
                                                  Насколько я знаю, на Хабре есть люди, которые используют Go в продакшне, лучше всего у них спрашивать :). Я не вижу особого смысла в nginx ни для этой задачи, ни для каких-либо других. Разве что для раздачи статики лучше nginx использовать, но это обычно итак делается с других IP и доменов.
                                                  • +1
                                                    Был Pirro, он ещё сериал про создание сайта на го запускал. Только пропал он и на лс не отвечает
                                              • +3
                                                Попробуйте тот же Go только используя компилятор GCCGO. Обычно это дает ощютимый прирост производительности. На данный момент стандартная связка для Go значительно слабее оптимизирует чем GCC. Это скорей всего улучшиться в будующем, но сейчас удобней разрабатывать с стандартным компилятором, а в продакшн с GCCGO.

                                                Кроме того библиотеки в Go достаточно свежы и возможно что-то и где-то можно оптимизировать. Если у вас есть идеи/пожелания — посылайте их golang-nuts или golang-dev рассылки и вас скорей всего выслушают, а если будет еще и какие-то изменения, которые очевидно улучшают производительность — с радостью их приймут.

                                                Наверное самым слабым местом в Go сейчас являеться планировщик, который определенно будет улучшен в будующем (GOMAXPROCS — хак, а не решение всех проблем).
                                              • 0
                                                Я, честно говоря, тоже себе примерно так это и представлял, но видимо это не вся правда…
                                            • 0
                                              10к это было давно для обычных сокетов, сейчас для той же джавы 10к уже не проблема.

                                              А веб сокеты что ли только подбираются к этому пределу? Или я что-то не так понял?
                                              • +2
                                                а зачем вебсокет… надо было tcp сокет делать
                                                • +7
                                                  Тоже смотрел на результаты с недоумением. Также для питона не плохо было бы добавить результат по Tornado.
                                                  • 0
                                                    А лучше сразу для gevent
                                                    • –1
                                                      O_o
                                                      А сейчас там что?
                                                      • +2
                                                        Там в ws4py старый gevent, а не 1чка, насколько я помню. 1чка на другой либе с кучой багфиксов и крэшфиксов.
                                                        Более того, насколько видно сравнение некорректно, т.к. процесс не параллелили.
                                                        Пускай запустят например даже gunicorn+gevent, это вполне возможно, с учетом использования wsgi.

                                                        • 0
                                                          gevent 1.0 еще не зарелизили, так что всё честно ^_^ Ну и сомневаюсь, что обновление до 1.0 хоть что-то существенно исправит.

                                                          wsgi в вебсокетах не используется, насколько мне известно.

                                                          Ну и, пожалуй, есть смысл сделать erl -smp disable для эрланга и замерить как эрланг будет себя вести, если отключить расползание по процессорам.
                                                          • +2
                                                            Исправит фундаментальные баги в libevent, который заменили на libev в gevent 1.
                                                            Ну значит тест не честный опять же.
                                                            Надо было переписать ws4py с мультифорком, чтобы у каждого хаба geventа была возможность заполнить все ядра. В эрланге это нативно.

                                                            Я это к чему. Мы держали 20000 соединений TCP постоянных на 2 серверах (по 5 тысяч соединений на сервер + mysql + memcache).
                                                            Если бы не проблема миддлвари можно было бы вешать и больше соединений.
                                                • 0
                                                  То что NodeJS и Python перестали работать — скорее всего уперлись в ограничения ОС (количество файл-хендлов) надо ОС подтюнить и должны заработать.
                                                • +1
                                                  Из описания непонятно, как рассчитывалось «Соединений» и с какой точностью. Может там до 10K одновременных далеко еще.

                                                  Кстати, автор там чего-то подрефакторил и будет повторно тестировать. Подождем.
                                                  • +3
                                                    Табличка вообще не имеет смысла, поскольку задача решена только Erlang. Остальные просто выпадают из сравнения, как не решившие задачу. Смысла сравнивать по остальным параметрам нет. Если же идти на компромисс и учитывать только отработанные запросы, то не понятна средняя задержка у NodeJS в 42 секунды — не верю!
                                                    • +3
                                                      По поводу средних 42 секунд (если вы считаете, что это много).

                                                      Вполне объяснимая задержка – нода ковыряется на одном процессореядре (про cluster писали выше ), очередь сообщений копится, node не успевает всё обрабатывать, и поэтому «вжжжиииууу» © получается только на старте.

                                                      Грубо говоря, запустив ещё один node.js на другом ядре можно удвоить скорость, если есть ещё свободные ядра – будет +100500 к скорости такой вот синтетической «обработки» сообщений. На практике цифры конечно не такие радужные, ибо бизнес логика, mongo/mysql + гремучая смесь различных модулей из npm, которые поголовно версии ~0.x / ~0.0.x.

                                                      Как по мне, так на данный момент развития node, дешевле расширять ферму, докупать «облака» и запускать ещё процессы, чем допиливать каждый модуль до состяния «чак норрис+».

                                                      PS: А ещё оно при «правильном» обращении умеет течь, причём всем сразу. Но это уже руки.
                                                    • 0
                                                      Кроме того, актуальность самой проблемы C10K мне кажется преувеличенной. Когда нагрузка вырастает до таких размеров, неизбежно начинается горизонтальное масштабирование по другим причинам. Хотя бы из-за надежности. Причем его можно начать уже с 1K и данной проблемой не париться.

                                                      Или я ошибаюсь?
                                                      • +8
                                                        Это концептуальная проблема. Она ценна не самом по себе, а для оценки системы в целом. В частности — когда именно пора делать горизонтальное масштабирование :).
                                                        • +1
                                                          Так моя мысль и состоит в том, что «пора» наступает намного раньше, чем исчерпываются возможности веб-сервера по обработке соединений. Не хватает CPU, памяти надежности и т.д.
                                                        • +5
                                                          Вебдевелопер?
                                                          Не всё так легко горизонтально масштабировать, есть приложения которые отлично справляются со своей задачей без горизонтального масштабирования и обслуживают по 10тысяч соединений.
                                                          • –1
                                                            Интересны ваши примеры. Я видел разные приложения, но с 10К — нет.
                                                            • 0
                                                              Ну если нужен пример того, что будет проблематично горизонтально масштабировать, то игровой сервер для игрушки типа wow с общим миром на 10к игроков.
                                                              А если просто сервера, обслуживающие 10ки тысяч полуактивных соединений, то это мессенджеры, системы мониторинга итд.
                                                              • +1
                                                                Нужны реальные примеры. Теоретически-то я представляю. А вот в реальности как системы работают, это интересно.

                                                                Например из Яндекса или из другого highload проекта кто-нибудь сказал бы, по сколько соединений у них обслуживают фронт-енд сервера. И как они понимают, что пора добавлять. Сдается мне, что упираются узким местом становится совсем не количество соединений.
                                                                • 0
                                                                  UO сервер, далёкий 2003ий год на старом железе и тогда ещё на тормозном .net'е: «During our stress test we had over 9,000 users logged into UOGamers: Hybrid. We were still able to walk, talk and run around despite some small amounts of lag. The server held it's own with over 9,000 users logged in»
                                                                  И сетевая часть там достаточно ужасно реализована.
                                                                  • +1
                                                                    Если я не ошибаюсь, в ультиме, если не стоят посреди города в самой гуще общения с сервером будет очень. Даже очень мало. Помню я где-то в начале 2000-х играл в УО на модеме и всегда обходил стороной центр города, а вроде-бы в где-то в 2004-м, когда в Москве только начал появлятся выделенный интернет (со скоростью чуть большей, примерно в 4-8 раз, нежели модемная) у меня друзья держали свой сервер где по вечерам играли до 500-600-700 человек (точные цифры уже они наверное и сами не помнят).
                                                                    • 0
                                                                      Во время стресс теста лаги появились из-за недостаточной пропускной способности канала 1Gbit.
                                                                      • 0
                                                                        А вот это уже интересно. Хотя и немного странно: во временя УО каналы были, мягко говоря, не такими широкими как сейчас. Не представляю себе ситуацию, как 15 лет назад на комманду логина мне могли прислать xml-лину или json-нину в пару тройку метров (как это делают сейчас многие).
                                                                        • 0
                                                                          На время теста была предоставлена дорогая по тем временам железяка и хороший канал. Но сам сервер можно считать что однопоточный, кроме идиотской реализации таймеров/таймаутов которая вынесена в отдельный тред, сохранение мира в несколько тредов, ну и сеть через iocp(tp).
                                                                  • +1
                                                                    Ну допустим игры в социальных сетях, там несколько десятков тысяч конкрарентов это нормально. То чем занимался я, не было столь успешно и держало всего лишь до 4к на одной ноде (около 1к io бинарных пакетов в секунду), просто больше народу не приходило :(. Загрузка, я бы не сказал что была такая уж и большая, таски выполнялись достаточно быстро. В среднем по мс на таску (типа посадить дерево, собрать урожайчик) — не подскажу уже, но там счет был в миллисекундах.

                                                                    Из достаточно популярных социалок, был перед глазами пример как 2 сервера обрабатывали до 27к+ конкарентов (соотношение по серверам примерно 3к1, io-пакетов в секунду примерно 3-4к), к сожалению что там и как дальше было — не в курсе, знаю что серверов стало чуточку больше как и пользователей.

                                                                    • +2
                                                                      Ещё кое-что вспомнилось по миллиону соединений :)
                                                                      www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-3
                                                                      blog.whatsapp.com/index.php/2011/09/one-million/
                                                                      • 0
                                                                        Да, впечатляет.
                                                                        Хоть и сделано было в обоих случаях, как я понял, чисто «на рекорд».
                                                                      • +3
                                                                        У нас («Мамба») сервера, которые обслуживают real-time штуки — соединение по amf-протоколу с флешкой и соединение через long polling/comet — держат порядка миллиона соединений каждый (или, во всяком случае, держали, когда я смотрел это последний раз). линукс, написаны на плюсах, особых проблем не наблюдается.
                                                                        • +1
                                                                          long polling это немного другой сценарий. Но все равно интересно, спасибо. Сколько памяти используется в среднем на сессию?
                                                                    • +2
                                                                  • +6
                                                                    Представьте, надо Вам обработать 30к соединений.
                                                                    Вот и вопрос: либо 4 (+1 для надежности) машины на Erlang, либо 10-20 машин на условом другом языке, который тянет только 1К.
                                                                    Есть разница с точки зрения стоимости решения?
                                                                    • 0
                                                                      Вот я к этому и клоню, к стоимости.

                                                                      Если честно, 30К не представляю. :) Но давайте прикинем, теоретически. Сколько нужно памяти на одну сессию? Допустим 300 Кб; тогда на всех нужно 8.5 Гб. Это скромная оценка, при 64-разрядном приложении может и все 16 выйдет. Так же прикинем необходимую мощность CPU, I/O и других подсистем. А дальше прикинем, как выгоднее — распределить все эти пощности на 1-2 сервера или на 10-20? Если на 1-2, то наш выбор ограничивается «большими» серверами от известных вендоров. Их стоимость, стоимость поддержки и особенно стоимость компонентов для апгрейда вы, надеюсь, представляете. В случае же с 10-20 блейдами стоимость в расчете на один мегагерц CPU, гигабайт ОЗУ или гигабайт дискового пространства выйдет намного дешевле.

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

                                                                      Так что разница есть.
                                                                      • 0
                                                                        > Допустим 300 Кб; тогда на всех нужно 8.5 Гб
                                                                        nginx: «10,000 inactive HTTP keep-alive connections take about 2.5M memory;»
                                                                        • 0
                                                                          Это прекрасно, но мы же говорим о системе в целом, а не об одном Nginx.
                                                                          • 0
                                                                            Ну берём опять же игровой сервер, весь мир хранится в памяти, так что без разницы сколько у нас там соединений, всегда будем отъедать nM памяти. Возьмём опять же ультиму, с жутко переполненым миром и будет у нас ~1G на динамические сущности + ~1G на карту/статику.
                                                                            Подключим к этому серверу 10,000 соединений, теперь наш сервер отъедает на 2,5M больше памяти.
                                                                            Как от кол-ва соединений может взлететь расход памяти мне не особо понятно.
                                                                            Предположим что к нам подключились какие-то мудаки, которые отправляют пакет максимально допустимой длины и висят недоотправив последний байт, мы изначально ограничили максимальный размер пакета в 64K, тогда конечно придётся к этим 10,000 соединениям прибавить ~625M.
                                                                            • 0
                                                                              > Как от кол-ва соединений может взлететь расход памяти мне не особо понятно.

                                                                              Данные самой сессии где-то держать надо?
                                                                              • 0
                                                                                typedef struct epoll_handler epoll_handler;
                                                                                struct epoll_handler {
                                                                                  int (*fn)(epoll_handler*);
                                                                                };
                                                                                
                                                                                struct session {
                                                                                  int fd;
                                                                                  int events;
                                                                                  epoll_handler handler;
                                                                                  list timeouts_node; // intrusive list, 16B на 64бит
                                                                                  buf read_buf; // 24B на 64бит +- расход на недогруженые пакеты в пределах 64B
                                                                                  queue write_queue; // 16B на 64бит +- расход на пакеты для отправки
                                                                                  size_t write_offset;
                                                                                  int player_id;
                                                                                }
                                                                                

                                                                                + затраты ОС
                                                                                + активация нескольких таймеров, связаных с залогинеными игроками.
                                                                                От этого расход памяти особо не взлетит.
                                                                                • 0
                                                                                  Вы так и не сказали, где держатся данные самой сессии — то есть данные залогиненного пользователя ;) только player_id можно не обойтись
                                                                                  • 0
                                                                                    Вся информация обо всех игроках уже находится в памяти и не зависит от количества сессий. Когда игрок выходит из игры, то просто переходит в состояние, когда другие его не могут видеть, но данные об этом игроке всё равно важны для нормального функционирования всего мира.
                                                                        • +4
                                                                          300Кб на одну сессию… в некоторых случаях жировато будет. Хотя в яве допустим 300кб — это смешные цифры, особенно если в хипе куча коллекций (там оверхед до 98% бывает, например ConcurrentHashMap с парой простых объектов из нескольих полей).

                                                                          А так, у меня при 1к онлайне и ~1.5к юзеров в памяти (при кэше в виде SoftReference) хип отъедал до 2 гигов. Собственно по метру на пользователя. При использовании кэша с WeekReference цифры были немного другие, при той же тысячи, в хипе около 1.2-1.3 гига.

                                                                          • 0
                                                                            32 бита?
                                                                            • +1
                                                                              64, у меня в среднем было 200-300кб памяти на казуала, всякие задроты и топ-левел игроки отъедали примерно по 0.7-2мб.
                                                                          • 0
                                                                            > Если честно, 30К не представляю. :)
                                                                            Все определяется приложением и проектом. У меня сейчас в пиках до 25К.

                                                                            > Но давайте прикинем, теоретически. Сколько нужно памяти на одну сессию?
                                                                            Это сильно теоретически, все зависит от того, что делать.
                                                                            В некоторых задачах на 1 коннект нужно меньше 1КБ.
                                                                            Есть даже пример — комет-сервер на Erlang, держащий 1 миллион(!) подклключений. Это на одной машине! Если не путаю, там 64ГБ оперативы. Вобщем не такие страшные цифры на сегодняшний день. Типовая машина.

                                                                            > Кроме того, при дальнейшем масштабировании стоимость каждой дополнительной единицы мощности в первом случае будет возрастать, а во втором — оставаться такой же или даже падать.
                                                                            Разве я написал, что надо работать на 1 супермашине?
                                                                            Ни в коем случае! Приложение должно эксплуатироваться минимум на 2 машинах, чтобы при сбое, оно могло продолжить работу. Даже пример привел: 3 рабочих сервера + 1 запасной.
                                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                                          • +2
                                                                            1к — это все таки довольно мало. Хотя опять же, смотря для чего. Если взять к примеру геймдев, то 1к юзеров в мморпг на одной машине — много, особенно если они в одном месте. Для тех же социалок, 1к — раз плюнуть. Одной строчкой кода ставим ограничение на клиенте на действие, раз в три-четыре секунды + анимация этого всего и у нас поток запросов снижается в несколько раз (больше чем в три). Тут и 10к нормально живет и вторую машину не требует (если коечно постоянно в рсубд не лезть).
                                                                          • +1
                                                                            Очень странные результаты. Проверю вечером на сервере.
                                                                            • +1
                                                                              Пожалуйста, выложите результаты. Очень интересно.
                                                                            • +2
                                                                              Немного большего ожидал от node.js
                                                                              • +2
                                                                                www.insight-it.ru/masshtabiruemost/arkhitektura-vkontakte/

                                                                                Утверждается, что чат у Вконтакта живет на node.js, на 5 серверах, используя по 4 процесса на сервер, при этом, пиковая нагрузка составляет 150 000 соединений. Итого, 150 000 / (5 * 4) = 7 500. При этом, здесь говорится, что node.js падает, грубо говоря, на 6 000 соединений.

                                                                                С другой стороны, Erlang, как и ожидалось (я, как увидел Erlang в списке тестируемых серверов, сразу глянул на автора статьи — и не ошибся), показал себя не просто лучше всех, а единственно правильно. То есть, безупречно. Блин… а ко мне, как раз, с Амазона в понедельник книжка приехала «Erlang programming».
                                                                                • +1
                                                                                  При том что эти сервера ещё и держали коннект с MySQL базой.
                                                                                  • +1
                                                                                    Да, кстати, немаловажное замечание: в случае, если данные о Вконтакте верны, там не просто синтетические соединения ради теста, а рабочие…
                                                                                    • 0
                                                                                      На момент написания поста данные верные, насколько это известно от разработчика той вресии сервера.
                                                                                  • 0
                                                                                    Это судьба.
                                                                                    • 0
                                                                                      Мы сами творцы своего счастья. Амазон же не от доброты душевной мне ее прислал ))

                                                                                      Но, честно сказать, вот так вот, после тесного общения с PHP и JS… Erlang кажется чем-то запредельным. К тому же, не изобилует комплит бегиннерс гайдами. Вот я уже почти неделю штудирую все вдоль и поперек в поисках такого про Webmachine — как создать Restful API с его помощью. А вот для node.js подробный гайд сразу нашелся.
                                                                                      • +1
                                                                                        > Вот я уже почти неделю штудирую все вдоль и поперек в поисках такого про Webmachine — как создать Restful API с его помощью.

                                                                                        Берется wiki.basho.com/Webmachine-Resource.html и потом любой проект с использованием webmachine, и смотрится в код :)

                                                                                        Ну и добро пожаловать в erlanger.ru/page/672/soobshhestvo (рассылка и чат)
                                                                                        • 0
                                                                                          и потом любой проект с использованием webmachine, и смотрится в код
                                                                                          Я пытался. Я честно пытался. Не поверите — мне потом снился Erlang.
                                                                                          • +1
                                                                                            На самом деле главная проблема в том, что webmachine — это HTTP-фреймворк, а не REST-фреймворк. Но в какой-то момент в голове происходит щелчок и становится понятно.

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

                                                                                              И вот одно такое: github.com/tegioz/wall
                                                                                      • +6
                                                                                        Чтобы понять эрланг, нужно забыть все, что знаете о программировании на императивных языках.
                                                                                        Мои основные ошибки при изучении:
                                                                                        1. Пытался использовать эрланг как питон
                                                                                        2. Считал эрланг высокоуровневым.
                                                                                        Насчет второго: эрланг примерно столь же низкоуровневый, как и Си. Только он отражает работу совершенно другого процессора.

                                                                                        Ну, и начинать изучение эрланга с использования webmachine – примерно то же, что начинать изучать Ruby с рельс.
                                                                                        • +1
                                                                                          Ну, и начинать изучение эрланга с использования webmachine – примерно то же, что начинать изучать Ruby с рельс.
                                                                                          Отчасти вы правы, но только отчасти. Я не хочу спорить. Я стал интересоваться им для решения конкретной задачи — организации четко определенного API и пока не более. Да, звучит довольно легкомысленно. Я на раз-два-три могу сбацать такое API, по крайней мере, на node.js. На раз смогу сбацать на PHP. Оба варианта будут в изрядной степени приемлемы (требования определяю я же).

                                                                                          Это похоже на то, как человека бросают в воду, а дальше два варианта — либо выплывет и научится плавать, либо спасают его.

                                                                                          Заранее, чтобы не плодить холивары — можете считать, что я так развлекаюсь и полностью отдаю себе отчет о возможных последствиях.
                                                                                          • +1
                                                                                            > Это похоже на то, как человека бросают в воду, а дальше два варианта — либо выплывет и научится плавать, либо спасают его.

                                                                                            Лучший способ учить язык, имхо :) Потому что хеллоуворды действительно неинтересны и ничему не учат
                                                                                          • +1
                                                                                            Если Эрланг такой же низкоуровневый как Си, то OCaml — это ассемблер :) У меня, при первом знакомстве с последним было впечатление, что я до этого момента никогда не видел функциональных языков. При том, что стандартную эрланговскую книжку уже прочитал.
                                                                                      • +3
                                                                                        > 7 500. При этом, здесь говорится, что node.js падает, грубо говоря, на 6 000 соединений.
                                                                                        Это числа одного порядка, чуть сильнее проц, чуть другие настройки ОС, немного более сложная обрабтка соединений, и одно превращается в другое. Вот если бы было 6К и 30К — это была бы ощутимая разница.
                                                                                    • 0
                                                                                      На Гитхабе отображается интересная статистика используемых языков:

                                                                                      • +3
                                                                                        Ну так все логично. Сам тест то на эрланге написан.
                                                                                      • +4
                                                                                        Судя по коду node.js работал всего лишь на одном ядре…
                                                                                        • +2
                                                                                          В этом, собственно, одна из проблем ноды — то что SMP надо устраивать ручками
                                                                                          • 0
                                                                                            Да я то в курсе… Щас просто понабегут нодахейтеры)
                                                                                            • –3
                                                                                              Это не проблема ))) А особенность
                                                                                              • +12
                                                                                                Для фреймворка, позиционирующего себя как для «building fast, scalable network applications.» отсутсвие smp — это не особенность, а недостаток
                                                                                                • 0
                                                                                                  Возможно, но сколько времени займет переписать написанный код на эрланге и написанный код на яваскрипте?
                                                                                                  • 0
                                                                                                    Если он уже написан, зачем его переписывать? :)

                                                                                                    Вопроса не понял :)
                                                                                                • 0
                                                                                                  вы ещё скажите «фича»
                                                                                                • –4
                                                                                                  С тем же успехом можно сказать, что если надо запустить erlang на одном ядре — это надо устраивать ручками.
                                                                                                  • +4
                                                                                                    Для фреймворка, позиционирующего себя как для «building fast, scalable network applications.» отсутсвие smp — это не особенность, а недостаток
                                                                                                    • +2
                                                                                                      Именно поэтому node cluster уже как полгода доступен. Попробую выжать вечером побольше RPS из этого бенчмарка.

                                                                                                      P.S. Я бы не тратил силы на критику проекта с версией 0.6.19 ;)
                                                                                                      • +2
                                                                                                        Поверьте, это не аргумент. Притом, что я, тем не менее, отношусь с большим уважением к node.js (ну не знаю… я вообще очень позитивный человек и верю в лучшее), но их главная страница, как это и полагается, довольно вызывающа. Типа, посмотрите, поцанчики — нас юзают и Yahoo, и ebay, и Linkedin. Так что отсыл к версии выглядит немного… по-детски, что ли. Как и утверждение «для каждой задачи свои инструменты» в данном контексте.

                                                                                                        Вот аргумент «у node.js все еще впереди» — это уже более весомо. И я, кстати, согласен. Но! Erlang, сволочь, харизматичный. Сначала я напугался. Сильно. Теперь у меня чувство… что-то вроде «вон сколько программеров осилили его, я чо, хуже, что ли».
                                                                                                        • 0
                                                                                                          И ведь действительно используют. И на больших нагрузках. И они смогли написать модуль для кластеризации и довели его до включения в ядро. о том я и говорю, что на данный момент это в Node.js есть и незачем ссылаться на статьи годовалой давности м надежде подкрепить свою убеждённость что node.js чего-то не умеет :) Год назад у них на сайте совсем другой текст бы :)
                                                                                                          • 0
                                                                                                            Вот что бывает, когда пишешь комментарии на Хабре во время работы :)
                                                                                                        • +2
                                                                                                          Вот кстати, с кластером очень интересный эффект получили.
                                                                                                          Запустили на нем приложение — без нагрузки 2 ядра загружены на 100%.
                                                                                                          • 0
                                                                                                            Они друг за другом следят
                                                                                                    • –1
                                                                                                      Не вижу как можно в ноде что-то выиграть от использования SMP, это же тупо запуск нескольких процессов. С тем же успехом можно и на NUMA гонять, у ерланга в этом плане более выигрышное положение.
                                                                                                      • 0
                                                                                                        Ну и я, в принципе, о том же :)
                                                                                                      • +1
                                                                                                        могу ошибаться, но вроде собственно IO в Erlang работает в отдельном одном потоке. А уже обработчики могут расползаться по ядрам.
                                                                                                        • 0
                                                                                                          I/O которое файловое — да. Насчет сети не знаю. Скорее всего тоже, но именно сетевая часть у Erlang'а быстра и непробиваема :)
                                                                                                    • +1
                                                                                                      Ох, лол. В вики написано, что Tornado успешно преодолевает 10k.
                                                                                                      • 0
                                                                                                        Вики лучше не верить. Вон, node.js как бы тоже должен его преодолевать :)
                                                                                                        Ну и про торнадо относительно старое: lionet.livejournal.com/42016.html
                                                                                                        • 0
                                                                                                          Вы погодите петь победную песню, погодите. Вечером вон товарищи обещали перепроверить данные.
                                                                                                          • +2
                                                                                                            На гитхабе уже накатали тесты для Tornado.
                                                                                                        • +2
                                                                                                          Все зависит от архитектуры, изначально предполагается, что торнадо будет запускаться в несколько апстримов с балансировщиком.

                                                                                                          Производительность отдельного воркера, имхо, достаточно зависимая и непоказательная величина, на которую влияет многое, но в основном количество блокирующих i/o операций в них (например, сделать запись в лог), так как сервер псевдоасинхронный.
                                                                                                          • +2
                                                                                                            Увы, ребята из мира Erlang привыкли что это работает из коробки и встроено в язык/VM. Пожалуй это единственное, что мешает сторонам договориться.
                                                                                                        • +1
                                                                                                          Никому не кажется, что c10k уже основательно устарела? Вот 100k еще актуальна, а для 10k соединений достаточно взять любой удобный хотя бы jit'ируемый язык без сборщика мусора (как известно, эта дрянь обожает стартовать в самые неподходящие моменты), и дело в шляпе.

                                                                                                          P. S. знаю о чем говорю, писал polling сервер, который не напрягаясь обслуживал 30k одновременных соединений в пике.
                                                                                                          • –1
                                                                                                            Да как бы пофиг на каком языке сделать accept 100k соединений, это не проблема. Большинство проблем с обслуживанием 100k соединений появляется от использования всяких libuv.
                                                                                                            • –1
                                                                                                              libuv


                                                                                                              В смысле от библиотек, которые делают веб-разработку удобнее? Это для области «менее 500 запросов в секунду». Проблема c10k/c100k, как правило, либо нивелируется фронтендом, за которым живут десятки бакендов с этими «libuv», либо решается вручную с минимумом фреймворков и элементами тактодрочерства.
                                                                                                              • 0
                                                                                                                >В смысле от библиотек, которые делают веб-разработку удобнее?
                                                                                                                >Проблема c10k/c100k, как правило, либо нивелируется фронтендом, за которым живут десятки бакендов с этими «libuv»
                                                                                                                Ох уж эти веб-разработчики :)

                                                                                                                Ну например Boost Asio делает разработку сетевых приложений удобнее, а вот libuv создаёт проблемы с масштабированием, что можно забыть про сотни тысяч соединений.
                                                                                                                • +1
                                                                                                                  А в чем заключаются проблемы libuv кстати?
                                                                                                                  • 0
                                                                                                                    всё завернули в proactor pattern из-за винды.
                                                                                                                    А на юниксах можно использовать reactor pattern и для обслуживания 100к тысяч полуактивных соединений не надо будет аллокэйтить 100к тысяч буфферов.
                                                                                                                    • +2
                                                                                                                      А не, сейчас глянул исходник, они в отличие от многих других библиотек, которые реализуют работу с сетью в винде/юниксах, пошли по более эффективному решению и сделали alloc_cb параметром read'а вместо готового буффера — это позволяет на юниксах делать этот alloc только когда в сокет что-то прилетело.
                                                                                                                      Хотя есть ещё куча претензий вроде отсутствия интерфейсов, которые используют readv, но это уже не так важно. Проблема с масштабированием на юниксах снимается :)
                                                                                                                  • +1
                                                                                                                    >libuv создаёт проблемы с масштабированием
                                                                                                                    а можно поподробнее?
                                                                                                                    • +1
                                                                                                                      Boost Asio

                                                                                                                      Зачем нужна эта громадина, когда есть libev/libevent или epoll/kqueue для любителей все делать своими руками?
                                                                                                                • +5
                                                                                                                  В Erlang'е есть сборщик мусора. И?
                                                                                                                  • –3
                                                                                                                    Возможно, если бы его не было, среднее время соединения было бы значительно меньше секунды.
                                                                                                                    • +5
                                                                                                                      Ели бы у бабушки был член, то она была бы дедушкой ©

                                                                                                                      Главное ведь — не имея на руках никаких данных по работе сборщика мусора, и имея на руках данные о прекрасной производительности (низкая задержка, обработка всех соединений), сказать хоть что-либо, что хоть как-то подтвердит фантазии насчет GC.

                                                                                                                      • –1
                                                                                                                        имея на руках данные о прекрасной производительности


                                                                                                                        Почти секунда на установку соединения как-то не вяжется в моем понимании с «прекрасной производительностью».
                                                                                                                        • +2
                                                                                                                          Ть вот эта установка соединения почти наверняка к GC не имеет никакого отношения.
                                                                                                                • 0
                                                                                                                  Ткните пожалуйста ссылкой на тест с Tornado?
                                                                                                                • +5
                                                                                                                  Pythin (ws4py)
                                                                                                                  Who is mr. Pythin? :)
                                                                                                                • +1
                                                                                                                  А есть результаты по EventMachine?
                                                                                                                  • 0
                                                                                                                    Пока нет. Если будут, будут тут: github.com/ericmoritz/wsdemo/blob/master/results.md
                                                                                                                    • 0
                                                                                                                      А можно их реквестировать в тексте статьи? Не сильно ведь будет страшно поставить второй UPD. Или третий…
                                                                                                                      • 0
                                                                                                                        если я не забуду и если будет время :)