Samsung Cloud의 대규모 Cassandra 운영: AutoHeal v3 자동복구시스템

September 12, 2025 정영갑 조회수 1,315

Samsung Cloud 서비스에서 약 1200대 규모의 Cassandra를 안정적으로 운영하기 위해 자동 복구 시스템을 적용하고 개선한 사례를 다룹니다.

Apache Cassandra 개요 및 Samsung Cloud 운영 현황



[출처] https://cassandra.apache.org/_/cassandra-basics.html


Cassandra는 분산 처리용 데이터베이스로, AWS DynamoDB와 유사한 특성을 가진 NoSQL 데이터베이스로 분류됩니다. 

클러스터의 노드들은 Gossip 프로토콜을 통해 정보를 교환하며, Gossip에 참여한 노드들은 서로의 상태 정보를 주고 받습니다. 그리고 파티션 키를 기준으로 각 노드에 데이터가 분산 저장됩니다. 이때 데이터의 안정성을 위해 RF(Replication Factor) 값에 따라 인접 노드에 복제본이 저장됩니다. 이러한 구조는 단일 노드에 장애가 발생하더라도 인접 노드가 해당 서비스를 즉시 대체하여 운영할 수 있도록 보장합니다. 결과적으로 시스템 전체의 **고가용성(High Availability)**을 유지할 수 있습니다.


Gossip 프로토콜로 클러스터 내 전체 노드 상태 관리

파티션 키를 통한 데이터 분산 저장

인접 노드에 복제본을 저장하여 가용성 향상


Samsung Cloud에서는 퍼블릭 클라우드 환경에서 1,200대 이상의 서버와 1페타바이트(PB) 규모의 데이터를 Cassandra로 운영합니다. 이 대규모 데이터베이스 시스템은 H/W(하드웨어)와 S/W(소프트웨어) 문제가 끊임없이 발생하기 때문에 이를 유지보수 하기위해 AutoHeal이라는 자동화 프로그램을 개발을 하게 되었습니다.

AutoHeal 개요

2021년 AutoHeal을 초기 개발하던 당시, 연간 86회의 노드 다운이 일어났고 이 중 50%는 야간이나 주말에 발생했습니다. 주 단위로 반복되는 잦은 노드 장애는 피로도를 극도로 높였습니다. 현재는 Cassandra의 규모가 당시보다 2배 이상 커진 만큼 AutoHeal은 아주 중요한 시스템이 되었습니다. 


AutoHeal의 동작 원리 

AutoHeal은 Python으로 작성된 프로그램으로, Linux의 cronjob에 등록되어 동작합니다. 프로그램이 시작되면 클러스터 상태 정보를 조회하고 문제 있는 노드가 발견될 경우 인스턴스 레벨로 처리할 수 있는 boto3 라이브러리를 이용하거나 Cassandra 노드 명령을 통해 복구하는 것이 기본적인 동작이라고 하겠습니다.


 

[그림 1] AutoHeal의 동작 원리


1. cronjob에 의해 AutoHeal 프로그램이 주기적으로 실행

2. 클러스터 내 무작위 노드로 nodetool 명령 전달

3. 수신을 받은 노드는 클러스터의 전체 노드 상태에 대한 응답 전달

4. DN(DownNode)이 있을 boto3 라이브러리를 통해 필요에 따른 인스턴스 관련 조치 수행

5. Cassandra를 시작하기 위한 노드 명령 전달

AutoHeal version3

2021년 초기 버전 이후, version2를 통해 많은 개선이 이루어졌습니다. 하지만 이전에 드물었던 AutoHeal의 자동 복구 실패 사례(최근 1년간 120회 중 27회)가 일어났기 때문에, 문제의 원인을 근본적으로 분석해야 했습니다. 분석을 해보니, 대부분의 경우 명령이 너무 빠르게 전달되었거나 명령 수행이 일시적으로 불가능했지만 일정 시간이 지나면 수행이 가능했던 것으로 확인되었습니다.


AutoHeal은 싱글 스레드로 만들어진 프로그램이기 때문에 이런 예외를 처리하려면 Loop+Sleep 구조로 코드를 작성해야 합니다. 이는 복잡성을 증가시킬 뿐 아니라, 여러 타이밍 이슈를 해결하는 근본 대책이 아니었습니다. 물론 멀티 스레드 프로그램으로 해결하는 방식도 있지만, 데이터베이스 운영상 코드를 유지보수하기 좋고 주기적 check 및 복잡한 상황을 다루는 scheduler를 구현할 필요가 없는 State Machine을 도입하여 해결하기로 했습니다.


분류

실패 원인

Temporary Normal Down Node

다운 노드의 원인 파악 시점에는 정상으로 판명되었으나, 1~2분 후 EC2 또는 Daemon Down 발생

EC2 Stop/Start

다양한 원인으로 EC2 Start 실패(: stop/start 1/2, 리소스 부족)

Mount

부팅 시 일시적 Logical Volume 생성 또는 Mount 설정 실패

Cassandra Daemon

다양한 원인으로 일시적 실패(: 토큰 범위 오류, 포트 점유)

[표 1] 2024년 AutoHeal 복구 실패 사례


State Machine의 동작 방식 

State Machine은 다운된 각 노드의 State Machine 상태를 저장하여 다음 프로세스 때 기억된 이전 상태부터 작업을 재개할 수 있도록 합니다. 특정 상태에서 일시적 실패가 일어나도 다음 프로세스 때 자동으로 재시도할 수 있는 자연스러운 구조를 갖게 됩니다. 이를 통해 Loop+Sleep 구조에서 벗어나고, Loop+Sleep 구조로 인해 특정 노드가 Starving되는 현상도 막을 수 있습니다.


 

[그림 2] State Machine 다이어그램


그럼 State Machine에 대해 알아보도록 하겠습니다. 

기본적인 State에는 시작 상태인 INIT, 문제점을 발견하는 DETECTED, 원인을 파악하여 복구를 진행하는 INPROGRESS, 인접 노드로부터 데이터를 받는 STREAMING, 완료 상태인 DONE이 있습니다. 또한 노드의 State Validation에 실패해 조치할 수 없다고 판단되면 INC로, Retry Counter를 모두 소진한 경우에는 FAIL로 전환되도록 해두었습니다. 


조금 더 세부적으로 살펴보면 DETECTED 상태에서는 인접 노드가 복구 중인 경우 해당 복구가 완료될 때까지 대기하는 단계가 포함됩니다. INPROGRESS에서는 복구 단계를 세분화한 Sub State를 두어 특정 단계에서 동일한 조치가 문제가 되는 경우 해당 단계에서 재시도하도록 구성했습니다. EC2 레벨로 복구가 필요한 경우에는 RESTART_EC2 단계를 거쳐 Mount 설정을 확인을 하는 CHECK_MOUNT 단계, 클러스터에 조인이 필요한 SEED 정보를 설정 파일에 설정하는 단계, 그리고 마지막으로 Full Data Sync가 필요한 경우와 Daemon만 재시작하는 상태로 나누었습니다. 


예외적으로, DETECTED 단계에서 Retry를 해도 모든 것이 정상인 경우는 Done 상태가 되고, STREAMING 단계에서 실패를 하게 되면 다시 INPROGRESS 상태로 바뀔 수 있습니다.

적용 현황, 효과 및 고려 사항

AutoHeal version3를 5월 말에 프로덕션 환경에 적용한 이후, 대부분의 작은 버그와 타이밍 관련 문제가 해결되며 시스템이 안정화 되었습니다. State Machine을 이용한 일반화된 코드를 통해 전체적으로 많은 예외 처리 코드를 삭제하고 이전에 없던 새로운 문제에도 유연하게 대응할 수 있었습니다. 구체적인 예를 들면, 6월 21일 토요일 저녁에는 3개 노드가 동시에 다운되는 심각한 상황이 발생했고, 특정 노드가 제대로 복구되지 않는 상황까지 이어졌습니다. 하지만 자동 재시도(Retry) 기능이 작동해 아무 문제없이 끝났습니다. 만일 문제가 있었다면 가족과의 즐거운 시간이 희생되었을 겁니다. 이런 개선된 시스템은 팀원들에게 시간적 여유와 함께 새로운 도전에 대한 동기를 부여해 줍니다.


AutoHeal version3 회고

AutoHeal version3을 구현하고 적용하는 과정에서 소스 구조를 전면적으로 변경하는 동시에 안정성을 확보해야 했습니다. 리스크를 줄이기 위한 고민과 노력을 아래와 같이 정리해 보았습니다.


철저한 코드 리뷰 시스템

프로그램 오류 시 시스템에 미치는 영향이 매우 크기 때문에 Git 기반 코드 리뷰를 필수화합니다. 이를 통해 팀원 간 검토를 거쳐 잠재적 버그를 사전에 차단합니다.


유지보수성 중시

코드는 단순하고 직관적이어야 합니다. 복잡한 멀티스레드 로직보다 시퀀스대로 실행되는 비동기 방식을 선호해 디버깅과 수정이 용이하도록 합니다.


State 파일 검증 프로세스

상태 파일의 유효성을 실행 전 반드시 검증합니다. JSON 대신 Human-Readable 형식을 사용해 운영자가 직접 수정할 수 있도록 합니다. 또한 필드 제한과 값 검증 로직을 추가해 오작동 범위를 최소화합니다.


실시간 모니터링 및 알림

Slack이나 다른 메신저로 주요 로그와 장애 알림을 즉시 전송합니다. 운영자가 실시간으로 현황을 파악하고 빠르게 대응할 수 있어 시스템 신뢰도가 향상됩니다.


중복 작업 방지

Cronjob으로 스케줄링된 작업이 중복 실행되지 않도록 Flock 같은 락(lock) 도구를 활용합니다. lock 파일이 있으면 즉시 작업을 중단해 리소스 낭비와 충돌을 방지합니다. Flock을 기본 유틸리티로 사용하면 해당 기능을 위한 코드를 추가 구현할 필요가 없습니다.


이번 블로그 포스팅에서는 꼭 필요한 핵심 내용만 최대한 쉽게 전달하려고 노력했습니다. 하지만 일부 내용은 이해를 위해 사전 개념이나 배경 지식이 필요해 다소 복잡하게 느껴졌을 수도 있습니다. 그렇지만 대규모 시스템을 관리하거나 자동화 시스템을 구현하려는 분들께는 도움이 되었기를 바라며, 다음 기회에는 Cassandra AutoHeal을 Refactor하여 Kafka 시스템에 적용한 사례를 공유해 드리고자 합니다.





저자

정영갑

Cloud운영그룹(MX)

이메일 문의하기