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

参考文档:

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

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

 

Redis链接字符串可以提出来放到 Config文件当中:

  
    "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" />
  

当有多个Redis实例时,可以设置链接多个实例,中间用逗号分隔即可(比如:使用Redis集群)。

  1     public class RedisCacheHelper
  2     {
  3         private readonly Logger _log = LogManager.GetCurrentClassLogger();
  4 
  5         /// 
  6         /// 连接字符串
  7         /// 
  8         private static string _connectionString;
  9 
 10         /// 
 11         /// redis 连接对象
 12         /// 
 13         private static IConnectionMultiplexer _connMultiplexer;
 14 
 15         /// 
 16         /// 实例化对象
 17         /// 
 18         private static RedisCacheHelper _cacheHelper;
 19         /// 
 20         /// 实例
 21         /// 
 22         private static RedisCacheHelper _instance;
 23 
 24         /// 
 25         /// 26         /// 
 27         private static readonly object Locker = new object();
 28 
 29         /// 
 30         /// 数据库
 31         /// 
 32         private IDatabase _db;
 33 
 34 
 35         /// 
 36         /// 默认链接实例
 37         /// 
 38         private RedisCacheHelper()
 39         {
 40             _connectionString = ConfigurationManager.ConnectionStrings["Connection_Redis"].ConnectionString;
 41             _connMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
 42             //添加注册事件
 43             AddRegisterEvent();
 44         }
 45 
 46         /// 
 47         /// 获取 Redis 连接对象
 48         /// 
 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         /// 
 68         /// 获取指定db,默认不指定
 69         /// 
 70         /// 
 71         /// 
 72         private IDatabase GetDatabase(int db = -1)
 73         {
 74             return Connnection.GetDatabase(db);
 75         }
 76 
 77         /// 
 78         /// 调用实例,通过该实例调用Redis
 79         /// 
 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         /// 
 97         /// 添加注册事件
 98         /// 
 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         /// 
111         /// 重新配置广播时(通常意味着主从同步更改)
112         /// 
113         /// 
114         /// 
115         private void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
116         {
117             _log.Info($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
118         }
119 
120         /// 
121         /// 发生内部错误时(主要用于调试)
122         /// 
123         /// 
124         /// 
125         private void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
126         {
127             _log.Error($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
128         }
129 
130         /// 
131         /// 更改集群时
132         /// 
133         /// 
134         /// 
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         /// 
142         /// 配置更改时
143         /// 
144         /// 
145         /// 
146         private void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
147         {
148             _log.Info($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
149         }
150 
151         /// 
152         /// 发生错误时
153         /// 
154         /// 
155         /// 
156         private void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
157         {
158             _log.Error($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
159         }
160 
161         /// 
162         /// 物理连接失败时
163         /// 
164         /// 
165         /// 
166         private void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
167         {
168             _log.Fatal($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
169         }
170 
171         /// 
172         /// 建立物理连接时
173         /// 
174         /// 
175         /// 
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集群)_第1张图片

然后在代码中进行操作验证,向缓存中插入一条数据,然后循环读写数据,循环的时候手动任意关闭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实例关掉 (上边运行的循环代码程序不要关闭)

StackExchange.Redis 之 操作Redis链接字符串配置(链接Redis集群)_第2张图片

发现程序正常运行:

但是上边的步骤,我经过多次测试,在任意关闭某个实例的时候,偶尔会报如下错误:集群挂了

我们把写的方法注释掉,只保留读取的代码,同样会偶尔报异常。

StackExchange.Redis 之 操作Redis链接字符串配置(链接Redis集群)_第3张图片

但是大部分情况下,关掉其中一个实例,程序都正常运行:

StackExchange.Redis 之 操作Redis链接字符串配置(链接Redis集群)_第4张图片

StackExchange.Redis 之 操作Redis链接字符串配置(链接Redis集群)_第5张图片

 

你可能感兴趣的:(StackExchange.Redis 之 操作Redis链接字符串配置(链接Redis集群))