NoSQL 데이터베이스 개요
NoSQL은 "Not Only SQL"을 의미하며, 전통적인 관계형 데이터베이스(RDBMS) 외의 다양한 데이터 저장 방식을 포괄하는 용어다. 주요 유형으로는 다음과 같은 것들이 있다:
- Key-Value Store: 단순한 키-값 구조로 빠른 접근이 특징. 예: Redis, Memcached
- Document Store: JSON, BSON 등의 문서 형식을 사용. 예: MongoDB, CouchDB
- Column-Family Store: 대용량 데이터 처리에 최적화. 예: HBase, Cassandra
- Graph Database: 노드와 엣지 기반의 복잡한 관계 표현에 강점. 예: Neo4j
- Time Series Database: 시계열 데이터 처리 전문. 예: InfluxDB, Prometheus
Memcached란?
Memcached는 오픈소스 기반의 고성능 분산 메모리 캐싱 시스템으로, 동적 웹 애플리케이션의 데이터베이스 부하를 줄이는 데 사용된다. 데이터를 RAM 상에 키-값 형태로 저장함으로써 반복적인 DB 조회를 방지하고 응답 속도를 크게 향상시킨다. 서버 프로세스는 C 언어로 작성되었으며, 클라이언트는 다양한 언어로 구현 가능하다.
단, 메모리 기반 시스템이므로 재시작 시 모든 캐시가 소실되며, 영속성(Persistence) 기능은 제공하지 않는다.
Redis와의 주요 차이점
| 항목 | Redis | Memcached |
|---|---|---|
| 지원 자료구조 | 문자열, 해시, 리스트, 집합, 정렬집합 등 | 키-값 (단순 문자열) |
| 데이터 영속화 | 지원 (RDB, AOF) | 미지원 |
| 고가용성 | Redis Cluster, Sentinel 지원 | 클라이언트 수준에서 구현 필요 |
| 최대 값 크기 | 512MB | 1MB |
| 메모리 관리 | 동적 할당, 조각화 가능성 있음 | Slab Allocator로 사전 할당하여 효율적 관리 |
| 멀티스레딩 | v6 이전까지 싱글스레드 | 멀티스레드 지원 (CPU 활용 우수) |
| QPS 성능 | 약 10만 | 약 60만 |
| 과거 데이터 정리 | 배경 스레드에서 삭제 | 접근 시 확인 후 무효화 (Lazy Expiration) |
| 수평 확장 | Redis Cluster로 지원 | 내부 미지원, 클라이언트에서 해시 기반 분산 |
핵심 동작 메커니즘
1. Slab 기반 메모리 할당
Memcached는 메모리 조각화를 방지하기 위해 Slab Allocator를 사용한다. 전체 메모리는 고정 크기의 Page(기본 1MB)로 나뉘고, 각 Page는 동일한 크기의 Chunk로 분할된다. 서로 다른 크기의 Chunk는 별도의 Slab Class로 그룹화된다.
예를 들어, 100바이트 데이터는 96바이트보다 큰 첫 번째 Chunk(예: 128바이트)에 저장되어 소량의 공간 낭비가 발생할 수 있다. 이러한 크기 증가는 기본적으로 1.25의 Growth Factor에 따라 결정된다.
slab class 1: chunk size 96 slab class 2: chunk size 120 slab class 3: chunk size 150 ...
2. 지연 만료 (Lazy Expiration)
데이터의 TTL(Time-To-Live)이 지나도 즉시 삭제되지 않는다. 해당 키에 접근했을 때 비로소 만료 여부를 확인하고, 만료된 항목은 유효하지 않다고 판단한 후 새 데이터로 덮어쓸 수 있도록 한다.
3. LRU (Least Recently Used)
메모리가 부족해질 경우, 가장 오랫동안 사용되지 않은 데이터를 제거하여 새로운 항목을 위한 공간을 확보한다. 그러나 -M 옵션 사용 시 LRU를 비활성화하고 메모리 고갈 시 오류를 발생시킬 수 있다.
4. 클러스터링 아키텍처
Memcached 자체는 노드 간 통신을 하지 않으며, 클러스터링은 클라이언트 주도(Client-side Sharding) 방식으로 이루어진다. 일반적으로 키에 대한 해시 값을 계산하여 어떤 서버에 저장할지 결정한다. 일관된 해시(Consistent Hashing) 기법을 사용하면 노드 추가/제거 시 리해싱의 영향을 최소화할 수 있다.
설치 및 실행
Ubuntu/Debian 계열 기준 설치 절차:
# 의존성 설치 apt update && apt -y install gcc make libevent-dev # 소스 다운로드 및 컴파일 tar -xf memcached-1.6.20.tar.gz cd memcached-1.6.20 ./configure --prefix=/apps/memcached make && make install # 심볼릭 링크 생성 ln -s /apps/memcached/bin/memcached /usr/local/bin/
시스템 서비스 등록 예시 (/lib/systemd/system/memcached.service):
[Unit] Description=Memcached Server After=network.target [Service] User=memcached ExecStart=/usr/local/bin/memcached -m 100 -c 10240 -u memcached Restart=always [Install] WantedBy=multi-user.target
서비스 시작:
systemctl daemon-reload systemctl start memcached systemctl enable memcached
주요 실행 옵션
-u: 실행 사용자 지정 (root 금지)-p: 포트 설정 (기본 11211)-m: 할당 메모리(MB)-c: 최대 동시 연결 수-f: Slab 사이즈 증가 배율-d: 데몬 모드 실행-v[v]: 로그 출력 레벨-U 0: UDP 비활성화
기본 명령어 사용법
Telnet 또는 nc를 통해 직접 프로토콜 테스트 가능:
telnet localhost 11211
저장 (set/add/replace)
set mykey 0 60 5 hello STORED
mykey: 키 이름0: flags (사용자 정의 비트 플래그)60: 만료 시간(초)5: 값의 바이트 수
조회 (get)
get mykey VALUE mykey 0 5 hello END
삭제 (delete)
delete mykey DELETED
전체 비우기 (flush_all)
flush_all OK
모니터링 도구
libmemcached-tools 설치 시 제공되는 유틸리티:
apt install libmemcached-tools # 상태 확인 memcstat --servers=localhost # 핑 테스트 memcping --servers=localhost # 통계 정보 추출 예시 echo "stats" | nc localhost 11211 | grep -i "cmd_set\|get_hits"
사용 사례
Memcached는 다음 시나리오에서 효과적이다:
- 매우 높은 QPS가 요구되는 환경
- 간단한 키-값 조회 중심 애플리케이션
- 대규모 세션 저장소
- 정적 콘텐츠 또는 API 응답 캐싱
- 영속성이 필요 없는 일시적 데이터 보관