포스트

C# .NET vs Python FastAPI 이미지 업로드 서버 구조: Redis, Docker 없이도 가능할까?


이미지 업로드 API가 느리고, 확장성이 떨어지며, 구조를 바꾸고 싶어도 어디서부터 손대야 할지 막막하다면?

sticker

.NET 기반 회사에서 자주 겪는 문제지만, 해결 방법은 언어가 아니라 설계 방식과 구조에 있습니다.

sticker

이 글에서는 이미지 업로드 API 를 개선할 수 있는 다음 세 가지 방식을 짚어보겠습니다.

sticker

  1. C# .NET만으로도 충분히 개선할 수 있는 방법,

  2. C# .NET + Redis 구조,

  3. Python FastAPI + Redis + Docker 구조


1. 현재 상태: 전형적인 느린 이미지 업로드 구조

C# .NET 기반 소규모 회사에서 자주 사용하는 방식은 다음과 같습니다.

1
2
3
1. 클라이언트가 이미지 업로드 요청을 보냄
2. 서버가 파일을 받아 로컬 경로에 동기적으로 저장
3. 저장 완료 후 응답 반환
  • 디스크 I/O 병목
  • 비동기 처리가 없음
  • 처리 순서가 직렬이라 응답 지연
  • 서버 확장 시 파일 공유 문제

  • 업로드는 메모리에 저장 (MemoryStream 사용)
  • 메모리 큐에 저장 요청 추가
  • 백그라운드 워커가 큐에서 꺼내 비동기로 디스크에 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 업로드 컨트롤러
[HttpPost("upload")]
public async Task Upload(IFormFile file)
{
    var memStream = new MemoryStream();
    await file.CopyToAsync(memStream);
    ImageQueue.Enqueue(new UploadItem { Name = file.FileName, Data = memStream.ToArray() });
    return Ok("Queued");
}

// 백그라운드 서비스
public class FileWriter : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            if (ImageQueue.TryDequeue(out var item))
            {
                var path = Path.Combine("C:\\Images", item.Name);
                await File.WriteAllBytesAsync(path, item.Data, token);
            }
            await Task.Delay(10);
        }
    }
}
  • 사용자 응답 속도 개선
  • 디스크 저장과 업로드 요청 분리
  • 별도 인프라 필요 없음

  • 업로드 요청 → 메모리 저장
  • Redis 큐에 저장 요청 (RPUSH)
  • 백그라운드 서비스가 Redis에서 **LPOP**하여 디스크에 저장
  • 여러 서버가 동시에 Redis 큐를 공유 가능
  • 분산 처리 가능
  • 서버 확장 시 세션이나 파일 상태 공유에 유리
  • Redis 설치 및 연결 관리 필요
  • 도입 학습 곡선 존재

4. 방법 3: Python FastAPI + Redis + Docker 조합 구조 요약

1
2
3
4
1. FastAPI 서버에서 이미지 업로드 요청 받음
2. Redis에 큐로 저장 요청 (썸네일, 메타 정보 등 포함)
3. Celery 워커가 비동기적으로 파일 처리 및 저장
4. Docker로 배포 구성
  • 완전히 분리된 구조: API 서버, 저장 로직, 큐 분리
  • 빠른 확장성과 배포 자동화 가능
  • Python 생태계의 유연함 (OpenCV, PIL 등 이미지 처리 도구 풍부)
  • Docker, Redis, Celery 등 학습과 설정 시간이 필요
  • 단순한 업로드만 필요한 경우 과한 설계일 수 있음

5. 3가지 방식 비교

항목.NET 단독.NET + RedisFastAPI + Redis + Docker
개발 난이도낮음중간높음
준비 시간짧음 (1~3시간)중간 (반나절~1일)길음 (1~2일)
구성요소 수1 (ASP.NET)2 (ASP.NET, Redis)3~4 (FastAPI, Redis, Celery, Docker)
확장성낮음높음 (멀티서버 가능)매우 높음 (마이크로서비스)
파일 처리 속도개선 가능빠름매우 빠름
기술 도입 부담없음Redis 운영 필요컨테이너 및 DevOps 필요

sticker

  • 대부분 **단일 IIS 서버, 하나의 프로젝트 구조**
  • 로컬 저장소, 세션, 캐시를 모두 메모리에 종속
  • 분산 환경에서의 **상태 공유 도구를 도입하지 않음**
  • Docker나 Redis 도입에 대한 **거부감 또는 무지**

sticker

반면 Python은 처음부터 “작은 모듈을 조합하여 큰 시스템을 만든다”는 철학이 강해서 처음부터 분리 설계가 자연스럽습니다.


✅ 최종 결론

목적추천 방식
지금 당장 느린 업로드 문제 개선.NET MemoryStream + Queue + Worker 구조
Redis를 도입할 수 있고, 멀티 서버 확장이 필요.NET + Redis 구조
새로운 이미지 서버를 독립적으로 만들고 싶다FastAPI + Redis + Docker 구조

언어의 한계가 아니라, 사용하는 방식의 한계입니다. ** **.NET만으로도 충분히 좋은 구조를 만들 수 있고, ** **Redis와 Docker도 필요할 때 천천히 도입하면 됩니다. ** **그리고 python을 도입한다면 Fastapi를 사용한 독립적인 이미지 서버도 고려할 수 있습니다. ** **감사합니다. **

sticker


#닷넷개발 #CSharp #ASPNetCore #이미지업로드 #파일서버 #서버성능개선 #레디스 #Redis도입기 #Docker사용법 #FastAPI예제 #파이썬서버 #PythonBackend #백엔드아키텍처 #파일업로드속도 #MemoryStream #비동기처리방법 #Queue처리 #백엔드성능 #분산서버구조 #마이크로서비스 #서버확장성 #서버구조개선 #모놀리식에서마이크로서비스로 #개발회사기술스택 #실무개발팁 #실전아키텍처 #IT개발팁 #웹서버구조 #개발자블로그 #백엔드시스템

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.