IIS 7 C++ Module API Sample: Controlling http.sys caching
IIS 7 C++ Module API Sample: Controlling http.sys caching
Introduction
In my previous post we saw that http.sys caching can be very useful for high traffic (gigabits/sec) sites. In this post we create a sample module that allows configuring which URLs can enter the cache.
Code
There is very little non-template, IIS-specific, code in this module. In fact here is everything that is important:Important points:REQUEST_NOTIFICATION_STATUS MODULE::OnSendResponse( IHttpContext* pContext, ISendResponseProvider* pProvider ) { if( !pProvider->GetHeadersBeingSent( ) ) { // // headers not being sent, not first send response notification, nothing to do // goto Finished; } if( !g_pUrlHash->Exists( pContext->GetScriptName( ) ) ) { // // not a pre-determined "hot" url, no caching.. // IHttpResponse* pResponse = pContext->GetResponse( ); pResponse->DisableKernelCache( 123 ); } Finished: return RQ_NOTIFICATION_CONTINUE; }
- RQ_SEND_RESPONSE is a "non-deterministic" notification that can fire multiple times (e.g. whenever someone calls IHttpResponse::Flush). To determine the first time we're being notified, the module checks ISendResponseProvider::GetHeadersBeingSent. This is only true on the first notification for the request.
- IHttpContext::GetScriptName is often the URL you want to compare to. It has been "sanitized" and had PATH_INFO removed.
- IHttpResponse::DisableKernelCache trumps any cache policy configured with IHttpResponse::GetRawHttpResponse()->...
Setup
As mentioned, there are many caches and caching algorithms in IIS. To simplify the testing of this module I:- disabled my file cache module (simply removed it from the pipline - "appcmd uninstall module FileCacheModule").
- disabled the "hotness" detection algorithm in iiscore ("appcmd set config -section:serverRuntime -frequentHitThreshold:1")
Test
This time I'm using a newer dual-core machine with 1GB ram and running the perf client locally. There are 4000x184kb "hot" files, and 4000x184kb "cold" files. Total = 8000x184kb = 1.4GB. Hot files are hit 32x more frequently than cold files. For the Cacheit test, I installed the module and only gave it the full list of 4000 hot URLs.
Test | Req/s | Cache Content | |
Hot | Cold | ||
Baseline | 770 | 3994 | 765 |
Cacheit | 833 (+8%) | 4001 | 13 |
Request/sec came from wcat's log. Cache contents was determined by running "netsh http show cachestate > out.txt" and then "findstr /i hot out.txt" and "findstr /i cold out.txt".