基于Java的动态图像缓存

基于Java的动态图像缓存,java,servlets,Java,Servlets,我有一个带有API的servlet,它从GET请求中提供图像。servlet根据GET请求的参数创建CAD命令的数据文件。然后将该数据文件传递到图像解析器,该解析器在文件系统上创建图像。servlet读取图像并返回响应中的字节 所有IO和图像解析器程序的调用都非常繁重,大约80kb的图像在本地系统上以3-4000ms的速度呈现 大约有20个参数组成GET请求。每个都与图像的不同部分相关。因此,可能的图像组合非常大 为了减少加载时间,我计划在数据库中存储渲染图像的blob。如果GET请求与之前执行

我有一个带有API的servlet,它从GET请求中提供图像。servlet根据GET请求的参数创建CAD命令的数据文件。然后将该数据文件传递到图像解析器,该解析器在文件系统上创建图像。servlet读取图像并返回响应中的字节

所有IO和图像解析器程序的调用都非常繁重,大约80kb的图像在本地系统上以3-4000ms的速度呈现

大约有20个参数组成GET请求。每个都与图像的不同部分相关。因此,可能的图像组合非常大

为了减少加载时间,我计划在数据库中存储渲染图像的blob。如果GET请求与之前执行的请求匹配,我将从缓存中提取。否则,我将渲染一个新的。这不会修复“首次”运行,但有助于“n+1次运行”


关于如何提高性能还有其他想法吗?

您可以将文件存储在磁盘上,将映像路径存储在数据库中,因为数据库存储通常比文件系统存储更昂贵

对http get参数进行排序,并将其散列为该图像记录的索引,以便按参数进行快速查询

为了确保程序在磁盘容量不足时不会崩溃,您应该删除未使用或很少使用的记录:

为每条记录存储lastAccessedTime,并在每次请求映像时更新

使用计划程序检查lastAccessedTime,删除低于指定权重的记录。
您可以使用不同的策略来计算权重,例如lastAccessedTime、accessedCount、图像大小、,等等。

您可以以可预测的方式将输入渲染管道的所有参数转换为单个字符串,这样您就可以计算输入的SHA1哈希,然后将输出文件存储在以SHA1作为文件名的目录中,这样,如果您得到一个具有相同参数的请求,您只需计算散列,然后检查文件是否在磁盘上,如果是,则返回它,否则将工作发送到渲染管道并创建文件

如果您有很多文件,您可能希望使用多个目录,那么可以看看git如何通过SHA1的前几个字符将文件划分到多个目录中,以获得灵感


我在我的应用程序上使用了类似的设置我不做渲染只是存储文件,文件存储在db中,但出于性能原因,我使用文件内容的sha1散列作为文件名/URI从磁盘提供这些文件。

使用wget并通过脚本预加载图像,然后在第一个请求传入时使用这些图像如何?你也可以运行一个调度程序,作为一个异步进程周期性地调用wget,这也是我的第一直觉。然而,所需的图像数量是巨大的。我不确定确切的数量,但肯定大于1t并不断扩展。我最终通过哈希代码对图像进行索引,并使用调度程序自动将大量常用图像预缓存到数据库中。到目前为止,性能还不错。我喜欢你清理旧文件的策略。我不确定磁盘上的文件与数据库是否重要,因为我的数据库位于硬件上。好主意。给了我很多思考的机会。