我需要在我的Web服务中缓存数据库查询的结果。在服务呼叫周期中查询了大约30个表。我相信服务会经常访问某个日期范围内的数据,我想预先缓存这些数据。这意味着在应用程序启动时缓存大约800,000行,数据是只读的。数据不需要动态刷新,这是参考数据。无法在每个服务呼叫上加载缓存,因此数据太多了。此频道以外的数据经常使用'窗口不是时间关键,可以延迟加载。大多数查询将返回1行,并且没有一个表彼此具有父/子关系,尽管会有一些连接。不需要动态的sql支持。
我打算使用myBatis,但是没有一个很好的方法来预热缓存。 myBatis无法理解启动预缓存查询select * from table where key = ?
已涵盖服务查询select * from table
。
据我所知(文档重载),Hibernate也有同样的问题。另外,这些表是使用复合键设计的,没有主键,这对Hibernate来说是一个额外的麻烦。
首选:针对此问题是否有myBatis解决方案?我非常想用它。 (熟悉,简单,表现,有趣的名字等)
或者:是否有ORM或DB友好的缓存提供我正在寻找的东西?
答案 0 :(得分:1)
您可以使用分布式缓存解决方案,如NCache或Tayzgrid,它们提供索引和查询功能以及缓存启动加载程序。
您可以在缓存中配置实体属性的索引。可以将cache startup loader配置为在缓存启动时从缓存中的数据库加载所有数据。在加载数据时,缓存将为内存中的所有实体创建索引。
提供类似于SQL的查询的Object Query Language (OQL)功能可用于查询内存数据。
答案 1 :(得分:0)
第三方产品(免费和付费)的各种选项过于宽泛,过于依赖您的特定要求和运营能力,无法回答"这里。
但是,我建议您替换显式的只读数据缓存。
您清楚地认为数据集的内存占用量将适合合理大小的服务器上的RAM。我的建议是你直接使用你的数据库引擎(没有额外的外部缓存),但配置数据库的内部缓存大到足以容纳你的整个数据集。如果您的所有数据都驻留在数据库服务器的RAM中,则可以非常快速地访问它。
我已经成功地使用了这种技术与mySQL,但我希望这同样适用于所有主要的数据库引擎。如果你无法弄清楚如何正确配置你选择的数据库,我建议你按照一个单独的详细问题来解决。
您可以在启动系统时通过执行代表性查询来加热缓存。这些查询相对较慢,因为它们必须实际执行磁盘I / O以将相关的数据块拉入缓存。访问相同数据块的后续查询会快得多。
这种方法可以为您带来巨大的性能提升,而且代码或操作环境不会增加复杂性。
答案 2 :(得分:0)
Sormula可能想要你想要的。您需要注释每个要缓存的POJO,如:
@Cached(type=ReadOnlyCache.class)
public class SomePojo {
...
}
通过为每个方法调用selectAll方法预先填充缓存:
Database db = new Database(one of the JNDI constructors);
Table<SomePojo> t = db.getTable(SomePojo.class);
t.selectAll();
关键是缓存存储在Table对象中。因此,您需要保留对t的引用并将其用于后续查询。或者在许多表的情况下,继续引用数据库对象db,并使用db.getTable(...)来获取要查询的表。
请参阅javadoc并在org.sormula.tests.cache.readonly包中进行测试。