NFS Performance Tuning

NFS hang-up 현상

NFS를 사용 시 여러 Client에서 Server의 NFS 디렉토리에 접근할 때,
프로그램 내에서 NFS 디렉토리에 접근하는 fopen() 코드에서 Hang-up 현상이 발생하였고 1, 2분 이후에 정상적으로 진행하였습니다.
원인 파악 도중 NFS 마운트 시 옵션을 추가한 후에 Hang-up 현상이 발생하지 않았을 뿐만 아니라 기존 대비 프로그램 내에서의 처리 속도 또한 향상되었습니다.


NFS 성능 조정은 세 가지 방향으로 분류할 수 있습니다.
1. NFS에 영향을 미치는 기본 디스크 관련 성능
2. NFS 응용 프로그램 기반 성능
3. 네트워크 관련 NFS 조정 (NFS는 네트워크에 크게 의존하는 기술입니다.)

NFS 서버와 NFS 클라이언트 튜닝하는 것은 네트워크 파일 시스템 통신 매우 중요합니다. 
클라이언트 측에서 NFS 성능을 조정하기 위해 사용한 일부 마운트 명령 옵션입니다.

mount -t nfs -o rw,rsize=32768,wsize=32768,nfsvers=3,tcp,bg,nointr,noac 192.168.0.XX:[서버 마운트 디렉토리] [클라이언트 마운트 디렉토리]

 

 

Server 및 Client 파일 마운트

Server : /etc/exports 파일

[마운트 디렉토리] 192.168.0.*(rw,async,no_root_squash,no_subtree_check)

 

Clinet : /etc/fstab 파일

192.168.0.XX:[서버 마운트 디렉토리] [클라이언트 마운트 디렉토리] nfs rw,rsize=32768,wsize=32768,nfsvers=3,tcp,bg,nointr,noac 0 0

 

 

NFS 마운트 옵션 설명

Server : /etc/exports 파일 설정 옵션

- sync

파일을 쓸 때 서버와 클라이언트 싱크를 맞춥니다.
서버는 데이터가 저장소에 안전히 쓰였음을 확인 한 후, 

응답을 보내는데 이는 변경 사항을 디스크에 기록하기 전에는 서버가 요청에 응답하는 것을 허용하지 않는다는 뜻입니다.


- async

async는 sync 옵션을 사용하지 않는 경우에 Default로 사용됩니다.
서버는 데이터가 저장소에 안전히 저장됐는지를 확인하지 않고, 클라이언트의 데이터 쓰기 요청이 들어오면 바로 응답을 보냅니다.
데이터 안정성 문제가  발생할 수 있지만 성능 향상을 기대할 수 있습니다.

 

- no_root_squash

이 옵션을 사용하면, 로컬 사용자와 원격 사용자를 모두 ID 0 즉 root로 취급합니다.

따라서 원격 사용자는 파일과 디렉토리에 대한 모든 권한을 획득할 수 있는데 편리하게 사용할 수 있지만 보안에 취약할 수 있습니다.

서버와 클라이언트의 root 사용자를 같도록 설정하는 것으로 default 값은 root 사용자의 사용자 ID와 그룹 ID는 모두 0입니다.

이 옵션을 사용하시면 익명 사용자의 사용자 ID와 그룹 ID에 사용자 ID 0와 그룹 ID 0를 부여하여 원격 루트 사용자를 로컬 루트로 취급합니다.

따라서 클라이언트 상의 루트 사용자는 디렉토리를 내보내기할 수 있는 권한을 갖게 되고 이 옵션을 선택하시면 시스템 보안이 매우 약해지기 때문에, 필요한 상황이 아니면 root_squash 옵션을 선택하지 않는 것이 좋습니다.

- no_subtree_check

파일 시스템의 전체 디렉토리가 아닌 하부 디렉토리가 내보내진 경우, 서버는 내보낸 하부 디렉토리에 요청된 파일이 존재하는지를 검사합니다.

이러한 검사 과정을 하부구조 검사라고 부른다.

옵션 선택 시 하부구조 검사를 사용하지 않고 전체 파일 시스템이 내보내진 경우 하부구조 검사를 하지 않음으로 전송률을 높일 수 있습니다.

 

Client : /etc/fstab 파일 설정 옵션

- actimeo

NFS 성능 튜닝에서 가장 많이 설정하는 것이 actimeo 값으로 이는 nfs로 마운트된 곳의 파일 어트리뷰트를 캐시하는 시간을 일괄적으로 지정합니다.
갱신 후 파일 및 디렉토리 항목이 파일 속성 캐시에 보존되는 절대 시간입니다. 
일괄적으로 acdirmax, acdirmin, acregmax, acregmin 값을 각각 지정하는 번거로움 없이 actimeo를 적어주면 앞의 4가지 값이 모두 동일하게 변경됩니다. 4가지 속성의 기본 값은 acdirmax=60,acdirmin=30,acregmax=60,acregmin=3 으로 단위는 초입니다.
예를 들어 actimeo=30 으로 설정하면, 4가지 속성 모두 30(초)으로 세팅됩니다. 
즉, acdirmax=30,acdirmin=30,acregmax=30,acregmin=30 과 같습니다.
 
- acregmin : 갱신 후 파일 항목이 보존될 최소 시간으로 디폴트 값은 3초입니다.  
- acregmax : 갱신 후 파일 항목이 보존될 최대 시간으로 디폴트 값은 60초입니다. 
- acdirmin : 갱신 후 디렉토리 항목이 보존될 최소 시간으로 디폴트 값은 30초입니다. 
- acdirmax : 갱신 후 디렉토리 항목이 보존될 최대 시간으로 디폴트 값은 60초입니다. 
    

- bg/fg

마운트 실패시 background로 재시도, foreground로 재시도. 기본값은 fg
내보내기 마운트 시도가 실패한 경우 mount (8) 명령의 작동 방식을 결정합니다.

fg 옵션을 사용하면 마운트 요청의 일부가 시간 초과되거나 실패하면 mount (8)가 오류 상태로 종료됩니다.

이것을 "포그라운드" 마운트라고하며 fg 또는 bg 마운트 옵션을 지정하지 않은 경우 기본 동작입니다.


bg 옵션이 지정되면 제한 시간 초과 또는 실패로 인해 mount (8) 명령이 하위를 포크하여 내보내기 마운트를 계속 시도합니다. 

부모는 즉시 제로 종료 코드와 함께 반환하고, 이를 "백그라운드"마운트라고합니다.
로컬 마운트 포인트 디렉토리가 없으면 mount (8) 명령은 마운트 요청이 시간 종료 된 것처럼 작동합니다. 

따라서 일부 NFS 서버를 아직 사용할 수없는 경우에도 시스템 초기화 중에 /etc/fstab에 지정된 중첩 NFS 마운트가 순서에 관계없이 진행될 수 있습니다. 

또는 이러한 문제는 자동 마운트를 사용하여 해결할 수 있습니다.

 

- tcp/udp

udp 옵션은 proto = udp를 지정하는 대신 사용할 수 있습니다. 다른 운영 체제와의 호환성을 위해 포함되어 있습니다.
tcp 옵션은 proto = tcp를 지정하는 대신 사용할 수 있습니다. 다른 운영 체제와의 호환성을 위해 포함되어 있습니다.

- intr/nointr

이 마운트 지점에서 신호가 파일 작업을 중단하도록 허용할지의 여부를 선택합니다. 
옵션이 지정되지 않은 경우 (또는 nointr이 지정되지 않은 경우) 신호는 NFS 파일 작업을 중단하지 않습니다. 
intr을 지정하면 진행중인 NFS 작업이 신호에 의해 중단되면 시스템 호출은 EINTR을 반환합니다.


소프트 옵션을 사용하는 것보다 intr 옵션을 사용하는 것이 데이터 손상을 유발할 가능성이 훨씬 낮기 때문에 선호됩니다.
커널 2.6.25 이후에는 intr / nointr 마운트 옵션이 더 이상 사용되지 않습니다. 
SIGKILL만이 이러한 커널에서 보류중인 NFS 작업을 중단 할 수 있으며, 지정된 경우이 마운트 옵션은 무시되어 이전 커널과의 하위 호환성을 제공합니다.

 

- forcedirectio

directio를 강제로 사용고자 할 경우 옵션을 주면 됩니다. 
버퍼링 없이 클라이언트/서버 간에 데이터가 전송되고 actimeo=0 옵션과 같이 DBMS의 데이터 파일처럼 큰 파일을 핸들링 할 때 주로 사용됩니다.

 

- rsize, wsize

NFS 서버에서 파일을 읽을 때 NFS가 사용하는 바이트 수 최대 읽기버퍼(rsize), NFS 서버에 파일을 쓸 때,

NFS가 사용하는 바이트 수 최대 쓰기버퍼(wsize)의 크기 지정합니다. 
rsize는 서버와 클라이언트 사이에서 협상되어 둘 다 지원할 수있는 가장 큰 블록 크기를 결정합니다. 

이 옵션으로 지정된 값은 사용할 수있는 최대 크기입니다. 
그러나 사용 된 실제 크기는 더 작을 수 있습니다.

이 크기를 지원되는 최대 블록 크기보다 작은 값으로 설정하면 성능이 저하됩니다.

rsize = 32768 및 wsize = 32768 설정은 읽고 쓰는 동안 각 RPC 패킷이 취하는 데이터의 크기를 지정합니다. 
이를 조정하면 성능이 향상되거나 성능이 저하 될 수 있습니다. 
rsize 및 wsize 조정은 항상 네트워크 용량뿐만 아니라 클라이언트 및 서버의 처리 및 성능을 유지하여 수행해야 하는데, 
마운트에서 rsize & wsize의 크기를 줄이기로 결정했다고 가정해 볼 경우 RPC 패킷의 읽기 및 쓰기 크기를 줄이면 

네트워크를 통해 전송해야하는 총 네트워크 IP 패킷 수가 증가합니다.
즉, 1MB의 데이터가 있는 경우 데이터를 동일한 크기로 32KB로 나누면 개수가 증가하고, 64KB의 동일한 크기로 나누면  개수가 줄어 듭니다. 
따라서 size 값을 줄이면 네트워크를 통해 많은 수의 IP 패킷을 보내야 하지만, size 값을 늘리면 네트워크를 통해 더 적은 수의 IP 패킷을 보낼 수 있습니다.

따라서 이 매개 변수 수정에 대한 결정은 항상 네트워크 기능에 따라 달라집니다. 
NFS 서버와 클라이언트에 1기가 비트 포트가 있고, 

해당 서버를 연결하는 네트워크 스위치도 1G 포트를 사용할 수 있다고 가정하면 이 매개 변수를 더 높은 값으로 조정하는 것이 좋습니다.
아래와 같이 마운트하는 동안 rsize 및 wsize 값을 쉽게 수정할 수 있습니다.

설정할 수 있는 최대 값은 현재 커널 버전에 따라 다릅니다.

 

- noac

데이터 및 파일 속성 캐시 안함(noac), 모든 형태의 속성 캐싱을 완전히 비활성화합니다. 

이로 인해 상당한 성능 저하가 발생하지만 두 클라이언트가 서버의 공통 내보내기에 적극적으로 쓸 때,

두 개의 다른 NFS 클라이언트가 합리적인 결과를 얻을 수 있습니다. 

 

- nointr

[hard]옵션으로 마운트된 파일 시스템에서 행이 걸렸을 경우 프로세스를 죽이기 위해 키보드 인터럽트를 허용하지 않음(nointr).

기본값은 캐시함, 허용함.

 

- soft, hard

NFS서버에서 응답이 없는 경우, 서버 응답하거나 타임아웃될때까지 재시도하거나(hard), 

에러를 발생하고 마운트 프로세스 종료(soft). NFSv4에서는 soft를 지원하지 않는다. 기본값은 hard.

- vers

사용할 NFS 프로토콜을 정의. vers=3 인경우 NFSv3. 기본값은 4

 

- noacl

ACL (액세스 제어 목록) 처리를 비활성화합니다.

 

- nocto

파일을 생성할 때 새 속성 검색을 억제합니다.

- noatime

이 값을 설정하면 NFS 서버가 inode 액세스 시간을 업데이트하지 못합니다. 

대부분의 응용 프로그램에이 값이 반드시 필요한 것은 아니므로이 업데이트를 안전하게 비활성화 할 수 있습니다.

 

- nodiratime

이 값을 설정하면 NFS 서버가 디렉토리 액세스 시간을 업데이트 할 수 없습니다. 

이것은 noatime과 동등한 디렉토리 설정입니다.

 

NFS 성능 모니터링

서버 모니터링

워크로드 활동 중 NFS 서버에서 vmstat 및 iostat 명령으로 CPU 사용량, 입출력 활동 및 메모리 사용량을 검사하여 서버의 프로세서, 메모리 및 입출력 구성이 적절한지 확인해야 합니다. nfsstat 명령을 사용하면 서버에서 NFS 조작 활동을 모니터할 수 있습니다.

 

- nfsstat -s 명령

NFS 서버는 수신된 NFS 호출 수인 calls 및 인증으로 인해 거부된 badcalls뿐 아니라 다양한 종류의 호출에 대한 개수와 백분율을 표시합니다.

 

클라이언트 모니터링

워크로드 활동 중 NFS 클라이언트에서 vmstat 명령으로 CPU 사용량과 메모리 사용량을 검사하여

클라이언트의 프로세서 및 메모리 구성이 적절한지 확인해야 합니다.
nfsstat 명령을 사용하면 클라이언트의 NFS 조작 활동을 모니터할 수 있습니다.

 

- nfsstat -c 명령

NFS 클라이언트는 전송 및 거부된 NFS 호출 수뿐 아니라 클라이언트 핸들의 수신 횟수(clgets),

 다양한 종류의 호출 수 및 각각의 백분율 정보를 표시합니다.

 

- nfsstat -m 명령

nfsstat -m 명령은 서버 이름 및 주소, 마운트 플래그, 현재 읽기 및 쓰기 크기, 재전송 수, 

클라이언트의 각 NFS 마운트에 대한 동적 재전송에 사용된 타이머를 표시합니다.