Dirty Page Issues

dirty page가 무엇인지 알아보고 이가 I/O에 끼치는 영향을 알아본다.

Dirty Page

특정 파일에 대한 쓰기 작업이 이루어지면 커널은 Page Cache에 올라가 있는 파일의 캐시를 수정한다. 이렇게 될 경우 디스크에 있는 내용과 Page Cache에 있는 내용이 서로 달라진다. 그래서 커널은 해당 메모리 영역에 Dirty 비트를 켜고 특정 조건이 만족되었을 때 이를 디스크로 동기화하는 작업을 수행한다. 이 과정을 page writeback이라고 부르며 dirty page 동기화라고도 한다. (보통 flush라는 단어가 들어간 커널 스레드가 이 작업을 진행한다)

I/O가 많이 발생하는 서버에서는 dirty page를 언제 얼마나 동기화시키느냐가 중요한 성능 튜닝의 요소가 된다.

현재의 dirty page 양은 다음 명령어로 조회할 수 있다.

$ cat /proc/meminfo | grep -i dirty 

또한 I/O에 대한 사용량은 iostat 명령어로 볼 수 있다.

$ iostat

Kernel Parameter

dirty와 관련된 커널 파라미터는 총 6개가 있다.

vm.dirty_background_ratio

dirty page의 내용을 백그라운드로 동기화할 때 그 기준이 되는 비율을 의미한다. 예를 들어 이 값이 10이고 전체 메모리가 8GB라고 가정한다면 dirty page의 크기가 800MB가 되었을 때 백그라운드 동기화를 진행한다.

vm.dirty_background_bytes

vm.dirty_background_ratio와 비슷하지만 절대적인 bytes를 기준으로 동작한다.

vm.dirty_ratio

vm.dirty_background_ratio가 soft limit이라면 vm.dirty_ratio는 hard limit이라고 볼 수 있다. dirty page가 메모리의 특정 비율을 점유했을 때 커널은 해당 프로세스의 I/O 작업을 모두 멈추고 page writeback을 진행한다. 이 값은 5보다 낮아질 수 없다.

vm.dirty_bytes

vm.dirty_background_bytes에 대해서 vm.dirty_ratio와 같이 동작한다.

vm.dirty_writeback_centisecs

flush 커널 스레드를 몇 초 간격으로 깨울 것인지를 결정한다. 설정되는 값은 1/100초 값이다.

vm.dirty_expire_centisecs

vm.dirty_writeback_centisecs로 깨어난 flush 커널 스레드가 dirty page 중 writeback시킬 대상을 정하는데 쓰이는 값이다. 역시 설정되는 값은 1/100초이다. 예를 들면 flush 커널 스레드가 깨어나서 30초 동안 디스크로 동기화되지 않은 페이지를 동기화시키는 역할을 한다.


백그라운드 동기화와 주기적인 동기화는 flush 커널 스레드를 깨우는 기준이 다른 것이지 실제로 하는 작업이 다른 것은 아니다. 결국은 커널 내의 wb_do_writeback()라는 함수를 통해서 동기화를 진행한다.

Kernel Parameter Tunning

flush 커널 스레드가 자주 깨어나면 io util(%)가 비교적 적지만 잦은 스케줄링에 대한 오버헤드가 발생할 수 있으며, 멀티 스레드 어플리케이션의 경우 커널이 불필요하게 cpu 리소스를 사용할 수 있다. 반면에 flush 커널 스레드가 간간히 깨어나면 io util(%)이 높아질 위험이 있다. 그렇기에 dirty page 동기화 시 발생하는 I/O 작업 멈춤(즉 성능 저하)이 일어나지 않는 한에서 flush 커널 스레드가 깨어날 수 있도록 파라미터를 적절히 설정해주는 것이 중요하다.

comments powered by Disqus