go to post list

두 번째 프로젝트 회고

2023. 10. 08 • 기술 도입으로 문제를 해결…하려다 실패한 경험

두 번째 프로젝트의 조건은 도메인이었는데요, 빅데이터의 분산처리 기술을 활용하는 것이었습니다. 첫 번째 프로젝트는 어디 가고 왜 두 번째 프로젝트 회고가 첫 글이냐고 물으실 것도 같은데요, 첫 번째 프로젝트 회고는 아직까지도 할 일이 계속해서 생기는 중이라 두 번째 프로젝트 회고부터 적게 됐습니다.

빅데이터의 분산처리 기술에 대한 개념조차 모르는 상태였기 때문에 관련 학습을 하면서 기획을 해야 해서 실질적인 개발 기간이 부족했고 데이터셋을 모으기도 난해했습니다. 저는 프론트엔드를 맡아 직접적인 분산처리 부분을 담당하지는 않았지만, 프론트엔드 기술로 문제를 해결하려고 시도(했다 장렬하게 실패)한 경험을 이야기해 보고자 합니다.

저희는 한국의 모든 드라마와 영화, 예능 프로그램, 배우, 출연진, 감독 등 관련 인물과 작품을 아카이브하고, 이 자료를 바탕으로 작품간의 연관성과 관계를 간단하게 계산해 작품 간의 지도를 그려 보는 프로젝트를 진행했습니다.

프로젝트 아키텍처. 클릭하면 크게 보실 수 있습니다.

프로젝트 아키텍처. 클릭하면 크게 보실 수 있습니다.

최종적인 프로젝트 아키텍처는 위와 같은데요, 전체적인 데이터 구조는 아래와 같이 저장됩니다.

  • 스크래핑 서버가 자료를 AWS RDS에 일차적으로 삽입합니다. RDS에 있는 자료는 검색 기능을 제공할 때 사용됩니다.
  • SPARKRDS에 있는 자료를 가지고 매일 한 번 연산합니다. 이 결과를 MongoDB에 업데이트합니다.
  • Next.js app은 MongoDB에서 5분마다 한 번씩 데이터를 쿼리하고, 쿼리한 데이터를 가지고 D3.js를 통해 force-directed-graph (FDG)를 그립니다.
d3.js가 렌더링한 force-directed graph

d3.js가 렌더링한 force-directed graph

최종적으로 사용자는 5분마다 ISR로 생성된 다른 지도 페이지를 보게 됩니다.

온몸 비틀기의 과정

스크래핑한 데이터셋을 MongoDB에 넣었을 때 600MB가 넘었습니다. 전체 데이터셋은 인물 30,000명, 작품 12,500개 정도로 추정되었는데요, 이 중 10*10의 그래프를 쿼리하는 데에만 15초 이상이 걸리는 상황이었고, 최적화 후에도 5초 남짓이 걸렸습니다. 페이지가 로딩되는 데에는 10초 정도가 걸렸고, Next.js가 에러를 내는 경우도 있었습니다. 초기 구상으로는 CSR이나 SSR로는 이 시간을 감당할 수 없다고 판단해 ISR로 페이지를 미리 빌드해야 한다고 생각했고, 이 빌드 아웃풋을 구글 지도처럼 이어붙일 생각이었습니다. (데이터셋 자체를 공간좌표화해 타일로 저장했다면 CSR로도 충분했을 것 같은데, 이 아이디어는 기술적인 문제로 실현되지 못했습니다)

이 작업을 위해 검색을 위한 Next.js 서버와 지도를 위한 Next.js 서버를 분리해야 한다고 생각했고, 그러면서도 두 사이트가 하나의 서비스로 작동했으면 좋겠다는 생각을 했습니다. 이때 알게 된 개념이 Module Federation이었고, 이 프로젝트에 적절한 기술이라고 생각했습니다.

실패 1.

  1. 그럼에도 지도가 너무 방대했기 때문에 수만 개의 정적 HTML을 빌드해야 했고, (빌드를 시도했을 때 최소 3일 이상이 걸릴 것으로 예상됐습니다)
  2. 이 HTML을 타일링을 통해 이어붙일 로직을 구현하려면 결국 (실현되지 못한) 데이터셋의 공간좌표화가 필요하다는 문제가 있습니다.

저희는 프레임워크에 묶여 있었기 때문에 (새로운 프레임워크를 생각하거나 2를 직접 구현할 수 있을 만큼의 기술 숙련도가 없기 때문에) 이 아이디어를 배제할 수밖에 없었습니다. 결국 검색 기능을 구현하고 난 후, 지도는 5분마다 한 번씩 랜덤한 작품을 중심으로 작은 지도를 그려 교체하는 식으로 구현하게 됐습니다.

실패 2.

Module Federation으로 지도 모듈을 분리해 dynamic import하려는 생각은 좋았지만, Incremental Static Regeneration으로 생성된 정적 페이지는 컴포넌트로서 dynamic import 를 할 수 없었기 때문에 결국 서로 다른 두 개의 Next App을 이어 붙이기만 한 셈이 되었습니다.

프로젝트로 얻은 것

이 프로젝트의 가장 큰 실패 요인이 기술 역량 부족이라고 할 수도 있지만, 사실 기술 역량에 대한 과대평가를 했다는 것이 진짜 실패 요인입니다. 기간 안에 구현할 수 있다는 확신과 기술에 대한 레퍼런스 모두 없는 상태에서 프로젝트를 강행했기 때문입니다.

이 이후로 제 기술 역량에 대한 지표가 필요하다는 생각을 하게 되어서 태스크에 대한 수행 시간을 측정할 필요가 있겠다는 생각을 했습니다. 아직은 개인 프로젝트를 하는 단계여서 반복적인 상황이 많이 없는데, 실무에 진입하게 된다면 어느 정도 지표가 쌓일 수 있을 것입니다.

여담

지도 자체를 멋들어지게 그리는 데는 실패했지만 기술적으로는 성장한 부분이 많은 프로젝트였습니다. 특히 프론트엔드 기술에 대한 시야를 많이 넓힐 수 있었다고 생각합니다.

  • Next.js를 처음 사용해 보았습니다. Hydration SSR, SSG, ISR에 대한 개념을 익히고 세 가지 모두를 사용해 본 게 가장 큰 수확이라고 할 수 있습니다.
  • 이런 SSR 프레임워크가 쓰이기 시작하면서 같은 코드가 자바스크립트의 두 런타임에서 모두 정상적으로 작동해야 할 필요성이 생기게 된 맥락을 체감했습니다.
  • 프론트엔드 파트에서 서버를 사용할 수 있을 때 프로젝트에서 능동적인 액션을 취할 수 있게 된다는 사실을 알았습니다.
  • 마이크로 프론트엔드라는 개념을 알게 됐고, 아키텍처에 대해 조금 더 고민하고 생각해보게 됐습니다.

또, 시간과 기술이 절대적으로 부족했지만 빠르게 실험하고 실패해본 경험, 팀원 전체가 어떻게든 포기하지 않고 치열하게 프로덕트를 만들어서 최악만은 피했다는 경험도 하게 된 셈이 됐습니다. 저희 프로젝트를 옆에서 지켜보는 입장에서는 허탈하다고 생각할 수도 있었던 것 같은데, 저는 프론트엔드 개발자로서 치열하게 기술적으로 고민하는 과정이 정말 재미있었던 프로젝트였습니다.

다른 글