Ubuntu 캐쉬 메모리를 주기적으로 지워서 메모리 확보하기

HYEONG HWAN, MUN/ 4월 2, 2015/ 미분류/ 23 comments

https://blog.lael.be/post/1090

라엘이는 게임서버를 하나 운영하고 있다.

 

게임서버는 웹이나 DB서버보다 자원을 많이 필요로 하기에 모니터링과 튜닝을 잘해야 한다.

1. CPU 사용량

게임서버는 일반적으로 사람의 활동 시간과 일치하는 경향이 있다.

또한 주말마다(불금 ~ 일요일) 접속자가 늘어나므로 CPU 상태를 잘 보아야한다.

CPU 사용량이 150%를 넘어서면 간헐적인 렉 현상이 일어난다.

> 해결책 : 게임의 속성을 잘 조절해서 부하량을 낮추어야 한다. 또는 코어를 왕창 할당하면 됨.

 

2. 메모리 사용량

CPU 만큼 중요한게 메모리이다.

물론 메모리가 부족하면 새로운 프로세스가 생성이 안되는 문제가 발생하기도 하지만, 작은 여유 공간에 데이터를 넣었다가 뺏다가 intensive(강렬) 한 작업을 해야하기 때문에 CPU 또한 과부하가 걸려서 문제가 발생한다. (연쇄반응)

접속자가 없을 때 게임서버가 자동 재부팅되도록 설정해 두었지만.. 메모리 사용량이 순 증가 하는 현상이 발생하더라.

tar 압축 같은 Disk I/O 할 때 캐쉬메모리가 대폭 증가하는 것을 알 수 있다.

프로그램을 끄면 USER 메모리는 해제가 되는데 캐쉬 메모리는 자동해제가 되지 않는다.

그래서 캐쉬메모리의 크기는 커지기만 한다.

이 공간을 주기적으로 초기화 해서 메모리를 확보해보도록 하자.

 

스크린샷 2015-04-02 오전 1.26.44

 

스크린샷 2015-04-02 오전 1.27.10

* 사용한 메모리(2351MB) = 유저 프로그램 메모리(1.96GB=2007MB) + 캐쉬 메모리(330 MB)

 

캐쉬 메모리를 지워보자.

#sync && echo 3 > /proc/sys/vm/drop_caches

스크린샷 2015-04-02 오전 1.32.54

 

캐쉬메모리가 비워지고 전체적인 메모리 사용량이 줄어든 것을 볼 수 있다.

스크린샷 2015-04-02 오전 1.34.57

 

매 시간마다 캐쉬메모리를 지우도록 설정

#crontab -e
0 * * * * sync && echo 3 > /proc/sys/vm/drop_caches

스크린샷 2015-04-02 오전 1.36.20

 

 

서버 호스트 PC를 한달동안 재부팅 안해도 메모리 공간이 원활하게 유지된다.

 

주의 사항

캐시메모리는 속도가 다른 장치간의 속도 개선을 위해 사용된다. 특히 디스크 I/O의 경우.

디스크 I/O 가 활발히 일어나는 시스템에서 drop_caches 를 사용하면, 일시적으로 CPU 부하량이 크게 증가한다. (다운될 정도는 아니다)

이런 경우 drop_caches 를 아예 사용하지 않거나, 사람이 접속하지 않는 시간대에 실행하도록 하자.

 

drop_caches 는 non destructive operation 이기 때문에 자주써도 데이터 손실이 발생하지 않는다.

캐쉬 메모리중에 write buffer 라는 파일 쓰기 대기 버퍼(dirty cache 라고도 함)가 있는데, 이러한 것들은 drop_cache 로 사라지지 않는다.

sync 명령어는 이러한 write buffer 내용을 디스크에 쓰고 drop 할 수 있는 cache 로 바꾼다.

즉, sync 후에 drop_caches 를 하면 최대한 많은 메모리가 확보되는 것이다.

As this is a non-destructive operation, and dirty objects are not freeable, the user should run “sync” first in order to make sure all cached objects are freed.

 

* 매일 새벽 4시에 캐시메모리를 비우는 방법. (저는 아래와 같이 사용합니다.)

#crontab -e
0 4 * * * sync && echo 3 > /proc/sys/vm/drop_caches

 

 

23 Comments

  1. 항상 많이 배우고 있습니다. ^^
    쉽게 설명해 주셔도 워낙 초보자라 다 소화를 못하는 부분이 있어 아쉽네요.

    제 서버에 ssh접속을 하면 한번씩 재부팅이 필요하다는 메세지가 뜹니다.
    메모리 확보를 해도 메세지가 뜨는 관계로
    새벽시간대에 접속자가 없을때 재부팅을 할수 있도록 설정하는 방법을 가르쳐주실수 있으신지요?
    아니면 메모리 확보만 해주면 되는 것인지요???

    1. 재부팅 요청메시지는 프로그램을 최신버전으로 업그레이드 했을 때 나타납니다.

      윈도우 업데이트후에 재부팅 요청 메시지 뜨는 것과 같습니다. 안하고 사용해도 되는데, 해주면 좋죠.

      1. 답변 감사합니다. ^^

  2. 좋은 팁 고맙습니다.

    근데,
    크론탭에서 위 명령어 입력하고, 어떻게 저장하고 빠져나오죠? ^^;;;

    1. vi 에디터와 사용법이 같습니다.
      i 누르고 insert 모드에서 입력한 후에, ESC 누르고 명령모드로 돌아와서 :wq 엔터 입력하면 됩니다.

      1. 답변 고맙습니다.

        근데, 제 상황과 좀 안 맞는 것 같아요.

        제 리눅스는 … 나노편집기 같은 걸로 연결되네요.

        crontab -e 입력하면 나노편집기 상태에서 자동으로 열리며,
        i 누를 필요없이 입력이 되네요.
        그리고, 위에 적어주신 명령어를 입력 후 빠져나오려고 ESC키 누르니까 명령모드로 안 빠져나오고 그대로 편집모드 상태입니다.

        http://i.imgur.com/N6o2JzH.gif

      2. 기본 에디터를 변경해줬더니, 이젠 잘 되네요.

  3. 감사합니다.
    마인크래프트 서버를 운영중에 메모리 할당량이 자꾸 이상하게 누수되는것 같아서 찾아봤는데
    이런 좋은 글이 있었네요 ^-^

  4. 라엘 님, 궁금한 게 여러 개 생겼습니다. 질문이 많아 송구스럽네요. ^^;;;

    1.
    아래 명령어가 정해진 시간마다 잘 작동하는지 로그를 남겨 확인하고 싶은데, 어떻게 해야 하는지?
    0 4 * * * sync && echo 3 > /proc/sys/vm/drop_caches

    2.
    좀비프로세스를 제거 위해 아래 명령어를 수행하면, putty가 로그아웃되면서 튕겨 꺼져버립니다.
    ps -ef | grep defunct | awk ‘{print $3}’ | xargs kill -9

    확인해보니, 아래처럼 아파치 관련 프로세스가 좀비로 잡혀 이 프로세스를 죽여서 그러더라구요.
    root 22560 2813 0 21:32 pts/0 00:00:00 grep –color=auto defunct

    왜 grep –color=auto 이게 좀비가 된건지… ㅜㅜ

    신기하게, top 명령어를 입력했을 때 우측 상단에 보이는 zombie 갯수는 0으로 찍힙니다.
    letsencrypt 보안 SSL 적용 전엔 그러지 않았던 것 같은데, 최근 확인해보니 그렇더라구요.

    3.
    30분마다 좀비 프로세스 찾아죽이도록, 아래 명령어 넣었는데 잘 작동하는지 로그로 확인하려면?
    */30 * * * * ps -ef | grep defunct | awk ‘{print $3}’ | xargs kill -9

    예를 들어, crontab에 실행 명령어를 적어줄 땐 경로까지 적어줘야 하던데.. 위처럼만 적어도 작동할까요?
    10 4 * * * /sbin/shutdown -r now (작동 함)
    10 4 * * * shutdown -r now (작동 안 함)

    4.
    사용자 쓰기 권한 있는 폴더 (예: 777 또는 772) 경우, 폴더 배경색이 연두색으로 찍혀 알아보기 힘들게 나옵니다.
    예전엔 이러지 않았는데, 이 역시 ssl 적용과 관련된건지… ?
    에전처럼, 다시 일반적인 색으로 보이게 하거나, 연두색 배경색을 다른 색으로 변경이 가능한지 궁금합니다.

    질문이 많네요. 죄송합니다. ㅜㅜ

    1. 1. https://www.whatap.io/ 여기 가입한 후에 발급되는 키로 서버에 서버 모니터링 프로그램을 설치하세요.
      그래프로 확인하시면 됩니다.
      2. grep 으로 kill 을 하시면 무조건 튕기게 됩니다.
      3. 저라면 전체경로로 안쓸것 같습니다.
      4. ssl 적용과 관련이 없습니다. 색을 없애시려면 명령어 sh 를 입력하세요.

      1. 자세한 답변 감사합니다.

        추가로 궁금한 게요…

        2.
        grep 앞서 내린 명령어의 결과를 취합하는 역할을 하던데..
        그럼, 어떤 명령어로 취합해 제거해야 하는지?

        3.
        전체 경로를 안 쓰면 shutdown 처럼 작동 안 되는 명령어가 있다보니….
        아무래도 다른 파일에 명령어 경로를 정의해야 그렇게 쓸 수 있는 것 같더라구요.

        4.
        sh 명령어 입력하니까, 색은 다 흰색으로 나오는데…
        문제는 #모드가 경로가 표시 안 되네요.
        예를 들어,
        cd /home 명령어를 입력하면 예전에는 id@호스트명: /home # 처럼 바뀌었는데,
        sh 명령어를 입력하면 달랑 #만 찍히면서 현재 폴더 위치를 표시 안 해주더라구요.
        재부팅하면 다시 원상태로 돌아오긴 하던데,
        재부팅 않고 바로 다시 예전 모드로 돌아오려면 어떤 명령어를 넣어야 하는지?

        1. 2. 특정 명령어를 제외하고 다시 grep 하면 됩니다.
          ps -ef | grep -v “grep” | grep defunct | awk ‘{print $3}’ | xargs kill -9
          3. 명령어는 PATH 라는 기본탐색 폴더를 먼저 탐색합니다. PATH 에 /sbin 등을 추가해 주거나 전체경로를 지정하면 됩니다.
          4. 원상태로 돌아오려면 exit 를 입력하면 됩니다.

  5. CPU에서는 명령어가 잘 되는데
    GPU 서버에서는
    bash : /proc/sys/vm/drop_caches : Read-only file system
    라는 에러가 뜨면서 캐시 메모리가 지워지지 않네요..
    혹시 해결할 수 있는 방법이나 다른 방법이 있는 지 알고 싶습니다..
    (구글링 하면서 했는데 해결 방법을 못 찾겠네요..)

    1. 저도 잘 모르겠네요. 다만 캐쉬메모리 명령어이므로 CPU, GPU의 특성차이는 아닐겁니다.

  6. 블로거님 정말 친절하게 설명 해주셨네요..ㅋ

    그런데 정말 귀찮으실수도 있으실텐데 대단한거 같습니다 ^^;

    1. 글을 많이 쓰다보니까 점점 더 잘써지는 것 같아요. 감사합니다!

  7. 안녕하세요, 라엘님.
    저희 사이트는 평균동접 400명대 입니다.
    피크타임때는 800대 입니다.
    피크타임때 CPU 사용량도 2.8 이하였고, 메모리 사용량도 전체 4GB에서 400MB 정도 밖에 차지하지 않았습니다.
    그런데 갑자기 동접 810명대를 돌파하는 순간 사이트에 엄청난 렉이 걸렸습니다.
    회선문제인줄 알았으나, 서버를 재부팅해보니 다시 사이트 속도가 원상태로 돌아왔습니다.
    이런 경우에는 MYSQL이 문제인가요? PHP 문제인가요?
    매일매일 주기적으로 서버재부팅을 시켜줘야하는지 궁금합니다..
    Mysql은 기본 설정 그대로이며, php는 ram값을 좀 많이 주었습니다.
    해결책알려주시면 감사하겠습니다.

    1. 아파치인가요 엔진엑스인가요? 웹서버 세팅값을 제 블로그에서 쓰여진 대로 설정하셨나요?

  8. dump_cache 를 사용하면 개선이 될지 정확히 모르겠네요
    운영중인 서버는 웹서버 4대 DB1대인데 웹서버 3대만 로드밸런싱이고 매 시 00분~15분에 느려질때 보면 아파치 + free -m또는 top으로 보면 15GB 풀 차면서 cached 가 증가는 합니다. 그리고 내려왔다가 다시 메모리 10GB 정도 유지하고 있고요
    서버는 메모리는 16GB 입니다.
    php 5.4이고 centOS 6.7 이구요 구글을 통해 검색해서 prefork.c, 아파치 튜닝을 해도 그대로니 답답할 심정이네요
    작년 3월말에 매 새벽에 배치를 돌리던 재부팅을 제외하고는 딱히 없거든요 (=모든 서버 포함된 배치)
    캐쉬를 날리거나 메모리 증설 두 가지 말고는 답이 안보이네요..

    1. 하루에 두번 (새벽 4시 10분, 오후 2시 10분) 아파치를 재시작해보세요.

  9. 매일 4시 반에 서버 컴퓨터 재부팅하고 있었는데, 이 글 보고 매일 캐시 메모리만 비우고 재부팅은 1주일에 한 번만 하도록 바꿨습니다.
    감사합니다~!!

  10. 캐시 메모리 대부분은 디스크에 저장된 데이터의 빠른 접근을 위하여
    한번 읽은 데이터는 캐시 메모리에 저장해둡니다.
    캐시를 비웠을때… 해당 캐시를 사용하던 process들이 캐시 미스 발생으로 Disk IO가 늘어나면서 CPU 사용량도 일시적으로 증가 할 수 있습니다.
    따라서 캐시 메모리는 안지워도 됩니다…
    메모리가 부족하면 OS에서 알아서 가져다 씁니다.
    캐시 메모리를 비워서 서버 상태가 원활해 졌다면 다른 원인 파악이 필요해보입니다.

    1. 안녕하세요. 좋은 의견 감사드립니다.
      간혹, 일부 프로그램이 새로 실행될 때 메모리 여유공간을 먼저 검사하는 경우가 있습니다.
      이미 프로세스가 실행중이라면 OS가 적절히 관리하겠지만, 그렇지 않은 경우에는 문제가 생길 수도 있습니다.
      drop cache 가 non destructive operation 이기 때문에, 가끔씩 reset 해서 확보해주는 것도 괜찮다고 생각합니다.
      물론 메모리가 충분히 큰 서버에는 고려하지 않아도 되는 이슈이죠.

      취향 차이라고 생각해요.
      서버 운영에 빗대어 비유하자면..
      – 서버 OS 는 robust 하기 때문에 절대로 재부팅 할 필요가 없다.
      – 서버를 가끔씩 재부팅 해주는 것이 좋다.

      저는 둘다 맞다고 생각합니다.

Leave a Comment

작성하신 댓글은 관리자의 수동 승인 후 게시됩니다.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*