Appfabric Cache的执行速度比SQL Server 2008快4倍?

时间:2012-09-28 20:51:45

标签: c# performance comparison appfabric distributed-caching

我正在运行一个测试,我将比较获取时间b / w appfabric和SQL Server 2008,看起来appFabric的执行时间比SQL Server慢4倍。

我有一个SQL Server 2008设置,它只包含一个包含4列的表(全部为nvarchar)。该表有6000行。我在appfabric缓存中插入相同的行(作为CLR serializable obj)。我正在运行一个循环来获取数据x次。

这是代码

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));
}

}

这是从缓存中获取数据的循环

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;
}
}

我从SQL Server检索数据的逻辑完全相同。它创建了一个

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

以下是结果......

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

我在这里遗漏了什么吗?为什么这么慢?

3 个答案:

答案 0 :(得分:2)

不同之处在于网络开销。在您的SQL示例中,您跳过网络一次并选择N行。在AppFabric示例中,您跳过网络 PER RECORD 而不是批量转发。这是不同的。为了证明这一点,暂时将您的记录存储在AppFabric中作为列表,只获得一次列表,或使用AppFabric批量API在一个请求中选择所有这些 - 这应该是差异的主要原因。

答案 1 :(得分:1)

这可能是由.Net的内置序列化引起的。

.Net序列化利用反射,反过来又具有非常性能差。我建议使用自定义编写的序列化代码。

答案 2 :(得分:0)

我认为您的测试有偏见且结果不理想。

关于分布式缓存

  • 本地缓存:您已停用local cache功能。始终从服务器检索缓存对象;网络转移和反序列化都有成本。
  • BulkGet:BulkGet在与小对象一起使用时可以提高性能,例如,在检索大小为1 - 5KB或更小的许多对象时。
  • 无数据压缩:AppFabric和缓存客户端之间无压缩。检查this

关于您的测试

另一个重要的事情是你没有测试同样的东西:一方面你测试SELECT *而另一方面测试N x GET ITEM。