web-dev-qa-db-ja.com

高いCPU +過剰なstat( "/ etc / localtime")およびclock_gettime(CLOCK_REALTIME)呼び出しを解決する方法


Ruby on Railsアプリ(以下のスタックを参照)で非常に高いCPUを経験しており、考えられる原因を診断しようとしても無駄です。

スタック:

  • Ruby 1.9.3
  • レール3.2.6
  • Apache/2.2.21(Debian)
  • Phusion Passenger 3.0.11

スパイクラックプロセスPIDに対してstraceを実行すると(以下の上部の抜粋を参照)、stat("/etc/localtime")clock_gettime(CLOCK_REALTIME)が呼び出され、これらを停止する方法がわかりません。


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


以下のStraceスニペット:

[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


グーグルを回ってみて、私が試したが成功しなかったいくつかの提案に出くわした。


これまでに試したこと:

  1. 推奨どおりにタイムゾーンを設定してみました ここ
    違いはなく、問題は引き続き発生します。
    私の/ etc/localtimeの内容:

    TZif2UTCTZif2UTC
    UTC0

  2. うるう秒バグの推奨修正を試しました:

    日付-s '日付'


これまでのところ喜びはありません。


私はアイデアが新鮮なので、診断または解決する方法についてのヘルプ/アドバイスをいただければ幸いです。


3
Yemster

export TZ =:/ etc/localtimeも機能します-起動時にファイルを読み取り、二度と読み取りません-これは、の内容を変更した場合、デーモンプロセスを再起動する必要があることを意味しますこのファイル。

ただし、あなたと同じように、すべてのサーバーでUTCを実行しているため、変更されることはありません。

「clock_gettime」では役に立ちません-ただし、VMではtime()は非常に高価であることがわかったため、共有メモリを割り当てて時間をかけるデーモンプロセスがありますそこで、時間を知りたいすべてのプロセスは、time() fnを使用する代わりに、共有メモリに接続して読み取ります。

1
James Stevens

/ etc/localtimeへの過剰な統計は、環境変数が欠落していることが原因であることがわかりました。

これを試して:

echo $TZ

空白の場合は、変数を正しい場所(つまり、/ home/Apache/.bash_profile)に設定します。 Webサーバーの実行を担当するユーザーに設定してから、デーモンをリロードする必要があります(apachectl gracefulなど)。

TZ='Europe/London'; export TZ

または、お住まいの地域の正しいタイムゾーンが何であれ( http://en.wikipedia.org/wiki/List_of_tz_database_time_zones )。

1
baronleaky