멱등성
멱등성(idempotency)이란 같은 연산을 한 번 실행하든 여러 번 실행하든 결과(시스템의 상태)가 똑같은 성질을 말합니다. 수학에서는 f(f(x)) = f(x)를 만족하는 함수를 멱등적이라고 하고, 프로그래밍에서는 재시도나 중복 클릭, 메시지 중복 수신으로 같은 요청이 다시 실행되어도 결제가 두 번 되거나 데이터가 중복 생성되는 부작용이 없는 연산을 멱등하다고 합니다.
이해하기 멱등성
멱등성은 신뢰성 있는 분산 시스템과 자동화를 위해 매우 중요합니다. 네트워크 장애가 발생하거나 서버가 재시작 되고, 메시지가 여러 번 전달되는 상황이 빈번하게 일어납니다. 멱등성이 없다면 결제가 두 번 이뤄지거나, 이메일이 세 번 보내지거나, 과제가 여러 번 만들어질 수 있습니다. 모두 한 번의 사용자 동작에 따른 재시도로 발생할 수 있는 일입니다.
멱등성 작업은 안전하게 재시도할 수 있습니다. REST의 GET 요청은 멱등적입니다(여러 번 조회해도 동일한 결과). PUT 요청도 멱등적으로 설계되어 있습니다(값을 여러 번 X로 설정해도 상태는 X로 동일함). 반면 POST 요청은 일반적으로 멱등적이지 않습니다(리소스가 여러 번 생성됨).
멱등성 구현에는 몇 가지 설계가 필요합니다: 멱등성 키(각 작업을 고유하게 식별하고 중복 처리를 막는 키) 사용, 작업 결과를 저장해 중복 요청에 캐시된 결과를 반환, 이미 실행된 동작인지 확인하는 방식의 부작용 설계 등이 그 예입니다.
GAIA처럼 웹훅, 재시도, 백그라운드 작업을 처리하는 AI 자동화 시스템에서도 멱등성은 필수입니다. 예를 들어 '새 이메일' 웹훅이 두 번 수신되는 경우(흔히 발생함), GAIA는 작업을 정확히 한 번만 만들어야 하며 두 번 생성해서는 안 됩니다.
멱등이라는 말의 뜻: 멱등(冪等)은 '거듭제곱해도 같다'는 뜻으로, 영어 idempotent(라틴어 idem '같은' + potent '힘')를 옮긴 수학 용어입니다. 절댓값은 멱등적입니다. ||x|| = |x|이기 때문입니다. 이미 반올림한 수를 다시 반올림해도 값이 바뀌지 않는 것도 같은 예입니다. 프로그래밍에서는 이 개념을 상태에 적용합니다. x = 5는 열 번 실행해도 x가 5이므로 멱등적이지만, x = x + 1은 실행할 때마다 값이 바뀌므로 멱등적이지 않습니다. SQL에서 UPDATE orders SET status = 'paid' WHERE id = 7은 멱등적이고, UPDATE accounts SET balance = balance - 10은 반복할 때마다 10씩 더 빠지므로 멱등적이지 않습니다.
멱등성은 응답이 아니라 효과가 같다는 뜻입니다. DELETE /users/42는 멱등적입니다. 첫 요청은 사용자를 삭제하고 두 번째 요청은 404를 돌려줄 수 있지만, 어느 쪽이든 사용자는 없는 상태입니다. 안전성(safe)과도 다릅니다. HTTP에서 GET과 HEAD는 아무것도 바꾸지 않으므로 안전하면서 멱등적이고, PUT과 DELETE는 데이터를 바꾸지만 멱등적이며, POST와 PATCH는 일반적으로 멱등적이지 않습니다.
멱등 처리 방법과 멱등성 키: 타임아웃 뒤에 요청을 재시도하는 클라이언트는 첫 요청이 처리됐는지 알 수 없습니다. 서버가 처리했는데 응답만 사라졌을 수도 있습니다. 그래서 재시도(지수 백오프 포함)는 멱등한 연산에만 안전하고, 멱등하지 않은 연산은 먼저 멱등하게 만들어야 합니다. 흔히 쓰는 방법은 세 가지입니다. 클라이언트가 요청마다 고유한 멱등성 키를 보내는 방법(예: Stripe는 POST 요청에 Idempotency-Key 헤더를 받습니다), 데이터베이스의 유니크 제약으로 중복을 거부하는 방법(PostgreSQL의 INSERT ... ON CONFLICT DO NOTHING), Redis의 SET NX처럼 조건부로 쓰는 방법입니다. '먼저 확인하고 나중에 쓰기'를 두 단계로 나누는 방식은 피하세요. 동시에 들어온 두 요청이 함께 확인을 통과할 수 있습니다.
데이터 멱등성: 데이터 파이프라인(ETL)에서는 같은 배치를 다시 실행해도 결과 테이블이 똑같아야 한다는 뜻으로 씁니다. 행을 무조건 추가(append)하는 대신 키 기준으로 덮어쓰기(upsert)하거나, 날짜 파티션을 통째로 교체하면 재실행해도 중복이 생기지 않습니다. 메시지 큐에서 '최소 한 번(at-least-once)' 전달을 쓰는 경우에도, 소비자가 멱등하게 처리하면 중복 메시지가 문제가 되지 않습니다.
GAIA 활용 방법 멱등성
GAIA는 중복이 들어오는 지점에 멱등 처리를 적용합니다. 연동 서비스가 웹훅을 보내면 GAIA는 Redis의 SET NX로 해당 웹훅 ID를 먼저 선점하고, 이후 한 시간 안에 같은 이벤트의 사본이 도착하면 버립니다. 워크플로 실행은 내용으로 만든 ID로 큐에 들어가므로, 같은 트리거가 반복돼도 같은 워크플로가 두 번 실행되지 않습니다. 덕분에 네트워크 재시도나 웹훅 재전송이 중복 작업을 만들지 않습니다.
관련 개념
Webhook
Webhook은 시스템 내에서 사전 정의된 이벤트가 발생할 때마다 지정된 URL로 자동화된 HTTP 요청을 보내는 HTTP 콜백 메커니즘입니다. 이를 통해 서비스 간 실시간 알림과 통합이 폴링 없이 가능합니다.
이벤트 기반 자동화
이벤트 기반 자동화(event-driven automation)는 정해진 시간이 아니라 새 이메일 도착, 이슈 생성, 스프레드시트의 새 행 추가처럼 어떤 일이 일어나는 순간 워크플로우를 실행하는 방식입니다. 각 자동화는 트리거 이벤트와 실행할 작업을 짝지으며, 이벤트가 일어난 시스템이 보통 웹훅으로 자동화 플랫폼에 알려 줍니다.
워크플로우 자동화
워크플로우 자동화(workflow automation)란 여러 단계로 이루어진 반복 업무를 사람이 매번 손으로 처리하는 대신, 정해진 조건(트리거)이 생기면 소프트웨어가 순서대로 실행하도록 만드는 것을 말합니다. 예를 들어 '새 문의 메일이 오면 내용을 정리해 CRM에 기록하고, 담당자에게 Slack으로 알리고, 할 일을 만든다'는 흐름을 한 번 정의해 두면 이후에는 자동으로 돌아갑니다.
REST API
REST(Representational State Transfer) API는 표준 HTTP 메서드(GET, POST, PUT, DELETE, PATCH)를 사용하여 URL로 식별되는 자원을 접근하고 조작하는 웹 서비스 인터페이스입니다. REST는 예측 가능하고 상호운용성을 높여주는 일련의 아키텍처 규약을 따릅니다.
데이터 동기화
데이터 동기화란 두 개 이상의 시스템(앱, 데이터베이스, 기기)에 있는 같은 데이터를 서로 일치하는 상태로 유지하는 것입니다. 한쪽에서 바뀐 내용이 다른 쪽에도 자동으로, 또는 정해진 주기에 따라 반영됩니다. 휴대폰과 노트북의 연락처가 늘 같게 유지되거나, CRM에서 바꾼 고객 이메일이 이메일 마케팅 도구에도 그대로 반영되는 것이 대표적인 예입니다.
