我在一个Spring多线程web服务上遇到了一个缓存问题,它有一个数据库后端和基于EHCache的缓存。该服务有许多客户端都在一次又一次地请求同一个对象,每秒钟有几十个请求。只有几个对象被频繁地请求,而大量其他对象被不频繁地请求。对象可以每隔几分钟改变一次,所以缓存的TTL设置为一分钟。从数据库加载对象很慢,至少需要几秒钟。
起初我使用了一个朴素的实现来获取对象:
当最初在本地进行测试时,它运行良好。但是,在速度更快的服务器上进行的性能测试显示,每当一个更频繁请求的对象在缓存中过期时,就会出现一些非常糟糕的负载峰值。发生这种情况时,在接下来的10秒内,对该对象的所有请求都将导致数据库加载,直到第一个线程完成数据库加载并将新对象放入缓存。结果是数据库的负载很短但很高,许多用户需要等待请求完成。
我当前的实现通过跟踪当前正在加载哪些对象来提高数据库负载:
使用这种实现,即使对象过期,也只有一个数据库操作。而且,由于数据库负载较低,它也将更快完成。但这仍然意味着在对象加载期间请求对象的所有用户都需要等待。
我真正想要的是,只有第一个线程等待数据库加载,而所有其他线程在加载对象时只返回“过期”对象。对我来说,响应时间比对象老了几秒更重要。
或者,当我注意到某个对象将在几秒钟后过期时,我可以异步刷新缓存。这更接近EHCache的单一TTL模型,这意味着没有人需要等待数据库加载。
我真正的问题是:在我重新发明轮子之前,是否有任何现有框架已经实现了类似的东西(在Spring/EHCache环境中)?或者可能Spring/EHCache中已经存在对此的支持,而我就是找不到正确的选项?
您的设计有缺陷,因为第二个线程无法从缓存中获取任何“过期”对象,因为没有(根据步骤#2:当对象在缓存中时立即返回)。
变通办法:
>
10秒加载单个对象太长了。检查您的SQL并尝试优化它。
缓存对象的时间更长,并运行更新线程来查询数据库中对象的新状态。这意味着线程#1只是触发一些后台工作,最终刷新缓存中的对象。缺点:缓存必须足够大,以便始终将大多数对象保存在内存中。否则“第一次加载对象”会太显眼。
在不加载对象的情况下显示网页,并在后台使用 AJAX 请求加载它们。在对象可用时更新网页。根据您的网站在并非一次准备好所有内容时的有用程度,这可能是响应性和准确性之间的良好平衡。
改善对象的装载。创建“视图”表,其中包含在每行中显示单个对象所需的所有数据。当您对“真实的”(规范化的)对象进行更改时,请更新这些行。“视图缓存”仅由该表填充。这使得加载对象的速度非常快,但代价是数据模型的改变。参见“命令-查询分离”获得一个极端的解决方案。
尝试将数据模型反规范化一点,以减少加载单个对象所需的连接数。或者,缓存一些通常要加入的对象,并在web服务器上进行过滤/聚合。
更新对象时,触发缓存的刷新。很可能有人很快就想看到这个对象。这种方法在人们手动编辑对象时效果最好,在外部系统(新闻代码、股票报价等)随机触发更改时效果最差。
如果您只需要大量的连接来显示所有的细节,请尝试加载概述,然后使用第二个缓存来存储细节,您可以在第二个线程中加载这些细节。与AJAX一起,您可以快速显示对象的概述,这将为您赢得一些等待细节的好感。
有两个Ehcache提供的结构可以帮助您:
两者都需要您更改与缓存交互的方式,因为它们需要配置CacheLoader
。
不幸的是,我找不到显示第二个选项示例的在线文档。它允许使用Quartz刷新缓存条目来调度它。它还可以根据密钥生成器仅刷新密钥的子集。看看 package net.sf.ehcache.constructs.scheduledrefresh
中的类
问题内容: 我在具有数据库后端和基于EHCache的缓存的Spring多线程Web服务上遇到缓存问题。该服务有许多客户端一次又一次地请求同一个对象,每秒有数十个请求。仅频繁请求几个对象,而不经常请求大量其他对象。对象可以每隔几分钟更改一次,因此将缓存的TTL设置为一分钟。从数据库加载对象很慢,并且至少需要几秒钟。 首先,我使用了一个简单的实现来获取对象: 检查对象是否在缓存中。 如果是,请从缓存中
我从缓存中读取数据。我正在使用ehcache。每次插入操作后,我都需要刷新缓存数据。如何使用注释?或者其他方式? ehcache。xml 存储库类: 公共接口NodeRepository扩展了JpaRepository{
我在这里观看了spring loaded的演示http://www.youtube.com/watch?v=GTrNkhVnJBU 它对于类更改非常有效,但是有没有办法让它在视图层工作,特别是SpringMVC和Thymeleaf模板。
问题内容: 我需要在应用程序中缓存一些数据,并且我正在考虑使用Ehcache。我有几个问题: 我是否需要其他服务器进行Ehcache? 我是否需要其他客户端来使用Ehcache? Ehcache如何与多个实例一起使用?甚至可以使用Ehcache创建类似共享缓存的内容吗? 问题答案: 我是否需要其他服务器进行Ehcache? 您可以在独立模式下使用Ehcache。在这种拓扑中,缓存数据保存在应用程序
该组件目前已经升级为Scroll,请移步Scroll
问题内容: 这是一个非常基本的问题-但我无法通过在线搜索找到答案。 我正在使用python控制ArcGIS,并且有一个简单的python脚本,该脚本调用了一些预先编写的代码。 但是,当我对预写代码进行更改时,它似乎没有导致任何更改。我导入了此模块,并尝试刷新它,但是没有任何反应。 我什至将它调用的文件移到了另一个位置,脚本仍然可以正常工作。昨天我做的一件事是我将所有python文件都添加到sys路