While researching the possibilities that the second level cache in nhibernate provides I tested some implementations. Currently the outcome is quite unexpected and I'am questioning if my expectations are wrong.
- Scenario (Read-Heavy)
At first 4 * 20000 simple objects with one string property are inserted into the database then four threads are getting them by the object-id (session.Get<SimpleObj>(id)
). Each thread only accesses the ids it did create. The access-pattern is random and gets 1000 objects and then recreates the session.
while (true)
{
using (var session = sf.OpenSession())
using (var tx = session.BeginTransaction())
{
for (int i3 = 0; i3 < 1000; i3++)
{
long id = (long)ids[rnd.Next(19999)];
var t = session.Get<SimpleObject>(id);
var no = t.StringProperty;
}
Interlocked.Add(ref ops, 1000);
tx.Commit();
}
}
Results
- Redis 5000 reads per second
- MemCached 8000 reads per second (EnyimMemcached)
- No Caching 15000 reads per second (Same machine, TCP-IP)
- No Caching 25000 reads per second (Same machine, shared memory)
- SysCache2 200000 reads per second
- HashtableCacheProvider 380000 reads per second
Versions used
- NHibernate 4.0.0.4000 and the current version of https://github.com/nhibernate/NHibernate-Caches
- Redis Server 3.0.501 from https://msopentech.com/opentech-projects/redis/
- MemCached 1.4.5_4_gaa7839e from Couchbase (http://www.couchbase.com/)
Is the different performance between those providers and the SysCache2 implementation to be expected?
Update 1
As Frederic pointed out the testing scenario does not make too much sense as two different classes of caching architectures with two different uses cases are compared. The first class (5 & 6) can not be scaled horizontally while 1 and 2 can. Currently the SQL-Server is running on the same machine so shared-memory as an IPC-Mechanism is used, therefore i disabled all IPC Connection possibilities an configured it to use TCP/IP to connect to the database. As result the performance of the no-cache-scenario drops about 10000 op/s which brings the fastest distributed caching provider into a reasonable distance.
With the comparison of the caching providers I want to test if these providers can be used in a session-per-request setup to cache reference data like countries, currencies or balance-sheet structures. As the performance of the best performing distributed cache is still only half the op/s of the plain NHibernate version I am not sure if this is the way to go.