Назад | Перейти на главную страницу

Как разрешить вызовы высокой загрузки ЦП + чрезмерной статистики («/ etc / localtime») и clock_gettime (CLOCK_REALTIME)


Я столкнулся с очень высокой загрузкой процессора в приложении Ruby on Rails (см. Стек ниже) и безуспешно пытался диагностировать возможные причины.

Стек:

Когда бы я ни бегал strace против пикового процесса Rack PID (см. верхний отрывок ниже), Я вижу тонну stat("/etc/localtime") и clock_gettime(CLOCK_REALTIME) звонки и понятия не имею, как их остановить.


Выдержка из Top showin PID:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11674 www-user  20   0  313m 182m 5076 R   99  2.3  63:04.60 Rack: /var/www/my_rails_app/current
11634 www-user  20   0  411m 216m 5144 S   10  2.7 197:55.63 Rack: /var/www/my_rails_app/current


Фрагмент страницы ниже:

[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 141474018}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 141577456}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 143073982}) = 0
[pid 11674] poll([{fd=15, events=POLLIN|POLLPRI}], 1, 0) = 0 (Timeout)
[pid 11674] write(15, "b\0\0\0\3SELECT `images`.* FROM `ima"..., 102) = 102
[pid 11674] read(15, "\1\0\0\1\0229\0\0\2\3def\23myappy_productio"..., 16384) = 2063
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 144138035}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
...
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 154076443}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 154189429}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 157185700}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 157298770}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 165076003}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 165212572}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 167542679}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 167683436}) = 0
....
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 62052248}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 62182486}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 62919948}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 63057266}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 63751707}) = 0
 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 73730686}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 75874687}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 76077133}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 78205019}) = 0
...
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 89370879}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 89583247}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 91637614}) = 0
[pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 91782149}) = 0


Попросил Google и наткнулся на ряд предложений, которые я безуспешно пробовал.


Что пробовали до сих пор:

  1. Пробовали установить часовой пояс в соответствии с рекомендациями Вот
    Никакой разницы, и проблема все еще сохраняется.
    Содержимое моего / etc / localtime:

    TZif2UTCTZif2UTC
    UTC0

  2. Попробовали рекомендованное исправление для ошибки leapsecond:

    дата -s 'дата'


Пока радости нет.


У меня только что закончились идеи, поэтому я буду благодарен за любую помощь / совет о том, как диагностировать или решить.


экспорт TZ =: / etc / localtime также работает - он будет читать файл при запуске и никогда больше - это означает, что процессы демона необходимо будет перезапустить, если вы когда-либо измените содержимое этого файла.

Однако, как и вы, мы также используем UTC на всех наших серверах, поэтому он никогда не меняется.

Не могу помочь вам с "clock_gettime" - однако я бы сказал, что на найденных нами виртуальных машинах время() быть довольно дорогим, поэтому у нас есть процесс-демон, который выделяет некоторую общую память и помещает туда время, а затем все процессы, которые хотят знать время, присоединяются к общей памяти и читают ее вместо использования время() fn.

Я обнаружил, что чрезмерная статистика в / etc / localtime связана с отсутствием переменных среды.

Попробуй это:

echo $TZ

Если он пуст, установите переменную в правильном месте (например, /home/apache/.bash_profile). Вам нужно будет установить его для пользователя, ответственного за запуск вашего веб-сервера, а затем перезагрузить демон (apachectl graceful и т. Д.).

TZ='Europe/London'; export TZ

Или любой другой часовой пояс для вашего региона (http://en.wikipedia.org/wiki/List_of_tz_database_time_zones).