백고등어 개발 블로그
Redis vs Memcached 면접에서 답변하는 법 - 실무 관점 정리 본문
인메모리 캐시는 현대 웹 애플리케이션의 성능 향상에 필수적인 기술입니다. Redis와 Memcached는 가장 널리 사용되는 두 가지 인메모리 캐시 솔루션인데, 면접에서도 자주 비교 질문이 나와요. 각각의 특징과 적합한 사용 시나리오를 명확히 정리해보겠습니다.
1. Redis와 Memcached의 기본 개념을 설명해주세요.
Redis (Remote Dictionary Server):
- 키-값 저장소이면서 동시에 다양한 자료구조를 지원하는 인메모리 데이터베이스
- 단순한 캐시를 넘어서 데이터베이스, 메시지 브로커 역할도 수행
- 영속성(Persistence) 지원으로 디스크에 데이터 저장 가능
Memcached:
- 고성능 분산 메모리 캐시 시스템
- 단순한 키-값 저장에 특화
- 메모리에만 데이터를 저장하는 순수 캐시
도서관으로 비유하면, Memcached는 책을 빠르게 찾을 수 있는 간단한 임시 보관함이고, Redis는 책뿐만 아니라 잡지, 신문, DVD 등 다양한 자료를 체계적으로 관리할 수 있는 복합 도서관과 같습니다.
2. 지원하는 데이터 타입의 차이점은 무엇인가요?
Memcached:
- 단일 데이터 타입: 문자열(String)만 지원
- 키-값 구조가 매우 단순함
// Memcached 사용 예시
memcachedClient.set("user:123", "김철수", 3600); // 1시간 TTL
String userName = memcachedClient.get("user:123");
Redis:
- 다양한 자료구조 지원
- String: 기본 문자열
- Hash: 필드-값 쌍의 모음
- List: 순서가 있는 문자열 리스트
- Set: 중복되지 않는 문자열 집합
- Sorted Set: 점수로 정렬된 집합
- Bitmap, HyperLogLog 등
// Redis 다양한 자료구조 사용 예시
// String
redisTemplate.opsForValue().set("user:123:name", "김철수");
// Hash - 사용자 정보를 구조화해서 저장
redisTemplate.opsForHash().put("user:123", "name", "김철수");
redisTemplate.opsForHash().put("user:123", "age", "30");
redisTemplate.opsForHash().put("user:123", "city", "서울");
// List - 최근 검색어 저장
redisTemplate.opsForList().leftPush("user:123:searches", "스프링 부트");
// Set - 사용자가 좋아요한 게시글 ID
redisTemplate.opsForSet().add("user:123:likes", "post:456");
// Sorted Set - 게임 순위표
redisTemplate.opsForZSet().add("leaderboard", "player1", 1500);
3. 성능 차이는 어떻게 되나요?
Memcached의 성능 특징:
- 순수 캐시에 특화되어 매우 빠름
- 멀티스레드 지원으로 CPU 코어를 효율적으로 사용
- 메모리 사용량이 상대적으로 적음
- 단순한 get/set 작업에서는 Redis보다 빠를 수 있음
Redis의 성능 특징:
- 싱글스레드 이벤트 루프 방식 (Redis 6.0부터 일부 멀티스레드 지원)
- 복잡한 자료구조 연산 지원
- Pipelining으로 네트워크 라운드트립 최소화
- 단순 캐시 작업에서는 Memcached에 비해 약간 느릴 수 있음
// Redis Pipelining 예시
RedisTemplate<String, String> redisTemplate;
List<Object> results = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
for (int i = 0; i < 1000; i++) {
connection.set(("key" + i).getBytes(), ("value" + i).getBytes());
}
return null;
});
벤치마크 기준:
- 단순 get/set: Memcached가 10-15% 빠름
- 복잡한 연산: Redis가 훨씬 유리
- 메모리 효율성: Memcached가 약 20% 더 효율적
4. 영속성(Persistence) 지원의 차이는 무엇인가요?
Memcached:
- 영속성 지원 없음
- 서버 재시작 시 모든 데이터 손실
- 순수 메모리 캐시로만 동작
Redis:
- RDB (Redis Database): 특정 시점의 스냅샷을 디스크에 저장
- AOF (Append Only File): 모든 쓰기 명령을 로그 파일에 기록
# Redis 영속성 설정 예시
# RDB 설정
save 900 1 # 900초 동안 1개 이상의 키가 변경되면 저장
save 300 10 # 300초 동안 10개 이상의 키가 변경되면 저장
save 60 10000 # 60초 동안 10000개 이상의 키가 변경되면 저장
# AOF 설정
appendonly yes
appendfsync everysec # 매초마다 디스크에 동기화
이런 특징 때문에 Redis는 캐시를 넘어서 데이터베이스로도 사용할 수 있어요.
5. 분산 환경에서의 차이점은 무엇인가요?
Memcached:
- 클라이언트 사이드 샤딩: 클라이언트가 어느 서버에 데이터를 저장할지 결정
- 서버 간 통신 없음: 각 서버가 독립적으로 동작
- 노드 추가/제거 시 데이터 재분배 필요
// Memcached 클러스터 설정
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("server1:11211 server2:11211 server3:11211"));
MemcachedClient client = builder.build();
Redis:
- Redis Cluster: 서버 사이드 샤딩으로 자동 데이터 분산
- Redis Sentinel: 마스터-슬레이브 구조에서 자동 장애 조치
- Redis Replication: 읽기 성능 향상을 위한 복제
// Redis Cluster 설정
@Configuration
public class RedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
RedisClusterConfiguration clusterConfiguration =
new RedisClusterConfiguration(Arrays.asList(
"redis-node1:7000",
"redis-node2:7000",
"redis-node3:7000"
));
return new LettuceConnectionFactory(clusterConfiguration);
}
}
6. 실제 사용 시나리오별 선택 기준은 무엇인가요?
Memcached를 선택해야 하는 경우:
1. 단순한 캐시가 필요한 경우:
// 데이터베이스 쿼리 결과 캐싱
@Cacheable(value = "users", key = "#userId")
public User getUserById(Long userId) {
return userRepository.findById(userId);
}
2. 최고 성능이 중요한 경우:
- 초당 수십만 건의 단순한 get/set 작업
- 메모리 사용량 최적화가 중요한 환경
3. 기존 시스템과의 호환성:
- 이미 Memcached 기반 인프라가 구축된 경우
Redis를 선택해야 하는 경우:
1. 복잡한 자료구조가 필요한 경우:
// 실시간 채팅방 사용자 목록 관리
redisTemplate.opsForSet().add("chatroom:123:users", "user456");
Set<String> users = redisTemplate.opsForSet().members("chatroom:123:users");
// 최근 알림 목록 (최대 100개 유지)
redisTemplate.opsForList().leftPush("user:123:notifications", notification);
redisTemplate.opsForList().trim("user:123:notifications", 0, 99);
2. 영속성이 필요한 경우:
// 장바구니 데이터 (서버 재시작 후에도 유지되어야 함)
redisTemplate.opsForHash().put("cart:user123", "product456", "2");
3. Pub/Sub 메시징이 필요한 경우:
@Component
public class NotificationService {
@EventListener
public void sendNotification(OrderCompletedEvent event) {
// 실시간 알림 발송
redisTemplate.convertAndSend("notifications", event.getMessage());
}
}
4. 분산 락이 필요한 경우:
@Component
public class InventoryService {
public boolean decreaseStock(String productId, int quantity) {
String lockKey = "lock:inventory:" + productId;
try (RedisLock lock = redisLockService.getLock(lockKey, 10)) {
if (lock.tryLock(5, TimeUnit.SECONDS)) {
// 재고 감소 로직
return updateInventory(productId, quantity);
}
return false;
}
}
}
7. 실무에서의 선택 가이드라인
성능이 최우선인 경우: Memcached
- 단순한 세션 저장
- 데이터베이스 쿼리 결과 캐싱
- 정적 컨텐츠 캐싱
기능과 유연성이 중요한 경우: Redis
- 실시간 기능 (채팅, 알림)
- 복잡한 비즈니스 로직
- 일시적 데이터 저장소 역할
메모리 사용량이 제한적인 경우: Memcached
- 제한된 메모리 환경
- 순수 캐시 용도로만 사용
확장성과 가용성이 중요한 경우: Redis
- 고가용성 요구사항
- 자동 샤딩 필요
- 백업/복구 요구사항
8. 면접에서 자주 나오는 추가 질문들
Q: 두 솔루션을 함께 사용할 수 있나요? A: 네, 가능합니다. 용도에 따라 구분해서 사용할 수 있어요. 예를 들어, 단순한 세션 데이터는 Memcached에, 복잡한 비즈니스 데이터는 Redis에 저장하는 방식으로 사용할 수 있습니다.
Q: 캐시 무효화 전략은 어떻게 다른가요? A: 두 솔루션 모두 TTL 기반 만료를 지원하지만, Redis는 더 정교한 무효화 전략을 구현할 수 있습니다. Redis의 Pub/Sub 기능을 활용해서 캐시 무효화 이벤트를 전파할 수 있어요.
Q: 메모리 부족 상황에서의 동작 차이는? A: Memcached는 LRU 방식으로 오래된 데이터를 자동 삭제합니다. Redis는 다양한 정책을 설정할 수 있어요 (allkeys-lru, volatile-lru, allkeys-random 등).
핵심 정리
Redis와 Memcached 선택은 "어떤 것이 더 좋은가"가 아니라 "어떤 상황에 더 적합한가"의 문제입니다. 단순한 캐시만 필요하다면 Memcached가, 복잡한 기능이 필요하다면 Redis가 더 적합해요.
면접에서는 이론적 차이점뿐만 아니라 실제 프로젝트에서 어떤 기준으로 선택했는지, 어떤 문제를 해결했는지에 대한 구체적인 경험을 말할 수 있어야 합니다. 성능 테스트 결과나 트러블슈팅 경험이 있다면 더욱 좋겠죠.
'면접' 카테고리의 다른 글
프론트엔드 면접 단골 질문 50선 (0) | 2025.09.17 |
---|---|
보안 관련 백엔드 면접 질문 정리 - 실무 보안 완벽 가이드 (0) | 2025.09.16 |
데이터베이스 트랜잭션 면접 질문 TOP 10 - 핵심 정리 (0) | 2025.09.16 |
REST API 관련 면접 질문 모음 - 실무 완벽 가이드 (0) | 2025.09.16 |
JPA / Hibernate 면접 질문 정리 - 완벽 대비 가이드 (0) | 2025.09.16 |