8

I am running a test where I am comparing fetch time b/w appfabric and SQL Server 2008 and looks appFabric is performing 4x time slower than SQL Server.

I have a SQL Server 2008 setup which contains only one table with 4 columns (all nvarchar). The table has 6000 rows. I insert the same row (as CLR serializable obj) in the appfabric cache. I am running a loop to fetch data x times.

Here is the code

public class AppFabricCache
{
readonly DataCache myDefaultCache;

public AppFabricCache()
{
//-------------------------
// Configure Cache Client 
//-------------------------

//Define Array for 1 Cache Host
var servers = new List<DataCacheServerEndpoint>(1);

//Specify Cache Host Details 
//  Parameter 1 = host name
//  Parameter 2 = cache port number
servers.Add(new DataCacheServerEndpoint(@"localhost", 22233));

//Create cache configuration
var configuration = new DataCacheFactoryConfiguration();

//Set the cache host(s)
configuration.Servers = servers;

//Set default properties for local cache (local cache disabled)
configuration.LocalCacheProperties = new DataCacheLocalCacheProperties();

//Disable exception messages since this sample works on a cache aside
DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);

//Pass configuration settings to cacheFactory constructor
DataCacheFactory myCacheFactory = new DataCacheFactory(configuration);

//Get reference to named cache called "default"
myDefaultCache = myCacheFactory.GetCache("default");
}

public bool TryGetCachedObject(string key, out object value)
{
value = myDefaultCache.Get(key);
bool result = value != null;
return result;
}

public void PutItemIntoCache(string key, object value)
{
myDefaultCache.Put(key, value, TimeSpan.FromDays(365));
}

}

And here is the loop to fetch data from the cache

public double RunReadStressTest(int numberOfIterations, out int recordReadCount)
{
recordReadCount = 0;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < numberOfIterations; i++)
{
for (int j = 1; j <= 6000; j++)
{
string posId = "PosId-" + j;
try
{
object value;
if (TryGetCachedObject(posId, out value))
recordReadCount++;
}
catch (Exception e)
{
Trace.WriteLine("AS%% - Exception - " + e.Message);
}
}
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
}

I have exactly the same logic to retrieve data from SQL Server. It creates a

sqlCommand = 'Select * from TableName where posId = 'someId'' 

Here are the results...

SQL Server 2008 R2  Reading-1(ms)   Reading-2(ms)   Reading-3(ms)   Average Time in Seconds
 Iteration Count = 5    2528              2649            2665                 2.614
 Iteration Count = 10   5280              5445            5343                 5.356
 Iteration Count = 15   7978              8370            7800                 8.049333333
 Iteration Count = 20   9277              9643            10220                9.713333333

AppFabric                 Reading-1         Reading-2   Reading-3   Average Time in Seconds
Iteration Count = 5        10301            10160            10186                10.21566667
Iteration Count = 10       20130            20191            20650                20.32366667
Iteration Count = 15       30747            30571            30647                30.655
Iteration Count = 20       40448            40541            40503                40.49733333

Am I missing something here? Why it is so slow?

Ashish Sharma
  • 331
  • 1
  • 5
  • 12

3 Answers3

2

The difference is the network overhead. In your SQL example, you hop over the network once and select N rows. In your AppFabric example, you hop over the network PER RECORD instead of in bulk. This is the difference. To prove this, temporarily store your records in AppFabric as a List and get just the list one time, or use the AppFabric Bulk API to select them all in one request - that should account for much of the difference.

Haney
  • 32,775
  • 8
  • 59
  • 68
  • 1
    dont think he is doing that: he appears to be retrieving data row by row: sqlCommand = 'Select * from TableName where posId = 'someId'' – Matt Evans Jun 04 '14 at 11:48
1

This may be caused by .Net's built in serialisation.

.Net serialisation utilises reflection which in turn has very poor performance. I'd recommend looking into the use of custom written serialisation code.

redcalx
  • 8,177
  • 4
  • 56
  • 105
0

I think your test is biased and your results are non optimal.

About Distributed Cache

  • Local Cache : you have disabled local cache feature. Cache objects are always retrieved from the server ; network transfert and deserialization have a cost.
  • BulkGet : BulkGet improves performance when used with small objects, for example, when retrieving many objects of 1 - 5KB or less in size .
  • No Data Compression : No compression between AppFabric and Cache Clients. Check this.

About Your test

Another Important thing is that your are not testing the same thing : On one side you test SELECT * and and the other side you test N x GET ITEM.

Cybermaxs
  • 24,378
  • 8
  • 83
  • 112
  • 1
    I don't think you have used d-cache before. Just knowing some stuff is not enough. >>If i enable local cache, that would be an unfair test. >>Bulk get - i could have done the same for SQL server as well and i m pretty sure that would be significantly fast. Sql Server hates nothing more than just retrieving a single row. >>Why would i wanna enable compression for only 6k records. each with only 4 string storage. – Ashish Sharma Oct 05 '12 at 13:34
  • @user1707312 I don't understand you comment . could you explain ? I am not a master of AppFabric. I used it since one year. If you have used d-cache before, you should also know that the use of d-cache does not target improving performance, but scalability. "Load Testing" in a for loop on a single client with a single data table is not the best approach. – Cybermaxs Oct 05 '12 at 13:40
  • forget -it lets not get into it. Btw- form performance point of view try comparing AppFabric with Memcache/Couchbase. – Ashish Sharma Oct 05 '12 at 13:45
  • @user1707312 Your scenario is also unclear. Also add the sql server test and the data (6000 rows OK, but what is inside each row). For efficient d-caching, you should categorize your data and use an appropriate access pattern. From my past experiences, the most difficult in caching (local or distributed) is how to find the best granularity. – Cybermaxs Oct 05 '12 at 13:57
  • 1
    I got a better answer on the MSDN form. http://social.msdn.microsoft.com/Forums/en-US/velocity/thread/f20d50e7-9521-49fb-bd81-5710fe64e282 – Ashish Sharma Oct 09 '12 at 14:09
  • Hey user1707312 can you pit the answer here and mark it as answered. – garfbradaz Dec 17 '12 at 17:52