2013-09-23 6 views
9

Pracuję nad kilkoma aplikacjami internetowymi .NET, które intensywnie wykorzystują Redis do buforowania wraz z klientem Redis usługi ServiceStack. We wszystkich przypadkach Redis działa na tym samym komputerze. Użyłem zarówno BasicRedisClientManager i PooledRedisClientManager (zawsze zaimplementowałem jako single) i miałem pewne problemy z obydwoma podejściami.Jak najlepiej zarządzać połączeniami Redis za pomocą ServiceStack?

Z BasicRedisClientManager, wszystko będzie działać dobrze przez jakiś czas, ale ostatecznie Redis zacznie odmawiać połączeń. Używając netstat odkryliśmy, że tysiące połączeń TCP z domyślnym portem Redis było zawieszonych w stanie TIME_WAIT.

Następnie przełączyliśmy się na PooledRedisClientManager, który natychmiast rozwiązał problem. Jednak niedługo później zaczęliśmy dostrzegać sporadyczne skoki procesora, które zawęziłyśmy do oczekujących wątków (wywołania System.Threading.Monitor.Wait) spowodowanych przez PooledRedisClientManager.GetClient.

W kodzie używamy metody get-in-get-out (używając wygodnych skrótów ExecAs ServiceStack), więc w ogólnych połączeniach uzyskuje się bardzo często, ale odbywa się tak krótko, jak to możliwe.

Dostajemy niewielki ruch, ale nie jesteśmy StackExchange, i nie mogę przestać myśleć, że klient ServiceStack jest gotowy do pracy i robimy coś złego. Czy PooledRedisClientManager to właściwe podejście? Czy wskazane byłoby po prostu zwiększenie wielkości basenu? A może to tylko maskowanie problemu za pomocą naszego kodu?

Po prostu szukam ogólnych wskazówek tutaj, nie mam konkretnego kodu, na który potrzebuję pomocy w tym momencie. Z góry dziękuję.

+0

Czysta i całkowita spekulacja - użyłem AppHarbor i miałem problemy z utrzymaniem połączeń Redis i przekroczeniem limitów połączeń Redis. Witryny otrzymują praktycznie zerowy ruch, więc spekuluję, że wynika to z tego, że usługi IIS trafiają w stan bezczynności i zamykają moją aplikację, i że w jakiś sposób nie poprawiają poprawnie połączeń Redis. Jednak SS "RedisClientManagers" obsługuje zamykanie połączeń w "Dispose". Ponownie, spekulacje, ale kilka przerw w działaniu IIS, które nie likwidują połączeń i kilka "Application_Starts" tworzących nowe połączenia Redis, wydaje się być wiarygodnym winowajcą. – paaschpa

+0

Czy jesteś pewien, że twoje połączenia są zamknięte? Sprawdź polecenie CLIENT LIST za pomocą redis-cli –

Odpowiedz

4

Czy jesteś całkowicie pewien, że wszystkie połączenia Redis są usuwane?

Z ServiceStack właściwość Redis na Service i ViewPageBase (jeśli używasz SS Razor) należy wyrzucać sobie, ale za każdym razem poprosić o połączenie z puli samemu trzeba zbywać siebie.

Jednak mimo to ostatnio mieliśmy problemy z naszą pulą, która wyczerpała wszystkie połączenia. Jeden z moich kolegów odkrył, że nie było odpowiedniego czyszczenia stron Razor i wykonał żądanie ściągnięcia. here - Oznacza to, że poprawiono usuwanie stron Razor od ServiceStack v4.0.21. Nie sprawdziłem, czy ta poprawka została przeniesiona do gałęzi v3.

Mój współpracownik dodał także TrackingRedisClientsManager, który może pomóc Ci wyśledzić niewłaściwe składowanie. Zobacz: here

Możesz również sprawdzić statystyki dotyczące PooledRedisClientManagerby using this helper method. Rzuciliśmy go na małą stronę brzytwy, żeby sprawdzić statystyki, jak uważamy za stosowne), ale możesz napisać lepszy kod, aby monitorować kondycję puli poszczególnych węzłów.