设为首页 收藏本站
查看: 1220|回复: 0

[经验分享] redis的安装、启动、主从配置,以及.Net下StackExchange.Redis的使用

[复制链接]

尚未签到

发表于 2017-12-21 20:33:11 | 显示全部楼层 |阅读模式
1     public static>
  2     {  

  3         private static string Constr = "";  

  4  
  5         private static object _locker = new Object();
  

  6         private static ConnectionMultiplexer _instance = null;  

  7  
  8         /// <summary>
  
  9         /// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 ConnectionMultiplexer 断开连接,便可以初始化新的连接实例。
  
10         /// </summary>
  
11         public static ConnectionMultiplexer Instance
  
12         {
  
13             get
  
14             {
  
15                 if(Constr.Length == 0)
  
16                 {
  
17                     throw new Exception("连接字符串为设置!");
  
18                 }
  
19                 if (_instance == null)
  
20                 {
  
21                     lock (_locker)
  
22                     {
  
23                         if (_instance == null || !_instance.IsConnected)
  
24                         {
  
25                             _instance = ConnectionMultiplexer.Connect(Constr);
  
26                         }
  
27                     }
  
28                 }
  
29                 //注册如下事件
  
30                 _instance.ConnectionFailed += MuxerConnectionFailed;
  
31                 _instance.ConnectionRestored += MuxerConnectionRestored;
  
32                 _instance.ErrorMessage += MuxerErrorMessage;
  
33                 _instance.ConfigurationChanged += MuxerConfigurationChanged;
  
34                 _instance.HashSlotMoved += MuxerHashSlotMoved;
  
35                 _instance.InternalError += MuxerInternalError;
  
36                 return _instance;
  
37             }
  
38         }
  
39
  
40         static StackExchangeRedisHelper()
  
41         {
  
42         }
  
43
  
44         public static void SetCon(string config)
  
45         {
  
46             Constr = config;
  
47         }
  
48
  
49         /// <summary>
  
50         ///
  
51         /// </summary>
  
52         /// <returns></returns>

  
53         public static>  
54         {
  
55             return Instance.GetDatabase();
  
56         }
  
57
  
58         /// <summary>
  
59         /// 这里的 MergeKey 用来拼接 Key 的前缀,具体不同的业务模块使用不同的前缀。
  
60         /// </summary>
  
61         /// <param name="key"></param>
  
62         /// <returns></returns>
  
63         private static string MergeKey(string key)
  
64         {
  
65             return key;
  
66             //return BaseSystemInfo.SystemCode + key;
  
67         }
  
68
  
69         /// <summary>
  
70         /// 根据key获取缓存对象
  
71         /// </summary>
  
72         /// <typeparam name="T"></typeparam>
  
73         /// <param name="key"></param>
  
74         /// <returns></returns>
  
75         public static T Get<T>(string key)
  
76         {
  
77             key = MergeKey(key);
  
78             return Deserialize<T>(GetDatabase().StringGet(key));
  
79         }
  
80
  
81         /// <summary>
  
82         /// 根据key获取缓存对象
  
83         /// </summary>
  
84         /// <param name="key"></param>
  
85         /// <returns></returns>
  
86         public static object Get(string key)
  
87         {
  
88             key = MergeKey(key);
  
89             return Deserialize<object>(GetDatabase().StringGet(key));
  
90         }
  
91
  
92         /// <summary>
  
93         /// 设置缓存
  
94         /// </summary>
  
95         /// <param name="key"></param>
  
96         /// <param name="value"></param>
  
97         /// <param name="expireMinutes"></param>
  
98         public static void Set(string key, object value, int expireMinutes = 0)
  
99         {
  
100             key = MergeKey(key);
  
101             if (expireMinutes > 0)
  
102             {
  
103                 GetDatabase().StringSet(key, Serialize(value), TimeSpan.FromMinutes(expireMinutes));
  
104             }
  
105             else
  
106             {
  
107                 GetDatabase().StringSet(key, Serialize(value));
  
108             }
  
109            
  
110         }
  
111
  
112         /// <summary>
  
113         /// 判断在缓存中是否存在该key的缓存数据
  
114         /// </summary>
  
115         /// <param name="key"></param>
  
116         /// <returns></returns>
  
117         public static bool Exists(string key)
  
118         {
  
119             key = MergeKey(key);
  
120             return GetDatabase().KeyExists(key); //可直接调用
  
121         }
  
122
  
123         /// <summary>
  
124         /// 移除指定key的缓存
  
125         /// </summary>
  
126         /// <param name="key"></param>
  
127         /// <returns></returns>
  
128         public static bool Remove(string key)
  
129         {
  
130             key = MergeKey(key);
  
131             return GetDatabase().KeyDelete(key);
  
132         }
  
133
  
134         /// <summary>
  
135         /// 异步设置
  
136         /// </summary>
  
137         /// <param name="key"></param>
  
138         /// <param name="value"></param>
  
139         public static async Task SetAsync(string key, object value)
  
140         {
  
141             key = MergeKey(key);
  
142             await GetDatabase().StringSetAsync(key, Serialize(value));
  
143         }
  
144
  
145         /// <summary>
  
146         /// 根据key获取缓存对象
  
147         /// </summary>
  
148         /// <param name="key"></param>
  
149         /// <returns></returns>
  
150         public static async Task<object> GetAsync(string key)
  
151         {
  
152             key = MergeKey(key);
  
153             object value = await GetDatabase().StringGetAsync(key);
  
154             return value;
  
155         }
  
156
  
157         /// <summary>
  
158         /// 实现递增
  
159         /// </summary>
  
160         /// <param name="key"></param>
  
161         /// <returns></returns>
  
162         public static long Increment(string key)
  
163         {
  
164             key = MergeKey(key);
  
165             //三种命令模式
  
166             //Sync,同步模式会直接阻塞调用者,但是显然不会阻塞其他线程。
  
167             //Async,异步模式直接走的是Task模型。
  
168             //Fire - and - Forget,就是发送命令,然后完全不关心最终什么时候完成命令操作。
  
169             //即发即弃:通过配置 CommandFlags 来实现即发即弃功能,在该实例中该方法会立即返回,如果是string则返回null 如果是int则返回0.这个操作将会继续在后台运行,一个典型的用法页面计数器的实现:
  
170             return GetDatabase().StringIncrement(key, flags: CommandFlags.FireAndForget);
  
171         }
  
172
  
173         /// <summary>
  
174         /// 实现递减
  
175         /// </summary>
  
176         /// <param name="key"></param>
  
177         /// <param name="value"></param>
  
178         /// <returns></returns>
  
179         public static long Decrement(string key, string value)
  
180         {
  
181             key = MergeKey(key);
  
182             return GetDatabase().HashDecrement(key, value, flags: CommandFlags.FireAndForget);
  
183         }
  
184
  
185         /// <summary>
  
186         /// 序列化对象
  
187         /// </summary>
  
188         /// <param name="o"></param>
  
189         /// <returns></returns>
  
190         private static byte[] Serialize(object o)
  
191         {
  
192             if (o == null)
  
193             {
  
194                 return null;
  
195             }
  
196             BinaryFormatter binaryFormatter = new BinaryFormatter();
  
197             using (MemoryStream memoryStream = new MemoryStream())
  
198             {
  
199                 binaryFormatter.Serialize(memoryStream, o);
  
200                 byte[] objectDataAsStream = memoryStream.ToArray();
  
201                 return objectDataAsStream;
  
202             }
  
203         }
  
204
  
205         /// <summary>
  
206         /// 反序列化对象
  
207         /// </summary>
  
208         /// <typeparam name="T"></typeparam>
  
209         /// <param name="stream"></param>
  
210         /// <returns></returns>
  
211         private static T Deserialize<T>(byte[] stream)
  
212         {
  
213             if (stream == null)
  
214             {
  
215                 return default(T);
  
216             }
  
217             BinaryFormatter binaryFormatter = new BinaryFormatter();
  
218             using (MemoryStream memoryStream = new MemoryStream(stream))
  
219             {
  
220                 T result = (T) binaryFormatter.Deserialize(memoryStream);
  
221                 return result;
  
222             }
  
223         }
  
224
  
225         /// <summary>
  
226         /// 配置更改时
  
227         /// </summary>
  
228         /// <param name="sender"></param>
  
229         /// <param name="e"></param>
  
230         private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
  
231         {
  
232             //LogHelper.SafeLogMessage("Configuration changed: " + e.EndPoint);
  
233         }
  
234
  
235         /// <summary>
  
236         /// 发生错误时
  
237         /// </summary>
  
238         /// <param name="sender"></param>
  
239         /// <param name="e"></param>
  
240         private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
  
241         {
  
242             //LogHelper.SafeLogMessage("ErrorMessage: " + e.Message);
  
243         }
  
244
  
245         /// <summary>
  
246         /// 重新建立连接之前的错误
  
247         /// </summary>
  
248         /// <param name="sender"></param>
  
249         /// <param name="e"></param>
  
250         private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
  
251         {
  
252             //LogHelper.SafeLogMessage("ConnectionRestored: " + e.EndPoint);
  
253         }
  
254
  
255         /// <summary>
  
256         /// 连接失败 , 如果重新连接成功你将不会收到这个通知
  
257         /// </summary>
  
258         /// <param name="sender"></param>
  
259         /// <param name="e"></param>
  
260         private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
  
261         {
  
262             //LogHelper.SafeLogMessage("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType +(e.Exception == null ? "" : (", " + e.Exception.Message)));
  
263         }
  
264
  
265         /// <summary>
  
266         /// 更改集群
  
267         /// </summary>
  
268         /// <param name="sender"></param>
  
269         /// <param name="e"></param>
  
270         private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
  
271         {
  
272             //LogHelper.SafeLogMessage("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
  
273         }
  
274
  
275         /// <summary>
  
276         /// redis类库错误
  
277         /// </summary>
  
278         /// <param name="sender"></param>
  
279         /// <param name="e"></param>
  
280         private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
  
281         {
  
282             //LogHelper.SafeLogMessage("InternalError:Message" + e.Exception.Message);
  
283         }
  
284
  
285         //场景不一样,选择的模式便会不一样,大家可以按照自己系统架构情况合理选择长连接还是Lazy。
  
286         //建立连接后,通过调用ConnectionMultiplexer.GetDatabase 方法返回对 Redis Cache 数据库的引用。从 GetDatabase 方法返回的对象是一个轻量级直通对象,不需要进行存储。
  
287
  
288         /// <summary>
  
289         /// 使用的是Lazy,在真正需要连接时创建连接。
  
290         /// 延迟加载技术
  
291         /// 微软azure中的配置 连接模板
  
292         /// </summary>
  
293         //private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
  
294         //{
  
295         //    //var options = ConfigurationOptions.Parse(constr);
  
296         //    ////options.ClientName = GetAppName(); // only known at runtime
  
297         //    //options.AllowAdmin = true;
  
298         //    //return ConnectionMultiplexer.Connect(options);
  
299         //    ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect(Coonstr);
  
300         //    muxer.ConnectionFailed += MuxerConnectionFailed;
  
301         //    muxer.ConnectionRestored += MuxerConnectionRestored;
  
302         //    muxer.ErrorMessage += MuxerErrorMessage;
  
303         //    muxer.ConfigurationChanged += MuxerConfigurationChanged;
  
304         //    muxer.HashSlotMoved += MuxerHashSlotMoved;
  
305         //    muxer.InternalError += MuxerInternalError;
  
306         //    return muxer;
  
307         //});
  
308
  
309
  
310         #region  当作消息代理中间件使用 一般使用更专业的消息队列来处理这种业务场景
  
311
  
312         /// <summary>
  
313         /// 当作消息代理中间件使用
  
314         /// 消息组建中,重要的概念便是生产者,消费者,消息中间件。
  
315         /// </summary>
  
316         /// <param name="channel"></param>
  
317         /// <param name="message"></param>
  
318         /// <returns></returns>
  
319         public static long Publish(string channel, string message)
  
320         {
  
321             ISubscriber sub = Instance.GetSubscriber();
  
322             //return sub.Publish("messages", "hello");
  
323             return sub.Publish(channel, message);
  
324         }
  
325
  
326         /// <summary>
  
327         /// 在消费者端得到该消息并输出
  
328         /// </summary>
  
329         /// <param name="channelFrom"></param>
  
330         /// <returns></returns>
  
331         public static void Subscribe(string channelFrom)
  
332         {
  
333             ISubscriber sub = Instance.GetSubscriber();
  
334             sub.Subscribe(channelFrom, (channel, message) =>
  
335             {
  
336                 Console.WriteLine((string) message);
  
337             });
  
338         }
  
339
  
340         #endregion
  
341
  
342         /// <summary>
  
343         /// GetServer方法会接收一个EndPoint类或者一个唯一标识一台服务器的键值对
  
344         /// 有时候需要为单个服务器指定特定的命令
  
345         /// 使用IServer可以使用所有的shell命令,比如:
  
346         /// DateTime lastSave = server.LastSave();
  
347         /// ClientInfo[] clients = server.ClientList();
  
348         /// 如果报错在连接字符串后加 ,allowAdmin=true;
  
349         /// </summary>
  
350         /// <returns></returns>
  
351         public static IServer GetServer(string host, int port)
  
352         {
  
353             IServer server = Instance.GetServer(host, port);
  
354             return server;
  
355         }
  
356
  
357         /// <summary>
  
358         /// 获取全部终结点
  
359         /// </summary>
  
360         /// <returns></returns>
  
361         public static EndPoint[] GetEndPoints()
  
362         {
  
363             EndPoint[] endpoints = Instance.GetEndPoints();
  
364             return endpoints;
  
365         }
  
366     }

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-426608-1-1.html 上篇帖子: python之redis和memcache操作 下篇帖子: Redis链表相关操作命令
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表