2

假设我们正在构建一个电子商务网站,允许消费者通过输入关键字来搜索产品。假设最多有 200,000 种产品,并且有数百万消费者在使用该系统。假设产品表更新得相当频繁。由于产品的数量并不多,我们可能可以将整个产品表存储在内存中并对其进行搜索而不是访问数据库。我们希望创建存储相同数据但驻留在不同服务器中的分布式缓存(出于高可用性和性能原因),并且我们需要能够在这些缓存之间同步数据并在修改产品表时使缓存无效。

我们的应用程序是使用 ASP.NET MVC 和 NHibernate 构建的。我试图了解 NHibernate 的 2 级缓存是否对我的情况有所帮助。如果你们能对此有所了解,我将不胜感激。

我知道二级缓存将有助于缓存查询结果,因此如果两个不同的用户使用相同的关键字进行搜索,则二级缓存将提供来自缓存而不是数据库的结果。但这对我们没有多大帮助,因为产品表经常更新并且缓存的结果会过时。我的问题是我是否正确理解 L2 缓存,是否有任何东西可以帮助我按照我想要的方式管理缓存(多个缓存、相同的数据、缓存之间的同步和无效缓存)。任何想法都受到高度赞赏。

4

3 回答 3

2

二级缓存是否有帮助取决于您的产品表相对于缓存命中的更新频率。如果您每小时添加 100 个新产品,但每小时收到 10,000 个查询,那么即使 10% 的缓存命中率也会产生很大的不同。如果速率相反,二级缓存将几乎没有价值。

我建议您设置一个与您的生产环境非常接近的压力测试环境,并在各种二级缓存提供程序上执行基准测试。

还要检查您的数据库是否针对更新繁重的场景进行了正确配置。

于 2010-02-11T17:05:42.290 回答
2

使用了二级缓存(使用 memcached 提供程序)和 NHibernate.Search 附加组件后,在我看来,您可以从两者中受益。

NHibernate.Search 组件依赖于 Lucene.Net 并且关键字搜索与其自身的数据库分离。每个映射的类都会创建一个不同的索引文件,并且可以使用属性在属性级别上设置优化,从而为您提供额外的粒度级别。此外,您可以实现最佳匹配和建议(检查 Lucene in Action 和/或 Hibernate Search in action)。请注意,您不必维护索引(除非您明确请求重建索引);尽管您可以根据需要操作索引,但该实现在幕后管理所有内容。因此,添加/删除/更新产品将自动更新相应的索引。

对于二级缓存,您可以立即获得性能提升。在具有大约 2 百万行数据集的测试环境中,即使请求数极少,我的改进也超过了 20%。随着请求数量的增加,性能提升逐渐变大 - 应用程序首先访问二级缓存,如果没有找到,则访问数据库以获取所需的行并将它们插入缓存以供将来查询。同样,您可以管理诸如缓存持续时间和其他配置设置之类的内容,以及如果您愿意的话,可以显式清除缓存(全部、部分或特定条目)。请注意,缓存状态在保存/更新/删除期间由应用程序管理。

对于可扩展性 * 二级缓存取决于提供者(即 memcached 具有高性能和可扩展性并支持分布式实例)。* 对于 Lucene.Net/NHibernate.Search,您需要设置索引将驻留的特定位置,并且该位置必须可供所有 Web 应用程序实例读取/写入。请注意,敏感链接是 I/O 和文件争用,因此设置具有比轻型文件系统更快的机器将防止这种情况发生(我说的是每秒有数千个搜索请求的场景)

作为旁注,我强烈推荐 NHibernate.Search,因为它比 LIKE 查询快得多,并且比在应用程序中实现 SQL-Server 的全文搜索更容易使用(我已经这样做了)。

于 2010-02-13T12:05:44.283 回答
1

我推荐使用带有 Lucene 的NHibernate.Search 。它与二级缓存一起工作。Lucene 可以快速进行复杂的文本搜索,然后将实体键返回给 NHibernate,NHibernate 将完整的实体从其二级缓存中拉出。NHibernate.Search 扩展负责使您的 Lucene 索引保持同步。

TekPub最近对您搜索产品描述的确切场景做了一集。这一集比较了 NHibernate 查询、SQL 全文索引和带有 NHibernate.Search 的 Lucene。

于 2010-02-11T17:09:57.040 回答