【问题标题】:Lightweight caching solution in Scala?Scala 中的轻量级缓存解决方案?
【发布时间】:2012-11-29 23:09:41
【问题描述】:

我只是想知道 Scala 中是否有任何可用的缓存解决方案。 我正在寻找类似 Guava 在 Java 中提供的东西。

我应该在 Scala 中也使用 Guava 吗? Scalaz 中是否有包装器/皮条客或类似的东西? 还有更适合 Scala 开发人员的替代方案吗?

Guava 提供了什么:

LoadingCache<Key, Graph> CACHE= CacheBuilder.newBuilder()
       .maximumSize(1000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .removalListener(MY_LISTENER)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });

Supplier<Animal> singleAnimalCache = Suppliers.memoizeWithExpiration(animalFromDbSupplier(), 365, TimeUnit.DAYS);

我需要一些基本的缓存管理,比如 Guava。

【问题讨论】:

  • @om-nom-nom 这看起来很棒,我正在寻找一个 memoizer(就像在 Guava 和 Supplyer 中一样),但我需要一些缓存管理,比如过期、最大缓存大小等。我不需要在 Scalaz 实现中看不到这一点
  • 你不会是第一个在 Scala 中使用 Guava 的 Cache 的人。
  • Twitter 有一个 helper 用于 MapMaker(现已适应 CacheBuilder)。相反,我直接使用 CacheBuilder 并隐含在 Guava 和 Scala 类型之间进行转换。
  • 这有帮助吗? Guava caching in scala

标签: scala guava


【解决方案1】:

我们有相同的要求,最终围绕 Guava 构建了包装器。我们最近开源了名为Mango 的库部分。如果你不介意额外的依赖,你可以像这样使用它

import org.feijoas.mango.common.cache._
import org.feijoas.mango.common.base.Suppliers._

val MY_LISTENER = (remNot: RemovalNotification[Key, Graph]) => ()
// > MY_LISTENER : RemovalNotification[Key,Graph] => Unit = <function1>

val CACHE = CacheBuilder.newBuilder()
  .maximumSize(1000)
  .expireAfterWrite(10, TimeUnit.MINUTES)
  .removalListener(MY_LISTENER)
  .build { (key: Key) => new Graph() }
// > CACHE : LoadingCache[Key,Graph] = <function1>

val animalFromDbSupplier = () => {
  // load from db
  new Animal()
}
// > animalFromDbSupplier  : () => Animal = <function0>

val singleAnimalCache = memoizeWithExpiration(animalFromDbSupplier, 365, TimeUnit.DAYS)
// > singleAnimalCache  : () => Animal = Suppliers.memoizeWithExpiration(<function0>, 365, DAYS)

【讨论】:

【解决方案2】:

只是添加一个答案来插入我自己的项目,但我推荐 ScalaCache。

  • 支持 Guava、Ehcache、Memcached 和 Redis(或者您可以根据需要插入自己的实现)
  • 简单、惯用的 Scala API
  • 支持每个元素的生存时间(即使是 Guava,它不提供开箱即用的功能)
  • 支持使用宏魔法自动生成缓存键

https://github.com/cb372/scalacache

【讨论】:

    【解决方案3】:

    Scalaz 中是否有包装器/皮条客或类似的东西?

    在 Scalaz 7 中有 Memo,我在 learning Scalaz day 16 中介绍了一点。

    这是 Adam Rosien 在 scalaz "For the Rest of Us" 谈话中提到的第一件事,所以也请检查一下。他正在使用 Scalaz 6。

    【讨论】:

    • 谢谢,您的链接看起来很棒。但是 Scalaz 提供的备忘录似乎不像 Guava 那样支持过期
    【解决方案4】:

    在 Scala 中使用 guava 缓存 很简单。

    import com.google.common.base._
    import com.google.common.cache._
    
    object Simple_Guava_Caches_in_Scala {
    
       def main(args: Array[String]): Unit = {
    
          // Simple scala guava cache
          val simpleCache1 =
             CacheBuilder
               .newBuilder()
               .build(new CacheLoader[String, String] {
                  def load(key: String): String = {
                     println(s"Simple scala guava cache, heavy work calculating $key")
                     s"It's me $key"
                  }
               })
          println(simpleCache1.get("1"))
          println(simpleCache1.get("1"))
          println(simpleCache1.get("2"))
          println(simpleCache1.get("2"))
          println(simpleCache1.get("2"))
    
    
          // Simple scala guava supplier cache / factory
          println()
          val supplier_cache: Supplier[String] = Suppliers.memoize(
             () => {
                println("Simple scala guava supplier cache / factory, heavy work creating singleton:")
                "It's me"
             }
          )
          println(supplier_cache.get)
          println(supplier_cache.get)
          println(supplier_cache.get)
       }
    }
    

    这是生产

    Simple scala guava cache, heavy work calculating 1
    It's me 1
    It's me 1
    Simple scala guava cache, heavy work calculating 2
    It's me 2
    It's me 2
    It's me 2
    
    Simple scala guava supplier cache / factory, heavy work creating singleton:
    It's me
    It's me
    It's me
    

    我已将此添加到build.sbt

    libraryDependencies += "com.github.cb372" %% "scalacache-guava" % "0.26.0"
    

    将上面的代码转换为 cb372 的 scalacache-guava 会很有趣。可以更简单/更标准化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 2010-11-05
      • 1970-01-01
      相关资源
      最近更新 更多