首页 > 解决方案 > 每个客户端都有子缓存的 Java 内存缓存

问题描述

我有一个 ConcurrentMap,它是我的 Web 应用程序的内存缓存/数据库。在那里,我以 id 作为键存储了我的实体。这就是我的实体基本上的样子。

public class MyEntity {
     private int id;
     private String name;
     private Date start;
     private Date end;
     ...
}

现在我有多个用户从我的地图请求不同的数据。User1 有一个开始日期的过滤器。例如,他只得到我地图的第 1、2 和 3 项。User2 还有一个过滤器,只获取地图的第 2、3、4、5 项。所以他们只能得到完整地图的一部分。我正在我的服务器上进行过滤,因为地图太大而无法发送完整的地图,我需要检查其他属性。

我现在的问题是地图中的条目可以从其他一些 API 调用中更新/删除/添加,我想实时更新用户端的条目。

现在我正在向用户发送地图已更新的通知,然后每个用户加载用户需要的完整数据。例如,第 8 项已更新。用户 1 收到通知并再次加载项目 1、2、3,即使更新仅在项目 8 上。因此在这种情况下,没有必要为用户 1 更新,因为他不需要项目 8。

现在我正在寻找一个好的解决方案,以便用户只收到必要的更新。

我正在考虑的一种方法是临时存储用户请求的所有项目 ID。因此,在更新通知中,我可以检查更新的项目是否在列表中,然后仅当更新的项目在用户列表中时才将更新的项目发送给用户。但我担心如果我有很多用户并且带有项目 ID 的用户列表也可能非常大,这将创建的内存使用情况。

仅在用户需要该项目时才将添加/更新/删除的项目发送给用户的好解决方案是什么?因此,就像只观察基础地图(缓存)的一部分,但对每个操作(如添加、更新和删除项目)都有通知。

标签: javacaching

解决方案


基本上没有“银弹”。可能的解决方案取决于使用模式、您的资源和要求。

要问的问题:

  • 现在和将来的总数据集有多大?
  • 显示的数据集有多大?
  • 有多少用户进行搜索?
  • 它是具有封闭用户组的业务应用程序还是需要扩展的公共 Web 应用程序?
  • 更新频率是多少,常见的更新类型有哪些?
  • 存在多少种不同的搜索模式?

最大的问题:

真的需要吗?

看着一堆搜索界面,只有当有交互时,用户才会期待更新。如果它类似于搜索,那么用户将不会期望即时更新。即时更新可能有用且“创新”,但您确实在该问题上花费了大量工程成本。

因此,在开始执行工程任务之前,请确保收益能够证明成本是合理的。也许首先检查这些替代方法:

  1. 不要这样做。仅更新用户交互。也许添加一个重新加载按钮。
  2. 仅通知用户发生了更新,但仅在用户点击“重新加载”时更新。这解决了用户可能没有关注浏览器选项卡并且传输是浪费的问题。

但我担心如果我有很多用户并且带有项目 ID 的用户列表也可能非常大,这将创建的内存使用情况。

在我们的应用程序中,我们观察到没有那么多不同的搜索模式/过滤器。假设您可能有 1000 个用户会话,但只有 20 个不同的热门搜索。如果这是真的,你可以这样做:

  • 对于每个搜索过滤器,您可以存储结果的哈希值。
  • 如果您更新主数据,您将再次运行搜索,并且仅在哈希值更改时才向用户发送更新。

如果它是一个公共的 Web 应用程序,则应该进行更多优化。例如,当应用程序没有焦点时不要发送更新。


推荐阅读