[Next Table Order #5] 주문이 많아지면 서비스는 버틸 수 있을까

2025. 3. 5.

[Next Table Order #5] 주문이 많아지면 서비스는 버틸 수 있을까

솔직히 말하면, 나도 처음엔 별 문제 없다고 생각했다.
"주문이 바뀌면 그냥 전체 목록 다시 불러오면 되지 않나?"

그리고…
미래의 내가 피눈물을 흘리게 됐다.

이 방식이 왜 문제였을까?
한번 제대로 뜯어보자.


1️⃣ 주문이 많아지면 터진다?

처음에는 단순하게 갔다.
"주문 상태가 바뀌면 그냥 API 요청해서 다시 가져오면 되지."

useEffect(() => {
  const eventSource = new EventSource('/api/admin/orders/stream');

  eventSource.onmessage = () => {
    fetchOrders(); // SSE 이벤트가 오면 전체 주문을 다시 불러옴
  };
}, []);

이 방식, 처음엔 완벽해 보였다.
주문이 몇 개 없을 땐 빠르게 동작했거든.

그런데 말이다…
주문이 많아질수록 느려지고, 무거워지고, 결국 서버가 터졌다.

💥 문제 1: 네트워크 과부하
→ 주문 하나 바뀔 때마다 모든 주문을 다시 불러옴
→ 주문이 많아질수록 트래픽 폭발

💥 문제 2: 서버 부담 증가
→ 주문 1개 바뀌었는데 10만 개 주문을 다시 조회 🤯

💥 문제 3: 프론트엔드 렌더링 문제
→ 필요 없는 데이터까지 불러오면서 불필요한 리렌더링

이건 실시간이 아니라 트래픽 과부하 시스템이었다.


2️⃣ 해결책: 바뀐 주문만 감지하면 안 될까?

문제를 마주하고 나니, 이건 아니다 싶었다.
"주문이 하나 바뀌었는데, 굳이 다 불러올 필요 있나?"

그래서 이벤트 로그 테이블을 도입했다.
✅ 주문 상태나 결제 상태가 바뀔 때 orders 테이블을 직접 감지하지 않는다.
✅ 대신 event log 테이블에 로그를 남기고, SSE는 orders가 아니라 event log만 감지하도록 수정했다.

CREATE TABLE order_events (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    order_id UUID REFERENCES orders(id) ON DELETE CASCADE,
    event_type TEXT NOT NULL,  -- ex) 'order_status_updated', 'order_paid'
    created_at TIMESTAMPTZ DEFAULT now()
);

이제 SSE 이벤트는 orders 테이블이 아니라 event log 테이블만 감지하면 된다.

useEffect(() => {
  const eventSource = new EventSource('/api/admin/orders/stream');

  eventSource.onmessage = async (event) => {
    const [eventType, orderId] = event.data.split(':');

    if (eventType === 'order_paid' || eventType === 'order_status_updated') {
      fetchUpdatedOrder(orderId); // 특정 주문만 다시 불러오기
    }
  };
}, []);

🚀 이제 바뀐 주문만 다시 불러온다.
📌 트래픽은 줄이고, 실시간성은 유지하는 최적화 완료!


3️⃣ 실험 - 정말 빨라졌을까?

말로만 하면 안 되지.
실제 데이터로 비교 실험을 진행했다.

응답 시간 비교 실험

주문 개수 기존 방식 (전체 refetch) 새로운 방식 (이벤트 로그 기반)
100개 5ms 3ms
10,000개 150ms 5ms
1,000,000개 💀 3.2s (서버 과부하) 6ms

결과:
✅ 기존 방식: 주문 개수가 많아질수록 응답 시간이 급격히 증가
✅ 최적화 방식: 이벤트 로그를 활용해 항상 일정한 응답 속도 유지


4️⃣ 결론 - 실시간 시스템, 진짜 실시간으로 만들자

🚀 "실시간이라고 무조건 다 가져올 필요는 없다!"
🚀 "변경된 데이터만 빠르게 가져오면 된다!"
🚀 "이벤트 로그 테이블을 활용하면 성능을 획기적으로 개선할 수 있다!"

이제 1억 개의 주문이 들어와도 문제없다.
🔥 "진짜 실시간"이 무엇인지 고민한 결과다.