Cześć.
Mam aplikację w PHP korzystającą z bazy danych MySQL (5.5). Aplikacja obsługuje niemały ruch (konfiguracja Apache + mod_php = mpm_prefork), od kilkuset do kilku tysięcy połączeń na sekundę. Keepalive jest wyłączony ze względu na fakt, że w większości przypadków połączenie nawiązywane jest przez nowego usera i keepalive staje się problematyczny (za dużo czasu musiałby być utrzymywany aby się przydać). Całość wspiera memcached, który skutecznie wspomaga bazę danych.
W sytuacji, gdy ruch jest mały, nie ma żadnego problemu - wszystko śmiga poprawnie. Kłopoty zaczynają się gdy zwiększy się liczba przychodzących połączeń. Kłopoty objawiają się dwojako: albo połączenie do bazy trwa długo, albo połączenie nie następuje i zwracany jest error.
-
Długi czas połączenia do bazy
Korzystam z PDO. Linijka, która otwiera połączenie z bazą - ma w sobie jedynie "new PDO(....)" i argumenty będące stałymi - potrafi się wykonywać nawet przez kilka sekund. Im większy ruch, tym dłuższe czasy oczekiwania. Wcześniej używałem połączenia na 127.0.0.1, po poczytaniu przerzuciłem się na unix_socket (rzekomo szybszy, gdyż po 127.0.0.1 leci po TCP co generuje zbędne narzuty - coś takiego, mogłem czegoś nie zrozumieć :P). -
Brak połączenia
W logach pojawia się:
(2002) SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Potrafi przez kilka sekund logować po 100 takich wiadomości na sekundę. Błąd pojawia się cyklicznie przy większym obciążeniu, czasem kilka sekund, czasem kilkanaście - zawsze sam mija i wszystko działa dalej poprawnie. Ta sama wiadomość pojawiała się przed zamianą na unix_socket, oczywiście było info o problemie z połączeniem na 127.0.0.1 (4).
W bazie regularnie odpalając "SHOW PROCESSLIST" zazwyczaj widoczne są jakieś pojedyncze procesy, zdarza się jednak, że w ciągu sekundy pojawia się ich i 100 - zostają jednak szybko wykonane i przy następnym wyświetleniu listy procesów znowu jest spokój.
CPU cały czas obciążony jest na poziomie około 25%, choć zdarza się, że pojedyncze rdzenie pracują przez kilka sekund na 100%.
Googlałem długo - wszystkie problemy z Can't connect to... rozwiązywane są poprzez poprawnie usera, hasła czy nadanie odpowiednich uprawnień. Nie trafiłem na problem, gdzie czasem jest can't connect a potem wszystko działa. Zaznaczę, że nie uświadczam błędów jak "too many connections".
Walczyłem zwiększając back_log i open_files, niestety nie pomogło. Czy duża ilość procesów apache'a, gdzie każdy łączy się do memcache'a, może w jakiś sposób "dławić" możliwość nawiązania połączenia z silnikiem bazy danych?
Czy ktoś spotkał się z takim problemem? Ewentualnie macie może sugestie jak próbować go zdebugować i znaleźć dokładną przyczynę tego dziwnego zachowania?
Ps. Tak konkretnie to korzystam z MySQL Cluster (MySQL 5.5 i NDB 7.2.10), ale liczę, że nie będzie to miało większego wpływu na rozwiązanie/debugowanie, gdyż problem jest z podłączeniem do "zwykłej" bazy danych.