인프라 공부

[Infra] 스왑메모리 딥다이빙(1. 서버 메모리 부족이 쏘아올린 작은 공)

장아장 2023. 12. 26. 16:11

서론

스왑메모리은 영상 인코딩을 하다가 서버가 부하를 버티지 못하는 문제로 사용해야겠다는 생각이 들었다. 

이전에 사용을 위해서 스왑메모리라는 것이 단순하게 서버가 가지는 저장공간(하드디스크)를 메모리로 치환해서 부족한 메모리를 보충해준다는 것을 알았다.

하지만, 부스트캠프 네트워킹 데이때 커피챗에서 스왑 메모리라는 단어 대신에, 내가 어떻게 풀어서 설명할 수 있어야 한다는 현업자분의 멘토링을 통해 한번 딥 다이빙을 해봐야겠다는 생각이 들었다.

 

그러면 뭐?


스왑메모리란?

우리의 RAM으로 받는 메모리 외에도, 하드 디스크 공간을 할당하여 RAM이상의 수요를 처리하기 위해 사용하는 가상 메모리이다. 

즉, 우리의 저장장치인 하드디스크(누군가에겐 HDD, 다른 사람에겐 SSD)를 가상 메모리화시키는 것이다.


특히 팀 프로젝트에서 EC2의 프리티어 상태에서 최선의 성능을 내기 위해 이번에 사용하였다. 

 

그렇다면 필요한 만큼 싹다 스왑 메모리화 시키면 어떨까?

이런 생각이 문득 지나갔다. 우리 서버에서 영상을 저장하는 공간이 존재하고, 영상을 인코딩하고 기존의 영상을 삭제하고 영상을 전송하는 과정을 거친다. 

그렇다면 써야할 공간을 빼고 싹다 스왑메모리화시켜버리면 어떻게 될까?라는 생각이 들었다. 

 

하지만, 우리가 영상을 저장하는 공간이 얼마나될지 모르고, 실제 메모리가 얼마나 있고 얼마나 더 써야할지 모른다. 

그래서 제대로 된 측정과, 개념이 뒷받침되어 제대로 얼마가 필요할지 알아야겠다는 생각이 들었다. 


메모리 확인 법

free -h라는 명령어로 total, used, free, shared, buff/cached, available이 있다는 것을 알았다. 

이를 어떻게 계산해야할지 궁금해졌다. 근데 검색은 안해보고 저 숫자들로 어떻게든 계산을 돌려보기 시작했다. 

이 때 내가 찾은 거라곤, 

  • total = available + buff/cached
  • available = used + free

라는 것이었다. 

이를 통해 각 단어들이 뜻하는 바를 찾아보고, 영단어 뜻(이정도는 개발한다면 다들 들어보지 않았을까)을 가지고 정리해보았다. 

  • total : 내 컴퓨터가 가진 총 메모리양
  • used : 이미 사용되고있는 메모리양
  • free : 아직 아무일도 안하고 실제로 사용가능한, 가용메모리양
  • shared : 공유되고 있는 메모리양
  • buff/cached : 버퍼/캐시가 할당받은 메모리양(사실 이걸 몰라서 이것도 딥다이빙 해보았다)
  • available : 할당되지 않고, 이 컴퓨터 직접 사용할 수 있는 메모리양

이 정도가 되었다. 

그런데, 나는 캐시라는 개념은 현금(?!)과 자바의 영속성 컨텍스트를 통한 1차 캐시(어느정도의 엔티티들을 DB에서 조회했을 때 이를 캐싱해서, 추가적인 DB 조회를 방지시키는 방식)을 제외하고는 들어본 적이 거의 없다. 

그래서 추가적인 딥 다이빙을 진행했다. 


사전 학습 : buff/cached 톺아보기

일단 버퍼와 캐시를 위해 사전에 알아야 할 부분들을 찾아보았다. 

  • 리눅스 커널은 블록 디바이스라고 부르는 디스크에서 데이터를 읽고 쓴다고 한다. 
    • 저장 장치를 말한다. 블록/섹터등의 정해진 단위가 존재한다. 
  • 항상 디스크에서 데이터를 가져오면 느리다는 문제가 있다. 
  • 그래서 한번 가져온 데이터들을 캐싱처리한다. 
  • 이를 통해 더 빠르게 데이터를 가져오게 된다. 

이 때 버퍼/캐시는 도대체 무엇이고 무슨 일을 할까?

 

Buffer

버퍼 캐시라고도 하며, 블록 디바이스에 대한 메타데이터(데이터의 구조 및 이에 대한 간단한 설명)을 메모리에 저장한다. 

 

Cache

Page Cache와 slab라는 것으로 이루어져 있다고 한다. 

그렇다면, 이 둘은 또 무엇인지 한번 정리해보았다. 

 

Page Cache

  • 저장 장치를 통해 한 번 읽어온 파일의 내용을 메모리에 저장한다. 
  • 버퍼에서 메타데이터를 저장하고 있는데 그렇다면 페이지 캐시는 무엇을 저장할까?
  • 파일의 메타데이터가 아닌, 실제 데이터를 저장하고 있는다.
  • 왜? 조회를 빠르게 하기 위해
  • 즉, 우리가 흔하게 Spring, NestJS에서 말하는 캐시 메모리이다. 

Slab

  • 위에서 캐시 메모리가 있는데 slab은 또 뭘까?
  • 위의 Page Cache는 디스크에서 읽은 데이터를 빠르게 조회하기 위한 캐시이다
  • slab은 리눅스 커널 자체가 직접 캐싱을 한다고 한다. 
  • 작은 크기의 메모리 할당에 관여한다. 
  • 왜 이걸 캐싱할까?
    •  작은 크기는 잦은 생성과 삭제를 반복한다. 
    • 만약 프로세스 오버헤드(하나의 작업에서 다른 작업으로 넘어가기)로 인한 메모리 사용 >= 작은 크기의 행동이면 어떻게 될까?
    • 오버헤드로 비용이 더 들어간다
    • 프로세스 제어, 파일 제어등의 작은 행동을 객체화 시켜 캐싱한다. 

 

Page Cache vs Slab

  • slab은 리눅스 커널 자체에서 동작하는 작지만 잦은, 우리가 자주 사용하는, cd/mkdir/cat등의 명령들이다. 
  • docker run과 같이 디스크에서 파일을 읽어와 로드시키는 과정은 페이지 캐시로 처리된다.
  • 크기 뿐만 아닌, 디스크 사용 여부 등도 생각해보자. 디스크에 저장된 데이터를 읽고 이를 메모리에 담는 것을 캐시로, 리눅스 커널 차제의 데이터를 메모리에 담는 것을 slab으로 이해했다. 

이정도 학습했을 때 무협소설로 치면 심마가 찾아왔다. 

본래의 방향을 못찾고, 다른 궁금증과 블록 디바이스와 같은 개념에 대한 공백이 생겼다. 

이쯤에서 한번 정리하고 스왑 메모리에 대한 정리를 하고 다시 학습을 시작해야겠다는 생각이 들었다. 


그래서 swap memory를 어떻게 설정하는데?

이렇게 내 EC2 인스턴스의 사양을 확인했다. 현재 빈 공간이 22GB가 존재한다. 

이 중에서 10G정도를 스왑 메모리로 할당했다. 

 

이후에 해당 스왑파일에 대한 현 사용자의 읽기, 쓰기 권한을 허용해주었다. 

(간단하게 다시 설명하자면 저 세 자리 숫자는 '나','그룹 내 다른 사용자', '모든 다른 사용자들'에 대한 권한이며, 권한은 1=실행, 2=쓰기, 4=읽기를 더해서 설정하면 된다)

 

이런 명령어를 통해 스왑 메모리를 활성화시켜준다. 

이런 명령어를 통해 스왑 메모리를 서버의 재부팅시에도 설정하게 해줄 수 있다. 

 

이후 스왑메모리가 적용되었는지 다시 free -h해주었다. 

 

이렇게 설정이 잘 된것을 알 수 있다. 


심마를 극복해보자!

내가 빠진 심마를 복기해보자(이렇게 말하니 진짜 이상해보이니 이제 정상적으로 부르겠다)

 

내가 직면한 호기심과 옆으로 빠지는 궁금증은, 

  • HDD에서 SSD로 바꿨을 때 스왑메모리는 더 빠른가?
  • 블록 디바이스는 어떻게 단위가 설정될까?

정도가 된다. 

이를 위한 학습을 다시 정리해봐야겠다.