본문으로 건너뛰기
&Dolphin
기술 블로그
설계

스트리밍 응답의 진짜 비용은 UX 가 아니라 트랜잭션이다

글자가 흐르는 동안 커넥션도 함께 붙잡혀 있다.

목차

스트리밍을 붙이면 체감 속도가 좋아진다. 그건 맞다. 문제는 그 아래에서 일어난다.

커넥션이 응답 시간만큼 붙잡힌다

java
@Transactional
public void answer(Long chatId, String question) {
    var history = repository.findHistory(chatId);   // DB
    llm.stream(question, history, chunk -> emit(chunk));  // 20초
    repository.save(new Message(...));              // DB
}

이 코드는 20초 동안 DB 커넥션을 쥐고 있다. 동시 사용자가 풀 크기를 넘는 순간 LLM 과 무관한 요청까지 전부 대기한다. 장애는 채팅이 아니라 로그인에서 먼저 보인다.

경계를 셋으로 나눈다

  1. 읽기 — 필요한 것을 읽고 트랜잭션을 닫는다
  2. 호출 — DB 없이 스트리밍한다
  3. 쓰기 — 다 받은 뒤 짧은 트랜잭션으로 저장한다

중간에 끊긴 응답을 어떻게 다룰지 정한다

사용자가 탭을 닫으면 2번 도중에 끝난다. 그때 저장하지 않으면 사용자는 "답을 봤는데 기록에 없다" 를 겪는다. 부분 응답을 저장하되 완결 여부를 표시하는 편이 낫다.

스트리밍은 화면의 문제가 아니라 트랜잭션 경계의 문제다.

스트리밍 응답의 진짜 비용은 UX 가 아니라 트랜잭션이다 | &Dolphin