首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RedisClient失败策略

RedisClient失败策略
EN

Stack Overflow用户
提问于 2014-12-24 15:39:07
回答 2查看 692关注 0票数 2

我在scala中使用了play框架。我还使用RedisScala驱动程序(这一个https://github.com/etaty/rediscala )与Redis通信。如果Redis不包含数据,那么我的应用程序正在MongoDB中查找数据。当Redis失败或只是由于某种原因而不可用时,应用程序等待响应的时间太长。如何在这种情况下实现故障转移策略。如果请求时间太长,我想停止请求Redis。当它恢复在线时,开始与Redis合作。为了澄清这个问题,我的代码如下所示

代码语言:javascript
复制
private def getUserInfo(userName: String): Future[Option[UserInfo]] = {
    CacheRepository.getBaseUserInfo(userName) flatMap{
      case Some(userInfo) =>
        Logger.trace(s"AuthenticatedAction.getUserInfo($userName). User has been found in cache")
        Future.successful(Some(userInfo))
      case None =>
        getUserFromMongo(userName)
    }
  }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-25 02:14:00

我认为你需要区分以下情况(按其发生的可能性排列):

  1. No Data in cache ( Redis ) --我猜在这种情况下,Redis会很快返回,您必须从Mongo获得它。在上面的代码中,您需要在从Mongo获得数据之后,在Redis中设置数据,以便将其保存在缓存中,以便后续的calls.You需要将RedisClient封装在应用程序代码中,以了解任何断开连接/重新连接的情况。本质上有两种状态--第一,当Redis正常工作时,第二,当Redis关闭/慢时。
  2. Redis是缓慢的--这可能是因为以下原因之一。 2.1。网络是慢的--:同样,除了向客户端返回一条消息之外,您不能对此做很多事情。如果你的网络本身发展缓慢,去蒙戈不太可能解决这个问题。 2.2。操作是缓慢的,:例如,当您试图获取大量数据或在排序集上运行范围查询时,就会发生这种情况。在这种情况下,您需要重新访问Redis数据结构,您使用的是在Redis中存储的数据量。但是,在您的示例中,这将不是一个问题。单个Redis操作在LAN上通常是低延迟的。
  3. Redis节点无法联系到--我不确定这种情况将多久发生一次,除非您的网络瘫痪。在这种情况下,连接到MongoDB也会遇到困难。我相信,当运行Redis的节点处于关闭状态或磁盘已满等情况下也会发生这种情况。因此,您应该在设计中处理这个问题。话虽如此,Rediscala客户端将自动检测任何断开连接并自动重新连接。我亲自做过这个。停止并升级Redis版本,并重新启动Redis,而不碰我正在运行的客户机(JVM)。

最后,您可以在上面的程序中使用带超时(参见- Scala Futures - built in timeout?)的未来。如果“未来”没有在超时之前完成,则可以执行其他操作(转到Mongo或向用户返回错误消息)。考虑到#1和#2可能发生的频率比#3高得多,超时值应该反映这两种情况。鉴于#1和#2在LAN上速度很快,您可以从超时值100 of开始。

票数 2
EN

Stack Overflow用户

发布于 2014-12-25 10:22:44

Simanta给出了详细的答案,我只想发布用于超时的代码。代码需要在我的项目中使用的Play框架。

代码语言:javascript
复制
private def get[B](key: String, valueExtractor:  Map[String, ByteString] => Option[B], logErrorMessage: String): Future[Option[B]] = {
    val timeoutFuture = Promise.timeout(None, Duration(Settings.redisTimeout))
    val mayBeHaveData = redisClient.hgetall(key) map { value =>
      valueExtractor(value)
    } recover{
      case e =>
        Logger.info(logErrorMessage + e)
        None
    }

    // if timeout occurred then None will be result of method
    Future.firstCompletedOf(List(mayBeHaveData, timeoutFuture))
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27639206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档