서비스 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가 설치된 다른 시스템을 비교할 수 있습니다.

관련 정보