Картиночный сервер, где хранятся и обрабатываются все картинки, начал глючить. Раз-два в неделю зависает так, что даже автоматический резет не помогал. Похоже проблема хардварная. В хетцнере это решается просто - отдаёшь сервер им на диагностику на 12 часов. Делать неработающими картинки на 12 часов не очень хотелось. Поэтому надо было перенести его на другой сервер.
Но тут я подумал - у меня, включая картиночный, уже есть 4. На трёх диски не загружены почти. Память есть. В основном используется процессор для отдачи php. Почему бы не сделать какую-нибудь кластерную фс и убрать одну из точек отказа? Тогда все сервера с апачем будут равноправными, все вместе писать/читать с этой фс и всё будет збс.
Посмотрел какие есть кластерные фс. Самая крутая - ceph. Уже год как вышли из беты. Пишут, что офигенно быстрая и надёжная. Самовосстанавливается, нет одной точки отказа. В будущем можно просто подключать к ней жёсткие диски и она всё будут перебалансировать.
Придумано - сделано. Код на php быстро подправил: ломать - не строить. По сути надо было сломать весь код, который отвечал за перенаправление картиночных запросов на картиночный сервер.
Поставил ceph. Во время установки удивило, что они полностью тестируют только на убунте с дефолтным ядром 3.2, но рекомендуют обязательно обновляться до ядра 3.4/3.6, ибо на более ранних версиях у них не работают серверные модули о_О. Ядро 3.6 и "стабильность" у меня в глове не укладывались, но можно было всё сделать и без модулей ядра. Поэтому ceph был успешно установлен и подмонтирован.
С первого взгляда, всё было хорошо. Есть на одном сервере создать файл, то он появлялся на другом сервере.
И тут я совершил роковую ошибку. Я доверился их заявлениям о скорости/стабильности и переключил сервера на использование ceph.
продолжение следует...
Но тут я подумал - у меня, включая картиночный, уже есть 4. На трёх диски не загружены почти. Память есть. В основном используется процессор для отдачи php. Почему бы не сделать какую-нибудь кластерную фс и убрать одну из точек отказа? Тогда все сервера с апачем будут равноправными, все вместе писать/читать с этой фс и всё будет збс.
Посмотрел какие есть кластерные фс. Самая крутая - ceph. Уже год как вышли из беты. Пишут, что офигенно быстрая и надёжная. Самовосстанавливается, нет одной точки отказа. В будущем можно просто подключать к ней жёсткие диски и она всё будут перебалансировать.
Придумано - сделано. Код на php быстро подправил: ломать - не строить. По сути надо было сломать весь код, который отвечал за перенаправление картиночных запросов на картиночный сервер.
Поставил ceph. Во время установки удивило, что они полностью тестируют только на убунте с дефолтным ядром 3.2, но рекомендуют обязательно обновляться до ядра 3.4/3.6, ибо на более ранних версиях у них не работают серверные модули о_О. Ядро 3.6 и "стабильность" у меня в глове не укладывались, но можно было всё сделать и без модулей ядра. Поэтому ceph был успешно установлен и подмонтирован.
С первого взгляда, всё было хорошо. Есть на одном сервере создать файл, то он появлялся на другом сервере.
И тут я совершил роковую ошибку. Я доверился их заявлениям о скорости/стабильности и переключил сервера на использование ceph.
продолжение следует...
Еще на тему
http://joyreactor.cc/post/701493#comment1944408
Так и должно быть?
1) скорость записи на ceph оказалась около 5Мб/с с пяти серверов, на каждом из которых почти незагруженный raid1 2x3Gb sata. Получалось, что каждый сервер добавлял к общей скорости 1МБ/с. И это был какой-то пипец.
2) "пинг" данных был жутко большим. То есть, время записи любого мелкого файла была в среднем несколько секунд.
3) На серверах вдруг началась огромная нагрузка на харды.
4) сервер метаданных - который хранит список файлов и их метаданные вроде размера, прав и т.д. - не хочет кластеризовываться. Их было запущено 3, но реально работал только один. При этом жрал память и проц очень нехило.
Единственный работающий сервер метаданных работал на достаточно загруженной железке. Я его туда хотел поставить просто как резерв. Начал искать как его исключить из кластера - нигде не написано. Ну остановил сервис. Файловая система перестала отвечать на ls. Мониторы состояния писали, что сервер метаданных наверное упал или лагает. Ну я подумал - они же самовосстанавливающиеся! Сейчас они посмотрят на это и переключатся на другой сервер метаданных.
Прошло 30 минут.
Мониторы всё так же говорили, что один сервер метаданных "подлагивает". А остальные замечательно работают, но запросы туда не идут - все ждут, когда этот самый лучший сервер поднимется обратно. Включил его обратно. Некоторые файлы побились.
После этого я перестал эксперементировать с ceph. Позже я прочитал две интересных записи по нему:
1) файловая система на основании ceph - эксперементальная и нифига не тестировалась. И когда они писали "ceph - стабильный и крутой!" они не имели ввиду файловую систему. А то, что во всех мануалах в первую очередь пишется как создать cephfs - это для наглядности
2) их демон время от времени запускает замечательную команду sync. Вернее, он её похоже постоянно запускает. И если у вас на одном сервере кто-то ещё работает с диском, то настаёт пипец и он перестаёт использовать файловый кэш.
Несмотря на фейл с ceph, я всё же хотел убрать эту точку отказа. День потратил на изучение других фс и вот что нашёл:
1) glusterfs - восстанавливается не вручную. Время от времени случаются фейлы и вся система умирает. Об этом опыте - во втором абзаце статьи http://habrahabr.ru/post/157029/ . У них на форуме нашёл пару вопросов "У меня на последней версии всё пало нахрен. Что делать?". И ответов "ага, у меня тоже. Буду откатываться до предпоследней". При попытках потрогать ручками обнаружил "интересную" поддержку ipv6:
- утилита для онлайн-конфигурирования не умеет ipv6. На форуме советовали в таком случае использовать конфигурирование через кофиг-файлы.
- начиная с версии 3.2 нельзя конфигурировать его через конфиг-файлы. Надо использовать утилиту (которая всё так же не умеет ipv6)
- если сервер слушает порт на ipv4, то подключиться к другому серверу через ipv6 он не сможет. Из трёх пунктов следует, что запустить кластер на ipv6 можно. Но его нельзя сконфигурировать. Зато напротив "ipv6 support" стоит галочка.
- нет никакой системы авторизации. Везде советуют убивать нафиг фаервол - он только мешает. Никаких логин-паролей. Можно подключиться к любому серверу и выполнять админские команды. Надо будет попробывать просканировать чужие сервера на предмет наличия этого порта и проверить возможность запуска команды gluster volume stop & delete.
2) lustre - есть только под ядро 2.6.16 - rhel5. Я уже всё обновил до rhel6, так что отпадает.
3) ocfs2 - официальные билды только под rhel5. Говорят с openvz плохо работает
4) gfs2 - поддержка от редхата, но похоже надо очень сильно мудрить с настройкой.
После этого я плюнул, перенёс картиночный сервер на другую железку и сейчас отдам старую на тестирование. Печаь и грусть. Нет нормальных кластерных фс =(
Да посты нахрен, я вообще много где по оптимизации www отметился, только это уже моё личное развлечение.
1) данная опция в линуксе включена по-умолчанию
2) во фре по-умолчанию стоит noasync. Несмотря на название, она означает не отсутвие асинхронности, а асинхронность с данными, но синхронность с метаданными. Даже если бы у меня была фря, затык у меня был явно не с метаданными и смена флага с noasync на async ничего бы не поменяло.
3) этот флаг говорит о том, должно ли ядро использовать различные кэши перед записью на диск или нет. При этом общение юзерспейса с ядром будет синхронным, если использовать read и асинхронным, если использовать aio_read, независимо от флагов монтирования.
таким образом, у тебя аж три фейла:
1) у меня этот флаг был включён, так как у меня линукс
2) даже если бы у меня была фря, этот флаг мог бы изменить только поведение работы с метаданными
3) этот флаг изменяет взаимодействие ядра с диском. Мне нужна была асинхронность юзерспейса с ядром.
2) см. п.1, и от чего затык я ещё не смотрел, я же не в курсе деталей, просто совет.
3) Этот флаг НЕ говорит о том, если у тебя частный случай реализации совпадает с этим - это может измениться как нефиг делать хоть в следующем патче, этот флаг говорит именно о последовательном выполнении операций, ни о каком кэше речь вообще не идёт. А уж с AIO это вообще свой разговор, при том в основном я его результат на практике вижу негативным.
А теперь аксиома от меня лично.
Первое - не думай что я тебе хуй с бугра, это всё уже видел.
Второе - нормальная асинхронность и мультипоточность под линукс(да и не только) до сих пор в жопе блеять. Форки и разделения по процессам до упора рулят и будет тебе асинхронность.
Третье - см. выше про memcache и приведи данные по рейдам, особенно vmstat, очень вероятно что всё упирается в это если интересно дальше придти к результатам.
журнал в ext4 у меня сейчас отключен. Прирост производительности при выключении заметен не был.
Ну, за неоценкой следующего шага смысла тогда говорить. Ты не понимаешь тех вещей что я пишу о железе.
[root@serv9 ~]# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 202196 127984 264900 11337516 0 0 4269 93 1 1 5 21 66 9 0
2 0 202188 98776 264832 11273216 13 0 58129 931 69537 11149 6 46 42 5 0
5 1 202188 106108 264956 11323012 0 0 55093 2248 70072 11071 7 46 41 6 0
6 0 202188 116636 265644 11397516 0 0 37802 1439 70752 11593 7 40 48 4 0
9 0 202188 100532 265776 11414192 0 0 44830 2246 68365 10704 7 39 50 4 0
[root@serv9 ~]#
Скажи, с какими опциями примонтировать фс, или изменить в sysctl, чтобы сервер смог обрабатывать в 2 раза больше запросов? =)
По стате diskio очевидно что нужен RAM кэш наиболее частого, хотя бы в виде apache hdd+ramdrive, под линухом он стабилен чего не скажешь о BSD, а в идеале то что описывал выше через модуль nginx memcache. Вообще может тут ничего и не нужно, но очень оптимально было бы. А на деле зависит от модели рейда и HDD что стоят, скажем так, для аппаратного это АБСОЛЮТНО ненормальный стат, так что у тебя какая-то хрень вместо контроллера стоит типа IntelServeRAID или софтрейд(что в принципе одно и то же, и даже побыстрее с рамкэшом чем LSI/Intel(один хрен на тех же чипах почти всегда) без набортного).
Далее АБСОЛЮТНО ненормальная стата по %CPU-System и Intrs/sec, увеличивать буферы сокетов и тюнить сетевые тут просто обязательно, тут чисто твои кривые руки, даже у базовых интелов есть interrupt moderation и tx/rx buffers, а вообще я бы сказал что говно сетевые стоят без аппаратного оффлоада или базовые/старые интеловские или того хуже, igb - не помню как оно там будет в живых названиях, но и они тюнятся.
И это только краткий перечень твоих косяков. Так что приводи полный конфиг железа включая конфиг массивов - я уже точно смогу сказать что делать по дискам, ну а по сетевым всё очевидно сходу... Только учитывай что увеличивая буферизацию от балды до файлосерверных размеров в метр теряется response time по сети, так что это плавно лучше смотреть, либо вообще тюнить auto increase buffer size.
диски там - Рамдиск на 1Гб + ссд 256Гб.
да, про intrs/sec - не знал. Сейчас почитаю как подтюнить сетевуху. Хотя как раз она беспокоит меньше всего - половина процессорных ресурсов не занята.
08:20:45 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
08:20:46 PM eth0 166805.00 42324.00 32858.76 198843.17 0.00 0.00 0.00
08:20:46 PM venet0 60588.00 52107.00 86054.00 4989.19 0.00 0.00 0.00
кстати, интел пишет, что у них interruptsThrotille стоит по-умолчанию 8000 в секунду на ядро. Так что получается 60к в секунду. Уменьшать советуют только в случае проблем, но вроде как оно не сильно поможет.
Во FreeBSD есть в дефолте очень забавная вещь для нубов:
net.inet.tcp.recvbuf_auto: 1
net.inet.tcp.sendbuf_auto: 1
При большом количестве запросов надо соблюдать баланс таки к ручному постоянному(ну или лимиты/интервалы роста менять), может и в линухе есть аналоги. В твоём раскладе оно не нужно(в районе recv=8192/16384, лучше ставить самим nginx, ну и куча вещей про оптимизацию nginx вроде accf если допилили в линухе), но всё же.
net.core.wmem_default = 4194394
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.ipv4.tcp_rmem = 4096 8388608 16777216
net.ipv4.tcp_wmem = 4096 4194394 1677721
По этой статистике ничего особенного кроме странного среднего [M]TU, но для нагруженного разным контентом сайта с кучей запросов, а не большими файлами это, ну почти нормально. Хотя у тебя что, хостинг что ли?
что значит "у меня хостинг"?
Ты вообще логи читал? Там боты небось 40+% запросов, у тебя хотя бы evasive настроено?
А какой средний размер пакета тебя не устраивает - rx или tx?
166805/32858 198843/42324
Пакет 1.5к, вообще должны быть забиты под завязку на раздаче, а на деле 166805/1024*1500=244343(ну -20% TCP max, а тут 32858!) или c обратной стороны 42324/1.5 примерно 28816 плюс оверхед опять же. Вопрос - откуда столько лишних? По раскладу не стоит даже blackhole судя по всему и сервер возвращает icmp unreachable.
берём txpck/s = 42324
делим первое на второе. Получаем, что средний пакет - это 4.69 кб.
Я где-то ошибся в расчётах?
Покажи ifconfig что ли. И чем статистику смотрел?
eth0 Link encap:Ethernet HWaddr 00:25:90:93:61:EE
inet addr:50.7.172.170 Bcast:50.7.172.175 Mask:255.255.255.248
inet6 addr: fe80::225:90ff:fe93:61ee/64 Scope:Link
inet6 addr: 2001:49f0:c000:300::2/64 Scope:Global
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:229254182276 errors:0 dropped:0 overruns:0 frame:0
TX packets:123498389274 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:41630275020299 (37.8 TiB) TX bytes:538200667051089 (489.4 TiB)
[root@serv9 ~]# ping -s 5000 ya.ru
PING ya.ru (87.250.251.3) 5000(5028) bytes of data.
5008 bytes from www.yandex.ru (87.250.251.3): icmp_seq=1 ttl=56 time=15.7 ms
5008 bytes from www.yandex.ru (87.250.251.3): icmp_seq=2 ttl=56 time=15.5 ms
5008 bytes from www.yandex.ru (87.250.251.3): icmp_seq=3 ttl=56 time=15.5 ms
^C
--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2294ms
rtt min/avg/max/mdev = 15.552/15.635/15.756/0.087 ms
[root@serv9 ~]#
что же делать? у меня, наверное, какой-то дефективный сервер, да?
[root@serv9 ~]# tcpdump -c 2 -n -i eth0 src host 50.7.172.170
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:37:24.085995 IP 50.7.172.170.http > 80.78.99.145.61173: Flags [.], seq 4233513459:4233519299, ack 3468385182, win 18428, length 5840
11:37:24.085995 IP 50.7.172.170.http > 46.228.104.252.59290: Flags [.], seq 1248194336:1248201496, ack 2094696992, win 16, length 7160
2 packets captured
Наверное надо фрибсд ставить, да? Там таких дефектов нет?
Ну и баги в pcap, TSO, итд. Но лично я их никогда не видел на бсд и линухе.
Вообще с кэшом и php opcode cacherом можно много чего забустить даже тут, но бля, eaccelerator то сдох с новым php, а аналогов нету, apc падучий, xcache только как кэш данных нормален и профайлер.
http://joyreactor.cc/post/667902
И да, FreeBSD "фарева", благо NGINX под него сначала разрабатывался и многие его фичи в линухе не доступны или не запилены. (З.Ы. я не против линуха)
Реально их заставить поменять винт когда SMART начинает показывать критичные показатели как pre-fail или если появляются ошибки, что винт не отвечает.
Еще, если они все таки предложат вариант замены то лучше чуть-чуть доплатить (кажись 10 евро) и поставить гарантировано новый винт. по умолчанию они предлагают поставить бу винт с менне 700 часов работы или refurbished. который показывает по SMART пару часов работы но такой винт не протянет и месяц снова появятся лаги.
каждый раз нагрузка снижалась.
На второй - удобство сильно ухудшается, а резульатат - или небольшой, или вообще нет. В своё время находил бенчмарки - там они идут практически вровень и производительность больше зависит от настроек. Единственное - апач немного больше жрёт памяти. Что-то вроде 15Мб больше на процесс. Но это копейки, по сравнению с остальными тратами.
при этом да, скорость отдачи между 2 и 3 вариантом была не особо значительная, но по нагрузке довольно прилично
Подозреваю, что кроме перехода апач на fastcgi, было что-то ещё. Или настройки в апаче были плохие.
в моем случае нагрузка реально упала, не знаю как у тебя обстоят дела. да и бенчмарки-бенчмарками, а я предпочитаю пробовать для каждого проекта что лучше.
попробуй взять в тест на том же хетзнере серв, настроить на нем nginx+fcgi, и на балансере закинуть какую-то большую подсеть пользователей на него как на постоянный бекэнд и посмотреть нагрузку. если нагрузка слабая а все работает так-же, то закинуть еще пользователей, и так до prefail. вот это и будет твой оптимальный конфиг и бенчмарк именно для твоего проекта.
хотя со своим в чужой монастырь :)
"а вдруг редис в 10 раз быстрее мемкэшед?"
"а вдруг ядро 3.5 в 10 раз быстрее 2.6?"
А потом ещё решать вопросы вида "я перешёл на Х и теперь всё падает раз в день. Что делать?".
А ещё лучше - смотреть где появляется оверхед и какой. Из таймингов видно, что на апаче оверхэд минимальный. Вместо тестирования fastcgi, лучше потратить время на оптимизацию запросов к БД. Даже если оверхэд от апача снизится до нуля - это даст меньший прирост скорости, чем избавится от нескольких запросов на каждой странице.
Оптимизация кода вещь полезная и нужная, но не всегда возможная.