我有一个应用程序,它实现了一个套接字连接来读取位置数据。每个位置都与一项资产相关。该流正在实时更新数百个资产的位置数据。下面是两个域对象的基本类表示:
public class Asset{
long id;
Set<Position> positions;
}
public class Position{
long id;
Double latitude;
Double longitude;
Date timestamp
}现在,我希望最后1天的位置数据可供远程客户端用于轮询。将有数百个客户端对每个资产的最后一天的位置数据进行轮询请求。每个资源将每5秒更新一次位置数据。要求客户端请求与实时更新的同步不超过10秒。
这给数据库带来了巨大的负载--这就是EHCache的用武之地--也许...
一个更好的替代方案(值得怀疑!)将配置一个高速缓存,当套接字连接读取它们时,任何新的资产和相关联的位置都将被存储在其中。此缓存将使一天前更新的任何资产过期,并负责定期(大约每分钟)将新资产和头寸写入数据库。远程客户端将命中缓存以获取资产和位置数据。
我只是想知道这种方法是否明智,以及EHCache的哪些功能可以促进它。
非常感谢
发布于 2011-12-21 05:38:17
这可能是EhCache和Hibernate query cache的一个很好的用例。这是基本的架构。首先,为Position对象启用二级缓存。我认为它忽略了代表一对多关系的asset字段,但这无关紧要。
我假设客户端正在运行与以下查询类似的查询:
SELECT p
FROM Position p
WHERE timestamp >= :timestamp
AND asset = :assert:timestamp参数表示最近24小时(当前时间- 24小时)。您需要对此查询启用cacheable查询提示。
结果如下:客户端使用一对(asset, timestamp)参数间接运行该查询。Hibernate试图在查询缓存中为这对(简化)查询缓存关键字查找查询结果。
如果查询结果丢失,它将运行查询并将结果放入查询缓存中。但它只放置匹配的Position实例的it,而不是实例本身。下一次某个客户端请求相同的(asset, timestamp)对时,Hibernate将在查询缓存中找到结果。然后,只有ids,它将在二级缓存中搜索Position实例。
正如你所看到的,这个场景相当复杂,有几个因素会影响整体的成功:
(asset, timestamp)?大致:。
86400 (number of different seconds in a day) times
number of different assets 键和值必须放入缓存中。请记住,每个值都是一个Position ids列表。那是很大的内存。您可能可以通过限制不同时间戳的数量来减少这一点。过去的24小时真的那么重要吗?这可能是在23到24小时之间吗?通过这种方式,您可以舍入时间戳并减小键空间的大小(缓存大小)。
Position实例都必须适合缓存。这可能是巨大的。但是,否则你将遇到N + 1问题,因为在从查询缓存获取时,如果L2缓存中没有Position实体,Hibernate将根据database.Position表都会使查询缓存失效。在您的情况下,完全预热缓存可能永远不可能。也就是说,您应该尝试在Hibernate中查询缓存。但是,查询缓存非常棘手,需要进行大量调优才能正确实现。
提示:如果内存不足,请尝试将EhCache溢出到磁盘。我从未尝试过,但我相信从本地磁盘获取序列化缓存值(特别是使用SSD时)可能比缓存未命中和数据库查询快得多。
https://stackoverflow.com/questions/8582069
复制相似问题