StackExchange.Redis 之 操作Redis鏈接字符串配置(鏈接Redis集群)


參考文檔:

https://blog.csdn.net/smj20170417/article/details/79928228

https://www.jianshu.com/p/0b3be884d2f5

 

Redis鏈接字符串可以提出來放到 Config文件當中:

  <connectionStrings>
    <add name="Connection_Redis" connectionString="127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,password=123456,abortConnect=false" />
  </connectionStrings>

當有多個Redis實例時,可以設置鏈接多個實例,中間用逗號分隔即可(比如:使用Redis集群)。

  1     public class RedisCacheHelper
  2     {
  3         private readonly Logger _log = LogManager.GetCurrentClassLogger();
  4 
  5         /// <summary>
  6         /// 連接字符串
  7         /// </summary>
  8         private static string _connectionString;
  9 
 10         /// <summary>
 11         /// redis 連接對象
 12         /// </summary>
 13         private static IConnectionMultiplexer _connMultiplexer;
 14 
 15         /// <summary>
 16         /// 實例化對象
 17         /// </summary>
 18         private static RedisCacheHelper _cacheHelper;
 19         /// <summary>
 20         /// 實例
 21         /// </summary>
 22         private static RedisCacheHelper _instance;
 23 
 24         /// <summary>
 25         /// 26         /// </summary>
 27         private static readonly object Locker = new object();
 28 
 29         /// <summary>
 30         /// 數據庫
 31         /// </summary>
 32         private IDatabase _db;
 33 
 34 
 35         /// <summary>
 36         /// 默認鏈接實例
 37         /// </summary>
 38         private RedisCacheHelper()
 39         {
 40             _connectionString = ConfigurationManager.ConnectionStrings["Connection_Redis"].ConnectionString;
 41             _connMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
 42             //添加注冊事件
 43             AddRegisterEvent();
 44         }
 45 
 46         /// <summary>
 47         /// 獲取 Redis 連接對象
 48         /// </summary>
 49         private IConnectionMultiplexer Connnection
 50         {
 51             get
 52             {
 53                 if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
 54                 {
 55                     lock (Locker)
 56                     {
 57                         if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
 58                         {
 59                             _connMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
 60                         }
 61                     }
 62                 }
 63                 return _connMultiplexer;
 64             }
 65         }
 66 
 67         /// <summary>
 68         /// 獲取指定db,默認不指定
 69         /// </summary>
 70         /// <param name="db"></param>
 71         /// <returns></returns>
 72         private IDatabase GetDatabase(int db = -1)
 73         {
 74             return Connnection.GetDatabase(db);
 75         }
 76 
 77         /// <summary>
 78         /// 調用實例,通過該實例調用Redis
 79         /// </summary>
 80         public static RedisCacheHelper Instance
 81         {
 82             get
 83             {
 84                 if (_cacheHelper != null) return _cacheHelper;
 85                 lock (Locker)
 86                 {
 87                     if (_cacheHelper != null) return _cacheHelper;
 88                     _cacheHelper = new RedisCacheHelper();
 89                 }
 90                 return _cacheHelper;
 91             }
 92         }
 93 
 94         #region 注冊事件
 95 
 96         /// <summary>
 97         /// 添加注冊事件
 98         /// </summary>
 99         private void AddRegisterEvent()
100         {
101             _connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
102             _connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
103             _connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
104             _connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
105             _connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
106             _connMultiplexer.InternalError += ConnMultiplexer_InternalError;
107             _connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
108         }
109 
110         /// <summary>
111         /// 重新配置廣播時(通常意味着主從同步更改)
112         /// </summary>
113         /// <param name="sender"></param>
114         /// <param name="e"></param>
115         private void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
116         {
117             _log.Info($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
118         }
119 
120         /// <summary>
121         /// 發生內部錯誤時(主要用於調試)
122         /// </summary>
123         /// <param name="sender"></param>
124         /// <param name="e"></param>
125         private void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
126         {
127             _log.Error($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
128         }
129 
130         /// <summary>
131         /// 更改集群時
132         /// </summary>
133         /// <param name="sender"></param>
134         /// <param name="e"></param>
135         private void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
136         {
137             _log.Info(
138                 $"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}");
139         }
140 
141         /// <summary>
142         /// 配置更改時
143         /// </summary>
144         /// <param name="sender"></param>
145         /// <param name="e"></param>
146         private void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
147         {
148             _log.Info($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
149         }
150 
151         /// <summary>
152         /// 發生錯誤時
153         /// </summary>
154         /// <param name="sender"></param>
155         /// <param name="e"></param>
156         private void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
157         {
158             _log.Error($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
159         }
160 
161         /// <summary>
162         /// 物理連接失敗時
163         /// </summary>
164         /// <param name="sender"></param>
165         /// <param name="e"></param>
166         private void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
167         {
168             _log.Fatal($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
169         }
170 
171         /// <summary>
172         /// 建立物理連接時
173         /// </summary>
174         /// <param name="sender"></param>
175         /// <param name="e"></param>
176         private void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
177         {
178             _log.Info($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
179         }
180 
181         #endregion
182     }

以上Redis鏈接就配置好了,使用方式如下:首先在把集群中的主從服務都開啟,3主、3從

然后在代碼中進行操作驗證,向緩存中插入一條數據,然后循環讀寫數據,循環的時候手動任意關閉Redis服務當中的 1~2個 服務器

 1             while (true)
 2             {
 3                 //設置age
 4                 RedisCacheHelper.Instance.Set("age", "10", new TimeSpan(0, 5, 0));
 5 
 6                 //獲取age
 7                 var getage = RedisCacheHelper.Instance.Get("age");
 8                 Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + "" + getage);
 9 
10                 Thread.Sleep(1000); // 等待1s
11             }

成功將緩存存入到服務器當中,運行效果如下:

此時查看Redis集群,發現主從實例都有數據了,接下來我們把其中任意1個 Redis實例關掉 (上邊運行的循環代碼程序不要關閉)

發現程序正常運行:

但是上邊的步驟,我經過多次測試,在任意關閉某個實例的時候,偶爾會報如下錯誤:集群掛了

我們把寫的方法注釋掉,只保留讀取的代碼,同樣會偶爾報異常。

但是大部分情況下,關掉其中一個實例,程序都正常運行:

 


免責聲明!

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



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