« Previous Next »

Thread: ARR HTTP Streaming Performance

Last post 05-22-2009 4:10 PM by karl_mcguinness. 3 replies.

Average Rating Rate It (5)

RSS

Page 1 of 1 (4 items)

Sort Posts:

  • 05-20-2009, 7:04 PM

    ARR HTTP Streaming Performance

    I am trying to determine the proxy overhead of ARR v1.0 RTM in a binary HTTP streaming scenario.  I have developed a very simple test WCF application that takes a GET request via a URI template for a number of bytes and streams the requested number of bytes back to the client.  The test environment is also simple.  1 Web Server running the WCF Service, 1 Web Server running ARR, and a client all connected on a dedicated 1 GB switch.

    The ARR Configuration is simple

    1 Rewrite Rule

    <globalRules>
          <rule name="WcfWebFarmRoute" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
            <match url="WcfPerfTest/*" />
            <conditions>
            </conditions>
            <action type="Rewrite" url="http://WcfWebFarm/{R:0}" />
          </rule>
        </globalRules>
      </rewrite>

     1 WebFarm

      <webFarms>
            <webFarm name="WcfWebFarm" enabled="true">
                <server address="wcfhost.test.com" enabled="true">
                    <applicationRequestRouting httpPort="80" />
                </server>
                <applicationRequestRouting>
                    <protocol minResponseBuffer="0"  />
                </applicationRequestRouting>
            </webFarm>
            <applicationRequestRouting>
                <hostAffinityProviderList>
                    <add name="Microsoft.Web.Arr.HostNameRoundRobin" />
                    <add name="Microsoft.Web.Arr.HostNameMemory" />
                </hostAffinityProviderList>
            </applicationRequestRouting>
        </webFarms>

    I have tried to follow the advice detailed in the posts below for streaming support.

    http://forums.iis.net/p/1154087/1888966.aspx

    http://forums.iis.net/p/1154087/1888966.aspx

     The IIS Configuration UI for the proxy does not allow 0 as a valid value, so the applicationHost file was edited manually.  I have tried setting both responseBufferLimit="0" as well as minResponseBuffer="0".  My test results have not show a difference.

     The client connecting through the ARR proxy to the wcf host is able to send 1000 requests for 512 KBytes in 46359.8026147287 ms, 11044 KB/sec

    The same client connecting directly to the WCF host (no ARR) is able to send 1000 requests for 512 KBytes in 6667.43178952004 ms, 76791 KB/sec

    Is there any settings/options to minimize the overhead I am experiencing.  It appears that the streaming option minResponseBuffer="0" does not seem to work.  The overhead I am experiencing seems too high for this simple test scenario.  I cannot find documentation on how ARR is implemented to understand the internal behaviour of the ARR proxy. Is there some instrumentation available to understand where the overhead is occuring in the request/response pipeline?

    Any help would be much appreciated.

     

     

  • 05-21-2009, 9:49 PM In reply to

    • wonyoo
    • Top 50 Contributor
    • Joined on 12-15-2007, 6:46 PM
    • Posts 125

    Re: ARR HTTP Streaming Performance

    karl_mcguinness

    Thanks for the detailed info.

    In your case, since you are doing the testing on a high speed network (1GB), I don't believe that setting responseBufferLimit to 0 is going to help.  In fact, it will hurt your throughput (because the rate at which the data is transmitted is faster than the code that is proxying the data.)

    I've done some basic testing using a similar set up as yours (1GB link, 512KB response size). 

    • My baseline (going directly to the source): 115 req/sec
    • ARR with default config: 83 req/sec (28% overhead)
    • ARR with responseBufferLimit 0: 70 req/sec (40 % overhead)

    Note that using the default value will increase your time to first byte time (since it fills up the buffer), but you should be able to get higher throughput.  So I would recommend using the default settings and rerun your test to see if you are seeing around 28% overhead.

    That said, for handling dynamic requests and/or web services, ARR's real value is around scalability and availability.  Using 2 content servers, I am able to increase the overall capacity well above 1 web service server with no additional overhead (beyond 28%).  ARR makes up this overhead in other ways, esp. in non-web services requests when the requests are mixture of dynamic and static contents via caching and also running in a hybrid mode (where ARR is both a proxy and a content server.)

  • 05-22-2009, 3:27 PM In reply to

    • anilr
    • Top 10 Contributor
    • Joined on 05-23-2006, 6:13 PM
    • Redmond, WA
    • Posts 2,343

    Re: ARR HTTP Streaming Performance

    I am not sure that you are comparing apples to apples - is your WCF service actually streaming the response, i.e. is it calling winsock multiple times with small chunks of "real-time" data?  Or is it just sending the 512kB response in one send to the client.  By setting minResponseBuffer to 0 in ARR, you are forcing ARR to send the response in multiple small chunks to winsock which is going to affect the latency of the response (6ms on average to 46ms on average).

    Anil Ruia
    Senior Software Design Engineer
    IIS Core Server
  • 05-22-2009, 4:10 PM In reply to

    Re: ARR HTTP Streaming Performance

    I am not sure how WCF implements streaming, but this following code snippet is what I am using (returning a memory stream with the service host binding transfermode set to streaming

    [ServiceContract]
        public interface IHttpPerformanceTest {
            [OperationContract]
            [WebGet(UriTemplate="/{fileSizeInBytes}")]
            Stream OnGet(string fileSizeInBytes);
        }

        [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
        public class HttpPerformanceTestService : IHttpPerformanceTest {
            static byte[] buffer = null;
            static int bufferSize = 0;
            public HttpPerformanceTestService() {
            }

            public Stream OnGet(string fileSizeInBytes) {
                int nrBytes = 0;
                System.Int32.TryParse(fileSizeInBytes, out nrBytes);
                if (nrBytes != bufferSize) {
                    buffer = new byte[nrBytes];
                    bufferSize = nrBytes;
                }
               
                MemoryStream stream = new MemoryStream(buffer);
                return stream;
            }
        }

     

      using (WebServiceHost host =
                    new WebServiceHost(new HttpPerformanceTestService(),
                    baseAddress))
                {
                    WebHttpBinding binding = new WebHttpBinding();
                    binding.MaxBufferPoolSize = 16 * 1024 * 1024; // 16 megs
                    binding.TransferMode = TransferMode.StreamedResponse; // Stream the responses

                    // add an endpoint using the custom binding
                    host.AddServiceEndpoint(typeof(IHttpPerformanceTest),
                        binding, "");
                    host.Open();

                    Console.WriteLine("HttpPerformanceTestService is up and running at uri " + baseAddress);
                    Console.WriteLine("...Press any key to exit");
                    Console.ReadKey();
                } 

     

Page 1 of 1 (4 items)
Microsoft Communities