サービス snmpd が gettimeofday システムコールを多すぎる

サービス snmpd が gettimeofday システムコールを多すぎる

最近snmpdサービスに問題が発生しました。 CentOS 6.9を実行するLinuxボックスがあり、localhostでsnmpwalkを実行すると、通常はタイムアウトのみが発生します。その後、10秒のタイムアウトを追加しようとしましたが、結果は良かったですが、まだ痛いほど遅いです。私はstraceを使ってカーネルを調べることにしましたが、snmpdサービスがsnmpリクエストに応答する前にgettimeofdayを何度も呼び出そうとすることがわかりました。 Debian 8 や Centos 6.3 を実行している他の Linux システムとは異なり、snmpd サービスは gettimeofday をまったく呼び出すことはありません。これが私が得た結果です:

rpm --query centos-release
centos-release-6-9.el6.12.3.x86_64

service snmpd status
snmpd (pid  28244) is running...

strace -r -e trace=gettimeofday -p 28244
Process 28244 attached
     0.000000 gettimeofday({1516589055, 372419}, NULL) = 0
     0.000048 gettimeofday({1516589055, 372448}, NULL) = 0
     0.000015 gettimeofday({1516589055, 372463}, NULL) = 0
     0.000015 gettimeofday({1516589055, 372477}, NULL) = 0
     0.003271 gettimeofday({1516589055, 375751}, NULL) = 0

0.000013 munmap(0x7f1950abf000, 4096) = 0
     0.000086 open("/proc/sys/net/ipv6/conf/eth3/forwarding", O_RDONLY) = 11
     0.000028 fstat(11, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
     0.000015 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1950abf000
     0.000015 read(11, "0\n", 1024)     = 2
     0.000017 close(11)                 = 0
     0.000012 munmap(0x7f1950abf000, 4096) = 0
     0.000017 open("/proc/sys/net/ipv6/neigh/eth3/base_reachable_time_ms", O_RDONLY) = 11
     0.000017 fstat(11, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
     0.000013 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1950abf000
     0.000014 read(11, "30000\n", 1024) = 6
     0.000016 close(11)                 = 0
     0.000012 munmap(0x7f1950abf000, 4096) = 0
     0.000015 read(9, "", 1024)         = 0
     0.000026 close(9)                  = 0
     0.000015 munmap(0x7f1950ac0000, 4096) = 0
     0.000014 close(10)                 = 0
     0.000028 gettimeofday({1516099695, 497691}, NULL) = 0
     0.000015 gettimeofday({1516099695, 497705}, NULL) = 0
     0.000012 gettimeofday({1516099695, 497718}, NULL) = 0
     0.000016 gettimeofday({1516099695, 497734}, NULL) = 0
     0.000012 gettimeofday({1516099695, 497746}, NULL) = 0
     0.000013 gettimeofday({1516099695, 497758}, NULL) = 0

CentOS 6.3を実行している他のLinuxシステムでsnmpdサービスのstrace結果を比較してみてください。

rpm --query centos-release
centos-release-6-3.el6.centos.9.x86_64

Process 4566 attached - interrupt to quit
     0.000000 select(10, [4 6 7 9], [], [], {1, 160003}) = 0 (Timeout)
     1.161298 open("/proc/diskstats", O_RDONLY) = 10
     0.000109 fstat(10, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
     0.000245 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e1d035000
     0.000047 read(10, "   1       0 ram0 0 0 0 0 0 0 0 "..., 1024) = 1024
     0.000109 read(10, "0 sda 240731 163874 8048386 2853"..., 1024) = 611
     0.000061 read(10, "", 1024)        = 0
     0.000023 close(10)                 = 0
     0.000064 munmap(0x7f6e1d035000, 4096) = 0
     0.000036 open("/proc/stat", O_RDONLY) = 10
     0.000034 read(10, "cpu  3775592 27347 3516548 70619"..., 4095) = 866
     0.000056 close(10)                 = 0
     0.000028 open("/proc/vmstat", O_RDONLY) = 10
     0.000031 read(10, "nr_free_pages 75722\nnr_inactive_"..., 4095) = 1964
     0.000042 close(10)                 = 0
     0.000037 select(10, [4 6 7 9], [], [], {4, 999068}) = 0 (Timeout)
     5.003442 open("/proc/diskstats", O_RDONLY) = 10
     0.000082 fstat(10, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
     0.000034 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e1d035000
     0.000029 read(10, "   1       0 ram0 0 0 0 0 0 0 0 "..., 1024) = 1024
     0.000126 read(10, "0 sda 240731 163874 8048386 2853"..., 1024) = 611
     0.000045 read(10, "", 1024)        = 0
     0.000023 close(10)                 = 0
     0.000076 munmap(0x7f6e1d035000, 4096) = 0
     0.000036 open("/proc/stat", O_RDONLY) = 10
     0.000037 read(10, "cpu  3775592 27347 3516551 70619"..., 4095) = 866
     0.000084 close(10)                 = 0
     0.000045 open("/proc/vmstat", O_RDONLY) = 10
     0.000035 read(10, "nr_free_pages 75722\nnr_inactive_"..., 4095) = 1964
     0.000100 close(10)                 = 0
     0.000055 select(10, [4 6 7 9], [], [], {2, 88417}

snmpdサービスがリクエストに応答する前にgettimeofdayを何度も呼び出すようにする特定の設定はありますか?

よろしくお願いします。

答え1

明らかにいくつかの問題があります。 TZ変数を設定すると、問題を解決できます。数千時間ライブラリがエンコードされる方法によるシステムコール。

実際にあなたの質問に関連しているので、フィードバックが必要です。

~から何千ものシステムコールを防ぐためにTZ環境変数を設定する方法

タイムゾーンを更新しない(またはタイムゾーンの更新中にプロセスを再開できる)サーバープロセスへの追加のシステムコールを回避するには、TZ環境変数を/ etc / localtime(または他のタイムゾーンファイル)に設定するだけです。選択)))プロセスです。これにより、glibcが追加(および不要)システムコールを防ぐことができます。

glibcのlocaltime関数は、TZ環境変数が設定されていることを確認することがわかりました。設定されていない場合(テストした両方のUbuntuに設定されていない場合)、glibcはlocaltimeを呼び出すたびにstatシステムコールを使用します。

つまり、システムは、カーネルに切り替えるコストを避けるために、LinuxカーネルのvDSOを介したタイムアウトシステムコール呼び出しをサポートします。ただし、プログラムが time を呼び出すとすぐに localtime を呼び出し、とにかくシステム呼び出しを呼び出します。したがって、vDSOを使用してあるシステムコールを削除し、それを別のシステムコールに置き換えました。

ファイルアクセスはしばしば時間依存システムコールも使用することに注意してください。 SNMP構成ファイルの名前の代わりに数値MIBSを使用してみてください。 (最初にのみ影響し、snmpdそれ以降はあまり影響しません)。

新しいファイルアクセスは時間依存システムコールを利用するため、起動時にこれらのいくつかを見るのが一般的です。snmpdMIBがインストールされていないシステムとMIBがインストールされている他のシステムとを比較できます。

関連情報