2011-08-25 140 views
2

我的脚本通过慢速连接获取很多JPEG文件。我将下载的文件存储在本地缓存中,并重新使用它们直到它们被更改。PHP中磁盘缓存清除/大小限制的模式?

现在的问题是:我该如何确保这个缓存不会超过16Mb(比如说)?

我可以清理时,我想:

  1. 计算总缓存中的所有文件的大小。
  2. 删除一些文件,直到16Mb以下减去需要的数量。

但是如果脚本的两个实例执行此操作会怎么样?两者都确保1Mb是免费的,然后每个使用1Mb,现在缓存为17Mb。 16Mb的规则被打破。

我知道我可以让“懒惰缓存”:只是不时清理它。但恶意用户可能会触发大量缓存并耗尽磁盘空间。这是一个共享主机,所以不能做。

我想出了(坏的)唯一的解决办法:

存储任何东西之前,锁定整个缓存,清理所需的空间,存储文件,解开缓存。为什么不好:我正在缓存很多文件,所以很多锁定和大量清理。慢。 (你怎么锁定/等待锁定在PHP?)

+0

在从远程位置获取文件之前,您是否知道文件大小?如果没有,您可以在获取文件后清理缓存目录。 –

+0

我确实有帮助吗?两个实例每个都获取1Mb,这两个实例都确保有1亿空闲空间,都写入1Mb => 2Mb。 – himself

+0

@himself你能解释缓存是PHP生成的HTML,源代码,序列化数据,JSON还是只是普通的静态图像? – ajreal

回答

1

Maby我误解了你 - 这看起来太简单了。如果您没有数据库可用 - 读取数据库=某些数据格式的文件。

在数据库中使用列创建表:文件名,文件大小,标志如果文件仍在下载(true/false)。

当您获得下载文件的新请求时 - 锁定此表。计算SUM(文件大小)。

  1. 如果它小于16MB减去新的文件大小然后将新的条目添加到表。下载文件后更改旗帜(锁定/解锁之前/之后的锁定)。
  2. 如果是更多:看看你是否有一些下载的文件,你可以删除和删除它们,当你没有足够的可用空间,然后添加条目到表。
  3. 如果你不能释放足够的内存 - 拒绝这个请求/等待一些文件下载。

在每种情况下都会立即解锁表格 - 每次只能锁定几个ms,所以不需要等待任何人。

+0

这是一个有趣的想法,因为它使锁定更容易,但不是它不一样吗?我每次都必须独占锁定。 – himself

+0

@himself:如果只锁定几个ms,排他锁的问题是什么?如果写入正确,大多数使用MySql的应用程序都会使用锁定。文件系统锁有点恶化,但大多数操作系统都会这样做。 – XzKto

+0

有很多文件需要缓存,所以我认为每次运行一次清理(独占锁定)都会导致瓶颈。它不仅仅是几毫秒,因为你正在删除文件并在其中插入文件,而磁盘IO速度很慢。 – himself

0

我不会走那么远,你的规则,但你可以使用以下命令:

file_put_contents -

LOCK_EX - 在文件上获取排它锁,同时在进行 写作。

在某处创建.txt文件,让脚本尝试获取内容。如果有一个脚本已经在运行,它将锁定该文件,以使新脚本无法访问该文件。如果您无法访问该文件,请不要执行缓存代码。

0

您可以使用漏桶。你需要存储lasttime(unix timestamp)和bucket(integer)。每次存储计算自上次保存到缓存以来的延时时间时,都会从桶中以秒为单位递减,然后再按字节x增加。如果存储桶的容量大于jpeg文件大小,则删除最旧的对象以释放所需的空间。