首页 文章

Clojure - 在磁盘上记忆

提问于
浏览
3

我想提高返回调整大小的图像的函数的性能 . 所请求的图像大小不应该变化很大(取决于设备),因此以某种方式缓存结果是有意义的 .

我当然可以将它存储在磁盘上,并检查调整大小的图像是否存在,并确保如果原始图像被删除,调整大小的版本也是......

或者,我可以使用memoized函数 . 但是由于结果可能很大(我认为图像大约为5-10 MB),将它们存储在内存中是没有意义的(几十GB图像及其修改后的版本会很快填满内存) ) .

那么,有没有办法让一个memoized函数像常规Clojure defmemo 一样,但是由本地磁盘中的文件夹而不是内存支持?然后我可以使用 ttl 策略来确保图像不会长时间不同步 .

类似于crache的东西,但由文件系统支持?

3 回答

  • 2

    你需要的东西听起来像是Datomic的完美用途 . 它很容易从Clojure中使用,非常高效,就像任何好的DB一样,它在内存中最近使用(LRU)缓存 . 它还可以使用各种各样的后备数据库作为基板,从严格的内存(最适合测试和实验)到Postgres,Redis,DynamoDB,Riak等 . 还有一个使用本地文件的“开发”模式所有存储 .

    查看此处的所有详细信息:

    标准版本具有适用于大多数用途的免费永久许可证 . 对于高级功能,可以使用付费版本 .

  • 1

    不要过度思考它 . 您的文件系统作为缓存是正确的想法 . 如果一个文件受欢迎并且文件被大量访问,那么您的操作系统将确保它在RAM中 . 这与许多数据库使用的策略相同 . 例如,Elasticsearch要求您留下足够的RAM以将Lucene索引文件放在RAM中 .

    也不要修改你的文件!以功能方式执行:将它们视为不可变数据 . 您的输入文件不应更改 . 如果是,则它是一个新文件 . 硬盘空间越来越便宜 . 不要害怕周围有很多文件 . 如果必须,您可以执行垃圾收集,在一段时间后删除旧/标记的文件 .

    要查看文件是否在缓存中,您只需检查文件是否存在 . 如果不是:你写一次 .

    总结一下:

    • 让你的操作系统工作缓存

    • 不要编辑文件 . 将它们视为不可变数据 . 写一次

    • 您的操作系统将释放未使用文件的RAM . 硬盘空间非常便宜 .

  • 3

    为什么不从clojure.core.cache实现TTL-Cache,用你需要的功能包装它呢?您的密钥可以是标识已调整大小的图像的任何值,其值将是它在磁盘上的位置 . 然后你可以实现某种get-or-set!函数,传递它将被调用以在不存在时生成图像的函数 . 例如

    (def Cache (atom (cache/ttl-cache-factory {} :ttl 20000)))
    
    (defn get-or-update!
      "wraps the recommended has-hit-get pattern
       https://github.com/clojure/core.cache/wiki/Using"
      [key fn]
      (if (cache/has? @Cache key)
        (get (swap! Cache #(cache/hit % key)) key)
        (get (swap! Cache #(cache/miss % key (fn))) key)))
    

相关问题