Notice
Recent Posts
Recent Comments
Link
250x250
반응형
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

백고등어 개발 블로그

Redis vs Memcached 면접에서 답변하는 법 - 실무 관점 정리 본문

면접

Redis vs Memcached 면접에서 답변하는 법 - 실무 관점 정리

백고등어 2025. 9. 16. 16:55
728x90
반응형

인메모리 캐시는 현대 웹 애플리케이션의 성능 향상에 필수적인 기술입니다. 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가 더 적합해요.

면접에서는 이론적 차이점뿐만 아니라 실제 프로젝트에서 어떤 기준으로 선택했는지, 어떤 문제를 해결했는지에 대한 구체적인 경험을 말할 수 있어야 합니다. 성능 테스트 결과나 트러블슈팅 경험이 있다면 더욱 좋겠죠.

728x90
반응형