天天看點

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從

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

然後在代碼中進行操作驗證,向緩存中插入一條資料,然後循環讀寫資料,循環的時候手動任意關閉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             }      

成功将緩存存入到伺服器當中,運作效果如下:

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

此時檢視Redis叢集,發現主從執行個體都有資料了,接下來我們把其中任意1個 Redis執行個體關掉 (上邊運作的循環代碼程式不要關閉)

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

發現程式正常運作:

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

但是上邊的步驟,我經過多次測試,在任意關閉某個執行個體的時候,偶爾會報如下錯誤:叢集挂了

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

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

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

但是大部分情況下,關掉其中一個執行個體,程式都正常運作:

StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)
StackExchange.Redis 之 操作Redis連結字元串配置(連結Redis叢集)

作者:PeterZhang

出處:https://www.cnblogs.com/peterzhang123

本文版權歸作者和部落格園共有,歡迎轉載,但必須給出原文連結,并保留此段聲明,否則保留追究法律責任的權利。