參考文檔:
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執行個體關掉 (上邊運作的循環代碼程式不要關閉)
發現程式正常運作:
但是上邊的步驟,我經過多次測試,在任意關閉某個執行個體的時候,偶爾會報如下錯誤:叢集挂了
我們把寫的方法注釋掉,隻保留讀取的代碼,同樣會偶爾報異常。
但是大部分情況下,關掉其中一個執行個體,程式都正常運作:
作者:PeterZhang
出處:https://www.cnblogs.com/peterzhang123
本文版權歸作者和部落格園共有,歡迎轉載,但必須給出原文連結,并保留此段聲明,否則保留追究法律責任的權利。