2012-05-15 18 views
9

Estoy diseñando un servicio web que usa Redis como base de datos, y quiero conocer las mejores prácticas para usar Redis conectando con el cliente StackService.Redis serviceStack pool connection client

El punto es que he estado leyendo sobre Redis y encontré que la mejor manera de interactuar con el servidor es mediante el uso de una única conexión simultánea.

El problema es que a pesar de que estoy usando PooledRedisClientManager cada vez que un cliente web hace una solicitud al servicio web me sale un un cliente más conectado (conexión abierta) al servidor Redis y este número de cliente conectado aumenta sin límite consumiendo más y más memoria.

La muestra 'culpa' código:

PooledRedisClientManager pooledClientManager = new PooledRedisClientManager("localhost"); 
var redisClient = pooledClientManager.GetClient(); 
using (redisClient) 
{ 
    redisClient.Set("key1", "value1"); 
} 

Lo que hice para resolver el problema, es crear una clase que implementa el patrón Singleton con una estática RedisClient var; Que si el redisClient no está inicializado crea uno nuevo, y si lo es, devuelve el inicializado.

Solución:

public class CustomRedisPooledClient 
{ 
    private static CustomRedisPooledClient _instance = null; 
    public RedisClient redisClient = null; 

    // Objeto sincronización para hacer el Lock 
    private static object syncLock = new object(); 

    private CustomRedisPooledClient() 
    { 
     redisClient = new RedisClient("localhost"); 
    } 

    public static CustomRedisPooledClient GetPooledClient() 
    { 
     if (_instance == null) 
     { 
      lock (syncLock) 
      { 
       if (_instance == null) 
       { 
        _instance = new CustomRedisPooledClient(); 
       } 
      } 
     } 
     return _instance; 
    } 
} 

CustomRedisPooledClient customRedisPooledClient = CustomRedisPooledClient.GetPooledClient(); 
using (customRedisPooledClient.redisClient) 
{ 
    customRedisPooledClient.redisClient.Set("key1", "value1"); 
} 

¿Es esta una buena práctica?

¡Gracias de antemano!

+0

¿Por qué sacó un ** redisClient ** del grupo pero no lo usa? pero están usando ** poolClientManager ** en su lugar? – mythz

+0

Fue un error al escribir la pregunta, ahora se corrigió –

+1

k, aunque podría editar su pregunta porque su 'código de falla' ahora funciona y la ** Solución ** provista no es la ideal. Agregue el problema y haga referencia a la respuesta aceptada para la solución ideal. – mythz

Respuesta

16

que utilizan PooledRedisClientManager y trabaja muy bien:

Código de ejemplo que corro sola vez:

static PooledRedisClientManager pooledClientManager = new PooledRedisClientManager("localhost"); 

y el código que se ejecutan en muchos hilos:

var redisClient = pooledClientManager.GetClient(); 
using (redisClient) 
{ 
    redisClient.Set("key" + i.ToString(), "value1"); 
} 

e I tener solo 11 clientes conectados al servidor.

+0

Si hago lo mismo, recibo un nuevo hilo en cada solicitud hecha por el navegador. Lo he depurado y se ha creado un nuevo hilo (cliente) cuando la línea redisClient.Set ("key" + i.ToString(), "value1"); se ejecuta y pierdo el control y parece que estará abierto para siempre. Hice una prueba para actualizar la página web que llama a la URL del servicio y he llegado a 100 clientes conectados –

+0

Quizás el problema es que ejecuto el código en cada solicitud, ¿o sí? –

+0

¿Estás seguro de que no ejecutas "PooledRedisClientManager pooledClientManager = new PooledRedisClientManager (" localhost ");" ¿cada vez? – eyossi