데이터도 시프트 레프트가 필요하다
컨텐츠 정보
- 조회 424
본문
필자가 이 업계에서 처음 일을 시작했을 때, 나쁜 관행이 하나 있었다. 모든 새 프로젝트는 데이터베이스 스키마부터 시작하는 것이었다. 오라클을 담당한 DBA나 관련 책임자가 오랜 회의 끝에 스키마를 확정하고, 개발자는 그 “허락된” 스키마를 받아 들었다. 이 스키마는 대부분 약간 잘못됐고 비효율적이었으며, 개발 중인 애플리케이션과도 맞지 않았다. 그래서 개발자는 억지로 돌아가는 비효율적인 쿼리를 작성하다가 결국 지적을 받고, 다 같이 수정하기로 합의하곤 했다.
자바의 하이버네이트(Hibernate)나 닷넷의 엔터티 프레임워크(Entity Framework) 같은 객체 관계 매핑(Object-Relational Mapping) 도구가 등장하면서 이런 관행이 바뀌기 시작했다. 이후 하둡을 시작으로 아마존 S3, 파케이(Parquet) 파일 등에서 ‘읽기 스키마(schema on read)’ 개념이 도입되면서 더욱 근본적으로 바뀌었다.
예전 방식은 느리고 고통스러웠지만, 예기치 못한 변경에 대한 방어 장치가 있었다. 반면, 현대적인 방식은 데이터 생성자가 자유롭게 변경할 수 있게 해주지만, 시스템의 안정성을 책임지는 사람을 무력하게 만든다. 대부분 기업에는 데이터 플랫폼팀이 있어 전사 데이터 흐름을 파악하려고 하지만, 인력은 항상 부족하다.
이는 개발자 입장에선 좋은 조건처럼 보일지도 모른다. 모든 권한은 있지만 책임은 없고, 누군가 대신 비난을 받을 사람이 따로 있기 때문이다. 그러나 현실은 그렇지 않다. 개발자는 종종 다운스트림 데이터 시스템을 깨뜨리거나(한창 인기있는 최신 AI 시스템 포함) 데이터 시스템을 깨뜨리는 것이 두려워너무 느리게 움직이게 된다.
데이터 소유권이 업스트림으로 이동할 때
이런 이야기를 생각해 보자. 서포트 플랫폼팀의 수석 엔지니어 제즈는 다음과 같은 페이로드를 발견했다.
{
"ticket_id": "zendesk:004123",
….
}10년 전, 회사는 포그버그(FogBugz)에서 젠데스크(Zendesk)로 이전했고, 티켓 ID 충돌을 피하기 위해 기존 데이터에는 시스템명을 접두어로 붙였다. 포그버그는 오래전에 아카이브됐지만, 모든 행에는 여전히 zendesk:라는 숫자가 아닌 접두어가 붙어 있다.
커밋 메시지는 “8자리 중복 문자열을 왜 유지해야 하는가?”이다.
제즈는 한 줄을 이렇게 수정했다.
- ticket.ticket_id = 'zendesk:' + source_system_ticket_id;
+ ticket.ticket_id = source_system_ticket_id;
단위 테스트는 통과했고, 로컬 빌드도 정상적으로 완료됐다. 그러나 코드 체크인은 즉시 실패했다.
❌ CONTRACT-CHECK FAILUREField “ticket_id” no longer matches ^zendesk:d+$
Breaks:
ml.model.ticket_attribution
finance.dashboard.ticket_volume
제즈는 코드를 빠르게 되돌리고 다시 푸시하자 빌드가 정상 처리됐다. 총 소요 시간은 30초.
제즈가 코드를 체크인하지 못한 이유는 데이터 계약(data contract)을 위반했기 때문이다. 깃 액션이 자동으로 계약 위반을 감지하고, 다운스트림 데이터 시스템이 깨질 위험을 차단했다.
만약 데이터 계약이 없었다면 어떻게 됐을까?
- ETL 작업이 잘린 ID를 파케이 파일에 기록함
- 속성 부여 모델이 새 레코드 중 40%를 조용히 누락함
- 규정상 어떤 데이터도 삭제할 수 없어, 두 포맷을 모두 처리하는 임시 코드가 필요함
- 30초짜리 최적화가 일주일짜리 고통스러운 프로젝트로 번짐
- 제즈는 단 한 줄로 모든 것을 망친 사람으로 기억됨
이 이야기는 실화지만, 죄 없는 이들을 보호하기 위해 이름과 세부사항은 바꿨다. 공개된 사례로는 화성 기후 탐사선 사고를 떠올려보면 된다. 한 필드에 미국식 단위를 넣는 바람에 미터법을 쓰는 시스템과 충돌이 생겨 수억 달러가 날아갔다.
데이터를 위한 시프트 레프트 도구 키트
“데이터는 코드”라는 관점을 중심으로 새로운 움직임이 확산되고 있다. 모든 데이터는 처음에 애플리케이션 로직 안에서 생성된다. 타입스크립트 이벤트, 자바 엔티티, 파이썬 변수 등으로 시작된다. 코드가 데이터를 만든다면, 기대값을 검증할 올바른 위치는 후속 시스템이 아니라 바로 코드베이스 내부다.
채드 샌더슨은 ‘시프트 레프트 데이터 선언문(Shift Left Data Manifesto)’에서 이를 강조하며, 신뢰할 수 있는 AI와 분석 시스템을 구축하는 지속 가능한 방법은 데이터 변경을 소프트웨어 변경처럼 다루는 것이라고 주장했다.
- 데이터가 코드라는 전제를 받아들이면, 기존의 시프트 레프트 도구 키트를 그대로 적용할 수 있다.
- 정적 분석은 애플리케이션 코드를 실행 전 분석해 데이터 생성 구조를 식별한다.
- 데이터 계약은 데이터의 구조, 의미, 계보, 소유권을 정의하고 CI(지속적 통합) 과정에서 자동 검증된다.
- 변경 영향 분석은 겉보기엔 무해한 리팩터링이 머신러닝 기능의 다운스트림을 깨뜨릴 경우 경고를 준다.
- 코드로 작성된 정책은 감사 시점이 아닌 빌드 시점에서 PII(개인 식별 정보) 처리나 보존 정책 준수 여부를 평가한다.
이 같은 변화가 가능하도록 지원하는 새로운 소프트웨어 플랫폼도 부상하고 있다. 대표적으로 샌더슨의 게이블(Gable)이 있다. 참고로, 필자는 게이블에 컨설팅을 한 적이 있다. 게이블은 소스 리포지토리를 스캔해 코드가 생성할 테이블, 이벤트, 문서를 식별한다. 이후 데이터 계약 초안을 작성하고 다운스트림 종속 관계를 매핑하며, 선언된 기대값을 위반하는 병합을 차단한다. 특히 알림 대상이 풀 리퀘스트를 연 동일한 개발자로 설정돼 있어, 책임과 통제를 일치시키고 “변경 관리를 애플리케이션 개발자 손에 넘긴다.”
이런 업스트림 검증 방식은 정적 애플리케이션 보안 테스트(SAST)가 보안 수정을 앞당긴 방식과 유사하다. 중요한 시스템이 의존하는 데이터에 사소한 변경이 생기면, 기능 브랜치 병합 전에 이를 사전에 감지할 수 있다.
제즈가 아주 무모한 사람은 아니었다. 단지 8바이트를 줄였을 뿐이다. 데이터 계약이 없었다면, 이 미세한 최적화가 여러 팀의 장애로 이어졌을 것이다. 시프트 레프트 검증이 있었기에 이 변경은 단지 30초짜리 무해한 해프닝으로 끝났고, 이는 단위 테스트와 SAST가 품질과 보안을 혁신시킨 것과 같다.
품질은 왼쪽으로 이동했다. 보안도 왼쪽으로 이동했다. 이제는 데이터 차례다. 계약이 CI 게이트에 통합되면, 개발팀은 더 빠르게 제품을 출시하고, 예기치 않은 8바이트 변화로 인해 밤잠을 설칠 일도 줄어든다.
dl-itworldkorea@foundryco.com
관련자료
-
링크
-
이전
-
다음






