2.10. 索引和查询缓存
查询数据网格缓存可让您分析和过滤数据以获取实时见解。例如,假设一个在线游戏,其中 players在某种程度上相互竞争。如果您要在任意一个时间使用前十个播放器实施领导板,您可以创建一个查询来找出哪个 players 在任意一个时间都有最大点,并将结果限制为最多 10:
Query topTenQuery = playersScores
.create("from com.redhat.PlayerScore ORDER BY p.score DESC, p.timestamp ASC")
.maxResults(10);
List<PlayerScore> topTen = topTenQuery.execute().list();
Query topTenQuery = playersScores
.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 Objects (POJO)还是使用 Protobuf 模式,您注解的更多字段都需要更长的时间来构建索引。如果您有一个带有五个字段的 POJO,但您只需要查询两个字段,请不要将 Data Grid 配置为索引您不需要的三个字段。
Data Grid 为您提供了多个选项来调优索引操作。例如,Data Grid 存储索引与数据不同,请将索引保存到磁盘而不是内存。每当添加、修改或删除条目时,Data Grid 使用索引写入器与缓存保持索引同步。如果您启用索引,然后观察较慢的写操作,并考虑索引会导致性能下降,您可以在写入磁盘前将索引保留在内存缓冲区中更长的时间。这会更快地索引操作,并有助于减少写入吞吐量降低,但消耗更多内存。对于大多数部署,但默认的索引配置适合,且不会减慢写速度。
在某些情况下,可能无法对缓存进行索引,例如,对于需要频繁查询且不需要结果的写密集型缓存。它都取决于您要实现的内容。更快的查询意味着更快的读取速度,但会牺牲索引较慢的写操作。
您可以通过正确设置 maxResults 和 hit-count-accuracy 值来提高索引查询的性能。
2.10.1. 持续查询和数据网格性能 复制链接链接已复制到粘贴板!
持续查询为应用程序提供持续的更新流,从而产生大量事件。Data Grid 会临时为它生成的每个事件分配内存,这可能会导致内存压力,并可能导致 OutOfMemoryError 异常,特别是对于远程缓存。因此,您应该仔细设计您的连续查询以避免出现性能影响。
Data Grid 强烈建议您将持续查询的范围限制为您需要的最小信息。要达到此目的,您可以使用 projections 和 predicates。例如,以下语句只提供与条件匹配的字段子集而不是整个条目的结果:
SELECT field1, field2 FROM Entity WHERE x AND y
SELECT field1, field2 FROM Entity WHERE x AND y
还需要确保创建的每个 continuous QueryListener 可以快速处理所有接收的事件,而无需阻塞线程。要达到此目的,您应该避免任何不必要地生成事件的缓存操作。