저번 시간에는 NoSQL에 대해 알아보았다. Redis는 In-Memory NoSQL DB니 이번엔 In-Memory DB에 대해서 알아보자.
In-Memory 데이터베이스
인 메모리 데이터베이스는 컴퓨터의 주 메모리에 데이터를 저장한다.
그렇다면 메모리란 무엇일까?
메모리는 컴퓨터 하드웨어 구성요소 3가지 중 하나로 저장을 담당하고 있는 부품이다.
컴퓨터 하드웨어 구성요소 3가지는 아래와 같다.
- 연산을 담당하는 CPU
- 기억을 담당하는 주 기억장치 RAM, 보조기억장치 HDD, SDD
- 입출력을 담당하는 키보드, 모니터, 프린터 등
컴퓨터가 데이터를 저장할 때 사용하는 것이 바로 RAM이고 인 메모리 데이터베이스는 여기에 데이터를 저장한다는 것이다.
그럼 왜 다른 데이터베이스들 처럼 HDD나 SSD에 저장하는 것이 아닌 RAM에 저장할까?
한번 알아보자.
Memory 사용 이유
간단하게 컴퓨터의 작동 원리를 보면 다음과 같다.
- 입력을 받으면 RAM에 저장된다.
- RAM에 적힌 값과 존재하는 명령을 해석하여 CPU가 연산을 한다.
- 결과를 RAM에 보내주면 그것을 출력한다.
즉, CPU는 그저 메모리에 올라와 있는 프로그램의 명령어들을 실행할 뿐이다. 메모리에 대해 좀 더 자세히 알아보자.
메모리 계층 구조 관점
출처
위의 이미지는 컴퓨터의 메모리 계층 구조를 나타내고 있다.
위로 갈수록 속도는 빠르고, 용량은 작다. 반대로, 아래로 갈수록 속도는 느리지만, 용량은 크다.
각각에 대해 간략히 설명하자면 아래와 같다.
- 레지스터 : CPU 안에 있는 작은 메모리이며 휘발성, 속도 가장 빠름, 기억 용량이 가장 적은 특징을 가지고 있다.
- 캐시 : L1, L2, L3 캐시를 지칭하며 휘발성, 속도 빠름, 기억 용량이 적은 특징을 가지고 있다.
- 주기억장치 : RAM을 뜻하며 휘발성, 속도 보통, 기억 용량이 보통인 특징을 가지고 있다.
- 보조기억장치 : HDD,SDD를 뜻하며 비휘발성, 속도 낮음, 기억 용량이 큰 특징을 가지고 있다.
여기서 CPU Register와 CPU Caches는 CPU 내부에 존재하기 때문에 CPU가 빠르게 접근이 가능하다.
하지만 메인 메모리는 CPU 외부에 존재하기 때문에 레지스터와 캐시보다 더 느리게 접근할 수 밖에 없다. 메인 메모리를 읽어오기 위해선 인터럽트를 통해 커널모드에서 가져올 수 있다.
하드 디스크는 심지어 CPU가 직접 접근할 방법조차 없다. CPU가 하드 디스크에 접근하기 위해서는 하드 디스크의 데이터를 메모리로 이동시키고, 메모리에서 접근해야 한다. 그렇기 때문에 느린 접근 밖에 불가능한 것이다.
이렇게 보면 메인 메모리에 데이터를 저장하는 In-Memory DB와 하드 디스크에 데이터를 저장하는 Disk I/O DB의 성능 차이는 당연한 것이다.
추가적으로 Disk I/O DB는 데이터를 페이지 단위로 읽어온다.
내가 원하는 데이터가 지금 메모리에 있는 페이지에 없다면 또 디스크에서 다른 페이지를 읽어야 하기 때문에 지연이 발생한다.
반면 in-memory DB는 애초에 메모리에 모든 데이터가 있기 때문에 지연이 적다. 또한, 메모리상에 색인을 넣어 필요한 모든 정보를 메모리상의 색인을 통해 빠르게 검색할 수 있다고 한다.
프로세스 관점
위 관점을 프로세스에서도 적용해서 살펴보자.
Disk I/O
운영체제 입장에선 데이터 베이스도 그저 프로세스이다.
운영체제는 CPU가 한정적이기 때문에 시분할 방식으로 동작하며, Disk I/O와 같이 외부 장치를 이용하는 시스템 콜을 사용할 땐 프로세스가 한동안 CPU를 양도하고 해당 프로세스를 Disk I/O 큐에 넣는다. 그리고 Disk I/O 작업이 끝날 때까지 Blocked 상태가 된다.
데이터 베이스에서 데이터를 가져오는 데 시간이 걸려 CPU가 당장 명령을 실행할 수 없으니 Blocked 상태로 두고 다른 작업을 수행하는 것이다.
위와 같이 프로세스의 정보를 담은 PCB들을 요청에 따라 CPU 준비 큐 혹은 장치들의 큐에 넣어 요청을 처리한다.
그리고 이때 장치들의 큐에 들어간 프로세스의 상태는 Blocked 상태가 된다.
Blocked 상태의 프로세스는 해당 I/O 요청이 완료되고, 처리 결과(데이터)를 메모리로 옮기고 나서야 Ready 상태가 된다.
Memory
반면에 메인 메모리에 데이터를 저장하는 경우, 다른 장치들의 I/O가 걸리지 않는다.
메인 메모리에 쓰기 및 읽기 작업을 위해 인터럽트를 발생하여 사용자모드를 커널모드로 바꿀 뿐, 프로세스의 상태는 Blocked가 되지 않고, Ready와 Running 상태를 반복한다.
즉, Memory가 프로세스 관점에서도 Disk I/O보다 빠를 수 밖에 없다.
결론
위의 두 관점에서 모두 Memory가 Disk I/O보다 빠르다는 것을 알 수 있었다.
즉, In-Memory 데이터베이스는 빠른 데이터 처리가 필요하기 위해서 사용한다.
In-Moery DB가 탄생한 이유
사물 인터넷(IoT)의 출현과 클라우드 기반 솔루션이 성장함에 따라 실시간으로 데이터를 처리해야 할 필요성이 생기게 되었고 메모리의 가격이 상대적으로 저렴해지면서 탄생하게 되었다.
결국 기존의 Disk I/O DB로는 급격하게 늘어난 데이터를 감당할 수 없었고 여러가지 중요한 시스템에 실시간에 가까운 데이터 처리가 필요해서 탄생하게 된 것이다.
그럼 In-Memory DB가 무조건 좋을까?
이는 상황에 따라 다르다.
In-Memory DB는 기본적으로 영속성(persistence)를 보장하지 않는다. 기본적으로 RAM에 저장하다보니 에러가 나서 갑자기 프로세스가 종료된다면 데이터가 유실되는 문제가 발생할 것이다.
이 문제는 주로 다음과 같은 방식으로 해결한다고 한다.
스냅샷
- 데이터베이스의 주기적 스냅샷을 생성하여 비휘발성인 디스크 드라이브에 저장한다.
- 스냅샷이란 특정 시점의 전체 데이터베이스 복사본이다.
- 주기적인 스냅샷이 데이터를 보존하는 방법이긴 하지만 지속성이 보장되진 않는다.
- 스냅샷을 저장한 후 시스템 오류가 발생하면 결국 스냅샷 이후의 모든 변경 사항은 손실되게 된다.
트랜잭션 로깅
- 데이터베이스에 대해 진행한 모든 수정 기록을 보관한다.
- 트랜잭션 로그에는 데이터베이스에 대한 모든 삽입 및 수정 연산에 대한 세부 정보가 들어가 있어 오류 발생 시 복구하는 데 사용할 수 있는 비휘발성 파일에 저장된다.
- 하지만 분당 수천건의 연산을 수행하는 데이터베이스에서 트랜잭션 로깅은 시스템의 성능과 저장 용량에 과부하를 제공하기 때문에 대부분의 인메모리 데이터베이스는 스냅샷이 만들어질 때까지 트랜잭션 로그를 보관하였다가 이후 삭제한다.
비휘발성 랜덤 액세스 메모리 (NVRAM)
- NVRAM은 전원이 꺼진 후에도 데이터를 유지한다.
- 인메모리 데이터베이스는 배터리로 작동하는 정적 RAM 또는 전기적으로 지울 수 있는 프로그래밍 가능한 읽기 전용 메모리(EEPROM)을 사용한다.
또한, In-Memory DB는 메모리에 데이터를 저장하기 때문에 저장 공간이 한정되어 있다. 메모리다 보니 한계에 도달하면 기존 데이터를 지우든가 아니면 새로운 데이터를 입력하지 못하게 된다.
하지만 반드시 영속성이 필요하지 않고, 저장 공간이 많이 필요한 것이 아니라면 In-Memory DB는 매우 유용할 것이다. 로그인 세션과 같은 서버가 꺼져서 날아가도 상관 없는 임시 데이터에 쓰이거나 테스트시에도 사용된다.
In-Memory DB != NoSQL
메모리에 데이터를 읽고 쓰는 DB를 In-Memory라고 부르는 것이지 NoSQL일 필요는 없다.
대표적인 RDBMS인 MySQL도 In-Memory 모드를 지원한다.
유명한 NoSQL인 Redis가 In-Memory DB여서 혼동될 수 있을 것 같지만 둘은 다르다.
Reference
'Back-End > Database' 카테고리의 다른 글
[왜 Redis를 사용했는가?] 03. Redis란? (1) | 2022.10.17 |
---|---|
[왜 Redis를 사용했는가?] 01. NoSQL (1) | 2022.09.23 |
댓글