假设我们正在构建一个电子商务网站,允许消费者通过键入关键字来搜索产品。假设最多有200,000种产品,并且有数百万消费者使用该系统。假设产品表经常更新。由于产品数量不是很高,我们可能会将整个产品表存储在内存中并搜索它而不是访问数据库。我们希望创建存储相同数据但位于不同服务器中的分布式缓存(出于高可用性和性能原因),我们需要能够在这些缓存之间同步数据,并在修改产品表时使缓存无效。
我们的应用程序是使用ASP.NET MVC和NHibernate构建的。我试图了解NHibernate的2级缓存是否有助于我的情况。如果你们能够对此有所了解,我将非常感激。
我知道二级缓存有助于缓存查询结果,因此如果两个不同的用户使用相同的关键字进行搜索,则二级缓存将从缓存而不是数据库中提供结果。但它并没有帮助我们太多,因为产品表经常更新,缓存的结果将是陈旧的。 我的问题是我是否正确理解L2缓存,是否存在任何有助于按照我想要的方式管理缓存的方法(多个缓存,相同的数据,缓存和无效缓存之间的同步)。任何想法都受到高度赞赏。
答案 0 :(得分:2)
二级缓存是否有用取决于产品表与缓存命中数的更新频率。如果您每小时添加100个新产品,但每小时收到10,000个查询,即使10%的缓存命中率也会产生很大的差异。如果费率相反,二级缓存几乎没有价值。
我建议您设置一个压力测试环境,该环境非常接近您的生产环境,并对各种二级缓存提供程序执行基准测试。
同时检查您的数据库是否配置正确,以适应更新繁忙的情况。
答案 1 :(得分:2)
使用了二级缓存(使用memcached提供程序)和NHibernate.Search附加组件,我觉得你可以从中受益。
NHibernate.Search组件依赖于Lucene.Net,关键字搜索与数据库自身分离。每个类映射都会创建一个不同的索引文件,并且可以使用属性在属性级别上设置优化,从而为您提供额外的粒度级别。此外,您可以实现最佳匹配和命题(检查Lucene in Action和/或Hibernate Search的运行情况)。作为注释,您不必维护索引(除非您明确请求索引重建);实现管理幕后的所有内容,但如果您愿意,可以操作索引。因此,添加/删除/更新产品将自动更新相应的索引。
对于二级缓存,您可以立即获得性能提升。在数据集大约为2 mil的测试环境中,即使在极低的请求数下,我也有超过20%的改进。随着请求计数的增加,性能提升逐渐变大 - 应用程序首先访问第二级缓存,如果找不到它,则命中数据库获取所需的行并将其插入缓存以供将来查询。您可以再次管理缓存持续时间和其他配置设置等内容,并在需要时明确清除缓存(所有缓存,其中的一部分或特定条目)。请注意,缓存状态由应用程序在保存/更新/删除期间进行管理。
可扩展性 *二级缓存依赖于提供程序(即memcached具有高性能和可伸缩性,并支持分布式实例)。 *对于Lucene.Net/NHibernate.Search,您需要设置索引将驻留的特定位置,并且所有Web应用程序实例都必须可以访问该位置以进行读/写。请注意,敏感链接是I / O和文件争用,因此设置具有快于光文件系统的计算机将阻止这种情况发生(我说的是每秒有数千个搜索请求的场景)
作为旁注,我强烈推荐NHibernate.Search,因为它比LIKE查询快得多,并且比在应用程序中实现SQL-Server的FullText搜索更容易使用(我已经完成了)。
答案 2 :(得分:1)
我建议使用NHibernate.Search w / Lucene。它与二级缓存一起使用。 Lucene可以快速进行复杂的文本搜索,然后将实体密钥返回给NHibernate,从而将完整的实体从其二级缓存中拉出来。 NHibernate.Search扩展可以使您的Lucene索引保持同步。
TekPub最近就您搜索产品说明的确切情况做了一集。该剧集比较了NHibernate查询,SQL全文索引和Lucene w / NHibernate.Search。