.NET中使用Redis總結——2.項目實戰


接上篇.NET中使用Redis總結 —— 1.Redis搭建

看一些Redis相關資料,.NET 方面ServiceStack.Redis 用的比較多,就直接拿來用了。

在使用過程中經常過出現假死狀態,Redis服務沒有掛,只是客戶端連不上。

錯誤信息如下(這里)

ServiceStack.Redis.RedisResponseException: Unexpected reply: +OK, sPort: 8223, LastCommand: 

重啟redis就正常了,初步懷疑是連接數超過最大值。

改為使用鏈接池

 1 public class RedisCaching
 2     {
 3         /// <summary>
 4         ///     redis配置文件信息
 5         /// </summary>
 6         private static readonly string RedisPath = ConfigurationManager.AppSettings["RedisPath"];
 7 
 8         /// <summary>
 9         /// 
10         /// </summary>
11         public static RedisClient Redis;
12 
13         /// <summary>
14         /// 構造方法
15         /// </summary>
16         static RedisCaching()
17         {
18             var prcm = CreateManager(new string[] { RedisPath }, new string[] { RedisPath });
19             Redis = prcm.GetClient() as RedisClient;
20         }
21 
22         /// <summary>
23         /// 創建鏈接池
24         /// </summary>
25         /// <param name="readWriteHosts"></param>
26         /// <param name="readOnlyHosts"></param>
27         /// <returns></returns>
28         public static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
29         {
30             //支持讀寫分離,均衡負載
31             return new PooledRedisClientManager(readWriteHosts, readOnlyHosts, new RedisClientManagerConfig
32             {
33                 MaxWritePoolSize = 300,//“寫”鏈接池鏈接數
34                 MaxReadPoolSize = 300,//“讀”鏈接池鏈接數
35                 AutoStart = true,
36             });
37         }
38 
39         //static readonly RedisClient redis = new RedisClient("localhost",6379);
40         //private static readonly RedisClient redis = new RedisClient(RedisPath);//長鏈接
41 
42         public static T Get<T>(string key)
43         {
44             return Redis.Get<T>(key);
45         }
46 
47         public static void Set( string key, string value)
48         {
49             Redis.Set(key, value);
50         }
51 }

隨着業務發展,發現還會出現上面出現的錯誤。

使用了lock鎖,之后沒這種問題發生了。

這個問題比較嚴重,每次訪問量上去就出現這種錯。

目前在做項目的性能優化,這次每次都lock嚴重影響效率,得找個方法解決。

首先分析下Redis 服務有時候是假死,重啟下就好了,是不是windows下安裝的Redis 不穩定(windows 這鍋我不背)?

或者是RedisClient有問題?

更換RedisClient成本比較低,可以優先考慮下。

目前使用的是ServiceStack.Redis 換成 StackExchange.Redis 

如果使用StackExchange.Redis 項目必須使用.NET 4.5. 要不然會編譯會報錯。

StackExchange.Redis 的使用

引用StackExchange.Redis.dll

經過一些修改測試后,發現沒有之前那種錯誤,心里竊喜,終於搞定這個問題了。

最后發現還是 too young too naive

遇到了新的問

Timeout performing GET test, inst: 4, mgr: ExecuteSelect, err: never, queue: 12, qu: 0, qs: 12, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: , IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=11,Free=32756,Min=4,Max=32767) (Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts)

 

No connection is available to service this operation: SETEX test; SocketFailure on Interactive, origin: CheckForStaleConnection, input-buffer: 0, outstanding: 2, last-read: 1s ago, last-write: 0s ago, unanswered-write: 1s ago, keep-alive: 60s, pending: 0, state: ConnectedEstablished, in: 0, ar: 0, last-heartbeat: 0s ago, last-mbeat: 0s ago, global: 0s ago, mgr: RecordConnectionFailed_ReportFailure, err: never; IOCP: (Busy=0,Free=1000,Min=24,Max=1000), WORKER: (Busy=3,Free=32764,Min=24,Max=32767), Local-CPU: n/a   at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)

找了一些解決方案,像下面這些方案都沒有解決這個問題

使用StackExchange.Redis客戶端進行Redis訪問出現的Timeout異常排查

Redis 詳解 (一) StackExchange.Redis Client

最后看了這個文章下面的評論有所啟發15天玩轉redis —— 第七篇 同事的一次緩存操作引起對慢查詢的認識

是因為可能某些查詢超過了鏈接超時時間,Redis是單線程的,阻塞了后面的請求,所以報超時。

有了這個方向可以着手解決問題。

  1. 拆分大的文件存儲
  2. 連接操作超時時間延長
  3. 同步操作時間延長
  4. 增加重試連接次數
 1 private static ConnectionMultiplexer GetManager(string connectionString = null)
 2         {
 3             if (string.IsNullOrEmpty(connectionString))
 4             {
 5                 connectionString = Connstr;
 6             }
 7 
 8             var options = ConfigurationOptions.Parse(connectionString);
 9             options.ConnectTimeout = 1000;//連接操作超時(ms)
10             options.KeepAlive = 180;//發送消息以幫助保持套接字活動的時間(秒)(默認為60秒)
11             options.SyncTimeout = 2000;//時間(ms)允許進行同步操作
12             options.ConnectRetry = 3;//重試連接的次數
13
14             return ConnectionMultiplexer.Connect(options);
15         }

經過測試上面的問題出現的概率小了很多,但是還是會出現。 

現在只能定時去監控redis,如果發現異常進行重啟進行解決。

小伙伴們有沒有好得解決方案,求分享~

 

 參考:

  StackExchange.Redis 訪問封裝類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM