Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions 08장/이진혁.md
Original file line number Diff line number Diff line change
@@ -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. 먼 미래를 가정한 설계보다 지금 문제에 맞는 선택을 한다. 어떤 결정도 최종이 아니다.
Loading