2.10. 索引和查询缓存
通过查询数据网格缓存,您可以分析和过滤数据以获取实时见解。例如,请考虑在线游戏,在某种程度上相互竞争。如果您要在任何一个时间使用前十个播放器实施领导板,您可以创建一个查询来找出哪个 play 是否有最多点,并将结果限制为最多十条:
QueryFactory queryFactory = Search.getQueryFactory(playersScores); Query topTenQuery = queryFactory .create("from com.redhat.PlayerScore ORDER BY p.score DESC, p.timestamp ASC") .maxResults(10); List<PlayerScore> topTen = topTenQuery.execute().list();
QueryFactory queryFactory = Search.getQueryFactory(playersScores);
Query topTenQuery = queryFactory
.create("from com.redhat.PlayerScore ORDER BY p.score DESC, p.timestamp ASC")
.maxResults(10);
List<PlayerScore> topTen = topTenQuery.execute().list();
前面的示例演示了使用查询的好处,因为它可让您查找匹配有百万个缓存条目条件的十个条目。
然而,在性能影响方面,您应该考虑索引操作与查询操作相关的利弊。将 Data Grid 配置为索引缓存会导致查询更快。如果没有索引,查询必须滚动到缓存中的所有数据,根据数据的类型和数量,按量级的排序来降低结果。
在启用索引时,会有可衡量的性能损失。但是,对您要索引的内容进行仔细的规划以及对要索引的了解,您可以避免面临风险的影响。
最有效的方法是将 Data Grid 配置为仅索引所需的字段。无论您存储 Plain Old Java 对象(POJO)还是使用 Protobuf 模式,您标注的更多字段都越长,使用数据网格构建索引所需的时间。如果您有一个带有五个字段的 POJO,但您只需要查询这两个字段,请不要配置 Data Grid 来索引您不需要的三个字段。
数据网格为您提供了几个调整索引操作的选项。例如,Data Grid 存储的索引与数据不同,请将索引保存到磁盘而不是内存。每当添加、修改或删除条目时,Data Grid 使用索引写入器使索引与缓存保持同步。如果您启用索引,然后观察较慢的写操作,并认为索引会导致性能丢失,那么在写入磁盘前,将索引保留在内存中缓冲区的时间较长。这会提高索引操作,并有助于降低写入吞吐量的降级,但会消耗更多内存。对于大多数部署,默认的索引配置合适,且不会减慢写入速度。
在某些情况下,无法对缓存进行索引,例如,需要查询缓存的写重缓存,且不需要以毫秒为单位。它都取决于您要实现的目标。更快查询意味着读取速度较快,但会牺牲索引的速度较慢的写入速度。
您可以通过正确设置 maxResults
和 hit-count-accuracy
值来提高索引查询的性能。
2.10.1. 持续查询和数据网格性能 复制链接链接已复制到粘贴板!
持续查询为应用程序提供持续更新流,这样可生成大量事件。Data Grid 会临时为它生成的每个事件分配内存,这可能会导致内存压力,并可能导致 OutOfMemoryError
异常,特别是远程缓存。因此,您应该仔细设计持续查询,以避免产生任何性能影响。
数据网格强烈建议您将持续查询的范围限制为您所需的最小信息量。为达成此目标,您可以使用 projections 和 predicates。例如,以下语句只提供有关符合条件而非整个条目的字段子集:
SELECT field1, field2 FROM Entity WHERE x AND y
SELECT field1, field2 FROM Entity WHERE x AND y
务必要确保创建的每个 ContinuousQueryListener
可以快速处理所有接收的事件,而不阻止线程。要达到此目的,您应该避免不必要的生成事件的缓存操作。