Skip to Content
BlogElastiCache 메인터넌스, 뭘 먼저 알아야 하나

ElastiCache 메인터넌스, 뭘 먼저 알아야 하나

node-based ElastiCache (Valkey/Redis OSS) 기준. 앱은 primary/reader/configuration endpoint를 사용하고, retry + backoff가 있다고 가정한다.

ElastiCache 운영을 하다 보면 엔진 업그레이드, 인스턴스 타입 변경, 레플리카 증감 같은 작업을 하게 된다. 겉보기엔 비슷한 “메인터넌스”지만, 실제로 겪어보면 작업마다 성격이 꽤 다르고 WAS에서 체감하는 영향도 다르다. 이 글은 그 차이를 정리한 기록이다.


엔진 업그레이드 — 가장 무거운 변경

왜 무거운가

엔진 업그레이드는 단순한 노드 교체가 아니다. 엔진 소프트웨어 자체를 바꾸는 작업이다. 그래서 기존 클라이언트 연결이 끊기고, failover가 일어나고, 버전 간 호환성까지 함께 확인해야 한다.

major 버전 업그레이드라면 parameter group family도 같이 바꿔야 하는 경우가 있어서, 단순히 “버튼 누르면 끝”이 아니라 사전 검증이 꽤 필요하다.

AWS 내부에서 일어나는 일

multi-shard 구성이면 shard들은 병렬로 처리될 수 있다. 하지만 각 shard 안에서는 replica를 먼저 처리하고, primary를 나중에 처리한다. primary는 전체 shard에서 한 번에 하나씩 순차 처리되기 때문에, shard 수가 많아도 primary 업그레이드 구간에서는 시간이 걸린다.

실제로 일어나는 순서 (CMD 기준)

순단이 왜 생기는지 이해하려면, AWS가 내부적으로 무엇을 하는지 알아야 한다.

  1. replica부터 업그레이드한다. 새 엔진 버전의 replica 노드를 준비하고, 기존 replica를 교체한다. 이 구간에서 read는 잠깐 흔들릴 수 있지만 write는 영향 없다.
  2. replica 업그레이드가 끝나면, primary를 처리한다. 여기가 순단 구간이다. 기존 primary에 연결된 모든 connection이 끊긴다.
  3. failover가 일어난다. 업그레이드된 replica 중 하나가 새 primary로 승격된다. Multi-AZ가 켜져 있으면 이 과정이 자동이다.
  4. DNS가 갱신된다. primary endpoint가 새 노드를 가리키게 된다. 클라이언트가 reconnect하면 새 primary에 붙는다.
  5. 구 primary가 새 엔진으로 업그레이드되어 replica로 합류한다.

순단은 34번 사이에 발생한다. 보통 수 초에서 수십 초. “작업 시간 2030분”은 전체 과정이고, 실제 write 불가 구간은 failover 전후의 짧은 시간이다.

single-node이거나 Multi-AZ가 꺼져 있으면 failover 대상이 없으므로, primary가 직접 내려갔다 올라와야 한다. 이 경우 순단이 훨씬 길어진다.

CME에서는 어떻게 다른가

CME에서도 흐름은 비슷하지만, shard 단위로 진행된다. shard 0001의 primary가 failover되는 동안 shard 0002, 0003의 key는 정상 서비스된다.

다만 클라이언트 입장에서는 topology refresh가 추가된다. failover 구간에서 MOVED 응답을 받고, slot map을 재학습하고, 새 노드에 reconnect하는 과정이 있다. multi-shard라면 “전체가 멈춘다”보다는 “일부 key에 대한 요청만 잠깐 흔들린다”에 가까울 때가 많다.

증폭되는 원인은 대부분 클라이언트 쪽

엔진 업그레이드 자체보다, 클라이언트 설정이 문제를 키우는 경우가 더 많았다.

  • retry/backoff 없이 aggressive reconnect → 연결 폭주
  • DNS 재조회가 느린 클라이언트 → failover 후에도 구 노드에 계속 붙어 있음
  • stale connection을 정리하지 않는 pool → 이미 끊긴 연결로 계속 요청
  • major 버전인데 parameter group이나 client 호환성 검증이 부족한 경우

경험상 이 네 가지만 잡아도 메인터넌스 중 장애가 크게 줄어든다.


인스턴스 타입 변경 — 예측 가능한 cutover

엔진 업그레이드와 뭐가 다른가

인스턴스 타입 변경은 소프트웨어를 바꾸는 게 아니라, 새 노드로 데이터를 옮기는 인프라 cutover에 가깝다. “새 capacity로 갈아끼운다”는 감각이 맞다. 엔진 업그레이드에 비해 호환성 리스크가 적고, 짧은 reconnect 이벤트에 더 가깝다.

실제로 일어나는 순서 (CMD 기준)

  1. 새 인스턴스 타입의 노드를 백그라운드로 준비한다. 이 시점에서 기존 노드는 정상 서비스 중이다.
  2. 기존 primary의 데이터를 새 노드로 복제한다. 데이터량에 따라 수 분에서 수십 분 걸린다. 이 구간은 서비스 영향 없다.
  3. 동기화가 완료되면 DNS cutover가 일어난다. primary endpoint가 새 노드를 가리키게 된다. 이 시점이 순단 구간이다.
  4. 기존 연결이 끊기고 클라이언트가 새 노드로 reconnect한다. 보통 수 초 이내.
  5. 구 노드가 정리된다.

엔진 업그레이드와 가장 큰 차이는, failover 없이 DNS 전환만으로 끝난다는 점이다. 엔진 업그레이드는 replica 승격 → primary 교체라는 failover 과정을 거치지만, 인스턴스 타입 변경은 새 노드에 데이터를 미리 복사해 두고 전환하는 방식이라 더 예측 가능하다.

primary endpoint를 쓰고 있으면 앱에서 endpoint 문자열을 바꿀 필요는 보통 없다.

CME에서의 인스턴스 타입 변경

CME에서도 shard 단위로 같은 과정이 진행된다. configuration endpoint 자체를 바꿀 일은 거의 없고, cluster-aware client가 바뀐 node topology를 다시 학습하는 과정이 핵심이다. connection churn과 topology refresh가 있지만, 엔진 업그레이드처럼 MOVED/slot 재배치가 일어나는 것은 아니라서 보통 더 덜 민감하다.

주의할 점

  • 데이터량이 크면 copy/sync 시간이 길어진다
  • downsize인데 reserved-memory/headroom 검토가 부족하면 OOM이 올 수 있다
  • write-heavy workload에서 reconnect storm이 발생할 수 있다

둘 다 해야 할 때

가장 안전한 건 작업을 분리하는 것이다. 실패 원인 분리, blast radius 축소, rollback 판단이 모두 쉬워진다.

순서가 중요하다면:

  • 업사이즈가 목적 → 인스턴스 타입을 먼저 키워서 headroom 확보 → 엔진 업그레이드
  • 다운사이즈가 목적 → 엔진 업그레이드 먼저 → 인스턴스 타입 줄이기

headroom이 충분한 상태에서 엔진을 바꾸는 게 snapshot/sync/failover 부하를 버티기 유리하다.


레플리카 추가/제거 — 가볍지만 무풍은 아니다

AWS 기준으로 레플리카 증감은 no cluster downtime으로 설명된다. endpoint 설계가 정상이면 큰 단절은 잘 안 나서, daytime non-peak에도 할 수 있는 변경에 가깝다.

다만 완전히 무풍은 아닌 이유가 있다.

reader endpoint는 진짜 load balancer가 아니라 DNS round-robin이다. 새 연결 기준으로 분산될 뿐, 이미 붙어 있는 장수명 커넥션을 즉시 재분배하지는 않는다. 그래서 레플리카를 추가해도 read traffic이 바로 균등하게 퍼지지 않을 수 있고, 레플리카를 제거하면 거기에 붙어 있던 read connection이 재연결되면서 잠깐 흔들릴 수 있다.

add vs remove는 성격이 다르다:

  • add: 작업 중 부하가 더 크다. 초기 sync, replication backlog 증가, primary의 네트워크/메모리 부담. write-heavy일수록 민감하다.
  • remove: 작업 중 부하는 적지만, 작업 후 HA가 줄어든다. read 분산 여력 감소, failover 내구성 저하.

daytime에 손대기 쉬운 건 remove처럼 보이지만, 서비스 안정성 관점에서는 remove가 더 조심스럽다.


Cluster Mode에서 메인터넌스는 어떻게 다른가

CMD와 CME는 같은 작업이라도 메인터넌스가 진행되는 방식이 다르다. 그 차이가 서비스 영향 범위를 바꾼다.

CMD — 모든 영향이 한 곳에 집중된다

CMD는 shard가 하나, primary도 하나다.

엔진 업그레이드든 인스턴스 타입 변경이든, primary를 건드리는 순간 전체 keyspace의 write path가 영향을 받는다. failover가 일어나면 전체 write가 잠깐 멈추고, 모든 클라이언트가 동시에 reconnect한다.

구조가 단순한 만큼 예측도 쉽다. “순단이 오면 전부 온다, 끝나면 전부 끝난다.” cluster protocol이나 slot 걱정이 없어서, 클라이언트 쪽 설정이 복잡하지 않다.

CME — 영향이 shard 단위로 나뉜다

CME는 shard가 여러 개이고, 메인터넌스도 shard 단위로 진행된다.

엔진 업그레이드를 예로 들면:

  1. shard 0001의 replica들이 먼저 업그레이드된다.
  2. shard 0001의 primary가 failover된다. 이 shard가 담당하는 slot 범위만 순단.
  3. shard 0001이 끝나면 shard 0002로 넘어간다.
  4. shard 0002가 진행되는 동안 shard 0001은 이미 정상이다.

즉, 3-shard 구성이면 메인터넌스 중에도 항상 2/3는 정상 서비스되는 셈이다. CMD에서는 불가능한 구조다.

인스턴스 타입 변경도 마찬가지로 shard 단위로 cutover된다. 각 shard의 새 노드 준비 → 데이터 복제 → DNS 전환이 순차적으로 일어나서, 한 shard가 전환 중일 때 나머지 shard는 영향 없이 서비스된다.

대신 클라이언트가 더 똑똑해야 한다

CME에서는 메인터넌스 중에 클라이언트가 처리해야 할 일이 늘어난다.

  • MOVED 응답 처리: failover로 slot의 주인이 바뀌면, 클라이언트가 MOVED를 받고 새 노드로 요청을 보내야 한다.
  • topology refresh: cluster-aware client가 주기적으로 또는 에러 시 slot map을 갱신해야 한다.
  • 부분적 reconnect: 전체 연결이 끊기는 게 아니라 특정 shard 연결만 끊기므로, connection pool이 shard별로 관리되어야 한다.

CMD에서는 “끊기면 전부 reconnect”라서 오히려 단순한데, CME에서는 “일부만 끊기고 일부는 살아있는” 상태를 클라이언트가 제대로 다뤄야 한다. topology refresh 주기가 너무 길거나, MOVED 처리가 미흡한 클라이언트라면 CMD보다 오히려 더 혼란스러운 상황이 될 수 있다.

1-shard CME라면?

여기서 빠지기 쉬운 함정이 있다. 1-shard CME는 shard가 하나뿐이라 메인터넌스 중 영향 분산 효과가 없다. cluster protocol 복잡도만 올라가고, blast radius는 CMD와 똑같다.

CME의 메인터넌스 이점은 2 shard 이상에서 살아난다. “cluster mode를 켤까?”보다 **“shard를 실제로 나눌 이유가 있는가?”**를 먼저 결정해야 한다.

CMD → CME 전환 시 알아둘 것

  • compatible → enabled 2단계를 거친다
  • compatible 상태에서는 scaling과 engine version 변경이 막힌다
  • enabled로 전환하면 endpoint가 바뀐다
  • 되돌릴 수 없다

모니터링 — 지표보다 흐름을 읽는다

지표를 많이 보는 것보다, 네 가지 시그널의 흐름을 읽는 게 중요하다.

ReplicationLag 상승 → replica가 primary를 못 따라가고 있다. 레플리카 추가 직후나 write-heavy 구간에서 올라간다. 지속되면 failover 시 데이터 유실 가능성이 커진다.

CurrConnections / NewConnections 급증 → reconnect storm. 메인터넌스 중 연결이 끊기고 클라이언트가 한꺼번에 재연결하면 이 지표가 튄다. aggressive reconnect 설정이 있으면 여기서 2차 장애가 날 수 있다.

SaveInProgress = 1 → 백그라운드 저장이 진행 중이다. snapshot이나 sync 계열 작업이 리소스를 잡아먹고 있다는 뜻이다. 이 상태에서 다른 heavy operation이 겹치면 latency가 올라간다.

IsMaster 전환 → 실제로 failover가 발생했다. 이 시점 전후의 write latency spike가 앱이 체감하는 실제 영향 구간이다.


정리

세 줄로 요약하면 이렇다.

엔진 업그레이드는 소프트웨어를 바꾸는 것이고, 인스턴스 타입 변경은 하드웨어를 바꾸는 것이다. 같은 “메인터넌스”라는 이름이지만 리스크 프로필이 다르다. 엔진 업그레이드가 더 무겁다.

Cluster Mode의 진짜 가치는 multi-shard일 때 blast radius를 줄이는 것이다. 1-shard CME는 복잡도만 올라간다. “켤까?”보다 “shard를 나눌 이유가 있는가?”를 먼저 묻자.

문제는 대부분 Redis가 아니라 클라이언트에서 터진다. retry, backoff, DNS 재조회, stale connection 정리. 이 네 가지가 메인터넌스 체감 품질을 결정한다.