Felsöka överskridna tidsgränser för Azure Cache for Redis

I det här avsnittet beskrivs felsökning av timeout-problem som uppstår vid anslutning till Azure Cache for Redis.

Anteckning

Flera av felsökningsstegen i den här guiden innehåller instruktioner för att köra Redis-kommandon och övervaka olika prestandamått. Mer information och instruktioner finns i artiklarna i avsnittet Ytterligare information.

Redis-serverkorrigering

Azure Cache for Redis uppdaterar regelbundet sin serverprogramvara som en del av de funktioner för hanterade tjänster som den tillhandahåller. Den här korrigeringsaktiviteten sker i stort sett bakom kulisserna. Under redundansen när Redis-servernoder korrigeras kan Redis-klienter som är anslutna till dessa noder uppleva tillfälliga tidsgränser när anslutningar växlas mellan dessa noder. Mer information om vilka sidoeffekter som korrigering kan ha för ditt program och hur du kan förbättra hanteringen av korrigeringshändelser finns i Hur en redundans påverkar mitt klientprogram.

StackExchange.Redis-timeoutundantag

StackExchange.Redis använder en konfigurationsinställning med namnet för synkrona åtgärder med synctimeout standardvärdet 5 000 ms. Om ett synkront anrop inte slutförs under den här tiden blinkar StackExchange.Redis-klienten ett timeout-fel som liknar följande exempel:

    System.TimeoutException: Timeout performing MGET 2728cc84-58ae-406b-8ec8-3f962419f641, inst: 1,mgr: Inactive, queue: 73, qu=6, qs=67, qc=0, wr=1/1, in=0/0 IOCP: (Busy=6, Free=999, Min=2,Max=1000), WORKER (Busy=7,Free=8184,Min=2,Max=8191)

Det här felmeddelandet innehåller mått som kan hjälpa dig att hitta orsaken till och en möjlig lösning på problemet. Följande tabell innehåller information om måtten för felmeddelanden.

Mått för felmeddelande Information
inst I den senaste tidssegmentet: 0 kommandon har utfärdats
mgr Sockethanteraren gör socket.select , vilket innebär att operativsystemet uppmanas att ange en socket som har något att göra. Läsaren läser inte aktivt från nätverket eftersom den inte tror att det finns något att göra
queue Det finns 73 totala pågående åtgärder
qu 6 av pågående åtgärder finns i kön som inte finns i kön och har ännu inte skrivits till det utgående nätverket
qs 67 av pågående åtgärder har skickats till servern, men ett svar är inte tillgängligt ännu. Svaret kan vara Not yet sent by the server eller sent by the server but not yet processed by the client.
qc Noll av pågående åtgärder har fått svar men har ännu inte markerats som slutförd eftersom de väntar på slutförandesloopen
wr Det finns en aktiv skrivare (vilket innebär att de sex osentliga begärandena inte ignoreras) byte/activewriters
in Det finns inga aktiva läsare och noll byte är tillgängliga för läsning på nätverkskortsbyte/activereaders

I föregående undantagsexempel innehåller IOCP avsnitten WORKER och ett värde som är större än Busy Min värdet. Skillnaden innebär att du bör justera ThreadPool dina inställningar. Du kan konfigurera dina ThreadPool-inställningar för att säkerställa att trådpoolen skalas upp snabbt under burst-scenarier.

Du kan använda följande steg för att eliminera möjliga rotorsaker.

  1. Som bästa praxis bör du se till att du använder ForceReconnect-mönstret för att identifiera och ersätta avstannade anslutningar enligt beskrivningen i artikeln Anslutningsåter återhämtning.

    Mer information om hur du använder StackExchange.Redis finns i Anslut till cachen med StackExchange.Redis.

  2. Kontrollera att servern och klientprogrammet finns i samma region i Azure. Du kan till exempel få tidsgränser när cachen är i USA, östra, men klienten är i USA, västra och begäran inte slutförs inom intervallet, eller om du får tidsgränser när du felsöker från den lokala synctimeout utvecklingsdatorn.

    Vi rekommenderar starkt att ha cacheminnet och i klienten i samma Azure-region. Om du har ett scenario som omfattar anrop mellan regioner bör du ange intervallet till ett värde som är högre än standardintervallet på 5 000 ms genom att inkludera en egenskap i synctimeout synctimeout anslutningssträngen. I följande exempel visas ett kodfragment av en anslutningssträng för StackExchange.Redis som tillhandahålls av Azure Cache for Redis med en på synctimeout 8 000 ms.

    synctimeout=8000,cachename.redis.cache.windows.net,abortConnect=false,ssl=true,password=...
    
  3. Se till att du använder den senaste versionen av StackExchange.Redis NuGet-paketet. Det finns buggar som hela tiden åtgärdas i koden för att göra den mer robust för tidsgränser, så det är viktigt att ha den senaste versionen.

  4. Om dina begäranden är bundna av bandbreddsbegränsningar på servern eller klienten tar det längre tid för dem att slutföras och kan orsaka tidsgränser. Om du vill se om tidsgränsen beror på nätverkets bandbredd på servern kan du gå till Begränsning av bandbredd på serversidan. Om du vill se om tidsgränsen beror på klientens nätverksbandbredd kan du gå till Begränsning av bandbredd på klientsidan.

  5. Får du CPU-bunden på servern eller på klienten?

    • Kontrollera om du blir bunden av CPU på klienten. Hög CPU-användning kan leda till att begäran inte bearbetas inom synctimeout intervallet och att en begäran får en time out. Om du flyttar till en större klientstorlek eller distribuerar belastningen kan du kontrollera det här problemet.
    • Kontrollera om du får CPU-bunden på servern genom att övervaka prestandamåttet för CPU-cache. Begäranden som kommer in när Redis är CPU-bunden kan orsaka att dessa begäranden får en time out. För att lösa det här tillståndet kan du distribuera belastningen över flera shards i en Premium-cache eller uppgradera till en större storlek eller prisnivå. Mer information finns i Begränsning av bandbredd på serversidan.
  6. Tar det lång tid att bearbeta kommandon på servern? Långvariga kommandon som tar lång tid att bearbeta på Redis-servern kan orsaka timeouter. Mer information om långvariga kommandon finns i Långvariga kommandon. Du kan ansluta till din Azure Cache for Redis instansen med redis-cli-klienten eller Redis-konsolen. Kör sedan kommandot SLOWLOG för att se om det finns begäranden som är långsammare än förväntat. Redis Server och StackExchange.Redis är optimerade för många små begäranden i stället för färre stora begäranden. Att dela upp dina data i mindre segment kan förbättra saker här.

    Information om hur du ansluter till cachens TLS/SSL-slutpunkt med redis-cli och stunnel finns i blogginlägget Announcing ASP.NET Session State Provider for Redis Preview Release.

  7. Hög Redis-serverbelastning kan orsaka tidsgränser. Du kan övervaka serverbelastningen genom att övervaka Redis Server Load prestandamåttet för cachen. En serverbelastning på 100 (maxvärde) innebär att Redis-servern har varit upptagen, utan inaktivitetstid, med bearbetning av begäranden. Om du vill se om vissa begäranden tar upp all serverfunktion kör du kommandot SlowLog, enligt beskrivningen i föregående stycke. Mer information finns i Hög CPU-användning/serverbelastning.

  8. Fanns det någon annan händelse på klientsidan som kan ha orsakat en nätverks blip? Vanliga händelser är: skala upp eller ned antalet klientinstanser, distribuera en ny version av klienten eller aktivera autoskalning. I vårt test har vi upptäckt att autoskalning eller upp-/nedskalning kan leda till att utgående nätverksanslutning går förlorad i flera sekunder. StackExchange.Redis-koden är motståndskraftig mot sådana händelser och återansluter. Vid återanslutning kan alla begäranden i kön få en time out.

  9. Fanns det en stor begäran före flera små begäranden till cachen som övergick i time out? Parametern i felmeddelandet visar hur många begäranden som skickades från klienten till qs servern, men inte har bearbetat något svar. Det här värdet kan fortsätta att växa eftersom StackExchange.Redis använder en enda TCP-anslutning och bara kan läsa ett svar i taget. Även om den första åtgärden tog för lång tid stoppas inte mer data från att skickas till eller från servern. Andra begäranden blockeras tills den stora begäran har slutförts och kan orsaka time outs. En lösning är att minimera risken för tidsgränser genom att se till att cacheminnet är tillräckligt stort för din arbetsbelastning och dela upp stora värden i mindre segment. En annan möjlig lösning är att använda en pool med objekt i klienten och välja den minst ConnectionMultiplexer inlästa ConnectionMultiplexer när du skickar en ny begäran. Inläsning över flera anslutningsobjekt bör förhindra att en enda tidsgräns leder till att andra begäranden också får timeout.

  10. Om du använder ska du kontrollera att tidsgränsen för återförsök RedisSessionStateProvider har angetts korrekt. retryTimeoutInMilliseconds bör vara högre än operationTimeoutInMilliseconds , annars görs inga återförsök. I följande exempel retryTimeoutInMilliseconds är inställt på 3000. Mer information finns i ASP.NET sessionstillståndsprovider för Azure Cache for Redis och Så här använder du konfigurationsparametrarna för sessionstillståndsprovidern och utdatacacheprovidern.

    <add
      name="AFRedisCacheSessionStateProvider"
      type="Microsoft.Web.Redis.RedisSessionStateProvider"
      host="enbwcache.redis.cache.windows.net"
      port="6380"
      accessKey="…"
      ssl="true"
      databaseId="0"
      applicationName="AFRedisCacheSessionState"
      connectionTimeoutInMilliseconds = "5000"
      operationTimeoutInMilliseconds = "1000"
      retryTimeoutInMilliseconds="3000" />
    
  11. Kontrollera minnesanvändningen på Azure Cache for Redis servern genom att övervaka Used Memory RSS och Used Memory . Om det finns en avlägsningsprincip börjar Redis ta bort nycklar när Used_Memory cachestorleken nårs. Vi rekommenderar att Used Memory RSS du bara är något högre än Used memory . En stor skillnad innebär att det finns minnesfragmentering (intern eller extern). När Used Memory RSS är mindre än innebär det att en del av Used Memory cacheminnet har växlats av operativsystemet. Om den här växlingen inträffar kan du förvänta dig betydande svarstider. Eftersom Redis inte har kontroll över hur dess allokeringar mappas till minnessidor beror hög ofta på en Used Memory RSS topp i minnesanvändningen. När Redis-servern frigör minne tar den över minnet, men kan eventuellt lämna tillbaka minnet till systemet. Det kan finnas en avvikelse mellan värdet Used Memory och minnesförbrukningen som rapporteras av operativsystemet. Minnet kan ha använts och släppts av Redis men ges inte tillbaka till systemet. Du kan åtgärda minnesproblem genom att göra följande:

    • Uppgradera cacheminnet till en större storlek så att du inte kör mot minnesbegränsningar i systemet.
    • Ange förfallotider för nycklarna så att äldre värden avlägsnas proaktivt.
    • Övervaka used_memory_rss cachemåttet. När det här värdet närmar sig storleken på cacheminnet börjar du förmodligen se prestandaproblem. Distribuera data över flera shards om du använder en premium-cache eller uppgraderar till en större cachestorlek.

    Mer information finns i Minnestryck på Redis-servern.

Ytterligare information