프로세스당 Open FD 수를 효율적으로 모니터링합니까?

프로세스당 Open FD 수를 효율적으로 모니터링합니까?

Linux에서 열린 파일 수를 모니터링하고 싶습니다. 현재 /proc/<pid>/fd및 의 파일 수를 계산하고 있습니다 fdinfo.

내 로드 밸런서에는 약 백만 개의 FD가 있습니다. 따라서 이 작업을 수행하는 데 약 20초가 소요됩니다.

그러나 이로 인해 CPU 사용량이 높아집니다.47.18% [kernel] [k] __d_lookup

이 번호를 얻는 더 효율적인 방법이 있습니까?

답변1

전용 로드 밸런서의 경우 I/O 및 CPU 리소스를 프로세스별로 계산하여 낭비하는 대신 시스템에서 열린 총 파일 수를 추적합니다. 원하지 않는 프로세스에 의해 열려 있는 나머지 파일은 의도한 결과에 대해 의미 없는 값이어야 합니다.

Linux 시스템에서 전체 공개 파일을 알기 위해 이를 셀 필요가 없습니다. Linux 커널은 열려 있는 파일 수를 추적합니다.

이를 확인하려면 다음 중 하나를 실행하세요.

cat /proc/sys/fs/file-nr | awk ' { print $1 } '

또는

sysctl fs.file-nr | awk ' { print $1 } '

lsof이는 모든 디렉터리를 이동하고 /proc/$PID/fd시스템 I/O/CPU 리소스에 부정적인 영향을 미치는 의 출력으로 열려 있는 모든 파일을 계산하는 것보다 훨씬 더 효율적입니다 .

답변2

간단한:

lsof | wc -l

시스템에 열려 있는 파일 수를 알려줍니다.

답변3

귀하의 사용 사례에 대해 이 SystemTap 코드가 얼마나 효율적입니까? 시작 시점의 변경 사항만 추적하므로(따라서 시작 전에 열린 항목은 모두 누락될 수 있음) 출력을 더 읽기 쉽거나 적합하게 만들려면 추가 작업이 필요하므로 완벽한 보기는 아닙니다.

global procfdcount

probe begin {
    printf("begin trace...\n\n")
}

probe syscall.open {
    procfdcount[pid()]++
}

probe syscall.close {
    p = pid()
    procfdcount[p]--
    if (procfdcount[p] < 0) {
        procfdcount[p] = 0
    }
}

probe kprocess.exit {
    p = pid()
    if (p in procfdcount) {
        delete procfdcount[p]
    }
}

probe timer.s(60) {
    foreach (p in procfdcount- limit 20) {
        printf("%d %lu\n", p, procfdcount[p])
    }
    printf("\n")
}

다음과 같은 방법으로 실행하세요.

... (install systemtap here) ...
# stap-prep
... (fix any reported systemtap issues here) ...
# stap procfdcount.stp

이 방법의 단점은 모든 "열린 파일"(소켓 등)을 식별한 다음 적절한 시스템 호출 후크(사용 가능한 경우)를 통해 개수를 조정해야 한다는 것입니다. 위의 내용은 파일 파일만 추적합니다. 또 다른 옵션은 task_open_file_handlesCPU에 들어가는 작업을 호출 하고 가장 최근의 개수를 주기적으로 표시하는 것입니다.

global taskopenfh

probe begin {
    printf("begin trace...\n\n");
}

probe scheduler.cpu_on {
    p = pid();
    if (p == 0) next;
    taskopenfh[p] = task_open_file_handles(pid2task(p));
}

probe timer.s(60) {
    foreach (p in taskopenfh-) {
        printf("%d %lu\n", p, taskopenfh[p]);
    }
    delete taskopenfh;
    printf("\n");
}

하지만 이는 CPU에 없는 모든 것을 놓칠 수 있습니다. 완전한 목록을 얻으려면 전체 프로세스를 살펴보고 작업을 수행해야 합니다. 하지만 수백만 개의 FD가 있는 경우에는 너무 느리거나 비용이 많이 들 수 있습니다.

또한 이러한 프로브는 안정적이지 않은 것으로 보입니다. eBPF나 미래에는 어떤 것이 있을까요? 예를 들어 Centos 7의 두 번째 것은 잠시 후에 폭발합니다.

ERROR: read fault [man error::fault] at 0x0000000000000008 (((&(fs->fdt))))
near identifier 'task_open_file_handles' at
/usr/share/systemtap/tapset/linux/task.stp:602:10

관련 정보