The C10K problem
Интересует собственно сабж.
Подробно описан здесь - http://www.kegel.com/c10k.html
То есть, необходимо обеспечить одновременный доступ 10000 клиентов к серверу.
На сервере, допустим, выполняется скрипт, который подключается к БД и отдает ответ.
в основном выполняется SELECT, иногда INSERT.
Я хочу такую штуку настроить на любимой Gentoo.
Примерное решение предполагается такое:
1. Использовать 64 битную платформу.
2. В качестве веб-сервера front-end - nginx, backend - apache. Основную работу на загрузку берет nginx, apache обслуживает, допустим 100 подключений максимум в секунду.
3. Оптимизация nginx для обслуживания такого количества.
4. СУБД - MySQL. Возможно на отдельном сервере. Оптимизация
Я так понимаю скрипт будет уместнее писать на C и делать для него пул потоков (epoll).
Схожие запросы собирать в кучу и по таймауту отдавать клиентам - минимизация запросов к БД.
Вопросы:
1. где про это можно почитать - интересует сама технология, решение буду делать сам.
2. Справится ли с этим генту?
3. Сколько надо серверов и каких, чтобы решить проблему.
4. Есть ли какие-то test framework типа ab, siege чтобы проверить работу? Подойдет ли ab - ведь надо 10000 одновременно? Сколько надо компьютеров для проверки - кто тестировал, скажите. И если надо много, то есть ли софт для оффтопик? погуглил - нашел вот это http://code.google.com/p/c10k/ - подойдет?
5. Как настроить nginx, mysql на такое количество.
6. Какие настройки ядру требуются - файловые дескрипторы, порты, буфера и т.д.?
7. Архитектура скрипта, выполняющего основную работу? Статику, я думаю nginx и сам будет в состоянии отдать, как правильно сделать динамические?
По сути - это технология площадок Web 2.0 и за ними будущее.
Всякие там одноклассники и т.д. так и работают.
По такому же принципу работает джаббер и торрент.
Только в торрентах разрешается отложенная запись - статистике даже минута не помеха, мне это не подходит.
Запись должна быть сразу.
Буду ОЧЕНЬ признателен за любую помощь.
Как сделаю - готов поделиться с сообществом наработками.
Может поковырять сам nginx и посмотреть как там все это сделано?
- Для комментирования войдите или зарегистрируйтесь
Тестирование
Пока остановлюсь на 2 компах для теста - сервер и клиент.
Сначала от клиента запускаем
./deadconn se.rv.er.ip 80 1000
Потом
ab -n 100000 -c 100 -k http://se.rv.er.ip/index.html
Либо попробовать httperf (HP Labs)
Ссылки:
1. deadconn_last - запускает idle соединения.
http://hzliu.myweb.hinet.net/fdm/deadconn_last.c
2. httperf - http://www.hpl.hp.com/research/linux/httperf/
3. Книга, написанная разработчиками yahoo High Performance Web Sites:
http://books.google.com/books?id=jRVlgNDOr60C&printsec=frontcover&dq=%22High+Performance+Web+Sites%22+download&hl=ru&output=html
В формате pdf, доступна для скачивания - http://www.scribd.com/doc/49362/High-Performance-Web-Sites
4. PageDetailer, описанный в этой книге - продукт ibm. - http://alphaworks.ibm.com/tech/pagedetailer/download
Представляет графически сторону клиента - процесс загрузки. работает под оффтопик.
Обнаружил интересную
Обнаружил интересную вещь.
Когда я запускаю
./deadconn server.ru 80 10000
10000 мертвых соединений - это намертво вешает многие сайты.
Проверил на gentoo.ru - работает как ни в чем не бывало.
Это связано с nginx/apache ? Скорее всего, просто защита drupal.
Проверил также производительность nginx и своего event-driven http-сервера (http://www.monkey.org/~provos/libevent/doxygen-1.4.9/evhttp_8h.html) на статике.
Производительность при
1000 одновременных подключений, поддержка keep-alive, примерно одинакова - 12-15 тысяч запросов в секунду
Комп обычный домашний - Athlon X2 5600+ 4G RAM, gentoo работает на vmware под вистой, 1G памяти
Если ставить nginx как прокси и перекидывать запрос на мой http-сервер, то производительность снижается до 4 тысяч. И это при статике.
Очевидно, придется использовать несколько серверов для запросов на разных портах.
Завтра попробую на 2-х компах, в этом тесте пришлось использовать один для сервера и клиента.
Transfer rate: 5885.30 [Kbytes/sec]
так что сеть и loop значения не имеет.Плюс хочу попробовать все-таки большее concurrency - на одном компе больше открывать не дает -
too many files open(24)
выскакивает.хы
увелич лимиты.
c10k #
Как Увеличить?
Больше 1020 не дает. Похоже это проблема ab, а не лимита. Пробовал его натравить на другой хост - разницы нет. Другие приложения запускаются 10000 одновременно - deadconn.
Для сравнения - производительность самого Apache при -c 1000 = 4500, то есть в 3-4 раза ниже :)
Попробовал siege - он какой-то недоделанный.
Самый нормальный вроде httperf - правда его лучше с разных компов запускать. Он для этого и годится
httperf --hog --client=0/1 --server=localhost --port=8080 --uri=/index.html --rate=10000 --send-buffer=4096 --recv-buffer=16384 --num-conns=1000000 --num-calls=1
Идеально конечно его запустить --client=0-9/10 --rate=1000 и посмотреть.
Кажется нашел надо поменять
это хард лимиты, а soft лучше поменять в /etc/security/limits.conf
плюс TIME_WAIT для открытых соединений надо сделать маленьким.
в
в догонку
http://www.tigase.org/en/linux-settings-guide
Спасибо!Если TIME_WAIT=60s
Спасибо!
Если TIME_WAIT=60s для открытых соединений, то 65536/60 = 1000 в секунду
как его сделать 60000/10000 = 6 секунд?
Без keep-alive.
И еще вдогонку http://www.cs.uwaterloo.ca/~brecht/servers/openfiles.html
Перекомпилировать надо
#define __FD_SETSIZE 1024
?
Оптмизация сети
http://www.faqs.org/docs/securing/chap6sec75.html - здесь вроде понятно написано
заодно защита от DDos - http://www.hackzone.ru/articles/zashita_ot_ddos.html
Поставил
А вот это даже не знаю актуально или нет - http://www.faqs.org/docs/securing/chap6sec73.html (The atime and noatime attribute)
И не понял для чего нужны
net.ipv4.netfilter.ip_conntrack*
andribas написал(а):И5. Как
Пока нашел вот это - http://osdir.com/ml/apache.discussion.russian/2004-10/msg00012.html
Ответ самого Игоря Сысоева. Не совсем то, для начала пойдет.
http://blog.kovyrin.net/2006/04/13/epoll-asynchronous-network-programming/lang/ru/
Хорошее начало.
Также думаю понадобится
dev-libs/libevent
- http://www.monkey.org/~provos/libevent/doxygen-1.4.9/andribas wrote:2. В качестве
В общем решение мне представляется такое:
Используется 2 сервера(программы) http:
nginx и libevent и никакого индейца.
nginx слушает на 80 порту, libevent на другом (9999).
Запросы поступают nginx - статику он отдает быстро и без оптимизации (частые файлы попадут в дисковый кеш)
Динамику отправляем через FastCGI в php
С апачей будет медленно.
Настройки PHP:
1. Используем патч php-fpm для создания воркеров и обмена через сокет с PHP
2. Используем eAccelerator для помещения в кеш скомпилированных скриптов.
Такой сервер сможет обслужить думаю 500-1000 соединений в секунду. Надо потестировать.
Запросы AJAX (c10K) отправляем на libevent-сервер.
Вопрос:
1. Можно ли вставить в код ssi-include, чтобы на выдаче nginx "собрал" страницу из кусков php,статики и libevent-ответа? Так называемая модель сборщика. Чтобы не описывать логику дважды.
Прочитал, что на mail.ru и яндекс вообще написан собственный модуль к nginx HTML::Template - язык шаблонов типа smarty для компиляции ответов с разных серверов.
2. Нагуглил ебилд для php-fpm http://dev-null.org.ua/gentoo-php-fpm/ у украинских товарищей. Кто-нибудь пробовал его ставить?
Результаты тестов:
1. nginx статика
2. nginx + FastCGI через сокет (через порт долго)
3. nginx + proxy_pass - отдаем другому через сокет
4. libevent http сервер
выложу чуть позже.
сейчас не знаю как из
evhttp_bind_socket
выдрать fd сокета, чтобы сделатьbind()
Глобальную переменную добавить? :) а там ее присвоить. libevent изменять придется
А через TCP/IP медленно работает - в 3-4 раза падение производительности.
Примерно "nginx статика" = "libevent http сервер" = 20К/сек как и ожидалось
Если не пересобрать libevent, nginx, свои программы, ab(apache) то будет buffer overflow, либо останется 1024 по умолчанию. Так что компилировать надо
у меня нашлось в
На закуску хочу поделиться хорошей ссылкой - Best Practices for Speeding Up Your Web Site
http://developer.yahoo.com/performance/rules.html
Как минимум 12 правил оттуда всем пригодятся.
По поводу сокета
думаю проще сделать локальную копию http.c и заменить там AF_INET на AF_UNIX.
Потому как сокет там другой открывается.
Если функции одинаковые будут как и в -llibevent есть л какой-нибудь метод типа namespace, чтобы ошибок не было при линковке ведь имена совпадут?
Честно говоря, не очень хочется этот код править. Имена функций менять :(
Может я какой-то способ неправильный предлагаю?
Вот mysql к примеру делает bind на сокет и на адрес сразу.
Мне такой вариант идеально бы подошел. Как это сделать?
Или тогда придется две очереди обслуживать?
Дано: файловый дескриптор сокета типа AF_INET.
Как сделать bind на сокет типа AF_UNIX - файл сокета, вместо IP адреса и порта?