이 단계에서 얻는 것
이 단계는 “스프링을 안다”에서 한 단계 더 나아가, 데이터/정합성/성능을 근거 있게 다룰 수 있게 만드는 구간입니다.
- DB 성능 감각: 인덱스/실행 계획을 보고 “왜 느린지”를 추적하고, 튜닝 방향을 세울 수 있습니다.
- 정합성 감각: 트랜잭션/격리 수준/락/데드락을 이해해서 “깨지지 않는” 설계를 할 수 있습니다.
- 캐시/메시징 감각: Redis 캐시 패턴, Kafka/Outbox 같은 비동기 설계를 “언제/왜” 쓰는지 연결할 수 있습니다.
- 데이터 관측/운영 감각: “느린 쿼리/락 대기/캐시 미스/컨슈머 지연” 같은 신호를 지표/로그로 연결합니다.
이 모듈을 보는 방법
이 페이지 아래에 연결된 글이 순서대로 정렬됩니다.
- 인덱스/실행 계획으로 “느림”을 해부하고
- 트랜잭션/락으로 “정합성”을 확보하고
- 캐시/메시징으로 “확장/운영”을 설계하는 흐름으로 읽으면 좋습니다.
각 글의 연습은 “완성 프로젝트”가 목표가 아니라, 작은 재현/관찰로 감각을 만드는 것이 목표입니다.
왜 이런 순서인가
데이터 관련 문제는 결국 다음 순서로 좁혀집니다.
- 쿼리가 느리다 → 실행 계획/인덱스/풀/락 대기 중 어디가 원인인지 분해
- 정합성이 깨진다 → 트랜잭션 경계/격리 수준/동시성 제어를 재설계
- 트래픽이 커진다 → 캐시/비동기/샤딩 같은 확장 전략을 선택
그래서 “인덱스/EXPLAIN → 트랜잭션/락 → 캐시/메시징 → 설계 문제” 순서를 기본으로 둡니다.
이 단계의 핵심 주제
- 인덱스/실행 계획/쿼리 튜닝
- 트랜잭션/격리 수준/락/데드락
- 캐시 전략(Cache-Aside/Write-Through/Stampede)
- 메시징/이벤트 기반 설계(Kafka, Outbox)
- 데이터 관측(슬로우 쿼리/락 대기/컨슈머 지연)
데이터 변경 파이프라인으로 확장하기
데이터 시스템을 공부할 때 인덱스와 트랜잭션까지만 보면 “DB를 잘 쓰는 법"에서 멈추기 쉽습니다. 실무에서는 그다음 질문이 더 자주 나옵니다. 관리자가 엑셀 20만 행을 올리면 어떻게 처리할지, 외부 파트너 파일을 다시 받으면 중복 반영을 어떻게 막을지, 배치가 절반만 성공했을 때 어떤 기준으로 재처리할지 같은 문제입니다.
이런 작업은 단순 CRUD가 아니라 상태를 가진 데이터 변경 파이프라인으로 봐야 합니다. 요청 하나가 오래 걸리고, 일부 row가 실패하며, 사용자가 같은 파일을 다시 올리고, worker가 온라인 DB와 자원을 공유하는 상황을 모두 정상 경로로 다룹니다. 그래서 이 모듈의 후반부는 쿼리 튜닝 → 정합성 제어 → 비동기 처리 → 재처리/대조 순서로 확장해서 읽는 편이 좋습니다.
추천 흐름은 아래와 같습니다.
- Async Request-Reply Operation Resource로 긴 작업을 동기 응답에서 분리합니다.
- Bulk Import Job, 대량 업로드 운영 설계로 파일 업로드, 검증, dry-run, apply, row error를 하나의 job 모델로 묶습니다.
- Batch Idempotency/Reprocessing으로 같은 입력이 다시 들어와도 같은 업무 효과가 두 번 나지 않게 만듭니다.
- Workload-aware Queue Partitioning으로 대형 import와 짧은 온라인 후처리 작업이 같은 큐에서 서로 막지 않게 분리합니다.
- Reconciliation Ledger Pipeline으로 원장, 파생 테이블, 외부 시스템 사이의 불일치를 주기적으로 확인합니다.
실무 판단 체크리스트
- 처리 시간이 5초를 넘거나 row 수가 1,000개를 넘을 수 있으면 동기 API 대신 operation resource를 검토했는가?
- 업로드 성공, 검증 성공, 실제 반영 성공을 서로 다른 상태로 나누었는가?
- 파일 단위 fingerprint와 row 단위 effect key를 분리해 중복 업로드와 중복 반영을 따로 막는가?
- 부분 성공 허용률, 자동 중단 기준, 사람 승인 기준이 숫자로 정해져 있는가?
- 대형 job이 온라인 트래픽의 DB CPU, lock wait, queue lag를 악화시키면 자동 throttle 또는 pause할 수 있는가?
- 재처리 후에는 성공 로그뿐 아니라 reconciliation이나 샘플 대조로 실제 side effect를 확인하는가?
이 관점을 잡으면 데이터 시스템 학습이 “쿼리를 빠르게 만든다"에서 끝나지 않습니다. 느린 쿼리, 락, 캐시 미스, 큐 지연, 재처리, 데이터 불일치를 하나의 운영 흐름으로 연결할 수 있습니다. 특히 백오피스 import, 정산, 권한 변경, 파트너 동기화처럼 장애가 조용히 데이터 오염으로 번지는 기능에서는 이 흐름이 필수에 가깝습니다.
조회 결과를 운영 산출물로 바꾸기
데이터 시스템의 다른 축은 “많이 쓰는 것"이 아니라 “많이 읽어 내보내는 것"입니다. 관리자 화면의 전체 다운로드, 정산 파일 생성, 감사 로그 반출, 고객 데이터 export는 처음에는 단순 CSV 기능처럼 보이지만, 규모가 커지면 긴 쿼리, replica lag, 개인정보 노출, 재생성 불일치, 만료되지 않는 링크 문제가 한꺼번에 붙습니다.
그래서 import와 마찬가지로 export도 상태가 있는 파이프라인으로 다뤄야 합니다. 화면 조회와 파일 생성은 목적이 다릅니다. 화면 조회는 현재 상태를 빠르게 보여주는 것이 목표지만, export는 나중에 “어떤 조건으로, 어느 시점의 데이터를, 누가, 어떤 권한으로 받았는지” 설명할 수 있어야 합니다.
추천 흐름은 아래와 같습니다.
- HTTP QUERY, 복잡한 읽기 API가 GET과 POST 사이의 빈칸을 메운다로 즉시 응답 가능한 복잡한 조회와 긴 작업의 경계를 잡습니다.
- Cursor Pagination Consistency로 정렬, snapshot, 중복/누락 없는 탐색 기준을 먼저 정리합니다.
- 대용량 데이터 Export 파이프라인으로 전체 다운로드를 job, artifact metadata, signed URL, 감사 로그로 분리합니다.
- Object Storage와 파일 관리로 파일 저장, 만료, 접근 제어, checksum 기준을 보강합니다.
- Tamper-Evident Audit Log로 민감 export의 요청·생성·다운로드 기록을 나중에 검증 가능한 형태로 남깁니다.
Export 판단 체크리스트
- 결과가 1만 행 또는 10MB를 넘을 수 있으면 동기 다운로드를 기본값으로 두지 않는가?
- 화면 필터와 export 필터가 같은 계약을 쓰고,
filter_hash와schema_version을 남기는가? - 파일 생성 시점뿐 아니라 다운로드 시점에도 현재 권한을 다시 확인하는가?
- signed URL TTL, 파일 보관 기간, 민감 컬럼 마스킹 기준이 숫자로 정해져 있는가?
- heavy export worker가 primary DB와 온라인 트래픽을 밀어내지 않도록 replica, 큐, 동시성을 제한하는가?
- CSV formula injection, timezone, locale, null 표현처럼 파일 소비자가 겪는 문제를 schema 문서에 적었는가?
이 경로를 붙이면 데이터 시스템 모듈이 “입력 파이프라인"에만 치우치지 않습니다. import는 외부 데이터를 안전하게 들여오는 문제이고, export는 내부 데이터를 책임 있게 내보내는 문제입니다. 둘을 같이 보면 snapshot, 멱등성, 감사 로그, object storage, queue throttling 같은 운영 기준이 반복해서 등장한다는 점이 보입니다.
미니 실습
- EXPLAIN 읽기: 느린 쿼리를 만들고 실행 계획으로 병목 찾기
- 락/데드락 재현: 트랜잭션 두 개로 락 대기 상황 만들기
- 캐시 스탬피드 방지: TTL 지터 또는 락으로 붐 방지 실험
- Import job 모델링: 업로드/검증/apply/부분 실패 상태와 row error 코드를 표로 정의
- Export job 모델링: 전체 다운로드를 accepted/running/uploading/available/expired 상태와 artifact metadata로 나누기
- 재처리 안전성 점검: 같은 파일을 두 번 실행해도 중복 효과가 나지 않는 멱등 키 설계
완료 기준 (다음 단계로 넘어가기 전)
- EXPLAIN을 보고
ALL/filesort/temporary같은 위험 신호를 읽고, 인덱스/쿼리 개선 방향을 말로 설명할 수 있다 - 격리 수준/락 때문에 생기는 현상(데드락/락 대기)을 로그/지표로 구분할 수 있다
- 캐시를 “붙여서 빨라졌다”가 아니라, 키/TTL/무효화/스탬피드까지 포함해 설계할 수 있다
- 대량 데이터 변경을 동기 API, 비동기 operation, 배치 job 중 어디에 둘지 판단할 수 있다
- 대용량 export를 동기 다운로드, QUERY, 비동기 export job 중 어디에 둘지 판단할 수 있다
- 재처리와 reconciliation 기준을 함께 설명할 수 있다