LINUX.ORG.RU
решено ФорумAdmin

Много исходящих TCP-соединений (в секунду)


1

2

Здравствуйте. Есть web-сервер, работающий с mysql таким образом,что на каждый чих устанавливается соединение, что-то быстренько там делается, потом соединение разрывается (велосипед не мой). Соответственно, под нагрузкой число установки соединений в секунду с mysql достигает неразумных значений. Это приводило к известной проблеме, когда из-за закрытых, но висящих в состоянии TIME_WAIT, соединений заканчиваются локальные TCP порты, и соединения больше не открываются. Попытка уменьшить время ожидания по найденным в инете рекомендациям результата не дала (потом нашёл и почему), а вот установка параметра sysctl net.ipv4.tcp_tw_reuse в 1 помогла. По крайней мере соединения теперь устанавливаются без ошибок, хотя количество TIME_WAIT не уменьшилось. Ещё есть параметр net.ipv4.tcp_tw_recycle, его тоже можно установить в 1, тогда количество соединений не будет расти до запредельных значений, если это важно, однако это нарушает RFC, смысла не вижу, и в решении проблемы это не помогает.

А проблема вот в чём: установка TCP-соединений с такой частотой наглухо убивает процессор. При частоте запросов около 1500 в секунду полностью в астрал уходит i7-3770 всеми четырьмя ядрами с гипертредингом. Нет, он не виснет и даже не тормозит, запросы продолжает обрабатывать исправно, но загрузка становится строго 100%, и, видимо, дальнейшее увеличение частоты запросов невозможно. При этом web-сервер со всеми потрохами загружает процессор на считанные единицы процентов. Остальное - что-то системное. top показывает примерно 50/50 usr и sys, но процесс, съедающий процессорное время, не отображается. Что интересно - принимающий эти запросы сервер - mysql на другой машине, чувствует себя вполне комфортно, т.е. такая проблема только на исходящих соединениях, а не на входящих.

Вопросов, собственно, два: 1. Как посмотреть в top, какой скрытый процесс съедает процессор? Признаюсь - мне такое в последний раз очень давно нужно было, и я пользовался какой-то опцией top, вроде бы -S, но сейчас это не помогает - всё равно не видно. Понимаю, что ядро не увидеть, но ведь usr тоже много, кто-то же это съедает? 2. Что-нибудь с этим можно сделать, кроме как переписать всё, чтобы не открывать соединения в таких количествах (но это не в моей компетенции)?

ОС - Debian 7, хотя пробовалось и под Centos с тем же результатом.

1. Как посмотреть в top, какой скрытый процесс съедает процессор?

atop

2. Что-нибудь с этим можно сделать, кроме как переписать всё, чтобы не открывать соединения в таких количествах (но это не в моей компетенции)?

Довести информацию о проблеме до автора обычно возможно.

Насколько я знаю, проблема с количеством соединений на стороне mysql решается через sql прокси. Прокси держит постоянные соединения с БД и мультиплексирует запросы от sql клиентов

На строне apache.. Можно поднять несколько серверов с apache, балансировать запросы на них. Соответственно, на каждом из n серверов apache нагрузка будет в n раз меньше.

router ★★★★★ ()
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

бтв чота там было добавлено в ядро для оффлоада, уже не помню чо надо чанжлог смотреть

anonymous ()

а ты и не увидишь что проц нагружает, это же скрытый гипервизор с бекдором в железе интела)))
он сканирует на ключевую фразу соединения

anonymous ()
Ответ на: комментарий от anonymous

а ты и не увидишь что проц нагружает, это же скрытый гипервизор с бекдором в железе интела)))

Скорее, короткоживущие процессы. atop должен их показать

system можно наверное посмотреть через kerneltop, но нужно включать профилирование и перезагрузить ОСь.

router ★★★★★ ()

Если запускается много короткоживущих процессов, то проще включить аккаунтинг процессов через accton и посмотреть кто кушает cpu.

net.ipv4.ip_local_port_range уже выставлены в 1024 65530 ?

vel ★★★★★ ()
Последнее исправление: vel (всего исправлений: 1)

Нужно организовать пул соединений с БД.

unfo ★★★★★ ()
Ответ на: комментарий от thesis

http://dev.mysql.com/downloads/mysql-proxy/ Думаю, это именно то, чего тебе не хватает.

Посмотрел. Само по себе использование этого прокси ничего не меняет, какая там разница коннектиться к самому серверу или к этому прокси? Но есть один интересный режим. К прокси можно коннектится через локальный сокет, а потом через пул коннекций - к серверу. Даже скрипты есть для организации этих пулов, только вот не работают что-то. Если вкратце, то там всё строится на том, что либо создается новое соединение, или используется уже существующее из пула. Функция connect_server() в последнем случае возвращает значение proxy.PROXY_IGNORE_RESULT, что должно отменить отправку ответа клиенту. Логику этого я понять не могу, но клиент тут же отваливается и всё, что, в общем, логично. К тому же это значение описано для read_query() а не для connect_server().

Я к чему это? Может у кого-то есть работающий скрипт для MySQL proxy для объединения пользовательских коннекций в пул?

shamus24 ()
Ответ на: комментарий от shamus24

Ты знаешь, я вскоре понял, что написал не совсем в тему, полез редактировать камент, но было уже поздно и я забил.
А что, это твоё чудо-приложение умеет коннектиться к субд через локальный сокет? По идее работа через локальный сокет может избавить тебя от проблемы с висящими TIME_WAIT.
Если нет, то можно, конечно, попробовать зарезать значение tcp_max_tw_buckets, хотя эта штука может вылезти боком.

thesis ★★★★★ ()

Отрубить нафиг connaction tracking. Прописать в raw правило -j ACCEPT для всех пакетов от софтины к мускулю. Нагрузка должна немного упасть.

А, да, и оторвать автору софтины руки по самую жопу.

selivan ★★★ ()

Можно перенести MySQL на тот-же хост и подключаться к нему через unix сокет, нагрузка должна уменьшиться.
Можно использовать постоянные коннекты к MySQL (persistent connection), но при неправильной реализации возможны некоторые осложнения например из-за того что коннекты сохраняют состояние о чём код обращающийся к БД может и не знать.

MrClon ★★★★★ ()

{mysql_connect -> mysql_pconnect } if php

visual ★★★ ()
Ответ на: комментарий от vel

Если запускается много короткоживущих процессов

Вот человек попал в точку!

Спасибо всем за подсказки. atop очень выручил. В общем, оказалось, что tcp/ip тут ни при чем. С ним были свои заморочки, но они успешно поборены. А процессор кушали вполне нормальные короткоживущие fast-cgi процессы, которые просто не успевали появиться в топ-е.

net.ipv4.ip_local_port_range уже выставлены в 1024 65530

Ну это как-то сильно жестоко. Я выставлял 12000-65530. А то даже mysql в тот промежуток попадает. Но это всё не о том, как оказалось.

shamus24 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.