一个缓存系统在Windows上应该使用多少内存?

7
我正在开发一个客户端/服务器应用程序,其中服务器保存大的数据块,例如大型图片或视频文件,这些数据块由客户端请求,我需要创建一个内存中的客户端缓存系统来保存其中一些大数据以加快进程。只是为了明确,每个单独的图像或视频并不是很大,但所有数据的总大小可能非常大。

但我现在面临“我应该缓存多少数据”的问题,想知道在 Windows 上是否有关于采取哪种策略的黄金规则。缓存是在客户端上进行的,我不需要在服务器上进行缓存。

  1. 我是否应该始终保持全局内存使用率低于x%?这将是多少?如果启动了另一个程序并占用了大量内存,我应该清空缓存吗?
  2. 我是否应该在缓存之前请求可用的空闲内存量,并使用该内存的固定百分比来满足我的需求?
  3. 我希望不必这样做,但我是否应该询问用户愿意分配给我的应用程序多少内存?如果是这样,我如何计算该属性的默认值以及永远不会使用该设置的用户的值?

所以,一个图像可以被多个客户端请求吗?或者,在10分钟的时间间隔内可以多次请求一个图像吗? - Gabriel
图像可以在10分钟的时间间隔内由多个客户端多次请求,但我认为这与我的需求无关,因为我需要为客户端而不是服务器制定缓存策略。 - jonjbar
我不明白。在服务器端,您想为每个客户端创建单独的缓存? - Gabriel
不,我需要客户端缓存从服务器“下载”的数据,因为它们可能会被多次使用。 - jonjbar
5个回答

8
不要自己创建缓存算法,而是使用带有FILE_ATTRIBUTE_TEMPORARY属性的文件将数据写入,并利用客户端机器的缓存。尽管这种方法似乎意味着你使用文件,但如果系统中有可用内存,则该文件永远不会离开缓存并且始终保留在内存中。一些优点包括:1. 无需编写任何代码。2. 系统缓存考虑到所有运行的其他进程,你自己实现这一点并不实际。3. 在64位Windows上,系统可以使用其可用的所有内存作为缓存。在32位Delphi进程中,你受限于32位地址空间。4. 即使缓存已满并且需要将文件刷新到磁盘,本地磁盘访问比查询数据库然后通过网络传输文件要快得多。

1
这非常有趣,但我还是有点担心反病毒扫描器,正如下面的帖子所提到的那样,它会减慢进程速度:https://dev59.com/3m435IYBdhLWcg3wvys5 - jonjbar
3
您只需要编写一次,预计会多次阅读它。如果病毒扫描程序确实扫描了文件,则所花费的时间将很少。如果您在代码的热循环中一遍又一遍地写入文件,那么可能会有问题。缓存的整个目的是您不经常写入它,但更频繁地读取它。 - David Heffernan
@Altar 如果我控制服务器,那么这个方法是可行的,但是这将在多个客户端上发生,并且可能安装了大量的反病毒软件。 - jonjbar
1
@David:请注意文件缓存的工作原理及其默认设置。在操作系统的客户端和服务器版本中,它是不同的(请参见http://support.microsoft.com/kb/837331),并且在所有进程之间共享。应用程序缓存仅由应用程序控制,它知道如何处理其数据(例如MRU或LRU列表?)。 - user160694
2
@ldsandon,你说的对于服务器应用程序可能是正确的,因为它们被允许自私(即:获取尽可能多的非分页内存,而不考虑其他应用程序;如果RAM不足,管理员应该添加更多)。在桌面/客户端方面,情况并非如此,用户可能同时运行多个应用程序,所有这些应用程序都希望尽可能多地获取缓存。想象一下你的Web浏览器为其缓存分配大量非缓存内存,因为它真的“想要控制”。我会立即结束它的进程! - Cosmin Prund
显示剩余6条评论

1

这取决于服务器上运行的其他软件。首先,我会使其可以手动配置。开发一个可以使用特定内存量的系统。如果可以的话,在运行时可以更改该值。

如果您有这些可能性,可以尝试一些微调以查看哪种方法最有效。我不知道任何黄金规则,但我认为您应该能够设置总内存或可用内存的百分比,并保留特定数量的内存始终空闲供系统使用。如果您为服务器操作系统保存了至少500 MB的内存,则可以使用其余部分或其余部分的90%作为缓存。但是这些数字取决于操作系统的版本和服务器上运行的其他应用程序。

我认为最好从外部使这些数字可配置,并创建一个管理工具,让您首先手动设置这些值。然后,如果您找到了最佳方法,可以推导出计算这些值的公式,并将它们集成到您的管理工具中。此工具不应是缓存程序本身的组成部分(该程序可能是没有GUI的服务)。


1
留下一小部分给系统,使用剩余部分(这里说90%)的策略并不现实。内存碎片可能会减少可用于缓存的空间。 - az01
感谢你们两位的贡献。 - jonjbar

1

一个服务器应用程序通常需要由管理员设置的资源供其自己使用。我不关心其他应用程序的行为,我关心的是成为一个“有礼貌”的应用程序,因此它应该允许管理员配置内存缓存大小等,只有管理员才知道如何正确配置他的系统(通常...)

默认值应该考虑到整体可用内存有多少,特别是在32位系统上,内存小于4GB(只要Delphi提供的是32位应用程序),留出一些空间给操作系统,并避免过于频繁的交换。建议在安装时询问用户选择。

如果应用程序是在服务器上唯一运行的,则可以将可用内存的40%至75%之间的值视为可接受的(取决于缓存之外需要多少内存),但再次询问用户,因为几乎不可能知道其他正在运行的应用程序可能需要什么。您还可以拥有最小缓存大小和最大缓存大小,从分配较低的值开始,然后在需要时增加它,如果必要则缩小它。

在32位系统上,这是一种可以通过使用PAE/AWE来访问超过3GB内存的内存使用方式。

更新:您还可以监视缓存命中/未命中情况,并计算哪种缓存大小最适合用户需求(它可能太小,但也可能太大),然后向用户提供建议。


如果缓存在客户端上,同样需要考虑让用户选择最适合他的设置(像Photoshop这样的应用程序有这样的配置选项)。如果应用程序是用户在特定时间内将要使用的主要应用程序,他愿意允许尽可能多的内存来高效地工作,但是只有用户知道多少是可以的。此外,这个应用程序是面向“专业”用户还是“休闲”用户?前者通常需要控制,后者可能需要更多的指导和自动计算值。 - user160694

1

问题:

  1. 一张图片可以被多个客户端请求吗?或者,一张图片可以在短时间内被多次请求吗?

  2. 间隔时间有多短?

  3. 网络速度真的很快吗?比硬盘的读写速度快吗?如果你有一个正常的网络,那么硬盘将能够实时从磁盘中读取文件并通过网络传递它们。尤其是Windows已经做了一些良好的缓存,所以最近的文件已经在缓存中。

  4. 运行服务器应用程序的计算机的主要目的是运行服务器吗?还是普通计算机也用于其他任务?换句话说,它是专用服务器还是普通工作站/台式机?

但是我应该问用户愿意为我的应用程序分配多少内存吗?

我肯定会这样做!如果用户认为服务器应用程序不是重要的应用程序,它可能会给予低优先级(低缓存)。否则,如果它认为它是最重要的正在运行的应用程序,它将允许应用程序分配所需的所有RAM,而牺牲其他不那么重要的应用程序。

只需将该设置默认为可接受的值(例如总RAM量的x%)并交付应用程序即可。如果计算机的主要目的是托管此服务器应用程序,则我将使用总RAM量的70%,如果其目的是“通用使用”计算机,则使用总RAM量的40-50%。


如上所述,我的需求是一个客户端缓存系统,可以将从服务器“下载”的数据缓存以便快速访问。感谢您的建议。 - jonjbar

0
说实话,你问的问题并不是我的主要关注点。我更关心我的缓存有多有效。如果你的文件真的很大,你能在缓存中保存多少个?如果你的客户端服务器应用程序有很多用户,你的缓存实际上会缓存其他人会使用的东西的机会有多大?
在花费太多时间处理细节之前,进行分析可能是值得的。

缓存由客户端完成,因此每个客户端都拥有自己的缓存。关于文件大小,每个文件都不是很大,但是将它们全部放在客户端的缓存中所需的累加内存是问题所在,因此我想知道应该为客户端分配多少缓存。 - jonjbar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接