Крот
Новичок
Привет.
Возник весьма интересный вопрос и не очень понятно как подойти к его решению. Буду признателен любым идеям. Есть виртуальный сервер, который работает под KVM гипервизором. Серверу запинено 8 ядер. LA очень низкий. На сервере установлен nginx и php-fpm (v7.2), никакие кроны не выполняются. Есть скрипт, который обернут в легковесный фреймворк (routing + DI + fastcgi_finish_request). Скрипт читает из редиса (phpredis, TCP) и пишет логи через вызовы syslog().
Нагружаю yandex-tank'ом, 100-200-300rps, обычно скрипт отвечает стабильно (именно время ответа, без коннекта и получения данных) - 95 перцентиль до 100мс. Но иногда случается так, что время ответа подскакивает до 1-15 секунд. Начали проверять и экспериментировать:
Быстрый:
Медленный:
В быстром все ожидаемо, но в медленном наблюдается жесткая аномалия, например:
is_array
Calls: 2000
Incl. Wall Time (microsec): 906108
Incl. CPU (microsecs): 44127
Хотя в быстром кейсе этот же is_array выполняется суммарно 1-2мс. Такие же аномалии для всех функций без исключения.
Создается впечатление, что при выполнении медленного кейса, ОС начинает очень много переключать контекст что и приводит к такому огромному времени выполнения. Но как понять так ли это и причину, которая вызывает такое поведение?
Буду признателен за любые мысли, доводы и т.д. Спасибо.
Возник весьма интересный вопрос и не очень понятно как подойти к его решению. Буду признателен любым идеям. Есть виртуальный сервер, который работает под KVM гипервизором. Серверу запинено 8 ядер. LA очень низкий. На сервере установлен nginx и php-fpm (v7.2), никакие кроны не выполняются. Есть скрипт, который обернут в легковесный фреймворк (routing + DI + fastcgi_finish_request). Скрипт читает из редиса (phpredis, TCP) и пишет логи через вызовы syslog().
Нагружаю yandex-tank'ом, 100-200-300rps, обычно скрипт отвечает стабильно (именно время ответа, без коннекта и получения данных) - 95 перцентиль до 100мс. Но иногда случается так, что время ответа подскакивает до 1-15 секунд. Начали проверять и экспериментировать:
- Проверили opcache - validate_timestamp выключен, памяти достаточно, файлы в кэш попадают, hit 100% после "прогрева".
- Поэкспериментировали со спаунингом воркеров. Спаунинг static. max_children ~ 50. Проводили эксперименты с разными значениями, остановились на этом, которое в принципе логично коррелирует с расчетным (учет rps, кол-ва ядер, время в ожиданни ответа от блокирующих операций и т.д.).
- composer autoload оптимизирован (l1)
- Проверили Redis - всегда отвечает стабильно за константное+- время. Время ответа Redis проверялось также внешними скриптами, а также на самом Redis проверяли latency и qbuf - все ок, "очереди" запросов не образовывается. Мониторинг сети не показывает никаких аномалий.
Быстрый:
Overall Summary | |
---|---|
Total Incl. Wall Time (microsec): | 89,788 microsecs |
Total Incl. CPU (microsecs): | 73,232 microsecs |
Total Incl. MemUse (bytes): | 5,962,768 bytes |
Total Incl. PeakMemUse (bytes): | 6,429,160 bytes |
Медленный:
Overall Summary | |
---|---|
Total Incl. Wall Time (microsec): | 19,406,060 microsecs |
Total Incl. CPU (microsecs): | 826,779 microsecs |
Total Incl. MemUse (bytes): | 5,010,392 bytes |
Total Incl. PeakMemUse (bytes): | 5,546,416 bytes |
В быстром все ожидаемо, но в медленном наблюдается жесткая аномалия, например:
is_array
Calls: 2000
Incl. Wall Time (microsec): 906108
Incl. CPU (microsecs): 44127
Хотя в быстром кейсе этот же is_array выполняется суммарно 1-2мс. Такие же аномалии для всех функций без исключения.
Создается впечатление, что при выполнении медленного кейса, ОС начинает очень много переключать контекст что и приводит к такому огромному времени выполнения. Но как понять так ли это и причину, которая вызывает такое поведение?
Буду признателен за любые мысли, доводы и т.д. Спасибо.