I am currently trying to understand the best configuration for caching. I am using Azure In-Role caching (currently Colocated, but Dedicated at a later point) in a Web Api 2 application in .NET 4.5.1.
The transportProperties
element in dataCacheClient
have two seaminly important attributes, maxBufferPoolSize
and maxBufferSize
. I've done a bit of reading on these, most notably here and here, and it seems like these attributes can play an significant part in performance.
Currently I have different caching scenarios but one dataCacheClient
to conquer them all:
I understand that this is probably quite horrendous. After the reading and analysing my caching implemention, I have come to the following plan for each caching scenario.
Could someone with more knowledge about buffer pooling validate and critique my caching strategy below.
Disclaimer: I am estimating the size of my objects based on their field types. I understand that this won't be correct. DataCache uses the NetDataContractSerializer
which implementions some form of XML-based serialisation.
Many tiny, well-defined objects. Low expiry.
Scenario: +-50,000 objects at 16 bytes each. Very low expiry rate. High read rate (possibly 1000s per request)
The following would cater for all the items:
maxBufferPoolSize = 6,400,000 bytes (128 * 50,0000 items)
maxBufferSize = 128 bytes (the items will never exceed 128 bytes and 128 is the smallest pool size available)
Configuration:
<dataCacheClient name="MyTinyObjects">
<localCache isEnabled="true" sync="NotificationBased" objectCount="50000" ttlValue="30000" />
<clientNotification pollInterval="300" />
<transportProperties maxBufferPoolSize="6400000" maxBufferSize="128" />
</dataCacheClient>
Do I actually need to pre allocate pools here since they expire very rarely? Perhaps maxBufferPoolSize="0" is fine.
Due to a high read rate, I have included a localCache
to improve read latency.
Many small objects of varying size. Medium expiry.
Scenario: +-15,000 objects of up too 2048 bytes but mostly around the 256 - 512 bytes. They expire often as data is invalidated over time.
I should create the following cache:
maxBufferPoolSize = 1,280,000 bytes
maxBufferSize = 2048 bytes (the vast majority items should never exceed 2048 bytes)
This means there are essentially 10,000 buffers in the 128 pool, 5000 in the 256 pool, and so on until there are 62 buffers in the 2048 pool.
Configuration:
<dataCacheClient name="MyDynamicObjects">
<transportProperties maxBufferPoolSize="1280000" maxBufferSize="2048 " />
</dataCacheClient>
Few very large items. No expiry.
Scenario: +-50 objects of 1 mb each. Preloaded on application start-up and do not expire.
In this case, there is no point setting a maxBufferPoolSize, as there will be no performance improvement in having available pools as they will not be disposed until the application pool recycling. Actually, setting this to, let's say, 1048576 will created a lot of unused pools (a waste of memory).
But, maxBufferSize will need to be set above 1 mb (greater than 1,048,576 bytes).
Configuration:
<dataCacheClient name="MyBulkyObjects">
<transportProperties maxBufferPoolSize="0" maxBufferSize="1048576" />
</dataCacheClient>