在研究 nhibernate 中二级缓存提供的可能性时,我测试了一些实现。目前结果出乎意料,我怀疑我的期望是否错误。
- 场景(重读)
首先将 4 * 20000 个具有一个字符串属性的简单对象插入数据库,然后四个线程通过对象 ID ( session.Get<SimpleObj>(id)
) 获取它们。每个线程只访问它创建的 ID。访问模式是随机的,获取 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();
}
}
结果
- Redis 每秒 5000 次读取
- MemCached 每秒 8000 次读取 (EnyimMemcached)
- 无缓存每秒 15000 次读取(同一台机器,TCP-IP)
- 无缓存每秒 25000 次读取(同一台机器,共享内存)
- SysCache2 每秒 200000 次读取
- HashtableCacheProvider 每秒 380000 次读取
使用的版本
- NHibernate 4.0.0.4000 和 https://github.com/nhibernate/NHibernate-Caches的当前版本
- 来自https://msopentech.com/opentech-projects/redis/的 Redis 服务器 3.0.501
- 来自 Couchbase ( http://www.couchbase.com/ )的 MemCached 1.4.5_4_gaa7839e
这些提供程序和 SysCache2 实现之间的不同性能是否可以预期?
更新 1
正如 Frederic 指出的那样,测试场景没有太大意义,因为比较了具有两种不同用例的两种不同类别的缓存架构。第一类(5 和 6)不能水平缩放,而 1 和 2 可以。目前 SQL-Server 在同一台机器上运行,因此使用共享内存作为 IPC 机制,因此我禁用了所有 IPC 连接可能性,并将其配置为使用 TCP/IP 连接到数据库。结果,no-cache-scenario 的性能下降了大约 10000 op/s,这使最快的分布式缓存提供程序进入了合理的距离。
通过比较缓存提供程序,我想测试这些提供程序是否可以在每个请求的会话设置中用于缓存参考数据,例如国家、货币或资产负债表结构。由于性能最好的分布式缓存的性能仍然只有普通 NHibernate 版本的 op/s 的一半,我不确定这是否是要走的路。