Appfabric缓存比SQL Server 2008慢4倍?

8

我正在进行一项测试,比较AppFabric和SQL Server 2008的获取时间,结果显示AppFabric的速度比SQL Server慢了4倍。

我有一个SQL Server 2008设置,其中只包含一个具有4个列(全部为nvarchar)的表。该表有6000行。我将相同的行(作为CLR可序列化对象)插入到appfabric缓存中。我正在运行循环以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个回答

2

区别在于网络开销。在你的SQL示例中,你只要经过一次网络跳转并选择N行数据。在你的AppFabric示例中,你需要逐条记录进行网络跳转,而不是批量处理。这就是区别所在。为了证明这一点,可以将记录临时存储在一个列表中,并只获取该列表一次,或使用AppFabric批量API来一次性选择所有记录 - 这应该能解释很多差异。


1
不要认为他在那样做:他似乎是逐行检索数据:sqlCommand = 'Select * from TableName where posId = 'someId'' - Matt Evans

1

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

.Net 序列化利用反射,而反射的性能非常差。我建议研究使用自定义编写的序列化代码。


0

我认为你的测试存在偏差,结果不够优化。

关于分布式缓存

  • 本地缓存:你已经禁用了本地缓存功能。缓存对象总是从服务器检索;网络传输和反序列化需要成本。
  • BulkGet:BulkGet在使用小对象时可以提高性能,例如,在检索大小为1-5KB或更小的多个对象时。
  • 无数据压缩:AppFabric和Cache Clients之间没有压缩。请查看this

关于你的测试

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


1
我认为你以前没有使用过d-cache。仅仅知道一些东西是不够的。
如果我启用本地缓存,那将是一次不公平的测试。
批量获取 - 我也可以为SQL服务器执行相同的操作,并且我非常确定那将显着提高速度。 SQL Server最讨厌的就是只检索单个行。
为什么我要仅针对6k条记录启用压缩,每个记录仅具有4个字符串存储。
- Ashish Sharma
@user1707312,我不理解你的评论。你能解释一下吗?我不是AppFabric的专家。我使用它已经有一年了。如果你以前使用过d-cache,你应该也知道使用d-cache并不是为了提高性能,而是为了可扩展性。在单个客户端上使用单个数据表的“负载测试”并不是最好的方法。 - Cybermaxs
算了吧,我们不要深入讨论这个问题。顺便说一下,从性能角度来看,可以将AppFabric与Memcache/Couchbase进行比较。 - Ashish Sharma
@user1707312,您的场景也不太清楚。请添加SQL Server测试和数据(6000行没问题,但每行里面有什么内容呢)。为了实现高效的分布式缓存,您应该对数据进行分类,并使用适当的访问模式。根据我的过去经验,在缓存(本地或分布式)中最困难的是如何找到最佳的粒度。 - Cybermaxs
1
我在MSDN论坛上得到了一个更好的答案。 http://social.msdn.microsoft.com/Forums/en-US/velocity/thread/f20d50e7-9521-49fb-bd81-5710fe64e282 - Ashish Sharma
嘿,user1707312,你能把答案放在这里并标记为已回答吗? - garfbradaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接