Redis için Azure Cache zaman aşımı sorunlarını giderme

Bu bölümde, bağlantı sırasında oluşan zaman aşımı sorunlarını giderme Redis için Azure Cache.

Not

Bu kılavuzda yer alan sorun giderme adımlarının bazıları Redis komutlarını çalıştırma ve çeşitli performans ölçümlerini izleme yönergelerini içerir. Daha fazla bilgi ve yönergeler için Ek bilgiler bölümündeki makalelere bakın.

Redis sunucusuna düzeltme eki uygulama

Redis için Azure Cache, sunucu yazılımını, sağladığı yönetilen hizmet işlevselliğinin bir parçası olarak düzenli olarak günceller. Bu düzeltme eki uygulama etkinliği büyük ölçüde sahne arkasında yer alır. Redis sunucu düğümlerine düzeltme eki uygulama sırasında yük devretmeler sırasında, bu düğümlere bağlanan Redis istemcileri, bağlantılar bu düğümler arasında değiştirildiklerine göre geçici zaman aşımı durumlarını yaşayabilirsiniz. Uygulamanıza düzeltme eki uygulamanıza ekleyebilecek yan etkiler ve düzeltme eki uygulama olaylarını işlemeyi geliştirme hakkında daha fazla bilgi için bkz. Yük devretme istemci uygulamamı nasıl etkiler?.

StackExchange.Redis zaman aşımı özel durumları

StackExchange.Redis, varsayılan değeri 5000 ms olan zaman uyumlu işlemler için adlı synctimeout bir yapılandırma ayarı kullanır. Bu süre içinde zaman uyumlu bir çağrı tamamlanamazsa StackExchange.Redis istemcisi aşağıdaki örnekte olduğu gibi bir zaman aşımı hatası döndürür:

    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)

Bu hata iletisi sorunun nedenini ve olası çözümlerini size yönlendirmeye yardımcı olacak ölçümler içerir. Aşağıdaki tabloda hata iletisi ölçümleriyle ilgili ayrıntılar yer almaktadır.

Hata iletisi ölçümü Ayrıntılar
inst Son dilimde: 0 komut bırakıldı
mgr Yuva yöneticisi yapıyor, yani işletim sistemiyle ilgili bir şey socket.select olan bir yuvayı belirtmek istiyor. Okuyucu ağdan etkin bir şekilde okumaz çünkü yapacak bir şey olmadığını düşünmez
queue Toplam 73 devam eden işlem var
qu Devam eden işlemlerin 6'sı, devam eden kuyruktadır ve henüz giden ağa yazılmadı
qs Devam eden işlemlerin 67'si sunucuya gönderildi ancak yanıt henüz kullanılamıyor. Yanıt veya Not yet sent by the server olabilir sent by the server but not yet processed by the client.
qc Devam eden işlemlerin sıfırı yanıtları görmüş ancak tamamlanma döngüsünde beklediği için henüz tamamlandı olarak işaretlanmadı
wr Etkin bir yazıcı vardır (yani karşılanmamış altı istek yoksaymıyor) bayt/activewriters
in Etkin okuyucu yok ve NIC bayt/etkinreaders üzerinde okunan sıfır bayt yok

Yukarıdaki özel durum örneğinde, IOCP ve WORKER bölümlerinin her biri Busy değerinden büyük bir değer Min içerir. Bu fark, ayarlarınızı ayarlamanız gerektiği anlamına ThreadPool gelir. ThreadPool ayarlarınızı, iş parçacığı havuzu ölçeğinin hızla seri durumdaki senaryolarda ölçeklendirıldığından emin olmak için yapılandırabilirsiniz.

Olası kök nedenleri ortadan kaldırmak için aşağıdaki adımları kullanabilirsiniz.

  1. En iyi uygulama olarak, Bağlantının kalıcılığı makalesinde açıklandığı gibi, duran bağlantıları algılamak ve değiştirmek için ForceReconnect desenini kullanmaya emin olun.

    StackExchange.Redis kullanma hakkında daha fazla bilgi için bkz Bağlan StackExchange.Redis kullanarak önbelleğe.

  2. Sunucunuzla istemci uygulamanın Azure'da aynı bölgede olduğundan emin olun. Örneğin, önbelleğiniz Doğu ABD'dayken istemci Batı ABD'deyken zaman aşımı alıyor ve istek aralık içinde tamamlanmadı veya yerel geliştirme makinenizin hata ayıklaması sırasında zaman aşımı alıyor synctimeout olabilirsiniz.

    Önbelleğin ve istemcinin aynı Azure bölgesinde olması kesinlikle önerilir. Çapraz bölge çağrıları içeren bir senaryo varsa, bağlantı dizesine bir özellik dahil etmek için aralığı varsayılan 5000 ms aralığından daha yüksek bir synctimeout synctimeout değere ayarlayabilirsiniz. Aşağıdaki örnekte, 8000 ms ile Redis için Azure Cache StackExchange.Redis için bir bağlantı synctimeout dizesinin kod parçacığını gösterir.

    synctimeout=8000,cachename.redis.cache.windows.net,abortConnect=false,ssl=true,password=...
    
  3. StackExchange.RedisNuGet paketinin en son sürümünü NuGet olun. Kodda sürekli düzeltilen hatalar vardır ve bu nedenle en son sürüme sahip olmak önemlidir.

  4. İstekleriniz sunucu veya istemcide bant genişliği sınırlamalarına bağlı ise, bu isteklerin tamamlanması daha uzun sürer ve zaman aşımına neden olabilir. Zaman aşımının sunucusundaki ağ bant genişliği nedeniyle mi olduğunu görmek için bkz. Sunucu tarafı bant genişliği sınırlaması. Zaman aşımının istemci ağ bant genişliği nedeniyle mi olduğunu görmek için bkz. İstemci tarafı bant genişliği sınırlaması.

  5. Sunucuda veya istemcide CPU'ya bağlı mısınız?

    • İstemciniz üzerinde CPU ile bağlanıyorsanız bunu kontrol edin. Yüksek CPU, isteğin aralık içinde işlenmeyecek şekilde işlenmesine ve synctimeout isteğin zaman dışında işlenmesine neden olabilir. Daha büyük bir istemci boyutuna taşıma veya yükü dağıtma, bu sorunu denetlemeye yardımcı olabilir.
    • CPU önbelleği performans ölçümlerini takip edin ve sunucuya CPU bağlı olup olamaya bakabilirsiniz. Redis CPU'ya bağlıyken gelen istekler, bu isteklerin zaman uzmayacak şekilde ilerler. Bu durumu ele almaları için yükü premium önbellekte birden çok parçaya dağıtabilirsiniz veya daha büyük bir boyuta veya fiyatlandırma katmanına yükseltebilirsiniz. Daha fazla bilgi için bkz. Sunucu tarafı bant genişliği sınırlaması.
  6. Sunucuda işlemesi uzun süren komutlar var mı? Redis-server üzerinde işlemesi uzun süren uzun süre çalışan komutlar zaman aşımına neden olabilir. Uzun süre çalışan komutlar hakkında daha fazla bilgi için bkz. Uzun süre çalışan komutlar. redis-cli istemcisini Redis için Azure Cache Redis Konsolu'nu kullanarak örnek örneğinize bağlanabilirsiniz. Ardından SLOWLOG komutunu çalıştırarak beklenenden daha yavaş istekler olup olamay olduğunu bakın. Redis Server ve StackExchange.Redis, daha az büyük istek yerine çok sayıda küçük istek için iyileştirilmiştir. Verilerinizi daha küçük öbeklere bölmek buradaki işleri geliştirebilirsiniz.

    Redis-cli ve stunnel kullanarak önbelleğinizin TLS/SSL uç noktasına bağlanma hakkında bilgi için, Redis Için Oturum Durumu Sağlayıcısı yayınını ASP.NET blog gönderisine bakın.

  7. Yüksek Redis sunucusu yükü zaman aşımına neden olabilir. Önbellek performansı ölçümlerini izleerek sunucu Redis Server Load yükünü izleyebilirsiniz. 100 (maksimum değer) olan bir sunucu yükü, Redis sunucusunun boşta kalma süresi kalmadan istekleri işlemektedir. Bazı isteklerin tüm sunucu özelliğini alıp almayışlarını görmek için önceki paragrafta açıklandığı gibi SlowLog komutunu çalıştırın. Daha fazla bilgi için bkz. Yüksek CPU kullanımı / Sunucu Yükü.

  8. İstemci tarafında ağ blip'e neden olan başka bir olay var mı? Yaygın olaylar şunlardır: istemci örneklerinin sayısını ölçeklendirme, istemcinin yeni bir sürümünü dağıtma veya otomatik ölçeklendirme etkin. Testimiz sırasında otomatik ölçeklendirme veya ölçeğin artır/aşağı doğru artırarak giden ağ bağlantısının birkaç saniye boyunca kaybedilğına neden olduğunu bulduk. StackExchange.Redis kodu, bu tür olaylara ve yeniden bağlantılara karşı daha fazla kullanılır. Yeniden bağlanırken kuyrukta yer alan tüm istekler zaman zaman alamayabilirsiniz.

  9. Önbelleğe yapılan birkaç küçük isteğin öncesini zaman zaman alan büyük bir istek var mıydı? Hata iletisinde yer alan parametresi, istemciden sunucuya kaç istek gönderildiğini ancak bir qs yanıtın işlenmedi olduğunu belirtir. StackExchange.Redis tek bir TCP bağlantısı kullandığı ve aynı anda yalnızca bir yanıt okuyabiliyor olduğu için bu değer büyümeye devam ediyor. İlk işlem zaman dışında olsa da sunucuya veya sunucudan daha fazla verinin gönderilmelerini durdurmaz. Diğer istekler, büyük istek tamamlanıncaya kadar engellenir ve zaman buna neden olabilir. Çözümlerden biri, önbelleğinizin iş yükünüz için yeterince büyük olmasını ve büyük değerleri daha küçük öbeklere bölmesini sağlayarak zaman aşımı ihtimalini en aza indirmektir. Başka bir olası çözüm, istemcinizin nesne havuzunu kullanmak ve yeni ConnectionMultiplexer istek gönderirken en az ConnectionMultiplexer yükleneni seçmektir. Birden çok bağlantı nesnesi arasında yükleme, tek bir zaman aşımının diğer isteklerin de zaman aşımına neden olup olmadığını engellemeli.

  10. kullanıyorsanız yeniden deneme RedisSessionStateProvider zaman aşımını doğru ayara sahip olduğundan emin olun. retryTimeoutInMilliseconds , 'den yüksek operationTimeoutInMilliseconds olmalı, aksi takdirde yeniden denemeler oluşmaz. Aşağıdaki örnekte retryTimeoutInMilliseconds 3000 olarak ayarlanmış. Daha fazla bilgi için bkz. ASP.NET için Oturum Durumu Sağlayıcısı Redis için Azure Cache ve Oturum Durumu Sağlayıcısı ve Çıktı Önbelleği Sağlayıcısı'nın yapılandırma parametrelerini kullanma.

    <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. ve 'i kullanarak Redis için Azure Cache sunucusunda bellek kullanımını Used Memory RSS kontrol Used Memory edin. Çıkarma ilkesi varsa Redis önbellek boyutuna ulaştığında anahtarları Used_Memory çıkarmaya başlar. İdeal olarak, Used Memory RSS yalnızca biraz daha yüksek olması Used memory gerekir. Büyük bir fark, bellek parçalanması (iç veya dış) olduğu anlamına gelir. Used Memory RSS'den küçük Used Memory olduğunda, önbellek belleğinin bir kısmının işletim sistemi tarafından değiştir olduğu anlamına gelir. Bu değiştirme işlemi gerçekleşirse bazı önemli gecikme süreleri yaşanabilir. Redis, ayırmalarının bellek sayfalarına nasıl eşlenmiş olduğu üzerinde denetime sahip olamaysa da, yüksek genellikle bellek kullanımında ani Used Memory RSS bir artışa neden olur. Redis sunucusu belleği serbest bıraksa da, bu, belleği alır ancak belleği sisteme geri verir veya vermeyebilirsiniz. İşletim sistemi tarafından bildirilen değer ile Used Memory bellek tüketimi arasında bir tutarsızlık olabilir. Bellek Redis tarafından kullanılmış ve serbest bırakılana ancak sisteme geri verilmedi. Bellek sorunlarını azaltmak için aşağıdaki adımları gerçekleştirebilirsiniz:

    • Sistemde bellek sınırlamalarına karşı çalışmamanızı için önbelleği daha büyük bir boyuta yükseltin.
    • Daha eski değerlerin proaktif olarak çıkarılana kadar anahtarlarda sona erme sürelerini ayarlayın.
    • Önbellek used_memory_rss ölçümlerini izleme. Bu değer önbelleklerinin boyutuna yaklaştığında, performans sorunları görmeye başlamaya başlayabilirsiniz. Premium önbellek kullanıyorsanız verileri birden çok parçaya dağıt veya daha büyük bir önbellek boyutuna yükselt.

    Daha fazla bilgi için bkz. Redis sunucusunda bellek baskısı.

Ek bilgiler