MyStock - Dropbox 동기화 #1 DB File Sync POC

MyStock에서 클라우드 동기화를 다시 고민하게 될 줄은 몰랐다. 초기 MyStock에서도 비슷한 시도가 있었다. 당시에는 계좌의 자금 흐름을 파악하기 위해 KIS OpenAPI에서 조회한 계좌 상태를 JSON 형태로 저장하고 Google Drive를 이용해 여러 환경에서 같은 데이터를 사용할 수 있도록 구성했다.

 

그런데 실제로 사용하면서 생각하지 못했던 문제가 생겼다. KIS OpenAPI에서 조회한 계좌 예수금의 의미와 값이 내가 기대한 것과 달랐고, 자금 흐름을 맞추기 위해 만든 JSON과 동기화 로직의 책임은 점점 커졌다. 결국 어느 순간 이런 질문으로 돌아왔다.

나 혼자 쓰는 프로그램인데 굳이 이 정도의 동기화가 필요한가?

당시에는 Google Drive Sync를 제거하는 쪽을 선택했다. 계좌 정보의 원본은 한국투자증권에 있었고, 프로그램을 실행할 때 다시 조회하면 됐다. 동기화를 유지하기 위해 Local과 Cloud의 상태를 비교하고 충돌까지 관리하는 것보다, 필요한 데이터를 다시 받아 사용하는 구조가 MyStock의 목적에 더 맞다고 판단했다. 이전 Google Drive Sync를 제거한 과정은 기존 글에 따로 정리해두었다.

조회 도구에서 분석 도구로

그런데 이후 MyStock의 목적이 달라졌다. 처음에는 여러 계좌의 잔고와 보유 종목을 한 화면에서 빠르게 확인하는 정도면 충분했다. 프로그램을 실행하면 REST API로 데이터를 받아 화면에 보여주고, 다음에 다시 실행하면 또 조회하면 됐다. 별도의 DB를 오래 유지할 이유가 크지 않았다.

 

하지만 투자현황, 투자분석, 투자기록 기능을 추가하면서 상황이 달라졌다. 가격 이력, ETF 구성종목 변화, 시장지표, 투자자 수급, 거래내역처럼 이전 데이터를 쌓아두고 비교해야 하는 기능이 늘어났다. 매번 메뉴를 열 때마다 REST API에서 필요한 데이터를 다시 받아오는 방식은 조회 시간이 점점 길어졌다. 특히 투자분석이나 투자기록은 지금 시점의 값 하나만으로는 의미가 없었다. 이전 데이터가 계속 쌓여 있어야 비교와 분석이 가능했다.

 

결국 MyStock은 단순한 계좌 조회 도구에서 데이터를 누적해 분석하는 도구로 목적이 바뀌었고, 그 시점부터 SQLite DB를 사용하기로 했다.

DB를 쓰고 싶어서 기능을 만든 것이 아니라, MyStock의 목적이 바뀌면서 DB가 필요해졌다.

여러 PC에서 달라지는 데이터 원본

DB를 사용하자 다른 문제가 생겼다. 나는 MyStock을 한 대의 PC에서만 사용하지 않는다. 회사와 집에서 번갈아 실행하고, Windows와 macOS 환경도 함께 사용한다. DB가 없다면 MyStock은 필요한 과거 데이터를 다시 구성할 수 있지만, ETF 구성종목처럼 초기 30일 범위의 데이터를 다시 만들려면 시간이 꽤 걸린다. 처음에는 이 재구성 시간이 가장 불편한 문제라고 생각했다. 그런데 실제로 더 중요한 문제는 따로 있었다.

 

각 PC의 DB가 서로 다른 시점에 만들어지고 갱신되면서 데이터 원본이 달라진다는 점이었다. 회사 PC에서 며칠 동안 MyStock을 사용하고 집 PC는 실행하지 않았다면 두 DB에 저장된 이력은 같지 않을 수 있다. 반대로 집에서 갱신한 데이터가 회사 PC에는 없을 수도 있다.

MyStock 자체 화면만 본다면 약간의 차이를 그냥 지나칠 수도 있다. 하지만 지금은 MyStock의 데이터를 LLM에 전달해 내 계좌를 기준으로 시장 상황과 투자 상태를 분석하는 방식도 사용하고 있다.

 

이 경우 어떤 PC에서 분석을 실행했느냐에 따라 LLM에 전달되는 데이터 원본이 달라질 수 있다. 같은 계좌를 분석하면서도 회사 PC와 집 PC에서 서로 다른 DB를 기준으로 판단하게 되는 셈이다. 그래서 이번 동기화의 목적은 예전 Google Drive Sync와 달랐다.

예전
자금 흐름을 보기 위한 JSON 데이터를 여러 환경에서 공유

현재
여러 PC의 MyStock과 LLM이 동일한 DB를 기준으로 분석

단순히 파일을 편하게 공유하기 위한 기능이 아니라, 여러 환경에서 분석의 기준이 되는 데이터 원본을 하나로 맞추기 위한 작업이 됐다.

Google Drive 대신 Dropbox

클라우드 저장소로 Google Drive를 다시 사용할 수도 있었다. 하지만 예전에 MyStock에서 Google Drive 동기화를 사용하면서 Local과 Cloud 상태가 꼬이는 경험을 이미 했고, 이번에는 같은 방식으로 돌아가고 싶지 않았다. 반면 Dropbox는 개인적으로 여러 장치에서 파일을 사용하면서 상대적으로 안정적이라는 인상이 있었다. 이미 계정도 사용하고 있었고, App Folder와 API를 이용하면 MyStock이 사용하는 파일만 별도로 관리할 수도 있었다.

 

다만 이번에는 Dropbox Desktop의 파일 동기화 기능에 SQLite DB를 그대로 맡기는 방식으로 접근하지 않았다. 과거 경험 때문에 오히려 반대로 생각했다. 클라우드는 저장 공간과 파일 전송 수단으로 사용하되, 언제 올리고 언제 받을지에 대한 판단은 MyStock이 직접 관리하는 편이 낫다고 봤다. 그 전에 먼저 확인해야 할 것이 있었다.

실행 중인 MyStock의 SQLite DB를 안전한 파일로 만들어 Dropbox에 보내고, 다시 받아 사용할 수 있는가?

바로 구현하지 않고 POC부터

나는 SQLite 내부 구조나 클라우드 파일 동기화 알고리즘을 직접 구현해본 사람이 아니다. 이번에도 코드를 직접 작성하기보다 내가 원하는 동작과 피하고 싶은 상황을 먼저 정리했다. 기존 DB를 망가뜨리면 안 되고, 오래된 PC의 파일이 최신 파일을 조용히 덮어쓰면 안 되며, 실제 MyStock에 기능을 붙이기 전에 가능한 방식인지부터 확인하고 싶었다.

 

이 조건을 ChatGPT와 검토하면서 바로 Production Sync를 구현하지 않고 작은 POC로 기술적인 가능성부터 확인하기로 했다. ChatGPT와 현재 구조와 위험 요소를 정리하고, 실제 구현과 반복 검증은 Codex에 맡겼다. POC에서는 Production MyStock의 동작을 변경하지 않았다. 실제 DB 파일을 실행 중 그대로 복사하는 대신 SQLite가 제공하는 backup 기능으로 별도의 Snapshot을 만들고, 그 파일이 정상적인 DB인지 확인한 뒤 Dropbox에 올리는 방식부터 검증했다.

SQLite DB
   ↓
Snapshot 생성
   ↓
DB 무결성 확인
   ↓
Dropbox Upload
   ↓
Metadata / Revision 확인
   ↓
Download
   ↓
다시 DB 검증

여기에 한 가지를 더 확인했다. 다른 PC가 Dropbox의 파일을 이미 변경한 상황에서 오래된 상태를 가진 PC가 다시 파일을 덮어쓰려고 하면 어떻게 되는가 하는 문제였다. Dropbox는 파일마다 revision 정보를 제공했고, 이전에 확인한 revision을 기준으로 Update를 요청할 수 있었다. 그 사이 다른 쪽에서 파일이 변경됐다면 오래된 revision의 Update는 충돌로 거부됐다.

 

이것도 문서만 보고 끝내지 않고 실제 Dropbox 계정에서 Upload, Download, Metadata 조회, 정상 Update와 오래된 revision의 충돌까지 확인했다. Connector Review에서 POC의 충돌 처리와 복구 경로에 대한 문제도 몇 차례 발견됐고, 이를 수정한 뒤 최종적으로 14개의 관련 테스트와 실제 Dropbox 왕복 검증을 완료했다. 여기까지의 결론은 단순했다.

SQLite DB를 안전한 Snapshot으로 만들고 Dropbox를 통해 전달하는 것은 가능하다.

파일 전송 다음의 문제

POC가 성공했으니 이제 바로 MyStock에 붙이면 될 것 같았다. 그런데 Dropbox는 오래된 revision으로 최신 파일을 덮어쓰는 것은 막아줄 수 있었다. 하지만 회사 PC의 DB와 집 PC의 DB 중 어느 쪽이 논리적으로 최신인지는 알려주지 않는다. 앱을 실행할 때 무조건 Dropbox DB를 받아야 하는지, Local DB가 변경됐는지는 어떻게 판단할지, 두 PC가 모두 변경됐다면 어느 쪽도 덮어쓰지 않고 어떻게 처리할지, 그리고 DB 갱신이 계속 진행되는 MyStock에서 정확히 언제 Snapshot을 올려야 할지도 결정해야 했다. 즉 POC에서 확인한 것은 파일을 안전하게 전달할 수 있다는 기술적인 가능성까지였다. 실제 동기화를 만들려면 Push와 Pull의 기준부터 먼저 정해야 했다.

 

처음에는 DB 파일 하나를 Dropbox에 올리면 되는 일이라고 생각했는데, POC를 끝내고 나니 오히려 무엇을 설계해야 하는지가 선명해졌다. 다음 작업은 구현이 아니라 정책을 정하는 일이 됐다.

 

MyStock - Dropbox 동기화 #2 DB File Sync 정책 설계에서 이 부분을 이어서 정리하려고 한다.