diff --git "a/08\354\236\245/\354\235\264\354\247\204\355\230\201.md" "b/08\354\236\245/\354\235\264\354\247\204\355\230\201.md" new file mode 100644 index 0000000..0ce3fd0 --- /dev/null +++ "b/08\354\236\245/\354\235\264\354\247\204\355\230\201.md" @@ -0,0 +1,74 @@ +# 8장. 다양한 데이터 기술을 적절하게 사용하는 방법 + +## 데이터는 결국 선택의 문제다 + +> 데이터 관리에 완벽한 해결책은 없고, 특정 용도에 적합한 해결책만 있다. + +8장에서 제일 기억에 남는 말이다. 5장의 테스트 피라미드, 6장의 점진적 정신 모델과 같은 결이라고 느꼈다. +어떤 걸 쓸지 고민할 때는 지금 요구사항에서 뭘 얻고 뭘 포기하는지부터 따져봐야 한다. + +FE 개발자는 DB를 직접 고르는 일이 드물다. 하지만 BE가 어떤 저장소와 일관성 모델을 골랐는지 알면 내가 받는 데이터의 성격이 보인다. + +- 최종 일관성 기반이면 방금 쓴 데이터가 목록에 바로 안 보일 수 있다. +- 강한 일관성이 필요한 도메인이면 API가 느리거나 실패할 수 있다. + +이걸 모르면 설계상 당연한 동작을 버그로 오해할 수 있다. + +## 형식과 시간 데이터 + +JSON은 FE에게 가장 자연스러운 형식이지만 한계가 있다. 주석이 없고, 날짜 타입이 없고, 이진 데이터는 인코딩이 필요하다. +그중 날짜가 가장 위험하다고 느꼈다. 책의 원칙은 단순하다. + +- 저장과 교환은 UTC, ISO 8601 +- 표시할 때만 로컬 시간대로 변환 +- 직접 구현하지 말고 검증된 라이브러리 사용 + +출석 마감처럼 시간이 곧 결과인 기능에서는 서버 시간과 클라이언트 시간이 어긋나는 것 자체가 장애가 된다. +그래서 시간 기준은 서버에 두는 게 맞다고 생각한다. + +## 일관성 모델과 캐시, FE에서도 똑같이 일어나는 일 + +책에서 설명하는 캐시 전략은 FE에서도 비슷하게 보인다. + +- cache-aside + TTL은 React Query의 staleTime으로 조회하는 방식과 비슷하다. (최종 일관성) +- 낙관적 업데이트는 write-back처럼 먼저 반영하고 나중에 확정한다는 점이 비슷하다. 대신 실패하면 롤백이 필요하다. + +캐시를 넣기 전에 책이 던지는 질문이 실용적이었다. + +- 이 데이터가 얼마나 자주 바뀌는가? +- 오래된 데이터를 보여줬을 때 손실은 얼마나 큰가? +- 지금 병목이 실제로 있는가? + +실시간 가격처럼 오래된 값이 곧 손실인 데이터는 캐시가 이득보다 위험이 크다. +출석 현황 같은 실시간 데이터에서 폴링과 SSE를 비교했던 것도 결국 같은 질문이었다. +얼마나 최신이어야 하는지를 먼저 정해야 방식이 정해진다. + +## 질의 성능, 페이지네이션은 FE도 관련 있다 + +- `SELECT *` 금지, 필요한 컬럼만 조회 +- OFFSET 페이지네이션은 뒤로 갈수록 느리다. 대안은 키셋(`WHERE id > last_seen_id`), 총 개수 캐시, 무한 스크롤이다. + +총 페이지 수가 꼭 필요한 UI인지, 무한 스크롤로 충분한지는 UI 결정인데, 이 결정이 BE의 COUNT 쿼리 비용을 없앨 수도 있다. + +N+1 문제도 FE에서 비슷하게 생긴다. 목록 API를 1번 부르고 상세 API를 N번 부르는 경우가 BE 쿼리 N+1과 같은 구조다. + +그리고 "느리다"는 추측하지 말고 관측해야 한다. +BE에는 EXPLAIN과 분산 추적이 있고, FE에는 Network 탭과 Performance 탭, 에러 모니터링이 있다. + +## 스키마 변경과 이전, 하위 호환이 핵심 + +스키마를 버전 관리하는 건 코드를 Git으로 관리하는 것과 같다. (Flyway, 순차 실행, 멱등성) +FE 입장에서 와닿은 부분은 하위 호환이다. + +- BE 스키마와 API가 바뀔 때 FE 배포 순서가 어긋나면 그 사이에 장애가 난다. +- 그래서 필드를 한 번에 바꾸지 않고, 추가해서 둘 다 지원한 뒤 FE를 옮기고 나중에 제거하는 순서가 안전하다. +- 이중 쓰기, 롤백 계획, 작은 샘플 먼저 검증하는 방식은 디자인 시스템 v1에서 v2로 옮기는 작업에도 쓸 수 있을 것 같다. + +## 내가 가져갈 것 + +1. 기술 이름보다 요구사항(변경 빈도, 일관성, 읽기/쓰기 비율)을 먼저 적어본다. +2. 오래된 데이터를 보여줘도 되는지부터 정하고, 그다음에 캐시와 실시간 방식을 고른다. +3. 목록 UI를 정할 때는 BE 비용(COUNT, OFFSET)도 같이 생각해 보려 한다. +4. 느리다고 느껴지면 추측하기 전에 먼저 관측한다. +5. 변경은 하위 호환으로 하고, 이전은 작게 시작해서 검증한다. +6. 먼 미래를 가정한 설계보다 지금 문제에 맞는 선택을 한다. 어떤 결정도 최종이 아니다.