ServiceStack.Redis的PooledRedisClientManager蛋痛的設計

來源:互聯網
上載者:User

PooledRedisClientManager是ServiceStack.Redis的串連池管理類,通過串連池可以實現更高效的Redis操作.但PooledRedisClientManager相關GetClient的設計似乎存在一些問題,如果你只Pool只指向一台Redis這倒不會有什麼問題,但如果指向多台Redis那就可能產生悲劇的事情.下面解釋一下指向多台Redis存在的一些問題.

具體代碼
 1 /// <summary> 2         /// Called within a lock 3         /// </summary> 4         /// <returns></returns> 5         private RedisClient GetInActiveWriteClient() 6         { 7             var desiredIndex = WritePoolIndex % writeClients.Length; 8             //this will loop through all hosts in readClients once even though there are 2 for loops 9             //both loops are used to try to get the prefered host according to the round robin algorithm10             for (int x = 0; x < ReadWriteHosts.Count; x++)11             {12                 var nextHostIndex = (desiredIndex + x) % ReadWriteHosts.Count;13                 var nextHost = ReadWriteHosts[nextHostIndex];14                 for (var i = nextHostIndex; i < writeClients.Length; i += ReadWriteHosts.Count)15                 {                    16                     if (writeClients[i] != null && !writeClients[i].Active && !writeClients[i].HadExceptions)17                         return writeClients[i];18                     else if (writeClients[i] == null || writeClients[i].HadExceptions)19                     {20                         if (writeClients[i] != null)21                             writeClients[i].DisposeConnection();22                         var client = RedisClientFactory.CreateRedisClient(nextHost.Host, nextHost.Port);23 24                         if (nextHost.RequiresAuth)25                             client.Password = nextHost.Password;26 27                         client.Id = RedisClientCounter++;28                         client.ClientManager = this;29                         client.NamespacePrefix = NamespacePrefix;30                         client.ConnectionFilter = ConnectionFilter;31                         32                         writeClients[i] = client;33 34                         return client;35                     }36                 }37             }38             return null;39         }
工作原理

以上代碼的原理非常簡單,就是輪循不同host下的可用串連,如果相關串連可用測直接返回.如果串連損耗則釋放重新建立.

存在問題

如果只使用一個host倒沒什麼問題,但使用多個host的時候那你會發現如果其中一台的redis服務異常那對應的host還是會被輪循到,那就會導致輪循到應該服務的操作所有都異常,還有更悲劇的情況就是當一台伺服器擋機了,就會導致串連到對應host的串連建立逾時導致程式長時間等待然後報錯,這情況對於並發應來說算是一個非常悲劇的事情.

解決方案

其實可以針對host來劃分節點,每個節點存自有的串連池.當相關host的串連操作出現網路異常的時候,應該把host從當前循環配置資源中排除.這樣可以快速地保證操作會馬上遷移到正常的host上面去.

建立一個host恢複機制,PooledRedisClientManager應該存在一個內部機制對損壞的host 進行檢測,通過connect到redis執行ping指令來確認host是否正常,如果正常馬上把host恢複到輪循範圍內.

思考

作者在串連的儲存上並沒有使用Stack,其實使用Stack在設計和管理上更簡單,也是許是為不想在串連push到池中存線上程同步處理環節的開銷.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.