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: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;
}
Important points:
- 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".