【问题标题】:Appfabric Cache is performing 4x slower than SQL Server 2008 ??Appfabric 缓存的执行速度比 SQL Server 2008 慢 4 倍??
【发布时间】:2012-09-20 18:21:31
【问题描述】:

我正在运行一个测试,我正在比较黑白 appfabric 和 SQL Server 2008 的获取时间,并且看起来 appFabric 的执行时间比 SQL Server 慢 4 倍。

我有一个 SQL Server 2008 设置,它只包含一个包含 4 列的表(全部为 nvarchar)。该表有 6000 行。我在 appfabric 缓存中插入同一行(作为 CLR 可序列化 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

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

【问题讨论】:

    标签: c# performance comparison appfabric distributed-caching


    【解决方案1】:

    区别在于网络开销。在您的 SQL 示例中,您跳过网络一次并选择 N 行。在您的 AppFabric 示例中,您 PER RECORD 跳过网络而不是批量。这就是区别。为了证明这一点,请将您的记录作为列表临时存储在 AppFabric 中,然后仅获取该列表一次,或者使用 AppFabric Bulk API 在一个请求中将它们全部选中 - 这应该会造成很大的差异。

    【讨论】:

    • 不要认为他在这样做:他似乎在逐行检索数据:sqlCommand = 'Select * from TableName where posId = 'someId''
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我认为你的测试有偏见,你的结果不是最优的。

      关于分布式缓存

      • 本地缓存:您已禁用local cache 功能。缓存对象总是从服务器获取;网络传输和反序列化是有成本的。
      • BulkGet : BulkGet 在用于小对象时提高性能,例如,在检索许多大小为 1 - 5KB 或更小的对象时。
      • 无数据压缩:AppFabric 和缓存客户端之间无压缩。检查this

      关于您的测试

      另一件重要的事情是你测试的不是同一件事:一方面你测试 SELECT *,另一方面你测试 N x GET ITEM。

      【讨论】:

      • 我认为您以前没有使用过 d-cache。仅仅知道一些东西是不够的。 >>如果我启用本地缓存,那将是一个不公平的测试。 >>批量获取 - 我也可以为 SQL 服务器做同样的事情,我很确定这会非常快。 Sql Server 讨厌的只是检索单行。 >>为什么我只想为 6k 记录启用压缩。每个只有 4 个字符串存储。
      • @user1707312 我不明白你的评论。你能解释一下吗?我不是 AppFabric 的大师。我用了一年。如果您之前使用过 d-cache,那么您应该也知道使用 d-cache 的目标不是提高性能,而是可扩展性。在具有单个数据表的单个客户端上的 for 循环中的“负载测试”不是最佳方法。
      • 算了,别扯了。顺便说一句,从性能角度尝试将 AppFabric 与 Memcache/Couchbase 进行比较。
      • @user1707312 你的场景也不清楚。还要添加 sql server 测试和数据(6000 行可以,但每行里面是什么)。为了有效的 d-caching,您应该对数据进行分类并使用适当的访问模式。根据我过去的经验,缓存(本地或分布式)最困难的是如何找到最佳粒度。
      • 我在 MSDN 表单上得到了更好的答案。 social.msdn.microsoft.com/Forums/en-US/velocity/thread/…
      猜你喜欢
      • 2020-02-19
      • 2012-07-08
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 1970-01-01
      • 2019-08-05
      相关资源
      最近更新 更多