Local config cache feature

Caches accesses to the main cache, only for Configs. This is a tradeoff between responsiveness (of the changes in Admin UI) and performance (avoiding network round trips)

- Usage : set `memcached.configLocalBuffer` with a value in milliseconds.
- Recommended: a few seconds in dev/QA, more in production.
I would suggest to use a `GuavaCache[String,Any]` and to do a pattern match w/ the type when getting from the cash. The result is no more `asInstanceOf`in the code. It should hopefully work the same:

```scala
class MemoryBufferingRawCache(networkCache: RawCache, localCacheDuration: Duration) extends RawCache {

  private val memoryCache: GuavaCache[String, Any] =
    CacheBuilder.newBuilder()
      .expireAfterWrite(localCacheDuration.toMillis, TimeUnit.MILLISECONDS)
      .build[String, Any]()

  override def set[T](key: String, value: T, exp: Duration)(implicit codec: Codec[T]): Future[Unit] = {
    if (exp >= localCacheDuration) {
      memoryCache.put(key, value)
      if (Logger.isTraceEnabled) {
        Logger.trace(LTSV.dump("Key set in local cache" -> key, "for" -> localCacheDuration.toString))
      }
    }
    networkCache.set(key, value, exp)
  }

  override def get[T](key: String)(implicit codec: Codec[T]): Future[Option[T]] = {
    val local = Option(memoryCache.getIfPresent(key))
    local match {
      case Some(obj: T) => Future.successful(Some(obj))
      case None =>
        if (Logger.isTraceEnabled) {
          Logger.trace(LTSV.dump("Key missing in local cache" -> key))
        }
        networkCache.get(key)
    }
  }

  override def close(): Unit = {
    memoryCache.asMap().clear()
    networkCache.close()
  }

}
```