Django의 일반 HTTP 응답은 전체 콘텐츠를 메모리에 로드하여 대용량 데이터나 실시간 스트리밍에 비효율적입니다. 💾
StreamingHttpResponse는 대용량 응답(예: CSV 내보내기) 처리 및 실시간/동적 콘텐츠(예: 서버 전송 이벤트) 전송을 위해 설계되었습니다. 🚀
이 기능은 고급 사용 사례에 해당하며, WSGI(동기) 및 ASGI(비동기) 환경에서 동작 방식에 차이가 있음을 인지해야 합니다. ⚠️
StreamingHttpResponse는 제너레이터 함수와 같은 이터러블을 인자로 받아 데이터를 청크 단위로 즉시 클라이언트에 스트리밍합니다. 🔄
일반 HttpResponse와 달리 StreamingHttpResponse는 HttpResponse의 서브클래스가 아니며, HttpResponseBase라는 공통 기반 클래스를 공유합니다. 🌳
일반 응답은 전송 후 연결을 닫지만, 스트리밍 응답은 모든 데이터 청크가 전송될 때까지 클라이언트와의 연결을 유지합니다. 🔗
스트리밍 응답은 전체 응답 크기를 미리 알 수 없으므로 Content-Length HTTP 헤더를 포함하지 않습니다. 📏
대용량 CSV 내보내기 시 일반 HttpResponse를 사용하면 모든 데이터를 메모리에 로드하고 쿼리셋을 캐싱하여 높은 메모리 사용량과 긴 응답 대기 시간을 초래합니다. 📉
StreamingHttpResponse를 활용하면 queryset.iterator()와 제너레이터를 통해 대용량 데이터를 메모리 효율적으로 스트리밍할 수 있으며, 특히 서버 측 커서(Postgres, Oracle)를 사용하면 청크 단위로 데이터를 가져와 성능을 최적화할 수 있습니다. 💡
queryset.iterator()는 쿼리셋 결과를 내부적으로 캐싱하지 않아 대량의 객체를 한 번만 접근할 때 메모리 사용량을 크게 줄일 수 있지만, 여러 번 접근해야 하는 경우에는 적합하지 않습니다. ♻️
데이터베이스 드라이버 수준에서 청크 크기를 조절하여 데이터베이스와의 왕복 횟수를 줄일 수 있지만, 청크 크기가 커지면 메모리 사용량이 증가하므로 적절한 균형을 찾아야 합니다. ⚖️