2013-09-23 1 views
9

Io lavoro su alcune app Web .NET che utilizzano Redis pesantemente per il caching con il client Redis di ServiceStack. In tutti i casi ho Redis in esecuzione sulla stessa macchina. Ho utilizzato sia BasicRedisClientManager e PooledRedisClientManager (sempre implementato come singleton) e ho riscontrato alcuni problemi con entrambi gli approcci.Come gestire le connessioni Redis con ServiceStack?

Con BasicRedisClientManager, le cose funzionavano bene per un po ', ma alla fine Redis avrebbe iniziato a rifiutare le connessioni. Usando netstat abbiamo scoperto che migliaia di connessioni TCP verso la porta Redis predefinita si aggiravano nello stato TIME_WAIT.

Abbiamo poi passato a PooledRedisClientManager, che sembrava risolvere il problema immediatamente. Tuttavia, non molto tempo dopo, abbiamo iniziato a notare picchi occasionali della CPU che abbiamo ridotto al thread in attesa (chiamate System.Threading.Monitor.Wait) causato da PooledRedisClientManager.GetClient.

Nel codice, utilizziamo un approccio get-in-get-out (utilizzando le comode scorciatoie di ExecAs di ServiceStack), quindi in generale le connessioni vengono acquisite molto frequentemente ma vengono mantenute nel modo più breve possibile.

Abbiamo una piccola quantità di traffico, ma non ci sono StackExchange, e non posso fare a meno di pensare che il client di ServiceStack è all'altezza del lavoro e stiamo solo facendo qualcosa di sbagliato. PooledRedisClientManager è l'approccio corretto qui? Sarebbe consigliabile semplicemente aumentare la dimensione della piscina? O è probabile che mascherino un problema con il nostro codice?

Solo cercando una guida generale qui, non ho un codice specifico a cui ho bisogno di aiuto a questo punto. Grazie in anticipo.

+0

Speculazione pura e totale: ho utilizzato AppHarbor e ho riscontrato problemi con i collegamenti Redis e il raggiungimento dei limiti di connessione Redis. I siti ricevono praticamente zero traffico, quindi suppongo che sia dovuto al fatto che IIS ha colpito l'idle-timeout e ha interrotto la mia app e in qualche modo non ha disposto correttamente le connessioni Redis. Gli SS 'RedisClientManagers' gestiscono le connessioni di chiusura su 'Dispose', però. Ancora una volta, solo la speculazione, ma alcuni timeout di inattività di IIS che non dispongono di connessioni e alcuni "Application_Starts" che creano nuove connessioni Redis sembrano un colpevole plausibile. – paaschpa

+0

Sei sicuro che le tue connessioni siano state chiuse? Controllare il comando ELENCO CLIENT utilizzando redis-cli –

risposta

4

Sei assolutamente sicuro che tutte le connessioni di Redis siano state smaltite?

Con ServiceStack, la proprietà Redis su Service e ViewPageBase (se si sta utilizzando SS Razor) do disporsi, ma ogni volta che si richiedere una connessione dal pool di te stesso è necessario smaltire da soli.

Tuttavia, nonostante ciò, recentemente abbiamo riscontrato problemi con il nostro pool che si è esaurito anche in tutte le connessioni. Uno dei miei colleghi ha scoperto che non c'era una pulizia adeguata per le pagine Razor e ha effettuato una richiesta di pull here - Ciò significa che c'è stato solo uno smaltimento corretto sulle pagine Razor da ServiceStack v4.0.21. Non ho controllato se quella correzione è stata backportata al ramo v3.

Il mio collega ha anche aggiunto TrackingRedisClientsManager che può aiutare a rintracciare lo smaltimento improprio. Vedere here

È inoltre possibile controllare le statistiche di un PooledRedisClientManagerby using this helper method. Lo abbiamo lanciato su una piccola pagina del rasoio per controllare le statistiche come riteniamo opportuno) ma potremmo scrivere un codice migliore attorno a questo per monitorare anche lo stato del pool di nodi specifici.