
들어가며
나조차 나를 믿지 못하던 순간에도, 누구보다 나를 믿어준 사람이 있습니다.
당신 덕분에 크고 작은 도전을 할 수 있었습니다. 목표했던 대학을 가기 위해 입시를 다시 준비하기도 했고, 남들이 대기업 연수원 사진을 올리는 시점에 개발자가 되겠다며 새로운 공부를 시작하기도 했습니다. 도전을 거듭하며 원하는 결과가 나오지 않을 때면 초조함과 더불어 스스로가 초라해지는 순간들이 있었습니다. 모두가 잠들 시간 집에 돌아와 표정이 굳은 채 조용히 밥을 먹고 있으면 당신은 "1, 2년 돌아가는 건 아무 일도 아니다"라며 굶지 말라고 몰래 비상금을 쥐여주곤 하셨습니다. 당신의 믿음이 있었기에 멈추지 않고 도전할 수 있었습니다.
은퇴 후에도 새 일터에서 고군분투했던 당신이 자리에서 일어나지 못하여 응급실에 다녀왔다는 소식을 들으면서 늦게나마 당신에게 보답하는 삶을 살았는가 돌아봅니다. 당신의 응원, 지지, 믿음 덕분에 하반기의 시간을 온전히 보낼 수 있었다고 정리할 수 있는 글이 되길 바라며 지난 6개월의 시간을 정리하는 글을 씁니다.

퍼펙트 데이즈
어떤 태도로 삶을 살아갈 것인가 고민될 때면 영화 <퍼펙트 데이즈>를 떠올립니다. 주인공 히라야마는 도쿄의 공중화장실 청소부입니다. 남들에겐 반복되는 허드렛일일지 모르지만, 그는 자신만의 도구를 만들어 보이지 않는 변기 구석까지 세밀하게 닦아냅니다. "기껏 청소인데 왜 그렇게까지 하느냐"라는 물음에도 그는 그저 찰나의 순간에 온 진심을 쏟을 뿐입니다.

묵묵히 자신의 일을 하는 히라야마의 모습을 보면서 정성을 다해 일하는 사람의 태도를 돌아보고자 지난 상반기 회고글을 다시 읽었습니다. 포크에 있는 물 자국 하나가 소중한 시간과 돈을 들여서 식당에 온 손님에게 실망을 줄 수 있다고 믿는 사람, 요리에 필요한 재료 손질을 모두 직접 하면서 이렇게 해야 일을 더 존중할 수 있고 시간을 잘 보낸 것 같다고 생각하는 사람을 보면서 새롭게 합류하는 팀에서도 정성을 다해 일하겠노라 다짐하며 하반기를 시작했습니다.

어떤 필요를 만들 것인가
하반기부터 '모먼트 스튜디오' 팀에서 '세시간전' 서비스를 개발하며, 단순히 코드를 짜는 개발자를 넘어 비즈니스의 실질적인 문제를 해결하는 사람이 되고자 했습니다. '세시간전'은 여행 상품(호텔, 항공권, 렌터카 등) 및 라이프스타일 브랜드의 상품 링크를 블로그, 유튜브, 인스타그램 등에 삽입해, 해당 링크를 통해 예약이 발생하면 링크를 공유한 사람이 수익을 얻는 CPA(성과형 광고) 플랫폼입니다. 하반기에는 팀에서 어떤 문제를 해결했는지 간략히 정리합니다.

데이터 레이크 및 데이터 분석 환경 구축
먼저 BigQuery를 활용한 데이터레이크 구축을 통해 팀의 데이터 드리븐한 의사결정을 할 수 있는 환경을 구축했습니다.
문제 정의
합류 당시 팀에는 데이터 분석을 위한 별도 DB가 구축되지 않았습니다. 그래서 팀원들은 데이터가 필요할 때마다 개발팀에 쿼리 실행을 요청해야 했습니다. 개발팀은 요구 사항을 듣고, 실행하고자 하는 쿼리문이 맞는지, 데이터는 정상적으로 조회된 것이 맞는지 등을 매번 확인해야 했습니다. 만약 개발팀이 바쁘다는 이유로 쿼리문을 실행하지 않으면, 데이터를 요청한 팀원들은 계속 기다려야 하는 상황이었습니다. 만약 팀원들에게 DB를 사용할 수 있도록 권한을 부여해도, 운영 DB에서 무거운 분석 쿼리를 실행하면 API 성능 저하를 일으킬 수 있는 상황이었습니다. 마지막으로 팀원들이 개인정보가 포함된 테이블에 직접 접근해서 정보를 볼 수 있도록 처리하기엔 큰 리스크가 있다고 판단했습니다.

문제 해결
팀의 리소스를 지키면서도 보안과 접근성을 모두 충족하는 시스템을 설계하고자 했습니다. 추가로 팀에서는 인프라 비용 절감이 필요했던 상황이라 비용이 최소한으로 들어갈 수 있는 설계가 필요했습니다. GCP 크레딧이 존재하는 상황에서 비용 효율적으로 분석용 인프라를 사용할 수 있도록 BigQuery를 데이터레이크로 구축했습니다. 이를 위해 먼저 AWS RDS의 데이터를 Google BigQuery로 이관하는 서버리스 파이프라인을 구축했습니다.

Step 1: 먼저 매시간 Lambda를 실행하여 RDS 스냅샷을 자동 생성하는 환경을 구성했습니다. 혹시나 DB에 문제가 생겼을 때 빠르게 데이터를 복구시킬 수 있도록 하기 위해 해당 작업을 먼저 진행했습니다.

Step 2: 일별로 새로운 데이터를 BigQuery에 옮기기 위해 KST 기준 01시에 생성된 스냅샷 정보를 Parquet 포맷으로 생성하여 S3 버킷에 Export 합니다.

Step 3: 약 2~30분 정도 진행되는 step2 과정이 마무리되면 KST 기준 02시에 S3에 적재된 데이터를 GCS(Google Cloud Storage)로 전송합니다.

Step 4: 최종적으로 BigQuery에 데이터를 로드하여 일별 배치로 동기화되는 분석 환경을 완성합니다. 물론 step function을 사용해서 각 step 별로 실행이 끝나면 순차적으로 다음 단계의 lambda를 실행해도 됐지만, 빠르게 환경을 구축하기 위해 다음과 같이 lambda 활용 환경을 구성했습니다.

BigQuery에 테이블 정보를 추가할 때 보안적으로 안전하게 DB를 사용할 수 있도록 BigQuery의 Policy Tag 기능을 도입하여 개인정보 컬럼을 암호화했습니다. 이를 통해 분석가들은 데이터의 전체적인 흐름은 보되, 민감한 정보는 보호받는 안전한 분석 환경을 가질 수 있었습니다. 또한 인프라 비용을 집요하게 최적화하여 월 예상 비용을 약 $11.97(한화 약 16,000원) 수준으로 데이터 분석이 가능하도록 설계할 수 있었습니다.

RDS 정보뿐 아니라 세시간전 웹사이트에서 처리하는 GA4 이벤트 데이터도 BigQuery에 통합하여 RDS, GA4를 통합한 데이터 분석이 가능해졌습니다.

마지막으로 BigQuery와 vertex.ai, Gemini를 활용하여 머신러닝 작업이 가능해졌고, ML을 통해 여러 종속, 독립 변수를 지정하여 다각도의 데이터 분석 처리가 가능해졌습니다.

마지막으로 Gemini 기반 Fine-tuned LLM을 직접 구축하여 다각도로 AI를 활용할 수 있는 환경을 준비할 수 있게 됐습니다.
결과
구축된 BigQuery 활용 환경을 통해 팀에서는 GA4 데이터와 RDS 데이터를 결합해 비즈니스 인사이트를 파악할 수 있게 됐습니다. 더 나아가 Vertex AI와 Gemini를 활용해 AI를 활용하여 데이터를 더 쉽게 탐색하고, Looker Studio 등을 통해 대시보드로 데이터를 시각화하여 팀에서 데이터를 보다 잘 다룰 수 있는 기반을 마련할 수 있었습니다.

테스트 코드 도입 및 효율화
두 번째로, 팀에 테스트 코드를 작성하고 실행하는 환경을 도입하여 서비스의 안정성을 올렸으며, Github Action CI script에서 약 4분 30초 정도 걸리던 테스트 실행 시간을 1분 내로 처리될 수 있도록 개선했습니다.

문제 정의
팀 합류 당시 부재했던 테스트 코드를 도입하기 위해 NestJS와 Jest 환경을 구축했습니다. 하지만 테스트 케이스가 늘어날수록 CI 스크립트 실행 시간이 길어져 배포 속도를 저하시키는 새로운 문제에 직면했습니다. 약 4분 30초에 달하는 대기 시간은 개발 생산성을 갉아먹고 있었습니다.
문제 해결
기존에는 jest의 --runInBand 옵션을 기준으로 실행했습니다.

해당 옵션을 사용하면 테스트 코드가 순서대로 실행되는데, 테스트 케이스가 많다면 그만큼 순서대로 테스트 실행 결과를 기다려야 하는 상황이었습니다.


그래서 Github Action의 Matrix와 jest의 shard 옵션을 활용하면 테스트 코드 실행을 나눠서 처리할 수 있으니 보다 빠르게 처리할 수 있다고 판단했습니다.

실행 결과 테스트 코드의 실행 시간을 절반 정도 줄일 수 있었지만 문제는 Matrix에서 6대의 러너가 실행되면 Github Action 사용 비용이 6배가 증가할 수 있었습니다. 실행 시간은 줄일 수 있지만 비용이 증가하는 문제가 있었고, 이는 최적의 방법이 아닐 수 있다고 판단했습니다.


그 후 생각한 것은 jest의 maxWorker 옵션과 DB 멀티 스키마를 사용하는 것을 선택했습니다. jest의 워커 수만큼 DB 스키마를 동적으로 생성하고, 각 워커가 독립된 스키마에서 테스트를 병렬로 실행하도록 구성했습니다. 이를 통해 자원 효율을 극대화하면서도 테스트 간의 독립성을 보장했습니다.

또한 DB를 사용하지 않는 단위 테스트의 경우는 Github Action에서 별도로 처리되게 만들어 독립적으로 테스트 코드가 실행되도록 구분했습니다.

결과
결과적으로 테스트 실행 시간을 264초에서 48초로 약 82% 단축했습니다. 전체 CI 단계 또한 6분대에서 3분대로 줄어들었습니다. 빨라진 피드백 루프를 통해 개발팀은 더 과감하고 안정적으로 코드를 수정할 수 있게 되었습니다.

크롬 익스텐션 개발
세 번째는 크롬 익스텐션 서비스를 개발하여 5단계의 제휴링크 생성 과정을 1단계로 줄일 수 있었습니다.

문제 정의
기존 유저가 제휴 링크를 생성하려면 스튜디오 페이지에 진입해 위의 단계를 거쳐야 했습니다. 이 복잡한 UX 때문에 사용자가 불편할 수 있다고 판단하여 크롬 익스텐션을 통해 불편한 UX를 개선하고 싶었습니다.


문제 해결
경쟁사 분석부터 기획, 익스텐션의 프론트와 백엔드 개발을 직접 수행하면서 한 번의 클릭으로 로그인을 연동하고, 현재 페이지에서 즉시 제휴 링크를 생성하는 UX를 구현했습니다.


확장 프로그램 아이콘을 클릭하면 popup이 노출되어 제휴 링크 생성이 가능합니다.


한 번의 클릭으로 로그인을 연동하고 이미 제휴링크를 생성한 상품이라면, 이미 제휴링크가 생성된 상품이라고 정보를 노출시켰습니다.

결과
익스텐션 개발 결과 약 1,000명의 크리에이터가 한 번의 클릭만으로도 링크를 생성할 수 있는 서비스를 만들 수 있었습니다.

정산 프로젝트 투입
마지막으로 기존 수익 업데이트 시간을 약 20배 이상 향상함과 동시에, 매주 수요일에만 확인할 수 있던 수익 현황을 특정 제휴사를 시작으로 데일리로 업데이트함으로써 유저들에게 빠르게 수익 발생 여부를 확인할 수 있는 환경을 구축했습니다.
문제 정의
서비스의 가파른 성장으로 협력 파트너사가 급증함에 따라, 각기 다른 데이터 규격과 정산 정책을 통합적으로 관리할 수 있는 확장성 높은 아키텍처가 요구되었습니다. 기존의 수익 현황 업데이트 주기는 데이터를 처리하는 과정에서 발생하는 리소스를 고려하여 주간 단위 배치를 유지하고 있었으나, 파트너사 및 트래픽 규모가 커질수록 운영 효율을 더욱 고도화하고 개발 리소스를 줄여야 할 필요성이 제기되었습니다.
문제 해결
먼저 주간 수익 업데이트 작업을 진행하면 특정 제휴사의 수익 업데이트 처리 속도가 20분 이상이 걸리면서 DB에도 부하를 주는 문제가 발생했습니다. 문제 해결을 위해 수익 업데이트 과정에서 발생하는 N+1 문제를 개선하여 데이터 처리 효율을 올렸습니다. 그리고 배치 처리 로직의 효율을 높여 특정 제휴사를 시작으로 데이터 반영 주기를 주간에서 일별(Daily)로 단축할 수 있는 기반을 마련했습니다.

결과
기존 20분 이상 소요되던 제휴 프로그램의 수익 업데이트 시간을 30초 내로 처리할 수 있도록 개선하여 운영 효율을 높였습니다. 그리고 특정 제휴사를 시작으로 일별 수익 업데이트 환경을 구축하여 사용자에게 전날의 예상 수익 현황을 매일 제공할 수 있도록 개선할 수 있었습니다.

최선(最善), 가장 선한 마음을 다한다는 것
2025년 하반기, 저에게 주어진 시간은 '할당된 일'과 '필요한 일' 사이의 간극을 메우는 과정이었습니다. 쉽사리 풀리지 않는 문제 앞에서 무력감을 느낄 때마다 저보다 저를 믿어준 동료들 덕분에 끝까지 문제를 해결할 수 있었습니다.
하반기의 시간을 통과하며 '최선'이라는 단어의 무게를 다시 가늠해 보았습니다. 우연히 읽게 된 칼럼 하나가 제 마음의 눈금을 바꾸어 놓았습니다.
최선(最善)의 반대말은 최악(最惡)이다. 최선이라는 말은 가장 선한 것, 즉 가장 좋은 것이라는 의미이다. 가장 나쁜 것의 반대말이다. 우리는 최선이라고 이야기하면서 ‘선한 것’이라는 점을 잊어버리고 있다. 우리는 ‘최선을 다한다.’는 말을 그저 열심히 한다는 말 정도로 생각하는 경향이 있다. 하지만 최선을 다한다는 말은 단순히 열심히 한다는 의미가 아니다. 있는 힘껏 노력한다는 의미로만 보기에는 무언가 부족함이 있다.
...
자신이 최선을 다한다고 말하는 것들을 살펴보라. 그 일이 그만한 가치가 있는가? 그 가치는 우선 목적이 선한 것이어야 한다. 우리는 공부를 최선을 다한다고 한다. 하지만 왜 공부를 하는지 생각해 보아야 한다. 우리에게 선한 목적이 있는가? 단순히 다른 사람을 누르고 나 혼자만의 안락한 삶을 위해서라면 최선은 아니다. 최선이라는 가치는 모든 이를 위한 것이어야 한다.
그동안 최선이라는 말속에 감추어진 내 모습을 돌아본다. 쉽게 최선을 다했다고 말하지만 그게 나를 위한 것인지 다른 사람을 위한 것인지에 대해서는 고민이 없었다. 열심히 했다는 말로 스스로를 위안하였을 것이다. 얼마나 많은 일들이 최선이라는 말 앞에서 핑계가 되었을까? 나는 최선을 다 했지만 어쩔 수 없었다는 말로 많은 사람들에게 아픈 상처를 주었을까? 최선이라는 가치 속에 담겨있는 착한 아름다움을 다시 생각해 본다.

칼럼을 읽으며 그동안 내뱉은 '최선'이라는 말속에 얼마나 많은 핑계가 숨어 있었는지 생각했습니다. 생각해 보면 공부를 하거나 업무를 하면서 결과가 좋지 않더라도 최선을 다했다는 말을 하면서 스스로 위안 삼았던 순간들이 스쳐 지나갑니다. 나만의 안락이나 실력을 증명하기 위한 노력이었다면, 그것은 최선이 아니라 그저 '치열함'이었을지도 모릅니다.
야근과 주말의 리소스를 투입하며 보낸 시간들 속에서 "나의 이 노력은 누구를 향해 있는가?" 스스로에게 묻곤 했습니다. BigQuery 환경을 구축하고, 테스트 코드를 최적화하며 보낸 시간들이 저에게는 '선(善)'의 실천이었습니다. 나의 수고로 인해 동료가 반복적인 쿼리 요청에서 해방되고, 배포를 기다리는 개발자의 초조함이 몇 분이라도 줄어들 수 있다면, 그것이 바로 제가 증명하고 싶은 최선이었습니다.















항상 최선을 다한다고, 정성을 다한다고 결과가 좋으리라는 보장은 없다는 것을 알고 있습니다. 그렇지만, 최선을 다하는 순간들이 모이면 언젠간 노력하는 이에게 조금의 행운이 따르지 않을까 하는 마음으로 2026년 상반기에도 도전을 멈추지 않고 지속하려 합니다.

마치며
온전한 사랑으로 저를 믿어준 당신이 있었기에, 삶을 대하는 적극적인 태도를 배울 수 있었습니다. 감사하게도 이제 제 곁에는 당신을 닮아, 나보다 나를 믿어주는 동료, 친구, 그리고 사랑하는 사람이 있습니다.
새로운 한 해를 맞이하며 다짐합니다. 언젠가는 당신처럼 누군가에게 조건 없는 신뢰를 보내는 큰 나무가 되고 싶습니다. 화려한 일은 아니더라도 누군가의 짐을 덜어주는 '선'을 다할 수 있다면, 사소한 코드 한 줄에도 정성을 담아낼 수 있다면, 그 묵묵한 쌓임이 언젠가는 당신의 노고를 덜어줄 수 있는 힘이 되리라 믿습니다.










나를 믿어준 이들을 지킬 수 있는 사람이 되겠습니다. 2026년 상반기에도 '최선'이라는 단어 속에 담긴 착한 아름다움을 기억하며 계속해서 도전하겠습니다. 나보다 나를 더 믿어준 가족, 친구, 나의 팀, 그리고 사랑하는 당신에게 함께 할 수 있어 행복했다고 이 글을 핑계 삼아 마음을 대신 전합니다. 긴 글 읽어주셔서 감사합니다.
참고 링크
최선(最善)을 다한다는 말은?
‘이게 최선입니까?’라는 말이 드라마에 나오면서 유행한 적이 있다. 우리는 최선을 다하는 삶을 칭찬하고 좋아한다. 얼마 전에 나는 아우렐리우스의 명상록에서 인생에 최선을 다해야 한다는
www.dongponews.net
<퍼펙트 데이즈> - 그대들은 어떻게 살 것인가.
반복은 매너리즘에 빠지게 한다. 매너리즘은 일상의 범위를 좁힌다. 좁아진 일상에선 내가 보는 것들의 가짓수도 적어진다. 보는 게 적어지면 생각할 것도 적어진다. 개인의 세계는 이렇게 소멸
newneek.co
'일상 정리 > 회고' 카테고리의 다른 글
| [회고] 2025년 상반기 - 정성이 들어가는 일 (0) | 2025.06.29 |
|---|---|
| [회고] 2024년 하반기 - 무용(無用)을 사랑하는 마음 (6) | 2025.01.01 |
| [회고] 2024년 상반기 - 등대가 되었던 사람 (3) | 2024.06.30 |
| [회고] 2023년 하반기 - 미련한 사람이 우물을 판다 (11) | 2024.01.01 |
| [회고] 2023년 상반기 - 친절한 자세를 흩뜨리지 않도록 (3) | 2023.07.02 |