vmtouch는 OS 에서 메모리에 캐시하는 파일 정보를 보거나 메모리에서 넣거나(touch/lock), 빼거나(evict) 할 수 있는 작고 재미있는 프로그램임.

파일을 이용해 뭔가를 한다면 한 번 봐두면 좋을 듯 함.


생각해 본 사용가능 시나리오는 아래와 같음.

- 특정 소스코드 파일 혹은 임시캐시로 사용하는 디렉토리를 항상 물리메모리에 캐싱. 

(좀 어이없을 수도 있지만 발상을 약간 전환해서, 로컬머신에 램 빠방하다면 캐시된 파일을 읽고 쓰는 것이 redis 보다 빠름..-_-)

- 캐시할 필요가 없다고 확실시 되는 파일이 캐시되었을 경우 해제.

- 특정 파일/디렉토리의 캐시상태 모니터링.

- MongoDB의 경우 secondary->primary 전환시 warm-up 용도로 사용할 수도 있음.



자세한 설치/설명/예제는 아래 링크 참조.

vmtouch



설치

// 다운로드

[root@localhost]# wget --no-check-certificate https://raw.githubusercontent.com/hoytech/vmtouch/master/vmtouch.c


// 컴파일

[root@localhost]# gcc -Wall -O3 -o vmtouch vmtouch.c


// 실행 테스트. 옵션에 대한 대략적인 설명도 확인 가능.

[root@localhost]# ./vmtouch


./vmtouch: no files or directories specified


vmtouch v0.8.0 - the Virtual Memory Toucher by Doug Hoyte

Portable file system cache diagnostics and control


Usage: vmtouch [OPTIONS] ... FILES OR DIRECTORIES ...


Options:

  -t touch pages into memory

  -e evict pages from memory

  -l lock pages in physical memory with mlock(2)

  -L lock pages in physical memory with mlockall(2)

  -d daemon mode

  -m <size> max file size to touch

  -f follow symbolic links

  -h also count hardlinked copies

  -w wait until all pages are locked (only useful together with -d)

  -v verbose

  -q quiet







사용법

// 캐시상태 확인

// _______________________________________________________________________________________

// 특정 파일이 얼만큼 메모리에 캐시되어 있는지 확인

[root@localhost]# ./vmtouch -v ./data.dat


// 캐시되어 있지 않음

./data.dat

[                                                            ] 0/25882


           Files: 1

     Directories: 0

  Resident Pages: 0/25882  0/101M  0%

         Elapsed: 0.000632 seconds


// 디렉토리도 지정가능

[root@localhost]# ./vmtouch -v /data1 

// 결과 생략


// 여러 파일/디렉토리도 지정가능

[root@localhost]# ./vmtouch -v /data1 /data2 /data3

// 결과 생략


// vmtouch의 기본 파일크기 제한은 500M임. 

// 그러므로 500M 이상되는 파일을 다룰땐 -m 옵션을 이용해 최대사이즈 지정을 따로 해줘야 함. 

// 그렇지 않으면 500M 이상 되는 파일은 skip됨.

// 아래는 /data1 디렉토리의 1G 이상되는 파일의 캐시여부 체크 예제

[root@localhost]# ./vmtouch -v -m 1G /data1




// 캐시 시도 (Touch - mmap())

// _______________________________________________________________________________________

// touch로 캐시 시도

[root@localhost]# ./vmtouch -vt ./data.dat


./data.dat

[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO] 25882/25882


           Files: 1

     Directories: 0

   Touched Pages: 25882 (101M)

         Elapsed: 0.79598 seconds


// 실제로 캐시 되었는지 확인

[root@localhost]# ./vmtouch -v ./data.dat  


// 99.9% 캐시되어있음. 

./data.dat

[OOOOOOOoOOoOOOOOOOOoOoooOoOOoOOOOOooOOOOOOOOOOOOOOOOOoOOoOOO] 25853/25882


           Files: 1

     Directories: 0

  Resident Pages: 25853/25882  100M/101M  99.9%

         Elapsed: 0.002606 seconds





// 캐시 해제 (Evict)

// _______________________________________________________________________________________

// 캐시에서 뽑아냄

[root@localhost]# ./vmtouch -ve ./data.dat 

Evicting ./data.dat


           Files: 1

     Directories: 0

   Evicted Pages: 25882 (101M)

         Elapsed: 0.013608 seconds


// 실제로 물리 메모리에서 뽑혔는지 확인

[root@localhost]# ./vmtouch -v ./data.dat  

./data.dat

[                                                            ] 0/25882


           Files: 1

     Directories: 0

  Resident Pages: 0/25882  0/101M  0%

         Elapsed: 0.000609 seconds





// 캐시 시도 (Lock = mlock())

// _______________________________________________________________________________________

// 캐시가 영속적으로 이루어지도록 lock  

// 이 명령어는 vmtouch 프로세스가 계속 실행 상태로 존재하게 되므로 실제 사용시에는 -d 옵션과 함께 daemon으로 실행해야 함.

[root@localhost]# ./vmtouch -vl ./data.dat

./data.dat

[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO] 25882/25882

LOCKED 25882 pages (101M)


// 실제로 물리 메모리에 전부 캐시되었는지 확인

[root@localhost]# ./vmtouch -v ./data.dat

./data.dat

[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO] 25882/25882


           Files: 1

     Directories: 0

  Resident Pages: 25882/25882  101M/101M  100%

         Elapsed: 0.002692 seconds








퍼포먼스 테스트

// 준비된 파일(data.dat)은 1.1G 가량되는 텍스트 파일.

// vmtouch의 기본 파일 사이즈 제한은 500M 이므로 해당 사이즈를 넘어선다면 옵션으로 최대 크기를 지정해줘야 함. ex) 1.5G 이상 => -m 1.5G


// 물리 메모리에서 전부 뽑아냄.

[root@localhost]# ./vmtouch -ve -m 1.5G ./data.dat

Evicting ./data.dat


           Files: 1

     Directories: 0

   Evicted Pages: 273623 (1G)

         Elapsed: 0.12695 seconds


// 실제로 뽑혔는지 확인

[root@localhost]# ./vmtouch -v -m 1.5G ./data.dat

./data.dat

[                                                            ] 0/273623


           Files: 1

     Directories: 0

  Resident Pages: 0/273623  0/1G  0%

         Elapsed: 0.005476 seconds


// 파일 전체를 한 라인씩 읽어들이는 테스트용 php 스크립트 실행. (소스코드는 본문 아래에 게시)

[root@localhost]# ./test.php

실행시간: 8.863 sec


// 이 상황에서 왠만하면 data.dat 가 캐시되어 있는 상태이지만 여튼 만전을 기하기 위해 한 번 더 뽑아냄.

[root@localhost]# ./vmtouch -ve -m 1.5G ./data.dat

Evicting ./data.dat


           Files: 1

     Directories: 0

   Evicted Pages: 273623 (1G)

         Elapsed: 0.13239 seconds


// 파일을 캐싱하기 위해 touch

[root@localhost]# ./vmtouch -vt -m 1.5G ./data.dat

./data.dat

[OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO] 273623/273623


           Files: 1

     Directories: 0

   Touched Pages: 273623 (1G)

         Elapsed: 8.5873 seconds


// 테스트용 스크립트 실행

[root@localhost]# ./test.php

실행시간: 0.910 sec


// 결과: 8.863 / 0.910 = 9.74 (거의 10배에 가까운 차이)





테스트에 사용한 php 스크립트 소스코드

#!/usr/bin/php
<?PHP
ini_set('memory_limit', -1);

$start_time = microtime(true);

$fp = fopen('./data.dat', 'r');
while (($line = fgets($fp))!==false) {
    //  단지 읽어들이기만
}
fclose($fp);

printf("실행시간: %.3f sec\n", microtime(true)-$start_time);







[참조]

vmtouch 홈페이지: http://hoytech.com/vmtouch/

vmtouch github: https://github.com/hoytech/vmtouch

















Posted by bloodguy
,