首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate SecondLevel缓存性能

NHibernate SecondLevel缓存性能
EN

Stack Overflow用户
提问于 2016-03-31 14:52:08
回答 2查看 1.5K关注 0票数 1

在研究nhibernate中的第二级缓存提供的可能性时,我测试了一些实现。目前的结果是相当出乎意料的,我怀疑我的期望是否错误。

  1. 情景(读得多)

在最初的4* 20000个带有一个字符串属性的简单对象被插入到数据库中,然后四个线程通过objects (session.Get<SimpleObj>(id))获取它们。每个线程只访问它创建的did。访问模式是随机的,获取1000个对象,然后重新创建会话。

代码语言:javascript
复制
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();
    }
}

结果

  1. 每秒读取数据5000次
  2. MemCached 8000每秒读取(EnyimMemcached)
  3. 每秒没有缓存15000读取(相同的机器,TCP-IP)
  4. 每秒没有缓存25000读取(同一台机器,共享内存)
  5. SysCache2 200000每秒读取
  6. HashtableCacheProvider 380000每秒读取

使用版本

这些提供者和SysCache2实现之间的不同性能是否是预期的呢?

更新1

正如弗雷德里克所指出的那样,测试场景没有太大意义,因为我们比较了两种不同用途的缓存体系结构。第一类(5 & 6)不能水平缩放,而1和2可以。目前SQL-Server运行在同一台机器上,因此使用了IPC -机制共享内存,因此我禁用了所有IPC连接的可能性--配置为使用TCP/IP连接到数据库。其结果是,无缓存场景的性能下降了约10000 op/s,从而使最快的分布式缓存提供者达到了一个合理的距离。

通过对缓存提供程序的比较,我想测试这些提供程序是否可以在每次请求的会话设置中使用,以缓存国家、货币或资产负债表结构等参考数据。由于性能最好的分布式缓存的性能仍然只有普通NHibernate版本op/s的一半,所以我不确定这是否可行。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-01 08:38:55

SysCache(2) (或者RtMemoryCache,如果您也尝试另一个)比RedisMemCached表现得更好,这一点也不足为奇。格式化程序是进程内的内存缓存,它们的使用不会引起任何网络IO或进程间通信.延迟器是分布式缓存,它们意味着至少进程间通信,在大多数情况下是网络IO,这会带来相当高的使用成本。

将分布式缓存性能与非分布式缓存性能进行比较并没有任何意义。只有当需要在多个进程之间共享缓存时,才应该使用分布式缓存。如果您有此要求,您将无法使用非分布式缓存。

令人惊讶的是,“无缓存”场景(所以,SQL查询)比分布式缓存执行得更好。

在我看来,您的测试描述中缺少一个关键点:在您的场景中,是什么驱动了SQL查询的性能成本?如果db服务器承载在与web服务器相同的物理主机上,则此成本比通常设置的要低。有些db解决方案(如SQL server )甚至可能跳过任何网络IO,当内存通信(通过命名管道)托管在与web服务器相同的主机上时,它们甚至可能跳过任何网络IO并进行进程间通信。

附带注意:如果您不考虑通过Server数据更改通知将SysCache2配置为无效,则应该测试SysCache,这样做更轻巧。(这可能不会真正改变测试场景中的结果。)

关于最新情况1:

首先要确保您确实需要分发您的缓存。在以下情况下,每个进程都可以安全地拥有自己的缓存:

  1. 缓存的数据是只读的(或者最终,如果某些进程服务陈旧的缓存数据在应用程序中不会造成麻烦的话)。
  2. 这不会导致过多的内存消耗。(缓存的数据并不重,在许多进程之间复制数据并不是问题。)

当然,对于非分布式缓存,数据缓存的预热速度会更慢,但是如果分布式缓存的性能太差,这不是重点。

如果需要分发SQL Server,则应该评估Server是否是负载下的瓶颈。如果在加载下,您的Server可能成为应用程序的瓶颈,那么分布式缓存将有助于卸载它。否则,如果在您的设置中,分布式缓存的性能始终比db服务器差,则最好不要使用它们。

附带说明:只要条件(2.)如果满足,还可以尝试使用SQL Server通知无效的非分布式缓存,从而避免陈旧的数据。有关由Server通知的SysCache2,请参见此处。

票数 1
EN

Stack Overflow用户

发布于 2016-06-07 17:07:57

弗雷德里克已经写过,你测试了两种完全不同类型的缓存,所以我不会再重复了。但是我会补充一些关于NH缓存是如何工作的信息,并回答弗雷德里克的评论:

令人惊讶的是,“无缓存”场景(所以,SQL查询)比分布式缓存执行得更好。

事实上,这并不奇怪:)你需要记住这一点:

  1. NHibernate试图安全地处理缓存,并在每个缓存实体上模拟“事务”。根据其实现,分布式(NHibernate)缓存可以向缓存服务器发送两个附加请求(锁和释放实体),从而导致严重的性能下降。
  2. 不同的缓存使用不同的序列化程序。例如,Redis缓存使用内置的.NET XML序列化程序,它的速度并不出名;)
  3. 根据配置的过期策略,如果使用分布式缓存,还可能会出现额外的性能下降。
  4. 一些缓存服务器(如Redis)由于资源压力而删除缓存的条目会导致严重的性能问题(在本例中,NH将缓存服务器,获得缓存丢失,然后尝试从数据库=> 2x网络调用中检索实体)。

此外,我必须说,你的测试不是很有代表性的。在运行这些性能测试之前,您需要

  • 检查将有多少实体存储在缓存中
  • 对于这些实体,有多少个“投入”与“获取”?
  • 缓存实体中有多少链接集合
  • 平均有多少项存储在链接集合中
  • 您有什么样的实体(只读的,主要是不可变的,或者所有的实体都是可更新的?)

当然,对您的数据运行测试,而不是对虚拟数据集进行测试;)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36336861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档