TIL

NFS 지연 회고록

하얀잔디 2026. 10. 13. 10:20

최근 운영 중인 파일 API에서 응답 지연이 발생해 NFS 상태를 확인했다.

 

기존엔 0.05초 이내로 서빙되던 파일이 0.5초 넘게 걸리는 현상이 발견되었다.

 

확인 과정에서 NFS 서버로 들어오는 TEST_STATEID 요청이 초당 약 200~300회 반복되는 현상을 발견했다.

 

NFS 서버 자체의 문제인지, 클라이언트가 이전 상태를 계속 확인하는 것인지 살펴봤고, 개발 환경에서 먼저 NFS 클라이언트 강제 만료(Expire)를 테스트한 뒤 운영 환경에도 적용했다.

이번에 사용한 명령어와 확인 과정을 정리해 둔다.

1. NFS 서버와 클라이언트 확인

먼저 어느 서버가 NFS 서버이고, 어디서 마운트해 사용하고 있는지 확인했다.

NFS 클라이언트(WAS)에서 실행한다.

findmnt -t nfs,nfs4

실제 개발 환경에서는 다음과 같이 확인됐다.

NFS 서버: ezariadevdb
NFS 클라이언트: ezariadevwas
NFS 버전: 4.1

/data/ezaria-file  (rw)
/data/ezaria-web   (ro)

Kubernetes에서 NFS PV를 사용하고 있었고, WAS 노드의 kubelet 경로에 마운트된 상태였다.

마운트 옵션을 자세히 확인할 때는 다음 명령어를 사용한다.

nfsstat -m

NFS 서버에서는 공유 중인 디렉터리도 확인할 수 있다.

sudo exportfs -v

 

2. TEST_STATEID 요청 확인

NFSv4는 클라이언트가 파일을 열거나 잠그는 등의 작업을 할 때 서버에서 관련 상태를 관리한다.

TEST_STATEID는 클라이언트가 서버에 특정 NFS 상태 식별자(State ID)가 유효한지 확인하는 요청이다.

이 요청 자체는 정상적인 NFS 동작이다. 다만 이번에는 같은 종류의 요청이 계속 반복되고 있어서 확인이 필요했다.

NFS 서버에서 다음 명령어로 요청량을 확인했다.

a=$(awk '$1=="proc4ops" {print $58}' /proc/net/rpc/nfsd)
sleep 10
b=$(awk '$1=="proc4ops" {print $58}' /proc/net/rpc/nfsd)

echo "TEST_STATEID: $(((b-a)/10)) 회/초"

/proc/net/rpc/nfsd는 NFS 서버의 RPC 처리 통계를 확인할 수 있는 파일이다.

위 명령어는 10초 동안 증가한 TEST_STATEID 요청 수를 이용해 초당 평균 요청량을 계산한다. $58은 이번 Linux NFS 서버 통계 형식에서 해당 요청에 대응하는 필드다.

확인 결과는 다음과 같았다.

  • 운영 환경: 초당 약 200~300회 반복 확인
  • 개발 환경: 초당 0회

개발 환경에서는 같은 요청이 반복되지 않았다.

이를 통해 운영 환경의 NFS 클라이언트 상태나 복구 동작을 추가로 살펴볼 필요가 있다고 판단했다.

다만 TEST_STATEID 요청이 많다는 사실만으로 응답 지연의 원인이 확정되는 것은 아니다.

 

3. NFS 클라이언트 상태 확인

NFSv4 서버에서는 현재 등록된 클라이언트 목록을 확인할 수 있다.

NFS 서버에서 실행한다.

sudo ls -l /proc/fs/nfsd/clients/

개발 환경에서는 다음과 같은 결과가 나왔다.

total 0
drw------- 2 root root 0 Mar 24 2026 12

여기서 12는 NFS 서버가 관리하는 클라이언트 디렉터리 번호다.

이 번호는 서버마다 다르고, 클라이언트가 다시 등록되면 변경될 수 있다.

실제 어떤 클라이언트인지 확인하려면 다음 명령어를 사용한다.

sudo cat /proc/fs/nfsd/clients/12/info

여기에서 클라이언트 IP, NFS 버전, 상태 등의 정보를 확인할 수 있다.

여러 클라이언트를 한 번에 확인할 때는 아래 명령어가 편리하다.

sudo grep -H -E 'address|name' \
  /proc/fs/nfsd/clients/*/info

특히 Expire를 실행하기 전에는 클라이언트 번호와 IP가 일치하는지 확인하는 것이 중요하다.

 

4. NFS 클라이언트 Expire 테스트

이번에는 NFS 서버에서 클라이언트의 기존 상태를 강제로 만료시키는 방법을 사용했다.

명령어는 다음과 같다.

sudo sh -c 'printf "expire\n" > /proc/fs/nfsd/clients/12/ctl'

expire는 NFS 서버가 관리하는 해당 클라이언트의 상태를 강제로 만료시키는 작업이다.

실제 저장된 파일을 삭제하거나 NFS 마운트를 직접 해제하는 작업은 아니다.

다만 파일 열기(OPEN), 잠금(LOCK) 등 기존에 유지하던 상태도 무효화될 수 있기 때문에 서비스에 영향을 줄 수 있다.

그래서 개발 환경에서 먼저 테스트했다.

개발 환경 테스트 결과

기존 클라이언트 번호는 12였다.

Expire 실행 후 다시 확인했다.

sudo ls -l /proc/fs/nfsd/clients/

처음에는 목록이 비어 있었고, 잠시 후 다음과 같이 나타났다.

drw------- 2 root root 0 Oct 12 04:16 13

클라이언트 번호가 12 → 13으로 변경됐다.

기존 상태가 제거된 뒤 새로운 클라이언트 항목이 등록된 것으로 확인됐다.

단, 새로운 번호가 생성됐다는 것만으로 애플리케이션의 모든 파일 접근과 잠금이 정상 복구됐다고 볼 수는 없다.

 

5. 운영 환경 적용

개발 환경에서 Expire 이후 새 클라이언트 항목이 생성되는 것을 확인한 뒤 운영 환경에서도 작업을 진행했다.

운영 NFS 서버에서는 대상 클라이언트 번호가 24였다.

sudo sh -c 'printf "expire\n" > /proc/fs/nfsd/clients/24/ctl'

명령어는 별도 오류 없이 실행됐다.

이후 클라이언트 목록을 조회했다.

sudo grep -H -E 'address|name' \
  /proc/fs/nfsd/clients/*/info

결과는 다음과 같았다.

grep: /proc/fs/nfsd/clients/*/info:
No such file or directory

기존 클라이언트 24가 사라졌고, 조회 시점에는 새로운 클라이언트 항목이 확인되지 않았다.

따라서 서버 측 상태 만료는 진행된 것으로 보이지만, 이 결과만으로 NFS 연결이나 파일 API 지연이 정상화됐다고 판단할 수는 없다.

 

6. 작업 후 확인할 사항

Expire 이후에는 NFS 서버와 클라이언트 양쪽을 확인하는 것이 좋다.

NFS 서버에서는 새 클라이언트가 등록되는지 확인한다.

sudo ls -l /proc/fs/nfsd/clients/

NFS 클라이언트에서는 마운트 상태를 확인한다.

findmnt -t nfs,nfs4

커널 로그에 NFS 관련 오류가 남았는지도 확인한다.

sudo journalctl -k --since "10 minutes ago" \
  | grep -Ei 'nfs|stateid|reclaim|expired|stale'

여기에 실제 NFS 경로의 파일 읽기·쓰기, 애플리케이션 응답 시간, TEST_STATEID 요청량까지 확인해야 작업 효과를 판단할 수 있다.

특히 NFS 마운트가 남아 있다고 해서 실제 파일 I/O가 정상이라는 의미는 아니다.

7. 정리

이번 작업에서 확인한 핵심은 다음과 같다.

  • findmnt로 NFS 서버와 클라이언트의 마운트 구조 확인
  • /proc/net/rpc/nfsd로 TEST_STATEID 요청량 측정
  • /proc/fs/nfsd/clients/에서 클라이언트별 상태 확인
  • 개발 환경에서 Expire 테스트 후 클라이언트 재등록 확인
  • 운영 환경에서 대상 클라이언트 상태 강제 만료 진행

이번에는 NFS 서버를 재시작하지 않고 특정 클라이언트의 상태를 정리하는 방법을 사용했다.

개발 환경에서는 기존 클라이언트가 만료된 뒤 새 번호로 등록되는 과정까지 확인했다. 운영 환경은 상태 만료 이후 실제 파일 I/O와 요청량 변화를 추가로 확인해야 하는 상황이다.

NFS 장애를 볼 때 단순히 마운트 여부만 확인하기보다는, 서버가 관리하는 클라이언트 상태와 실제 요청 패턴까지 함께 확인하는 것이 중요하다는 점을 알 수 있었다.

다음에는 운영 환경에서 TEST_STATEID 요청량과 파일 API 응답 시간이 어떻게 달라졌는지도 확인해 볼 예정이다.