2011-07-07 13 views
0

J'ai implémenté un serveur Redis (à utiliser comme cache de données) pour une application Web (ASP.NET). L'un des objectifs de conception est de permettre à l'application Web de fonctionner normalement si le serveur Redis tombe en panne.Détection d'une connexion Redis avant la connexion

Actuellement, cela fonctionne, mais il est très très lent.

ci-dessous est un morceau de code de la classe qui traite Redis:

public string GetCachedData(string k) 
    { 
     string res = string.Empty; 


     if (ConfigurationManager.AppSettings.GetValues("UseMemcache")[0].ToString() == "False") 
     { 
      return res; 
     } 

     try 
     { 
      using (RedisClient rs = new RedisClient(ConfigurationManager.AppSettings.GetValues("RedisServerIP")[0].ToString())) 
      { 
       byte[] buf = rs.Get(k); 

       if (buf != null) 
       { 
         res = System.Text.ASCIIEncoding.UTF8.GetString(buf); 
       } 
      } 
     } 
     catch (Exception) 
     { 
      res = ""; 
     } 

     return res; 
    } 

Question:

Sur la ligne

(RedisClient rs = new RedisClient) 

C'est là l'application bloquera pour longtemps avant de lancer une exception.

Comment cela peut-il être fait de telle sorte qu'il se déclenche immédiatement?

+0

Est-ce que Redis offre ce type de fonctionnalité maintenant? Cela fait près de quatre ans. – GaTechThomas

Répondre

1

Vous ne pouvez pas détecter les délais d'attente réseau instantanément, mais vous pouvez minimiser l'impact. Le problème est que vous essayez la connexion et obtenez le délai d'attente à chaque demande. Essayez cette version - s'il y a une erreur, il cessera d'essayer d'utiliser le cache pour les cinq prochaines minutes.

public DateTime LastCacheAttempt {get;set;} 
private bool? UseMemCache {get;set;} 

public string GetCachedData(string k) 
{ 
    string res = string.Empty; 

    if (UseMemCache == null) { 
     UseMemCache = ConfigurationManager.AppSettings.GetValues("UseMemcache")[0].ToString() != "False"; 
     if (!UseMemCache) LastCacheAttempt == DateTime.MaxValue; 
    } 

    if (UseMemCache || LastCacheAttempt < DateTime.Now.AddMinutes(-5)) 
    { 

    try 
    { 
     using (RedisClient rs = new RedisClient(ConfigurationManager.AppSettings.GetValues("RedisServerIP")[0].ToString())) 
     { 
      byte[] buf = rs.Get(k); 

      if (buf != null) 
      { 
        res = System.Text.ASCIIEncoding.UTF8.GetString(buf); 
      } 
     } 
    } 
    catch (Exception) 
    { 
     UseMemCache = false; 
     LastCacheAttempt = DateTime.Now; 
    } 
    } 
    return res; 
} 
+0

J'avais déjà pensé à quelque chose de similaire à votre solution. J'espérais que l'API du client avait quelque chose de intégré. Je suppose que ce n'est pas le cas, auquel cas je finirai probablement par suivre votre suggestion. – Darknight

+0

Je vais attendre un peu plus longtemps pour voir si d'autres solutions surface, sinon je vais marquer comme accepté. – Darknight

+0

Je ne connais pas de bibliothèque client polyvalente intégrant une stratégie de nouvelle tentative/échec, probablement parce qu'elle diffère trop de l'utilisation - ce code fonctionne pour la mise en cache facultative mais serait totalement inapproprié si redis est le magasin de données principal . –

Questions connexes