Автор | Сообщение |
rv82
46 сообщений |
#5882 2012-03-14 18:51 GMT+3 часа(ов) |
Здравствуйте! Как известно, в составе Racket есть web-сервер. Также, не составит труда и самому написать многопоточный web-сервер. Вопрос в том, сможет ли такой сервер работать под большими нагрузками (сотни тысяч или даже миллионы подключений)? Или лучше для этого использовать связку Apache+Racket (как CGI)? Правда, если использовать последний вариант, то отпадают такие приятности, как continuations.
Говорят, Tomcat может обслуживать огромное количество подключений. Также, говорят, что на Node.js тоже можно писать тяжелонагруженные приложения. Но ведь в составе Racket тоже есть JIT-компилятор! А сам язык несравненно более удобен, чем Java/JavaScript. |
|
megamanx
307 сообщений |
#5885 2012-03-15 00:04 GMT+3 часа(ов) |
Цитата Угу, каэшна, он один есть истина и свет во тьме. Цитата Хуясе, а чё не миллиарды? Цитата В одиночку нет, если сверху поставить кеширующий сервер (++архивирующий, а ещё статику вынести на отдельный сервер), то сможет. |
|
I wish I'd made you angry earlier
|
|
misha![]()
1275 сообщений |
#5888 2012-03-15 00:56 GMT+3 часа(ов) |
ЦитатаКонечно, но потребуется железо соответствующее текущим потребностям. ЦитатаЭтого невозможно добиться без средств выравнивания нагрузки. Для мощного сервера-одиночки максимум это 10000 активных подключений, т.к. большее количество может привести к непредсказуемым последствиям (вплоть до отказа ОС). ЦитатаЕще хуже, т.к. будет тратится много ресурсов на запуск интерпретатора. |
|
misha![]()
1275 сообщений |
#5889 2012-03-15 01:23 GMT+3 часа(ов) |
ЦитатаПисать Java/JavaScript не совсем корректно, ибо JavaScript - это самостоятельный язык (диалект ECMAScript) и к Java не имеет никакого отношения. Кстати, хорошие интерпретаторы JavaScript по производительности не уступают лучшим интерпретаторам Лиспа. |
|
megamanx
307 сообщений |
#5890 2012-03-15 02:30 GMT+3 часа(ов) |
Цитата И что, смогёт? Это вопрос, это не издёвка. Сборщик мусора справится и способен подгребать под себя много памяти, система расчитана на многоядерные сервера, как ведёт себя при превышении лимита памяти? |
|
I wish I'd made you angry earlier
|
|
misha![]()
1275 сообщений |
#5892 2012-03-15 03:01 GMT+3 часа(ов) |
ЦитатаПри нехватке памяти посылается исключение, которое можно перехватить и обработать. |
|
rv82
46 сообщений |
#5896 2012-03-15 11:30 GMT+3 часа(ов) |
misha Это я в курсе. Под словом Java подразумевал Java+Tomcat, а под JavaScript -- Node.js misha А как соотносится производительность Racket с лучшими интерпретаторами Лиспа? Нашёл кое что по GNU Lightning, который используется в качестве jit-компилятора в Racket. Цитата Точно! Если в JS ещё есть анонимные функции, то в жабе о них только говорят. О макросах и речи нет. Цитата А кто ж его знает! Просто одна контора хочет сделать один "социально значимый" проект. Поначалу больших нагрузок конечно же не будет. А потом, кто знает? Если сама контора до тех пор не сгинет. |
|
megamanx
307 сообщений |
#5897 2012-03-15 13:54 GMT+3 часа(ов) |
то в жабе о них только говорят Они есть, только требуют громоздкого кода... ну это к слову пришлось. Горизонтальная расширяемость слабо связана с языком программирования, и даже не так сильно связана с базой данных. Слабое звено - это кеширование данных и, скажем, синхронизация работы на многих серверах. Важна также скорость разработки, и вот тут могу поспорить, что рекет хорош. Плюс - безопасность (о которой вообще ничего не известно для твоего фреймворка на рэкете), стабильность работы (о которой тоже ничего не известно, ведь, как говорил misha, стабильность не померить). |
|
I wish I'd made you angry earlier
|
|
Kergan
300 сообщений |
#5898 2012-03-15 17:50 GMT+3 часа(ов) |
> Поначалу больших нагрузок конечно же не будет. А потом, кто знает?
Надо просто писать с учетом масштабируемости. Перестанет хватать производительности - купим еще пару серверов. |
|
misha![]()
1275 сообщений |
#5911 2012-03-20 21:15 GMT+3 часа(ов) |
rv82Я тестов не производил. Хотя с кем сравнивать? Реализации CL не поддерживают продолжения. А если среди Scheme, то Racket, пожалуй, самая быстрая реализация. Как вам уже известно, слабое место любой платформы с поддержкой продолжений - циклы. megamanxБезопасность - это слабое место любого фреймворка. А стабильностью и апач не может похвастать (у меня он падал и не раз). У него другое преимущество - комьюнити. |
|
Kergan
300 сообщений |
#5915 2012-03-21 19:58 GMT+3 часа(ов) |
> Как вам уже известно, слабое место любой платформы с поддержкой продолжений - циклы.
А можно подробнее? Что не так с циклами? > А если среди Scheme, то Racket, пожалуй, самая быстрая реализация. А аналог веб-сервера racket на stateless-continuations вообще существует? Просто иначе continuation-based сервер не масштабируется. Никак вообще. |
|
misha![]()
1275 сообщений |
#5916 2012-03-21 23:03 GMT+3 часа(ов) |
ЦитатаПроблема не в циклах, а в реализации vm. Т.е. требуется довольно сложная vm, но это проблема разработчиков. Кстати, в Racket циклы реализованы довольно хорошо, я бы даже сказал не хуже, чем у LispWorks и Allegro CL. ЦитатаЧто такое stateless-continuations? |
|
Kergan
300 сообщений |
#5917 2012-03-21 23:58 GMT+3 часа(ов) |
> Проблема не в циклах, а в реализации vm.
Так какая именно сложность с циклами? Точнее - с хвостовой рекурсией? > Что такое stateless-continuations? stateless-servlets точнее. #lang web-server в racket. Осуществляется за счет cps-подобного преобразования кода, в результате продолжение можно сохранять у пользователя и передавать - например, в http-запросе, так что запрос может быть обработан любым сервером, а не только тем, куда пришел предыдущий запрос того же пользователя (как в случае обычных продолжений). |
|
misha![]()
1275 сообщений |
#5918 2012-03-22 01:06 GMT+3 часа(ов) |
ЦитатаА зачем использовать хвостовой вызов (для локальной функции), когда можно использовать локальные переходы? Т.е. можно преобразовать локальные функции, которые не используются извне, в циклы. ЦитатаОни это называют serialized continuations. ЦитатаЛучше не дарить хакеру такие подарки. ЦитатаДля этого обычно используют сервер БД. |
|
Kergan
300 сообщений |
#5919 2012-03-22 04:11 GMT+3 часа(ов) |
Цитата Но зачем это делать-то? Хвостовой вызов в идеале - тот же самый переход. То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки. Но при чем тут продолжения все еще неясно ![]() > Они это называют serialized continuations. Ну так где-нибудь еще они есть? В какой-то схеме я слышал было serializable, но оно порождало жуткие тормоза. > Лучше не дарить хакеру такие подарки. Не понял. Вся информация со стороны клиента _в любом_ случае передается в http-запросе (если мы используем http конечно). Так что с точки зрения хакера разницы никакой. Цитата В этом случае запрос может быть обработан только тем сервером, у которого есть доступ к соответствующей базе (в которой лежит продолжение конкретного клиента) - то есть масштабируемость отсутствует. Как только мы подключаем балансировщик нагрузок - мы теряем возможность сохранять продолжение на сервере. |
|
misha![]()
1275 сообщений |
#5920 2012-03-22 18:04 GMT+3 часа(ов) |
ЦитатаА как будет устроена эта vm? Большинство стековых машин вынуждены удалять предыдущий кадр стека. И тут главную роль играет механизм передачи аргументов и то, где размещается этот кадр стека. (Может подробнее?) Поэтому не стоит удивляться, что для .net хвостовой вызов в 8 раз медленнее обычного, т.е. единственная от него польза - экономия стековой памяти. ЦитатаЦиклы должны быть реализованы максимально эффективно, но большинство разработчиков полагается на хвостовую рекурсию. А почему? Да, потому что простейшая реализация продолжений - cps. Поэтому в большинстве случаев кое-как реализовав оптимизацию хвостовых вызовов разработчики полагают, что этого вполне достаточно и далее не заморачиваются. Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы. |
|
misha![]()
1275 сообщений |
#5921 2012-03-22 18:32 GMT+3 часа(ов) |
ЦитатаЯ этим не интересовался. Кстати, как быстра процедура десериализации? ЦитатаАнализ продолжения может дать полезную информацию о работе веб-приложения. Кстати, как будем проверять корректность продолжения? А то вдруг неприятель пошлет модифицированное продолжение, которое в поможет ему взломать приложение. ЦитатаДопустим у всех серверов есть доступ к БД, хранящей информацию о активных сеансах. Передавать пользователю всю информацию о сеансе крайне опасно. Поэтому пользователю передается обычно только зашифрованный идентификатор сеанса. |
|
Kergan
300 сообщений |
#5922 2012-03-23 02:31 GMT+3 часа(ов) |
Цитата Так оптимизация хвостовой рекурсии в том и состоит, что кадр стека _не удаляется_. И новый, соответственно, тоже не создается. Цитата Конечо, не стоит, ведь задачи эффективной реализации хвостовых вызовов для разработчиков .net не стояло. Цитата Очевидно, потому, что по производительности хвостовая рекурсия ничем не отличается от цикла (если оптимизация реализована правильно). Цитата Непонятно. Выше мы выяснили, что циклы не нужны - ведь их можно заменить хвостовой рекурсией, которая не медленнее. но вопрос изначально стоял - какая связь между циклами и продолжениями? С какой стати эффективная реализация хвостовой рекурсии закрывает продолжения? Цитата Там же в #lang web-server продолжение как таковое не сериализуется. В месте захвата продолжения лифтится лямбда, имя лямбды с конкретными аргументами (которые представляют обычные числа, строки - любые типы ЯП) пакуется и куда-то уходит (в БД, пользователю, да хоть в памяти кешируется). При десереализации мы считываем эти данные, захватываем имя лямбды, десериализуем аргументы - продолжение готово. То есть никаких накладных расходов связанных с рантаймом тут нет - скорость десериализации ограничивается ровно тем, с какой скоростью мы можем получить данные и распарсить их. Цитата Еще раз - в любом веб-приложении вся та же информация все равно проходит в запросах. Продолжение должно содержать ту и только ту информацию, которая нужна для того, чтобы четко определить состояние. То есть ровно ту информацию, которая необходимо будет в строке http-запроса. Это не значит, конечно, что мы не можем напихать лишнего - но это уже другая проблема. Не надо пихать ![]() Цитата Рано или поздно этот сервер таки не выдержит нагрузки, а второй уже не добавишь в силу особенностей архитектуры. Здесь, конечно, все зависит от того, где же будет этот момент "не выдерживания нагрузки" - но тут без тестов не скажешь, а их нет. |
|
Kergan
300 сообщений |
#5923 2012-03-23 02:34 GMT+3 часа(ов) |
Цитата Это ортогональный продолжениям вопрос. Такого рода информацию вполне можно отделять, так же как она отделяется в вебе. Кроме того state-less и state-full сервлеты можно смешивать - то есть делать так, что часть продолжения уходит пользователя, а часть - остается на сервере. |
|
misha![]()
1275 сообщений |
#5924 2012-03-23 03:15 GMT+3 часа(ов) |
ЦитатаПод удалением стекового кадра подразумевают преобразование верхнего кадра стека, по крайней мере, так зачастую реализован хвостовой вызов.Ты ведь хотел сказать написав "Но зачем это делать-то? Хвостовой вызов в идеале - тот же самый переход. То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки.", что существует какой-то способ оптимизации хвостовых вызовов, который я не знаю. Предложи как это сделать максимально эффективно без преобразования локальных функций. ЦитатаА мне не очевидно! Нужен полный анализ функции. Т.е. как я уже писал ранее, необходимо преобразование локальных функций в циклы, если это возможно. Это и есть полная оптимизация хвостовых вызовов. ЦитатаЭто только твои утверждения, т.е. тебе это еще необходимо доказать. ЦитатаПовторяю: "Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы." Если тебе этого недостаточно, значит ты меня неправильно понял. Я не говорил о каком-то абсолюте, просто я еще не встречал реализации, где было бы все идеально реализовано. ЦитатаВот именно с какой? Не помню, чтобы я писал что-то подобное. |
|
misha![]()
1275 сообщений |
#5925 2012-03-23 03:44 GMT+3 часа(ов) |
ЦитатаТак какова скорость десериализации? А то судя по тому что ты написал, она довольно велика. Т.е. даже по скорости они не выигрывают. ЦитатаА чем это лучше классики "http://www.lisp.ru/forums.php?m=posts&q=949&n=last#bottom"? Наверное содержит кучу скобок ![]() ЦитатаЭто и без продолжений возможно. ЦитатаА кто сказал, что он один? Идентификатор сеанса может содержать идентификатор сервера на котором хранится состояние сеанса. отредактировал(а) misha: 2012-03-23 04:00 GMT+3 часа(ов) |
|
Kergan
300 сообщений |
#5926 2012-03-23 11:48 GMT+3 часа(ов) |
Цитата Стандартный способ хвосторекурсивной оптимизации. В качестве нового фрейма используется текущий фрейм (то есть на работу с фреймами вообще время не тратится), а хвосто-рекурсивный вызов превращается в в безусловный переход. Цитата Да не надо ничего преобразовывать, если оптимизация хвостовой рекурсии есть - оно _уже_ преобразовано. Ф-я после оптимизации хвостовой рекурсии выглядит в точности как цикл. Цитата Да это уже изучено и доказано стопицот раз. hint: циклов в scheme нету именно из-за того, что после оптимизации хвосторекурсивные вызовы как раз в них и превращаются. То есть никаких потерь скорости. Цитата Как не писал? Вот же: "Короче, разработчики стоят перед дилеммой - либо быстрые продолжения, либо быстрые циклы." ну я и повторяю вопрос - почему эффективная реализация хвостовой рекурсии исключает эффективную реализацию продолжений? Цитата Я, по-моему, вполне четко на этот вопрос ответил. Цитата Ну да. Ведь никаких накладных расходов нет (которые бывают в случае обычных продолжений). Цитата А они и не должны. Зачем? не будет хватать скорости - ставим еще сервер. В этом суть. Цитата Ну тем, чем лучше классики любой continuation-based сервер ![]() Прямой, интуитивно-понятный control-flow вместо реализации конечного автомата руками. Цитата Конечно. Речь шла о том, что продолжения тоже можно сделать безопасными. Как я уже вышел сказал - у продолжений лишь одно преимущество: "прямой, интуитивно-понятный control-flow вместо реализации конечного автомата руками.", остальное - недостатки. И их много. Цитата Так нагрузку балансировать ты не сможешь. В этом случае впонле реальна ситуация, при которой первый сервер падает от нагрузки, а второй загружен едва ли на 10%... |
|
misha![]()
1275 сообщений |
#5927 2012-03-23 22:31 GMT+3 часа(ов) |
ЦитатаТы отвечаешь не на тот вопрос. Я спрашивал об оптимизации хвостового вызова. Зачем ты писал "в качестве нового фрейма используется текущий фрейм", если после хвосторекурсивной оптимизации будет создана функция, содержащая цикл. Т.е. после её вызова будет создан новый фрейм, поэтому если подобные функции имеют незначительный "размер", то их желательно инлайнить. (define (tc-test0 i) РезультатыПопробуй объяснить результаты. Чтобы отключить оптимизации требующие предпросмотра раскомментируй сеты. Функции с префиксом tr и bad-tr даны для сравнения, но их также можно использовать, если раскомментировать их сеты, т.к. они отключат оптимизацию хвостовой рекурсии. ЦитатаФункция после оптимизации хвостовой рекурсии выглядит как функция, содержащая цикл. Если, конечно, её компилятор не использует как инлайн фунцию. Да и это ты описываешь полную оптимизацию хвостовой рекурсии, т.к. частичная не предполагает преобразование кода функции в цикл, т.е. она сродни оптимизации хвостовых вызовов. Кстати, подобная оптимизации хвостовой рекурсии для Лиспа требует предпросмотра (анализа) всего кода программы. Так о чем ты думал, когда писал: "То есть сделав оптимизацию хвостовых вызовов преобразование в циклы получается искаробки."? Оптимизация хвостовых вызовов обычно подразумевает просто замена call на его эквивалент, назовем его tail-call. Поэтому любой хвостовой вызов можно оптимизировать, а не только рекурсивный. ЦитатаГлавное - не путать с инлайнингом, который частенько имеет место. (define (tr-test0 i) С инлайнингом Без инлайнингаЕсли бы я где-то использовал tr-test0 в качестве значения, то создалась просто бы функция содержащая цикл. Вообще сама задача оптимизации хвостовой рекурсии требует сложного анализа кода программы, поэтому определить требуется ли оптимизация или нет довольно сложно. Например, добавление сета запрещает оптимизацию, а в данном случае сет необходимо проигнорировать. отредактировал(а) misha: 2012-03-24 03:49 GMT+3 часа(ов) |
|
misha![]()
1275 сообщений |
#5928 2012-03-23 23:27 GMT+3 часа(ов) |
ЦитатаНе хвостовой рекурсии, а вызовов функций вообще ![]() ЦитатаЯ хотел увидеть цифры. Хотя, сейчас мне это уже не важно. ЦитатаПросто я считал, что они имеют специальную структуру для облегчения распаковки. ЦитатаЯ думал, что это передовая технология ![]() ЦитатаА причем здесь конечный автомат? Просто разработчики захотели добавить скобок ![]() ЦитатаСервер БД может обработать только определенное количество клиентов (рассчитать это число заранее). Перед выдачей идентификатора необходимо определить менее загруженный сервер. Желательно, чтобы было разделение на сервера работающие с авторизованными клиентами и анонимными. Необходимо ограничить количество идентификаторов выдаваемых для одного IP. Каждому клиенту свой идентификатор (привязан к IP), необработанные запросы ложатся в стек, принадлежащий этому идентификатору. Если стек переполнен, то вероятна DoS-атака, поэтому необходимо принять соответствующие меры. В принципе, все можно рассчитать заранее. Кстати, не забывай, что я говорил об информации о сеансе (состояние сеанса), которая обычно содержит только важные сведения, такие как IP, id пользователя (если авторизован) и текущие привилегии пользователя, и возможно др. А остальное, например, содержание его корзины с покупками, можно хранить на стороне клиента. отредактировал(а) misha: 2012-03-24 04:17 GMT+3 часа(ов) |
|
kreol
87 сообщений |
#5929 2012-03-24 19:39 GMT+3 часа(ов) |
мдааа. смотрю на топик что-то жутко умное и ничего не понятное(((
Что такое инлан функция? и что значит заинлайнить? |
|
Kergan
300 сообщений |
#5930 2012-03-25 14:41 GMT+3 часа(ов) |
Цитата Новый фрейм создается только при первом вызове (на первой итерации цикла). Дальше никаких фреймов не создается. Цитата А что странного в этих результатах? Цитата Ну да. Так какие проблемы с этим? Цитата да нету никакого преобразования функции цикл. просто _так выходит_ (чисто случайно), что после хвосторекурсивной оптимизации результат выглядит как цикл. Цитата С чего вдруг? Цитата Да. Просто кроме tail-call обычно рассматривается еще и рекурсивный tail-call, в случае которого можно оптимизировать вызов еще лучше. Цитата Верно, если мы добавим сет, то уже не можем гарантировать, что вызов, собственно, рекурсивный. |
|
misha![]()
1275 сообщений |
#5931 2012-03-25 14:42 GMT+3 часа(ов) |
2 Kergan
Я думаю, необходимо создать отдельный тред. |
|
Kergan
300 сообщений |
#5932 2012-03-25 14:52 GMT+3 часа(ов) |
Цитата а какие здесь подводные камни? Цитата Весьма поспешно заявлять, что дело тут в прожорливых циклах - .net намного шустрее racket, т.к. и типизация статическая, и ВМ менее фичастая, и jit гораздо бодрее (в racket вообще gnu lightning, который не особенно эффективный по сравнению с, например, тем же llvm код генерирует). Цитата Ну конечно она специальная. Вот на счет того как она облегчает распаковка (и как вообще даже теоретически структура может облегчить распаковку) - я не в курсе ![]() Цитата Передовая в том, что масштабируема. В отличии от ![]() Цитата При том, что любое веб-приложение, в силу особенностей http-протокола, является реализацией конечного автомата Цитата Так в дальнейшем нагрузка вполне может измениться, а идентификатор _уже_ выдан. Мы заранее не сможем сказать какова нагрузка будет по данному идентификатору. |
|
misha![]()
1275 сообщений |
#6007 2012-04-20 16:13 GMT+3 часа(ов) |
ЦитатаЭто и ежу понятно ![]() ЦитатаПо ним можно приближенно судить о деталях реализации хвостовых вызовов в данной VM. Возможность применения конкретной оптимизации зависит от устройства VM, поэтому меня больше интересуют не оптимизации, а сама VM, т.е. как реализован фрейм стека, где хранятся аргументы функции, и т.д. Иными словами, предложи устройство VM, в которой хвостовой вызов будет реализован максимально эффективно. ЦитатаОбъясни понятнее, что ты хотел этим сказать. ЦитатаФункцию можно переопределить. ЦитатаМожно более детально? А то я впервые слышу про "рекурсивный tail-call", т.к. обычно вставляется обработка подобной ситуации. Т.е. вставляется проверка на рекурсивный вызов, и если он есть, то просто переопределяем параметры (присваиваем новые значения) и совершаем переход на начало. Иначе происходит tail-call. |
|
misha![]()
1275 сообщений |
#6008 2012-04-20 17:22 GMT+3 часа(ов) |
ЦитатаТребуется более продвинутый declaim. ЦитатаЯ использовал короткие целые, поэтому не было никакой распаковки (unboxing). ЦитатаТ.к. llvm на оптимизацию кода тратит много времени, поэтому обычно отключают большинство оптимизаций кода. ЦитатаСжатые данные всегда структурированы, а иначе как будем производить распаковку? ЦитатаРазве "старые" технологии запрещают хранить данные на стороне клиента? Вот только все это требует шифрования, поэтому возрастает нагрузка на сервер. Т.к. обычно чем лучше алгоритм, тем дольше расшифровка данных. ЦитатаБольшинство приложений работающих с данными является реализациями конечного автомата. Применение продолжений всего-лишь несколько упрощает его вид, и не более того. ЦитатаРечь идет о состоянии сеанса, поэтому мы всегда можем спрогнозировать максимально возможную нагрузку созданную одним пользователем. И если это значение превышено, то мы возможно имеем дело с DoS-атакой, поэтому необходимо принять соответствующие меры(например, временный бан ip), и тем самым избежать отказа в обслуживании. Если бы этот подход был бы таким уж плохим, то большинство веб-серверов не раздавало бы идентификаторы сеанса. А как ты предлагаешь бороться с DDoS-атаками? отредактировал(а) misha: 2012-04-20 17:31 GMT+3 часа(ов) |
|