Здравствуйте, C0x, Вы писали:
C0x>http://docs.python.org/library/socketserver.html C0x>Имеет смысл для прокси сервиса с кучей клиентов?
C0x>PS: Я слышал, что в питоне потоки не совсем хорошо реализованы.
Лучше использовать что-нибудь асинхронное -- tornado, twisted или asyncore на худой конец.
Здравствуйте, Daevaorn, Вы писали:
D>Здравствуйте, C0x, Вы писали:
C0x>>http://docs.python.org/library/socketserver.html C0x>>Имеет смысл для прокси сервиса с кучей клиентов?
C0x>>PS: Я слышал, что в питоне потоки не совсем хорошо реализованы.
D>Лучше использовать что-нибудь асинхронное -- tornado, twisted или asyncore на худой конец.
А вот к примеру в twisted нет проблемы с потоками из-за GIL? Мне очень важно, чтобы на многоядерной машине сервер использовал все ресурсы процессора, а не ограничивался только одним ядром.
Здравствуйте, C0x, Вы писали:
C0x>Здравствуйте, Daevaorn, Вы писали:
D>>Здравствуйте, C0x, Вы писали:
C0x>>>http://docs.python.org/library/socketserver.html C0x>>>Имеет смысл для прокси сервиса с кучей клиентов?
C0x>>>PS: Я слышал, что в питоне потоки не совсем хорошо реализованы.
D>>Лучше использовать что-нибудь асинхронное -- tornado, twisted или asyncore на худой конец.
C0x>А вот к примеру в twisted нет проблемы с потоками из-за GIL? Мне очень важно, чтобы на многоядерной машине сервер использовал все ресурсы процессора, а не ограничивался только одним ядром.
Twisted работает в одном потоке. Вы просто можете поднять столько инстансов вашего сервиса, сколько у вас ядер.
Здравствуйте, Daevaorn, Вы писали:
D>Здравствуйте, C0x, Вы писали:
C0x>>Здравствуйте, Daevaorn, Вы писали:
D>>>Здравствуйте, C0x, Вы писали:
C0x>>>>http://docs.python.org/library/socketserver.html C0x>>>>Имеет смысл для прокси сервиса с кучей клиентов?
C0x>>>>PS: Я слышал, что в питоне потоки не совсем хорошо реализованы.
D>>>Лучше использовать что-нибудь асинхронное -- tornado, twisted или asyncore на худой конец.
C0x>>А вот к примеру в twisted нет проблемы с потоками из-за GIL? Мне очень важно, чтобы на многоядерной машине сервер использовал все ресурсы процессора, а не ограничивался только одним ядром.
D>Twisted работает в одном потоке. Вы просто можете поднять столько инстансов вашего сервиса, сколько у вас ядер.
Как-то это не очень хорошо получается. Нужно ведь тогда еще данные синхронизировать между инстансами и на один порт их все завязывать.
Здравствуйте, C0x, Вы писали:
D>>Twisted работает в одном потоке. Вы просто можете поднять столько инстансов вашего сервиса, сколько у вас ядер.
C0x>Как-то это не очень хорошо получается. Нужно ведь тогда еще данные синхронизировать между инстансами и на один порт их все завязывать.
Для того, чтобы однопоточный *прокси*-сервер нагрузить до предела, нужно *очень* постараться.
А что за данные нужно шарить между инстансами?
Здравствуйте, HiSH, Вы писали:
HSH>Здравствуйте, C0x, Вы писали:
D>>>Twisted работает в одном потоке. Вы просто можете поднять столько инстансов вашего сервиса, сколько у вас ядер.
C0x>>Как-то это не очень хорошо получается. Нужно ведь тогда еще данные синхронизировать между инстансами и на один порт их все завязывать.
HSH>Для того, чтобы однопоточный *прокси*-сервер нагрузить до предела, нужно *очень* постараться. HSH>А что за данные нужно шарить между инстансами?
Это не совсем обычный прокси сервер, он еще сохраняет некоторую дополнительную информацию о соединениях + кеширование передаваемых данных.
C0x>>>http://docs.python.org/library/socketserver.html C0x>>>Имеет смысл для прокси сервиса с кучей клиентов?
C0x>>>PS: Я слышал, что в питоне потоки не совсем хорошо реализованы.
D>>Лучше использовать что-нибудь асинхронное -- tornado, twisted или asyncore на худой конец.
C0x>А вот к примеру в twisted нет проблемы с потоками из-за GIL? Мне очень важно, чтобы на многоядерной машине сервер использовал все ресурсы процессора, а не ограничивался только одним ядром.
Грубо говоря, вы не сможете создать прокси, который делает что-то вменяемое полезное и при этом нагружает процессор.
Здравствуйте, C0x, Вы писали:
C0x>Здравствуйте, HiSH, Вы писали:
HSH>>Здравствуйте, C0x, Вы писали:
D>>>>Twisted работает в одном потоке. Вы просто можете поднять столько инстансов вашего сервиса, сколько у вас ядер.
C0x>>>Как-то это не очень хорошо получается. Нужно ведь тогда еще данные синхронизировать между инстансами и на один порт их все завязывать.
HSH>>Для того, чтобы однопоточный *прокси*-сервер нагрузить до предела, нужно *очень* постараться. HSH>>А что за данные нужно шарить между инстансами?
C0x>Это не совсем обычный прокси сервер, он еще сохраняет некоторую дополнительную информацию о соединениях + кеширование передаваемых данных.
Я скажу так: если требование — выжать максимум из одного процесса на одном сервере, то не надо писать это ни на питоне, ни на любом другом скриптовом языке. Асинхронные сокеты + треды + быстрый язык.
Если максимум выжимать не надо — это можно написать на питоне, не глядя на его проблемы с GILом. Это будет на порядок быстрее в разработке. Когда на них наступите — эти части можно будет переписать на C++. Но по своем опыту скажу, чтобы уткнуться в GIL, нужно иметь очень хорошую нагрузку.
Есть несколько мест, про которые нужно помнить, чтобы раньше времени не наступить на проблемы с GIL'ом: Строковые операции. ('a' * 100000000).replace('aaa', 'bbb') не отпустит GIL и завесит весь процесс на серьезное время.
Регекспы. С ними ровно та же беда, поэтому писать их нужно с головой. В тройке собираются использовать новый модуль, без этой проблемы (а может уже используют?). В любом случае, если регекспы простые, я бы посоветовал написать свой биндинг к http://code.google.com/p/re2/ — они на порядок быстрее.
Всякие подозрительные внешние библиотеки.
Но опять же — проблемы с GIL'ом несколько преувеличены, нужно серьезно постараться, чтобы с ними столкнуться
Здравствуйте, Temoto, Вы писали:
C0x>>А вот к примеру в twisted нет проблемы с потоками из-за GIL? Мне очень важно, чтобы на многоядерной машине сервер использовал все ресурсы процессора, а не ограничивался только одним ядром.
Twisted их просто игнорирует:)
T>Грубо говоря, вы не сможете создать прокси, который делает что-то вменяемое полезное и при этом нагружает процессор.
Не надо вводить в заблуждение, сможет. С некоторыми затратами умственных ресурсов — сильно больше, чем у хорошо параллелизующейся системы — но сможет. В первую очередь можно применять модуль subprocess (начиная с 2.6 "в коробке"), он порождает системные процессы и даёт связь между ними механизмом очередей.
T>>Грубо говоря, вы не сможете создать прокси, который делает что-то вменяемое полезное и при этом нагружает процессор.
N>Не надо вводить в заблуждение, сможет. С некоторыми затратами умственных ресурсов — сильно больше, чем у хорошо параллелизующейся системы — но сможет. В первую очередь можно применять модуль subprocess (начиная с 2.6 "в коробке"), он порождает системные процессы и даёт связь между ними механизмом очередей.
Вроде бы достаточно уточнений сделал. И "грубо говоря", и "прокси", и "вменяемое", и "полезное". Конечно, сферический проект в вакууме настолько сложен и так много вычисляет, что упрётся в процессор. Но что-то мне подсказывает, что топикстартер будет делать нечто гораздо более приземлённое. И если не твистед и не треды, то в сумме проца оно сожрёт меньше, чем люди потратили на чтение этого треда.
Простите сарказм, если я неправ и там правда пишется нечто CPU-bound. Но пока не верю.
Здравствуйте, Temoto, Вы писали:
N>>Не надо вводить в заблуждение, сможет. С некоторыми затратами умственных ресурсов — сильно больше, чем у хорошо параллелизующейся системы — но сможет. В первую очередь можно применять модуль subprocess (начиная с 2.6 "в коробке"), он порождает системные процессы и даёт связь между ними механизмом очередей. T>Вроде бы достаточно уточнений сделал. И "грубо говоря", и "прокси", и "вменяемое", и "полезное". Конечно, сферический проект в вакууме настолько сложен и так много вычисляет, что упрётся в процессор.
Веду совсем не сферический в вакууме проект, собственно вычислений нет, сплошная сетевая активность, одного процессора катастрофически не хватает — приходится делать расщепления "на коленках". Вот опять сегодня гуглил на тему новостей типа "GIL убрали в сторону" — фигушки, пока летим по-старому.
T>Простите сарказм, если я неправ и там правда пишется нечто CPU-bound. Но пока не верю.
Простите за сарказм, но мир более разнообразен, чем кому-то кажется.
N>>>Не надо вводить в заблуждение, сможет. С некоторыми затратами умственных ресурсов — сильно больше, чем у хорошо параллелизующейся системы — но сможет. В первую очередь можно применять модуль subprocess (начиная с 2.6 "в коробке"), он порождает системные процессы и даёт связь между ними механизмом очередей. T>>Вроде бы достаточно уточнений сделал. И "грубо говоря", и "прокси", и "вменяемое", и "полезное". Конечно, сферический проект в вакууме настолько сложен и так много вычисляет, что упрётся в процессор.
N>Веду совсем не сферический в вакууме проект, собственно вычислений нет, сплошная сетевая активность, одного процессора катастрофически не хватает — приходится делать расщепления "на коленках". Вот опять сегодня гуглил на тему новостей типа "GIL убрали в сторону" — фигушки, пока летим по-старому.
ENOSENSE. Подумайте сами, если вычислений нет, как может не хватать процессора? Миллион сисколов в секунду что-ли?
Здравствуйте, Temoto, Вы писали:
T>>>Вроде бы достаточно уточнений сделал. И "грубо говоря", и "прокси", и "вменяемое", и "полезное". Конечно, сферический проект в вакууме настолько сложен и так много вычисляет, что упрётся в процессор.
N>>Веду совсем не сферический в вакууме проект, собственно вычислений нет, сплошная сетевая активность, одного процессора катастрофически не хватает — приходится делать расщепления "на коленках". Вот опять сегодня гуглил на тему новостей типа "GIL убрали в сторону" — фигушки, пока летим по-старому.
T>ENOSENSE. Подумайте сами, если вычислений нет, как может не хватать процессора? Миллион сисколов в секунду что-ли?
SIP softswitch. Разбираются входящие пакеты, строятся исходящие, посылаются запросы к биллингу, разбираются ответы. Ведётся база транзакций, база диалогов, база звонков, обмен с соседями частями этих баз. Движок событий, сообщения между подсистемами, очереди сообщений, таймеры, etc.
Собственно "вычислений" на уровне сложений-вычитаний-etc. там дай бог чтобы 1% (самое сложное — правила реавторизации — укладываются в полторы странички простого кода), ну ладно, с арифметикой указателей — 5%. Тем не менее работы — дофига и выше.
Хотите посмотреть, как оно помрёт под нагрузкой — задайте 100 новых звонков в секунду, треска будет на все окрестные сервера:)
Если Вы всё это назовёте "вычислениями" — Вы просто некорректно подобрали термины, но если Вы всерьёз так думаете и игноруете то, что компьютеры в основном занимаются обработкой данных, а не вычислениями — то я вынужден просто посоветовать повторить высшее образование заново. Надеюсь, что это временно (пока жара не спадёт). Извините, ничего личного, но такое наплевательское игнорирование моей работы меня удивляет. И таки да, забирайте свой ENOSENSE обратно, знание жаргона не заменяет самостоятельное мышление.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, Temoto, Вы писали:
T>>>>Вроде бы достаточно уточнений сделал. И "грубо говоря", и "прокси", и "вменяемое", и "полезное". Конечно, сферический проект в вакууме настолько сложен и так много вычисляет, что упрётся в процессор.
N>>>Веду совсем не сферический в вакууме проект, собственно вычислений нет, сплошная сетевая активность, одного процессора катастрофически не хватает — приходится делать расщепления "на коленках". Вот опять сегодня гуглил на тему новостей типа "GIL убрали в сторону" — фигушки, пока летим по-старому.
T>>ENOSENSE. Подумайте сами, если вычислений нет, как может не хватать процессора? Миллион сисколов в секунду что-ли?
N>SIP softswitch. Разбираются входящие пакеты, строятся исходящие, посылаются запросы к биллингу, разбираются ответы. Ведётся база транзакций, база диалогов, база звонков, обмен с соседями частями этих баз. Движок событий, сообщения между подсистемами, очереди сообщений, таймеры, etc. N>Собственно "вычислений" на уровне сложений-вычитаний-etc. там дай бог чтобы 1% (самое сложное — правила реавторизации — укладываются в полторы странички простого кода), ну ладно, с арифметикой указателей — 5%. Тем не менее работы — дофига и выше. N>Хотите посмотреть, как оно помрёт под нагрузкой — задайте 100 новых звонков в секунду, треска будет на все окрестные сервера
Из вычислений я здесь вижу разбор входящих пакетов и ответов биллинга. Ну, база ж наверное не самописный софт. А что показывает профилер?
N>Если Вы всё это назовёте "вычислениями" — Вы просто некорректно подобрали термины, но если Вы всерьёз так думаете и игноруете то, что компьютеры в основном занимаются обработкой данных, а не вычислениями — то я вынужден просто посоветовать повторить высшее образование заново. Надеюсь, что это временно (пока жара не спадёт). Извините, ничего личного, но такое наплевательское игнорирование моей работы меня удивляет. И таки да, забирайте свой ENOSENSE обратно, знание жаргона не заменяет самостоятельное мышление.
Здравствуйте, Temoto, Вы писали:
N>>SIP softswitch. Разбираются входящие пакеты, строятся исходящие, посылаются запросы к биллингу, разбираются ответы. Ведётся база транзакций, база диалогов, база звонков, обмен с соседями частями этих баз. Движок событий, сообщения между подсистемами, очереди сообщений, таймеры, etc. N>>Собственно "вычислений" на уровне сложений-вычитаний-etc. там дай бог чтобы 1% (самое сложное — правила реавторизации — укладываются в полторы странички простого кода), ну ладно, с арифметикой указателей — 5%. Тем не менее работы — дофига и выше. N>>Хотите посмотреть, как оно помрёт под нагрузкой — задайте 100 новых звонков в секунду, треска будет на все окрестные сервера:) T>Из вычислений я здесь вижу разбор входящих пакетов и ответов биллинга. Ну, база ж наверное не самописный софт. А что показывает профилер?
К сожалению, основные затраты — работа с SIP сообщениями (парсинг/разбор, сборка...) Из-за переусложнённости грамматики это выливается в большое количество копирований, модификаций... Существующие максимально эффективные реализации (типа SER и его клонов) делают это чуть ли не на ассемблере (специфический сишный код с заточкой на типичные разрядности вроде 32 бит).
T>Я не хотел обидеть, извините.
OK. Я тоже не то чтобы обиделся, но был крайне удивлён столь односторонним подходом.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, Temoto, Вы писали:
N>>>SIP softswitch. Разбираются входящие пакеты, строятся исходящие, посылаются запросы к биллингу, разбираются ответы. Ведётся база транзакций, база диалогов, база звонков, обмен с соседями частями этих баз. Движок событий, сообщения между подсистемами, очереди сообщений, таймеры, etc. N>>>Собственно "вычислений" на уровне сложений-вычитаний-etc. там дай бог чтобы 1% (самое сложное — правила реавторизации — укладываются в полторы странички простого кода), ну ладно, с арифметикой указателей — 5%. Тем не менее работы — дофига и выше. N>>>Хотите посмотреть, как оно помрёт под нагрузкой — задайте 100 новых звонков в секунду, треска будет на все окрестные сервера T>>Из вычислений я здесь вижу разбор входящих пакетов и ответов биллинга. Ну, база ж наверное не самописный софт. А что показывает профилер?
N>К сожалению, основные затраты — работа с SIP сообщениями (парсинг/разбор, сборка...) Из-за переусложнённости грамматики это выливается в большое количество копирований, модификаций... Существующие максимально эффективные реализации (типа SER и его клонов) делают это чуть ли не на ассемблере (специфический сишный код с заточкой на типичные разрядности вроде 32 бит).
Понятно.
А вы не рассматривали такой вариант: отдельный демон, например, на Haskell/Erlang/Go слушает SIP и парсит сообщения на всех ядрах, а потом отдаёт их вашему приложению в каком-то более простом формате ?
C0x>Имеет смысл для прокси сервиса с кучей клиентов? C0x>PS: Я слышал, что в питоне потоки не совсем хорошо реализованы.
Потоки в питоне реализованы хорошо.
В зависимости от платформы используется доступный поточный механизм —
для Windows это стандартные win32 потоки, для Unix, для упрощения
скажем, pthreads. Одному потоку в питоне соответствует один
платформенный поток. Так что все оптимально, лучше не сделать,
только усложнять.
Проблема в том, что потоки, одновременно выполняющие код виртуальной
машины Python, вынуждены часто втыкаться в синхронизацию
на пресловутой GIL. Поэтому многопоточное приложение на питоне,
выполняющее интенсивные вычисления (т.е. код вирт. машины), может
оказаться малоэффективным.
При активной работе с TCP все немного не так. Всякий раз, когда
вызывается TCP стек (ядро, и вообще, все что угодно "вне" питона),
поток заявляет, что он временно покидает зону GIL и уходит в вызов.
Примерно так:
int py_Send(...)
{
Py_BEGIN_ALLOW_THREADS
tcp.send(...)
Py_END_ALLOW_THREADS
}
между BEGIN и END поток свободен, им управляет только платформенный
шедулер и чихать он хотел на GIL.
Грубо говоря — внутри питона одновременно выполняется только один
поток, а вне — сколько угодно.
Так что многопоточное приложение на питоне, которое выполняет много
I/O, страдает меньше, чем то, которое выполняет много CPU.
Понятное дело, проблем при обработке полученных данных _внутри_
питона, это не снимает, так что увлекаться большим количеством
потоков в Python не стоит. YMMV.
Вот здесь у меня (в том числе) есть многопоточный TCP сервер,
в котором один поток принимает входящие соединения, накапливает
их, и опрашивает select-ом, готовые соединения читает/пишет,
после чего данные отдает в работу пулу рабочих потоков,
можете полюбопытствовать: