구글 스프레드시트에 기존 데이터 업데이트하기

2024년 2월 1일 목요일

Today I Learned

날짜

2024년 2월 1일 목요일

내용

스프린트 결과가 배포됐다. 다행히 큰 빵꾸는 없었다. 많은 유저가 몰려왔으면 좋겠다.

구글 스프레드시트에 데이터 추가하기

새로 만든 기능에 대한 KPI 데이터를 구글 스프레드시트에 추가하는 태스크를 맡았다. 이전에, 작동이 멈췄던 커맨드를 다시 돌리는 작업을 했었는데 이와 비슷할거라고 생각해서 별로 어렵지 않겠다 싶었다. 약간의 차이점이 있었는데 이 부분을 너무 쉽게 생각했다.

  1. 기존에는 매일매일 새로운 행에 데이터를 추가했지만, 이번에는 기존 데이터에 덮어써야 했다.

  2. 1개의 샵 당 1개의 데이터를 가지게 되며, 이미 데이터가 존재한다면 새로 행을 추가하지 않고 수정해야 한다.
  3. 오늘 이후 가입하는 유저는 데이터베이스에 추가한다.
  4. 이미 가입되어 있던 유저는 새로운 AI 서비스에 가입했을 때 데이터를 추가한다.
  5. AI만 가입되있던 유저가 리뷰 서비스로, 리뷰만 가입되있던 유저가 AI 서비스로 전환할 시의 시간을 기록해야 한다.

실시간으로, 데이터베이스에 발생한 이벤트를 감지하기엔 너무 비효율적이라고 생각했다. 짧은 주기로 변화를 탐지하도록 작성하는 것도, 트리거를 설치하는 것도 불필요하다고 생각했다. 시간을 기록하는 것이 필요할 뿐, 데이터의 실시간성은 중요하지 않기 떄문이다.

뒤늦게야 서비스 전환(AI → review or Review → AI)에 대한 데이터가 있다는 사실을 발견했다. 따라서 매일 아침 정해진 시간에, 하루동안 생긴 변화를 기록하도록 결정했다. 여기서 또 고민했던건, ECS Task를 사용할 것인지 lambda를 사용할 것인지 였다. 기존에 일정 주기로 실행되는 것들은 ECS Task로 처리했었지만 컨테이너를 열고 닫는 것에 대한 비용과 리소스 소비도 무시할 수 없다고 생각했기 때문이다.

ECS Task는 설정한 Task를 실행하기 위해 컨테이너를 열고 실행 후 닫는다. AWS Lambda는 AWS의 EC2와 비슷한 클라우드 컴퓨팅 서비스로, 서버를 설치할 수 있다. EC2와의 차이는 내가 서버의 구성에 대해 신경 쓸 필요 없고 사용하는 동안에만 서버가 가동되기 떄문에다. EC2에 웹 서버를 만들면 24시간 항상 가동되지만 Lambda에 만들면 특정 시간(요청이 온 이후 일정 시간동안 이라던가)동안만 서버가 가동되어 경제적이다. lambda에 함수를 정의할 수있는데, 내가 원하는 규칙에 맞춰 서버가 열리고 함수가 실행되고 서버가 닫힌다. ECS Task를 사용할 때 작성한 스크립트를 Lambda 함수로 작성하면 되는 것(물론 이와 관련하여 패키지나 라이브러리 등을 설치해주는 코드도 추가해야한다).

일반적으로, 실행 시간이 15분이 넘지 않는 짧은 Task는 Lambda로 설정하는 것이 여러모로 효율적이다. 이번 기회에 관련된 경험을 쌓고 싶어 사용하고자 했으나 역할 문제로 방법을 바꿨다. 이 Lambda를 위한 역할을 만들어줘야 하는데, 아직 난 IAM 사용자로서 해당 권한이 없기 떄문이다(사실 있으면 안되는게 맞다).

결국 cronjob을 작성했는데 기존에 사용하던 것과 조금 달랐다.

| 생성일 | 샵 이름 | 요청 횟수 | 전환 여부 | 전환일시 | | — | — | — | — | — |

이 중 생성일, 샵 이름은 가입해서 DB에 데이터가 생성되었을 때 입력된 이후 바뀔 일이 없다. 하지만 요청 횟수는 매일 기존의 값 대신 새로운 값이 입력되어야 하고 전환 여부는 경우에 따라 다르다. 이미 AI 서비스에 가입한 유저는 처음부터 True 가 입력되고 바뀔 일이 없지만 그렇지 않을 경우 우선 False로 입력하고 나중에 True로 바뀔것이다.

또한 구글 스프레드시트에 데이터를 입력할떄의 위치를 특정하는 방법은 행과 열의 값이다. Shop_name 이 “나이키”인 행을 찾아서 데이터를 입력하는 API는 없다. 구현을 하려면 할 수는 있다. 내가 입력할 shop의 이름으로 모든 행의 샵 이름을 뒤져서 같은 행의 행 번호를 찾아 거기에 업데이트 해주는 방식이다. 최악의 경우 데이터베이스에서 N개의 샵에 대한 기록을 찾기 위해 스프레드시트 전체를 N번 순회해야 한다. 실행 횟수는 무려 N^2이니 낭비도 이런 낭비가 또 있을까? 물론 한번만 방문해서 모든 데이터를 가져오고 거기서 원하는 shop의 행 값을 찾는 방법도 있겠지만 여전히 효율성에 대해 의문부호가 있다.

따라서 각 샵이 db에서 갖는 고유 id로 정렬시켰다. id가 1인 shop은 2행에, id가 1300인 shop은 1301번 행에 입력시키도록 했다. 읽기에 불편할 수 있으나 효율성을 따지자면 그나마 나은 방법이 아닐까..

내가 찾아본 구글 API 에선 입력하는 것과 업데이트 하는것은 다른 메소드를 사용한다. 특히 입력은, 어떤 행에 데이터가 있다면 다음 행에 입력되도록 처리된다. 위 5개의 데이터에서 요청횟수는 리뷰 서버에서 입력하고, 나머지 4개는 샵 서버에서 입력한다. 샵 서버의 입장에선 가운데를 비워놔야 하니 (A열~B열) 을 입력하는 요청을 하고 (D열~E열)을 입력하는 요청을 한번 더 해야 한다. 문제는 두번 쨰입력 떄 이미 그 행에 데이터가 존재하기 떄문에 다음 행으로 입력되버린다는 건데.. 내일 API를 좀 더 알아봐서 해결할 수 있을 듯 하다.

회고

쉬울 줄 알았는데 정말 복잡하다.