在研究nhibernate中的第二级缓存提供的可能性时,我测试了一些实现。目前的结果是相当出乎意料的,我怀疑我的期望是否错误。
在最初的4* 20000个带有一个字符串属性的简单对象被插入到数据库中,然后四个线程通过objects (session.Get<SimpleObj>(id))获取它们。每个线程只访问它创建的did。访问模式是随机的,获取1000个对象,然后重新创建会话。
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();
}
}结果
使用版本
这些提供者和SysCache2实现之间的不同性能是否是预期的呢?
更新1
正如弗雷德里克所指出的那样,测试场景没有太大意义,因为我们比较了两种不同用途的缓存体系结构。第一类(5 & 6)不能水平缩放,而1和2可以。目前SQL-Server运行在同一台机器上,因此使用了IPC -机制共享内存,因此我禁用了所有IPC连接的可能性--配置为使用TCP/IP连接到数据库。其结果是,无缓存场景的性能下降了约10000 op/s,从而使最快的分布式缓存提供者达到了一个合理的距离。
通过对缓存提供程序的比较,我想测试这些提供程序是否可以在每次请求的会话设置中使用,以缓存国家、货币或资产负债表结构等参考数据。由于性能最好的分布式缓存的性能仍然只有普通NHibernate版本op/s的一半,所以我不确定这是否可行。
发布于 2016-04-01 08:38:55
让SysCache(2) (或者RtMemoryCache,如果您也尝试另一个)比Redis或MemCached表现得更好,这一点也不足为奇。格式化程序是进程内的内存缓存,它们的使用不会引起任何网络IO或进程间通信.延迟器是分布式缓存,它们意味着至少进程间通信,在大多数情况下是网络IO,这会带来相当高的使用成本。
将分布式缓存性能与非分布式缓存性能进行比较并没有任何意义。只有当需要在多个进程之间共享缓存时,才应该使用分布式缓存。如果您有此要求,您将无法使用非分布式缓存。
令人惊讶的是,“无缓存”场景(所以,SQL查询)比分布式缓存执行得更好。
在我看来,您的测试描述中缺少一个关键点:在您的场景中,是什么驱动了SQL查询的性能成本?如果db服务器承载在与web服务器相同的物理主机上,则此成本比通常设置的要低。有些db解决方案(如SQL server )甚至可能跳过任何网络IO,当内存通信(通过命名管道)托管在与web服务器相同的主机上时,它们甚至可能跳过任何网络IO并进行进程间通信。
附带注意:如果您不考虑通过Server数据更改通知将SysCache2配置为无效,则应该测试SysCache,这样做更轻巧。(这可能不会真正改变测试场景中的结果。)
关于最新情况1:
首先要确保您确实需要分发您的缓存。在以下情况下,每个进程都可以安全地拥有自己的缓存:
当然,对于非分布式缓存,数据缓存的预热速度会更慢,但是如果分布式缓存的性能太差,这不是重点。
如果需要分发SQL Server,则应该评估Server是否是负载下的瓶颈。如果在加载下,您的Server可能成为应用程序的瓶颈,那么分布式缓存将有助于卸载它。否则,如果在您的设置中,分布式缓存的性能始终比db服务器差,则最好不要使用它们。
附带说明:只要条件(2.)如果满足,还可以尝试使用SQL Server通知无效的非分布式缓存,从而避免陈旧的数据。有关由Server通知的SysCache2,请参见此处。
发布于 2016-06-07 17:07:57
弗雷德里克已经写过,你测试了两种完全不同类型的缓存,所以我不会再重复了。但是我会补充一些关于NH缓存是如何工作的信息,并回答弗雷德里克的评论:
令人惊讶的是,“无缓存”场景(所以,SQL查询)比分布式缓存执行得更好。
事实上,这并不奇怪:)你需要记住这一点:
此外,我必须说,你的测试不是很有代表性的。在运行这些性能测试之前,您需要
当然,对您的数据运行测试,而不是对虚拟数据集进行测试;)
https://stackoverflow.com/questions/36336861
复制相似问题