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.
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.
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
synctimeoutolabilirsiniz.Ö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
synctimeoutsynctimeoutdeğere ayarlayabilirsiniz. Aşağıdaki örnekte, 8000 ms ile Redis için Azure Cache StackExchange.Redis için bir bağlantısynctimeoutdizesinin kod parçacığını gösterir.synctimeout=8000,cachename.redis.cache.windows.net,abortConnect=false,ssl=true,password=...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.
İ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ı.
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
synctimeoutisteğ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ı.
- İ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
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.
Yüksek Redis sunucusu yükü zaman aşımına neden olabilir. Önbellek performansı ölçümlerini izleerek sunucu
Redis Server Loadyü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ü.İ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.
Ö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
qsyanı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 yeniConnectionMultiplexeristek gönderirken en azConnectionMultiplexeryü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.kullanıyorsanız yeniden deneme
RedisSessionStateProviderzaman aşımını doğru ayara sahip olduğundan emin olun.retryTimeoutInMilliseconds, 'den yüksekoperationTimeoutInMillisecondsolmalı, aksi takdirde yeniden denemeler oluşmaz. Aşağıdaki örnekteretryTimeoutInMilliseconds3000 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" />ve 'i kullanarak Redis için Azure Cache sunucusunda bellek kullanımını
Used Memory RSSkontrolUsed Memoryedin. Çıkarma ilkesi varsa Redis önbellek boyutuna ulaştığında anahtarlarıUsed_Memoryçıkarmaya başlar. İdeal olarak,Used Memory RSSyalnızca biraz daha yüksek olmasıUsed memorygerekir. Büyük bir fark, bellek parçalanması (iç veya dış) olduğu anlamına gelir.Used Memory RSS'den küçükUsed Memoryolduğ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 aniUsed Memory RSSbir 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 ileUsed Memorybellek 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ı.