[번역]WCF에서 대량의 데이터 전송시 고려사항

최근, WCF 서비스와 클라이언트간에 대용량의 파일이나 데이터를 전송하는것과 관련된 질문을 많이 받는다. 질문은 다음과 같은 다양한 형식으로 온다.

  • 서비스에서 클라이언트로 수GB 사이즈의 파일을 어떻게 전송하나요?
  • 대용량의 파일을 전송하려면 꼭 MTOM(Message Transmission Optimization Mechanism, 메세지 전송 최적화 매커니즘)을 사용해야 하나요?
  • 제가 거대한 객체 그래프를 가지고 있고, 이 것을 회선으로 전송하고 싶은데 어떻게 해야하나요?

그래서, 지금부터 대용량의 데이터를 전송하는것과 관련된 문제점을 살펴보고 WCF에서 제공하는 해결책에 대해 알아보도록 하겠다.

 

문제 : 대역폭 사용(Bandwidth Utilization)

 기가바이트(GB) 단위의 데이터를 전송하는 것은 많은 대역폭을 사용해야 한다는 뜻이다. 100 Mbit 또는 1 Gbit 랜 환경에서 드물게 대역폭을 사용한다면 문제가 되지 않을 수 있다. 그러나 대역폭이 모자라거나 비용이 지불되어야 하는 상황에서는 반드시 문제가 된다. Base64를 사용하여 메세지를 텍스트 XML형태로 인코딩하는 interop 시나리오에서는 사이즈가 1/3정도 더 증가하기 때문에 더욱 문제가 된다. 시나리오에 따라 이 문제를 해결하는 3가지 해결책이 있다.

  1. 데이터가 텍스트이거나 Base64를 사용하여 텍스트 형태로 인코딩되었다면 압축(Compression)하는 방법이 있다. 압축/압축풀기는 사용자 WCF 인코더/디코더를 사용하여 구현할 수 있다. (IIS6에서는 기본으로 제공한다.)

  2. interop가 필요하지 않을 때는 텍스트 인코딩을 사용하지 않을 수 있다. WCF는 바이너리 데이터를 전송할 때, 텍스트 인코딩보다 훨씬 더 많은 대역폭을 효율적으로 사용할 수 있는 바이너리 인코딩을 제공한다.

  3. 만일 interop이 필요하고, 대량의 이진 컨텐츠를 전송해야 한다면, MTOM을 사용할 수 있다. MTOM은 Base64로 인코딩하지 않고 SOAP envelope 외부에서 이진 컨텐츠를 전송할 수 있다.

 

문제 : 메모리 사용(Memory Utilization)

기본적으로, WCF는 WS-ReliableMessaging과 WS-Security와 같은 buffered 메세지를 필요로 하는 프로토콜을 지원하기 위헤 메세지를 버퍼링한다. 만일 동시에 매우 큰 메세지를 전송하거나 받는일이 발생하면 out-of-memory 현상이 발생할 수 있다. 다행히, WCF는 out-of-memory 예외없이 무한의 대용량 메세지를 전송할 수 있도록 HTTP, TCP, Named Pipe 상에서의 스트리밍을 지원한다. 실제로, 메세지 사이즈는 Int64.MaxValue값인 9,223,372,036,854,775,807로 설정된다.

 

문제 : 장애에서 복구(Recovering from Failures)

만일 4GB의 스트림이 전송되고 있는 도중에 TCP 연결이 실패하게 되면 어떻게 될까? 프로그램에서는 예외를 캐치(catch)하고 복구해야 할 것이다. 그리고 한편으로 송신 프로그램은 수신프로그램이 마지막으로 수신한 바이트가 무었인지 알아내고 처리할 것이다.

다른 대안은 연결 실패를 복구하기 위해 Reliable Messaging을 사용하는 것이다. RM은 실패를 감지하여 연결을 재성립해주고 실패한 메세지를 다시 전송할 것이다. 이때의 문제점은 스트리밍 시, 모든 스트림이 하나의 메세지여서 근본적으로 재전송이 처음부터 시작된다는 것이다. 또다른 문제점은, RM은 버퍼링을 필요로하기 때문에 스트리밍시에는 동작하지 않는 다는 것이다. 이때의 해결책은 chunking을 사용하는 것이다. chunking은 송신 어플리케이션이 4GB의 파일을 4KB 크기의 메세지 1만개로 분리하고 그 메세지들을 버퍼 모드에서 전송하는 방법이다. 수신 어플리케이션에서는 받은 1만개의 메세지를 다시 4GB의 파일로 생성한다. 이제, RM은 4KB의 메세지만을 버퍼링할 것 이다. 전송이 실패하게 되면, RM은 자동으로 1개 또는 몇개의 실패한 메세지만 자동으로 재 전송할 것이다. chunking/dechunking 기술은 어플리케이션 프로그램에서 Stream을 사용하게 되면 하부에서 chunking을 사용하게 되므로 숨겨져 있다. 이것이 PDC에서 보여줬었던 chunking channel 샘플이다. RM에서 chunking을 사용함으로써 프로토콜의 오버해드가 증가하기 되므로 직접 스트리밍하는것 보다 결과가 안 좋을 것이다. 그러나, 당신이 4GB 전송을 거의 다 마쳐가는 상황이면서 연결 실패가 될 것 같은 상황이라고 생각해 보라!

 

요약 및 결론

  1. 서비스와 클라이언트가 둘다 WCF이거나 상호운용이 필요하면서 MTOM이면 바이너리 인코딩을 사용하라
  2. 텍스트 인코딩을 써야만 하는 상황이거나 데이터가 압축률이 좋은 형태라면 압축을 고려해라
  3. 스트리밍을 사용하거나, 신뢰성일 필요한 경우이면 chunking을 사용하라. 한가지 주의해야 할 점은 방향이다. 단지 한개의 파라미터만 존재하고, System.IO.Stream으로부터 상속받은 타입이어야 한다.

 

출처
http://blogs.msdn.com/yassers/archive/2006/01/21/515887.aspx

zemna

Programmer/Web/Mobile/Desktop

You may also like...

Leave a Reply