Tag: 회고

  • 배치에서 스트리밍으로: 6개월간의 전환 회고

    배치에서 스트리밍으로: 6개월간의 전환 회고

    우리 팀의 핵심 분석 파이프라인은 오랫동안 매일 새벽 한 번 도는 배치였습니다. 충분히 잘 작동했지만, 비즈니스가 성장하면서 마케팅 팀은 캠페인 반응을 몇 시간 내로 보고 싶어 했고, 운영 팀은 이상 징후를 다음 날이 아니라 즉시 알고 싶어 했습니다. 결국 우리는 준실시간 스트리밍으로의 전환을 결정했습니다. 이 글은 그 6개월의 솔직한 회고입니다.

    화려한 성공담이 아니라, 무엇을 잘했고 무엇에서 피를 봤는지 담았습니다. 비슷한 전환을 앞둔 팀에 참고가 되길 바랍니다.

    전환을 결정한 배경

    배치의 가장 큰 한계는 지연이었습니다. 데이터가 발생하고 대시보드에 반영되기까지 평균 18시간이 걸렸습니다. 의사결정 속도를 높이려면 이 간극을 분 단위로 줄여야 했습니다. 동시에 배치 윈도가 점점 길어져 새벽 처리가 업무 시작 시각까지 밀리는 일도 잦아졌습니다.

    우리는 모든 것을 한 번에 바꾸지 않기로 했습니다. 가장 가치가 높은 한 도메인(주문 이벤트)부터 스트리밍으로 전환하고, 나머지는 검증 후 점진적으로 옮기는 전략을 택했습니다.

    아키텍처 선택

    원천 데이터베이스의 변경을 잡기 위해 CDC(Change Data Capture)를 도입했습니다. Debezium으로 DB 트랜잭션 로그를 읽어 Kafka로 흘리고, 스트림 처리로 변환한 뒤 레이크하우스에 적재하는 구조입니다. 처음엔 람다 아키텍처로 배치와 스트리밍을 병행했지만, 두 코드베이스를 유지하는 비용이 커서 결국 키파 아키텍처에 가깝게 단순화했습니다.

    중요한 결정 하나는 정확히 한 번 처리(exactly-once)를 어디까지 보장하느냐였습니다. 모든 구간에 강한 보장을 걸면 복잡도와 지연이 폭증합니다. 우리는 멱등 업서트로 최종 결과의 정합성만 보장하는 실용적 절충을 택했습니다.

    피를 본 지점들

    가장 고생한 것은 늦게 도착하는 데이터(late-arriving data)였습니다. 네트워크 지연이나 모바일 오프라인으로 이벤트가 몇 시간 늦게 도착하면 이미 집계된 윈도를 어떻게 보정할지가 문제였습니다. 워터마크와 허용 지연(allowed lateness)을 설정해 일정 시간까지는 보정하고, 그 이후는 별도 정정 테이블로 처리했습니다.

    • 상태 폭증: 무한 윈도 집계로 상태 저장소가 커짐, TTL과 윈도 한정으로 해결
    • 중복 이벤트: CDC 재시작 시 재전송, 멱등 키로 방어
    • 스키마 변경: 원천 DDL 변경이 스트림을 깸, 스키마 레지스트리 도입
    • 디버깅 난이도: 흐르는 데이터는 재현이 어려움, 모든 단계 로깅 강화

    성과와 비용

    전환 후 데이터 지연은 18시간에서 평균 4분으로 줄었습니다. 마케팅 팀의 캠페인 의사결정 주기가 하루에서 시간 단위로 빨라졌고, 운영 이상 탐지도 거의 실시간이 됐습니다. 다만 인프라 비용은 약 1.4배 늘었고, 운영 복잡도는 그 이상으로 증가했습니다.

    스트리밍은 공짜가 아니다. 실시간이 정말 필요한 곳에만 적용하라. 나머지는 배치가 여전히 옳다.

    정리와 교훈

    가장 큰 교훈은 모든 것을 실시간으로 바꿀 필요는 없다는 것입니다. 비즈니스 가치가 분명한 도메인부터 점진적으로 전환하고, exactly-once 같은 이상에 매몰되지 말고 최종 정합성이라는 실용적 목표를 잡으세요. 늦게 도착하는 데이터와 상태 관리를 초기부터 설계에 포함하면 나중의 고통이 줄어듭니다.

  • 분석 보고 자동화 구축기: 매주 반복되던 리포트를 파이프라인으로

    분석 보고 자동화 구축기: 매주 반복되던 리포트를 파이프라인으로

    한때 우리 팀은 매주 월요일 오전을 통째로 “주간 리포트”에 썼습니다. 여러 소스에서 데이터를 받아 엑셀에 붙이고, 차트를 다시 그리고, 슬라이드에 옮기는 작업이었습니다. 한 사람의 반나절이 매주 사라졌고, 실수도 잦았습니다. 이 글은 그 반복 작업을 자동화 파이프라인으로 바꾼 과정과 그 과정에서 배운 것을 회고합니다.

    무엇이 문제였나

    가장 큰 문제는 시간이 아니라 신뢰였습니다. 매주 손으로 만들다 보니 지난주 정의와 이번 주 정의가 미묘하게 달라졌고, 누군가 셀 하나를 잘못 복사하면 숫자가 틀렸습니다. “이 숫자 맞아?”라는 질문에 자신 있게 답하지 못하는 리포트는 의사결정 근거가 될 수 없었습니다. 자동화의 목적은 시간 절약이 아니라 일관성과 신뢰 확보로 재정의했습니다.

    파이프라인 설계

    구조는 단순하게 잡았습니다. 데이터 웨어하우스에 정의된 지표를 SQL로 추출하고, 스케줄러가 매주 월요일 새벽에 실행하며, 결과를 대시보드와 자동 요약 메시지로 전달하는 흐름입니다.

    • 추출: 지표 정의를 SQL로 코드화하고 버전 관리(한 곳에서만 정의)
    • 변환: 코호트·증감률 등 계산 로직을 재사용 가능한 모듈로 분리
    • 적재: 결과를 BI 도구가 읽는 테이블에 저장
    • 전달: 핵심 지표 변화를 슬랙 메시지로 자동 요약 발송

    시행착오

    첫 시도는 너무 욕심을 부렸습니다. 모든 리포트를 한 번에 자동화하려다 6주를 쓰고도 완성하지 못했습니다. 방향을 바꿔 가장 자주 쓰는 5개 지표만 먼저 자동화하니 2주 만에 가치를 냈습니다. 또 하나의 교훈은 데이터 검증 단계의 중요성입니다. 자동화는 틀린 숫자도 자동으로, 빠르게, 그럴듯하게 만들어 냅니다. 그래서 “오늘 활성 사용자가 어제의 절반 미만이면 경고” 같은 이상 탐지 규칙을 파이프라인에 넣었습니다.

    자동화하면 안 되는 부분

    중요한 깨달음은 “해석은 자동화하지 않는다”였습니다. 숫자 추출과 차트 생성은 기계가 잘하지만, “왜 이번 주 가입이 줄었는가”를 묻고 맥락을 붙이는 일은 사람의 몫입니다. 그래서 파이프라인은 숫자와 변화를 자동으로 준비해 주고, 분석가는 그 위에 “이번 감소는 명절 연휴 효과로 보임” 같은 주석을 다는 방식으로 역할을 나눴습니다.

    자동화의 목표는 사람을 없애는 것이 아니라, 사람이 기계적인 일에서 벗어나 판단에 집중하게 하는 것이다.

    결과와 정리

    전환 후 주간 리포트 작성 시간은 반나절에서 30분으로 줄었고, 무엇보다 숫자에 대한 신뢰가 올라갔습니다. 핵심 교훈은 세 가지입니다. 지표 정의를 한 곳에 코드로 박아 일관성을 확보하고, 작게 시작해 빠르게 가치를 내며, 검증과 해석은 사람의 몫으로 남기는 것입니다. 자동화는 반복을 없애는 일이 아니라, 분석가가 진짜 분석에 시간을 쓰게 만드는 투자였습니다.

  • 온콜 장애대응 회고: 새벽 3시 알림이 가르쳐준 것들

    온콜 장애대응 회고: 새벽 3시 알림이 가르쳐준 것들

    새벽 3시, 휴대폰이 울립니다. 결제 성공률이 급락했다는 알림입니다. 잠에서 덜 깬 채로 노트북을 여는 그 순간이, 사실 한 조직의 운영 성숙도를 가장 정직하게 드러냅니다. 이 글은 여러 장애를 겪으며 배운 것들을 회고합니다.

    운영 문제: 영웅에 의존하는 대응의 한계

    초기에는 시스템을 가장 잘 아는 한 사람이 모든 장애를 해결했습니다. 빠르지만 위험한 구조였습니다. 그 사람이 휴가를 가면 복구가 멈췄고, 지식은 그의 머릿속에만 있었습니다. 좋은 온콜은 영웅이 아니라 누구나 따라갈 수 있는 절차에 의존해야 한다는 걸 비싸게 배웠습니다.

    대응 흐름: 진정하고, 좁히고, 복구한다

    • 감지: 좋은 알림은 증상이 아니라 사용자 영향(성공률·지연)을 알린다
    • 분류: 심각도(SEV)를 정해 호출 범위와 커뮤니케이션을 결정
    • 완화: 근본 원인보다 먼저 영향 차단(롤백·트래픽 차단)
    • 복구: 정상화 확인 후 임시 조치를 정식 조치로 대체

    가장 중요한 교훈은 ‘원인 규명보다 완화가 먼저’라는 순서였습니다. 새벽에 근본 원인을 파헤치느라 30분을 쓰는 대신, 직전 배포를 즉시 롤백했다면 영향 시간을 1/5로 줄일 수 있었습니다.

    비난 없는 포스트모템

    장애는 사람의 실수가 아니라 그 실수를 허용한 시스템의 문제다.

    포스트모템에서 ‘누가 잘못했나’를 묻기 시작하면 사람들은 사실을 숨깁니다. ‘어떤 안전장치가 없어서 이 실수가 장애로 번졌나’를 물어야 시스템이 개선됩니다. 우리 팀은 모든 SEV2 이상 장애에 대해 48시간 내 포스트모템을 작성하고, 거기서 나온 액션 아이템을 다음 스프린트에 반드시 반영하는 규칙을 세웠습니다.

    모니터링과 온콜 건강

    온콜 자체도 측정 대상입니다. 야간 호출 빈도, 오탐(false positive) 비율, MTTR을 추적했습니다. 오탐이 많은 알림은 사람을 둔감하게 만들어 진짜 장애를 놓치게 합니다. 6개월간 노이즈 알림을 정리하니 야간 호출이 절반으로 줄었고, 동시에 진짜 장애의 평균 복구 시간도 짧아졌습니다.

    정리

    장애는 피할 수 없지만 배움의 재료로 바꿀 수는 있습니다. 영웅 의존을 절차로, 비난을 학습으로, 노이즈를 신뢰로 바꾸는 과정이 곧 운영 성숙입니다. 새벽 3시의 알림은 괴롭지만, 그것을 줄여가는 여정이 결국 더 단단한 시스템을 만듭니다.

  • 데이터 조직을 처음부터 빌딩하며 배운 다섯 가지 교훈

    데이터 조직을 처음부터 빌딩하며 배운 다섯 가지 교훈

    3년 전 합류했을 때 회사에는 데이터 담당자가 한 명도 없었다. 의사결정은 임원의 직감과 엑셀 시트 몇 장으로 이뤄졌고, 같은 질문에 부서마다 다른 숫자를 내놓는 일이 흔했다. 나는 데이터 조직을 처음부터 만들어야 했고, 그 과정에서 가장 크게 깨달은 것은 “좋은 분석 도구를 도입하면 문화가 따라온다”는 생각이 완전히 틀렸다는 사실이었다.

    이 글은 정답을 제시하려는 것이 아니다. 비슷한 출발선에 선 누군가가 같은 함정을 조금 덜 밟기를 바라며, 내가 통과한 다섯 번의 갈림길을 솔직하게 기록한다.

    첫 채용은 스킬이 아니라 신뢰로 골랐어야 했다

    초기에 나는 가장 화려한 이력서를 골랐다. 머신러닝 논문 경력과 대규모 파이프라인 운영 경험이 있는 사람이었다. 그러나 조직에 데이터 신뢰가 0인 상태에서 정작 필요한 것은 정교한 모델이 아니라, 영업팀이 던지는 “이 숫자 맞아요?”라는 질문에 끈기 있게 답하며 신뢰를 쌓는 사람이었다.

    두 번째 채용에서 나는 기준을 바꿨다. 기술 점수는 평균이지만 비즈니스 맥락을 집요하게 파고들고, 모르는 것을 모른다고 말하는 후보를 뽑았다. 그가 6개월간 만든 것은 거창한 모델이 아니라 “모두가 믿는 단 하나의 매출 대시보드”였다. 그 대시보드가 조직의 데이터 문화 전체를 바꾼 변곡점이 되었다.

    중앙집중과 분산 사이에서 너무 일찍 결정했다

    조직이 6명이 되자 나는 성급하게 “플랫폼팀”을 만들었다. 인프라를 표준화하면 효율이 오를 거라 믿었다. 결과는 반대였다. 현업 부서는 플랫폼팀에 티켓을 넣고 2주를 기다려야 했고, 그사이 다시 각자 엑셀로 돌아갔다. 조직 구조를 비즈니스의 성숙도보다 앞서 설계한 대가였다.

    구조는 문제를 해결하기 위해 존재한다. 아직 존재하지 않는 문제를 위해 구조를 먼저 만들면, 그 구조가 새로운 문제가 된다.

    지표를 정의하는 일이 가장 정치적인 작업이었다

    “활성 사용자”를 어떻게 정의할 것인가는 기술 문제가 아니라 권력 문제였다. 마케팅은 느슨한 정의를, 재무는 보수적인 정의를 원했다. 나는 이 논쟁을 데이터팀이 중립적으로 중재하는 자리로 삼았고, 정의를 문서화해 모두가 합의한 단일 출처를 만들었다. 이 합의 과정 자체가 데이터 조직의 권위를 세웠다.

    • 핵심 지표는 반드시 정의와 산출 로직을 문서로 남긴다
    • 정의 변경은 버전과 변경 사유를 함께 기록한다
    • 지표 소유자를 명확히 지정해 책임을 분산하지 않는다

    가장 큰 적은 경쟁사가 아니라 무관심이었다

    훌륭한 분석을 내놓아도 아무도 읽지 않으면 의미가 없다. 나는 데이터를 만드는 것보다 데이터가 의사결정 회의 테이블에 오르게 만드는 일에 더 많은 에너지를 써야 한다는 것을 늦게 깨달았다. 분석 보고서를 던지는 대신, 임원의 다음 결정 한 가지에 직접 연결되는 한 장의 슬라이드를 만들기 시작하자 비로소 조직이 데이터를 찾기 시작했다.

    한계와 남은 질문

    물론 이 모든 교훈이 보편적이라고 주장할 수는 없다. 우리는 규제 산업이 아니었고, 데이터 양도 빅테크에 비하면 작았다. 규제가 엄격한 금융이나 의료 도메인이라면 거버넌스를 더 일찍, 더 무겁게 세워야 했을 것이다. 또한 신뢰 중심 채용은 조직이 일정 규모를 넘어서면 다시 전문성 중심으로 무게추를 옮겨야 한다는 반론도 타당하다.

    그럼에도 한 가지는 확신한다. 데이터 조직 빌딩의 본질은 파이프라인이 아니라 신뢰의 인프라를 까는 일이다. 도구는 1년이면 바뀌지만, 조직이 숫자를 믿는 습관은 그보다 훨씬 오래 회사를 지탱한다. 다시 시작한다면 첫날부터 “누가 이 숫자를 믿게 만들 것인가”라는 질문을 조직도의 가장 위에 적어 둘 것이다.

  • 갚지 못한 기술 부채가 조직을 어떻게 무너뜨렸는가

    갚지 못한 기술 부채가 조직을 어떻게 무너뜨렸는가

    모든 팀은 기술 부채를 진다. 빠르게 출시하기 위해 임시방편을 쓰고, “나중에 정리하자”고 약속한다. 문제는 그 나중이 거의 오지 않는다는 것이다. 이 글은 우리 팀이 2년간 미뤄둔 데이터 파이프라인 부채가 결국 한 분기 전체를 삼킨 과정을 솔직하게 복기한 회고다.

    이 이야기를 공유하는 이유는 변명을 하기 위해서가 아니다. 부채가 쌓이는 메커니즘은 놀랄 만큼 보편적이어서, 우리의 실패가 다른 팀에게는 조기 경보가 될 수 있다고 믿기 때문이다.

    처음엔 합리적인 타협이었다

    시작은 정당했다. 제품 출시 마감이 코앞이었고, 우리는 검증 로직 없이 데이터 파이프라인을 빠르게 띄웠다. 당시 데이터는 하루 수천 건이었고, 문제가 생기면 손으로 고칠 수 있었다. 그때의 결정은 옳았다. 부채 자체가 죄는 아니다.

    이자는 복리로 붙는다

    죄는 부채를 관리하지 않은 데 있었다. 데이터가 하루 수백만 건으로 불어나는 동안 검증 로직은 여전히 없었다. 새 기능들이 그 위태로운 파이프라인 위에 하나씩 쌓였다. 임시방편 위에 또 임시방편이 올라가며, 부채의 이자는 단리가 아니라 복리로 불어났다.

    기술 부채의 가장 잔인한 점은, 갚지 않은 동안에도 이자가 매일 조용히 청구되고 있다는 것이다.

    붕괴의 날

    붕괴는 예고 없이 왔다. 한 상류 시스템이 데이터 형식을 미묘하게 바꿨고, 검증이 없던 우리 파이프라인은 잘못된 데이터를 조용히 흘려보냈다. 3주 뒤 경영진이 본 매출 지표가 실제와 크게 어긋났다는 사실이 드러났다. 그 사이 그 잘못된 숫자로 내려진 결정들을 되돌려야 했다.

    복구가 아니라 재건이었다

    우리는 한 분기 전체를 갈아 넣었다. 새 기능 개발을 전면 중단하고 파이프라인을 재설계했다. 만약 부채가 작았을 때, 즉 데이터가 적었을 때 검증을 넣었다면 며칠이면 끝났을 일이었다. 부채를 키운 대가는 그 일을 80배쯤 비싸게 만들었다.

    • 부채를 진 즉시 “상환 기한”을 백로그에 명시적으로 기록한다
    • 데이터 규모가 N배 커질 때 부채 비용도 N배 커진다고 가정한다
    • 검증과 모니터링은 기능이 아니라 보험이다, 작을 때 든다

    균형 잡힌 교훈

    그렇다고 모든 부채를 즉시 갚아야 한다는 결론은 위험하다. 그것은 또 다른 과잉이다. 폐기될지도 모르는 실험적 기능을 완벽하게 만드는 것은 낭비다. 핵심은 부채를 지지 않는 것이 아니라, 어떤 부채인지 의식하고 의도적으로 관리하는 것이다.

    지금 우리 팀은 분기마다 “부채 가시화” 시간을 갖는다. 미뤄둔 타협들을 목록으로 펼치고, 각각의 이자율을 추정하고, 상환할지 의도적으로 더 끌고 갈지 결정한다. 부채는 적이 아니다. 보이지 않는 부채가 적이다. 이 회고가 누군가의 파이프라인이 조용히 무너지기 전에 닿기를 바란다.

  • 6개월을 갈아 넣고 폐기한 프로젝트가 남긴 것

    6개월을 갈아 넣고 폐기한 프로젝트가 남긴 것

    우리는 6개월을 갈아 넣은 프로젝트를 출시 직전에 폐기했다. 야심찬 추천 시스템이었다. 팀의 자존심이 걸려 있었고, 경영진의 기대도 컸다. 그런데도 우리는 스스로 그것을 묻기로 결정했다. 이 글은 그 실패를 정직하게 복기한 회고다. 미화도, 과도한 자기비하도 없이.

    실패를 글로 쓰는 것은 불편하다. 그러나 성공담보다 실패담에서 배울 것이 훨씬 많다는 것을, 나는 이 프로젝트를 통해 뼈저리게 알게 됐다.

    모든 것이 순조로워 보였다

    시작은 완벽했다. 명확한 목표, 충분한 데이터, 유능한 팀. 우리는 정교한 추천 모델을 만들었고, 오프라인 평가 지표는 훌륭했다. 정확도가 기존 대비 크게 올랐다. 모두가 출시만 하면 성공이라 믿었다. 바로 그 자신감이 첫 번째 위험 신호였다.

    잘못된 질문에 완벽하게 답했다

    문제는 출시 직전 작은 사용자 테스트에서 드러났다. 우리의 추천은 통계적으로 정확했지만, 사용자에게는 “이미 알거나 이미 산 것”을 추천하고 있었다. 우리는 “클릭 확률이 높은 항목”을 정확히 예측했지만, 정작 비즈니스가 원한 것은 “새로운 발견”이었다. 우리는 잘못된 질문에 완벽하게 답한 것이다.

    틀린 문제를 정확히 푸는 것보다, 옳은 문제를 대충 푸는 것이 거의 항상 낫다.

    왜 6개월 동안 몰랐을까

    가장 아픈 질문은 이것이었다. 이걸 왜 6개월이 지나서야 알았을까? 답은 명확했다. 우리는 모델 정확도라는 대리 지표에 빠져, 실제 사용자와 비즈니스 목표에서 너무 일찍 멀어졌다. 6개월간 우리는 한 번도 진짜 사용자에게 결과를 보여주지 않았다. 측정하기 쉬운 지표가 측정해야 할 지표를 가렸다.

    • 대리 지표가 좋아도 진짜 목표와의 연결을 의심하라
    • 아무리 초기라도 실제 사용자 피드백을 미루지 마라
    • 비싸지기 전에 가장 큰 가정을 가장 먼저 검증하라

    폐기 결정이 가장 좋은 결정이었다

    역설적이게도 이 프로젝트에서 가장 잘한 일은 폐기 결정이었다. 매몰비용에 끌려 출시했다면, 사용자 경험을 해치고 더 큰 비용을 치렀을 것이다. 6개월을 버린 것은 아팠지만, 잘못된 방향으로 12개월을 더 가는 것보다는 훨씬 쌌다. 손실을 인정하고 멈추는 것도 실력이다.

    실패가 조직에 남긴 자산

    물론 이 회고가 “실패는 무조건 좋다”는 식의 낭만으로 읽히면 곤란하다. 피할 수 있었던 실패였고, 더 일찍 사용자를 만났다면 비용을 줄일 수 있었다. 실패 예찬은 위험하다. 중요한 것은 실패 자체가 아니라 실패에서 무엇을 추출하느냐다.

    이 프로젝트 이후 우리 팀은 모든 프로젝트 시작 시 “우리가 틀렸다면 어디서 가장 먼저 알 수 있을까”를 먼저 설계한다. 가장 비싼 가정을 가장 싸게 검증하는 습관, 그것이 6개월의 학비로 산 가장 값진 자산이다. 묻어버린 프로젝트는 사라졌지만, 그 교훈은 이후 모든 프로젝트를 더 단단하게 만들었다.