Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵

摘要:
2.Sentinel模式配置修改主节点redis-6379中的redis.windows.conf配置文件如下修改从节点redis-6380中的redis.windows.conf配置文件以如下配置Sentinel,在Sentinel文件夹下添加Sentinel.conf配置文件a,以及如下所示的Sentinel Redis-26379配置文件修改其他哨兵节点的端口26379。

一,Redis哨兵模式配置

1,下载Redis,然后解压复制5个文件夹分别如下命名。

Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第1张

 2,哨兵模式配置

(1)修改主节点Redis-6379中redis.windows.conf配置文件如下

  Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第2张

   Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第3张

(2)修改从节点Redis-6380中redis.windows.conf配置文件如下

   Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第4张

   Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第5张

 (3)配置哨兵,在哨兵文件夹下添加Sentinel.conf配置文件

   Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第6张

  a,哨兵Redis-26379配置如下

  Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第7张

   其他哨兵节点修改26379端口即可。

 二,Redis帮助类封装(StackExchange.Redis)

  项目文件结构如下:

  Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第8张

   1,RedisHelper.cs

Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第9张Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第10张
   1 using Microsoft.Extensions.Configuration;
   2 using StackExchange.Redis;
   3 using System;
   4 using System.Collections.Generic;
   5 using System.IO;
   6 using System.Linq;
   7 using System.Runtime.Serialization.Formatters.Binary;
   8 using System.Threading.Tasks;
   9 
  10 namespace MS.Quality.Component.Cache.Redis
  11 {
  12     /// <summary>
  13     /// Redis 助手
  14     /// </summary>
  15     public class RedisHelper
  16     {
  17         /// <summary>
  18         /// 连接字符串
  19         /// </summary>
  20         private static readonly string ConnectionString;
  21 
  22         /// <summary>
  23         /// redis 连接对象
  24         /// </summary>
  25         private static IConnectionMultiplexer _connMultiplexer;
  26 
  27         /// <summary>
  28         /// 默认的 Key 值(用来当作 RedisKey 的前缀)
  29         /// </summary>
  30         private static readonly string DefaultKey;
  31 
  32         /// <summary>
  33         ///  34         /// </summary>
  35         private static readonly object Locker = new object();
  36 
  37         /// <summary>
  38         /// 数据库
  39         /// </summary>
  40         private readonly IDatabase _db;
  41 
  42         /// <summary>
  43         /// 获取 Redis 连接对象
  44         /// </summary>
  45         /// <returns></returns>
  46         public IConnectionMultiplexer GetConnectionRedisMultiplexer()
  47         {
  48             if ((_connMultiplexer == null) || !_connMultiplexer.IsConnected)
  49             {
  50                 lock (Locker)
  51                 {
  52                     if ((_connMultiplexer == null) || !_connMultiplexer.IsConnected)
  53                         _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
  54                 }
  55             }
  56 
  57             return _connMultiplexer;
  58         }
  59 
  60         #region 其它
  61 
  62         public ITransaction GetTransaction()
  63         {
  64             return _db.CreateTransaction();
  65         }
  66 
  67         #endregion 其它
  68 
  69         #region 构造函数
  70 
  71         static RedisHelper()
  72         {
  73             var builder = new ConfigurationBuilder()
  74                .SetBasePath(Directory.GetCurrentDirectory())
  75                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
  76             IConfigurationRoot configuration = builder.Build();
  77             if (configuration.GetSection("Redis:Sentinel").Exists())
  78             {
  79                 ConfigurationOptions sentinelOptions = new ConfigurationOptions();
  80                 var IpArray = configuration.GetSection("Redis:Sentinel").GetChildren();
  81                 foreach (var item in IpArray)
  82                 {
  83                     sentinelOptions.EndPoints.Add(item.Value);
  84                 }
  85                 sentinelOptions.TieBreaker = "";
  86                 sentinelOptions.CommandMap = CommandMap.Sentinel;
  87                 sentinelOptions.AbortOnConnectFail = true;
  88                 // Connect!
  89                 ConnectionMultiplexer sentinelConnection = ConnectionMultiplexer.Connect(sentinelOptions);
  90 
  91                 // Get a connection to the master
  92                 ConfigurationOptions redisServiceOptions = new ConfigurationOptions();
  93                 redisServiceOptions.ServiceName = configuration.GetSection("Redis:ServiceName").Value;   //master名称
  94                 redisServiceOptions.Password = configuration.GetSection("Redis:Password").Value;     //master访问密码
  95                 redisServiceOptions.AbortOnConnectFail = true;
  96                 redisServiceOptions.AllowAdmin = true;
  97                 _connMultiplexer = sentinelConnection.GetSentinelMasterConnection(redisServiceOptions);
  98             }
  99             else
 100             {
 101                 ConnectionString = configuration.GetSection("Redis:ConnectionStrings").Value;
 102                 _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
 103             }
 104             DefaultKey = configuration.GetSection("Redis:DefaultKey").Value;
 105 
 106             AddRegisterEvent();
 107         }
 108 
 109         public RedisHelper(int db = -1)
 110         {
 111             _db = _connMultiplexer.GetDatabase(db);
 112         }
 113 
 114         #endregion 构造函数
 115 
 116         #region String 操作
 117 
 118         /// <summary>
 119         /// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)
 120         /// </summary>
 121         /// <param name="redisKey"></param>
 122         /// <param name="redisValue"></param>
 123         /// <param name="expiry"></param>
 124         /// <returns></returns>
 125         public bool StringSet(string redisKey, string redisValue, TimeSpan? expiry = null)
 126         {
 127             redisKey = AddKeyPrefix(redisKey);
 128             return _db.StringSet(redisKey, redisValue, expiry);
 129         }
 130 
 131         /// <summary>
 132         /// 保存多个 Key-value
 133         /// </summary>
 134         /// <param name="keyValuePairs"></param>
 135         /// <returns></returns>
 136         public bool StringSet(IEnumerable<KeyValuePair<RedisKey, RedisValue>> keyValuePairs)
 137         {
 138             keyValuePairs =
 139                 keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
 140             return _db.StringSet(keyValuePairs.ToArray());
 141         }
 142 
 143         /// <summary>
 144         /// 获取字符串
 145         /// </summary>
 146         /// <param name="redisKey"></param>
 147         /// <param name="expiry"></param>
 148         /// <returns></returns>
 149         public string StringGet(string redisKey, TimeSpan? expiry = null)
 150         {
 151             redisKey = AddKeyPrefix(redisKey);
 152             return _db.StringGet(redisKey);
 153         }
 154 
 155         /// <summary>
 156         /// 存储一个对象(该对象会被序列化保存)
 157         /// </summary>
 158         /// <param name="redisKey"></param>
 159         /// <param name="redisValue"></param>
 160         /// <param name="expiry"></param>
 161         /// <returns></returns>
 162         public bool StringSet<T>(string redisKey, T redisValue, TimeSpan? expiry = null)
 163         {
 164             redisKey = AddKeyPrefix(redisKey);
 165             var json = Serialize(redisValue);
 166             return _db.StringSet(redisKey, json, expiry);
 167         }
 168 
 169         /// <summary>
 170         /// 获取一个对象(会进行反序列化)
 171         /// </summary>
 172         /// <param name="redisKey"></param>
 173         /// <param name="expiry"></param>
 174         /// <returns></returns>
 175         public T StringGet<T>(string redisKey, TimeSpan? expiry = null)
 176         {
 177             redisKey = AddKeyPrefix(redisKey);
 178             return Deserialize<T>(_db.StringGet(redisKey));
 179         }
 180 
 181         #region async
 182 
 183         /// <summary>
 184         /// 保存一个字符串值
 185         /// </summary>
 186         /// <param name="redisKey"></param>
 187         /// <param name="redisValue"></param>
 188         /// <param name="expiry"></param>
 189         /// <returns></returns>
 190         public async Task<bool> StringSetAsync(string redisKey, string redisValue, TimeSpan? expiry = null)
 191         {
 192             redisKey = AddKeyPrefix(redisKey);
 193             return await _db.StringSetAsync(redisKey, redisValue, expiry);
 194         }
 195 
 196         /// <summary>
 197         /// 保存一组字符串值
 198         /// </summary>
 199         /// <param name="keyValuePairs"></param>
 200         /// <returns></returns>
 201         public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<RedisKey, RedisValue>> keyValuePairs)
 202         {
 203             keyValuePairs =
 204                 keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
 205             return await _db.StringSetAsync(keyValuePairs.ToArray());
 206         }
 207 
 208         /// <summary>
 209         /// 获取单个值
 210         /// </summary>
 211         /// <param name="redisKey"></param>
 212         /// <param name="redisValue"></param>
 213         /// <param name="expiry"></param>
 214         /// <returns></returns>
 215         public async Task<string> StringGetAsync(string redisKey, string redisValue, TimeSpan? expiry = null)
 216         {
 217             redisKey = AddKeyPrefix(redisKey);
 218             return await _db.StringGetAsync(redisKey);
 219         }
 220 
 221         /// <summary>
 222         /// 存储一个对象(该对象会被序列化保存)
 223         /// </summary>
 224         /// <param name="redisKey"></param>
 225         /// <param name="redisValue"></param>
 226         /// <param name="expiry"></param>
 227         /// <returns></returns>
 228         public async Task<bool> StringSetAsync<T>(string redisKey, T redisValue, TimeSpan? expiry = null)
 229         {
 230             redisKey = AddKeyPrefix(redisKey);
 231             var json = Serialize(redisValue);
 232             return await _db.StringSetAsync(redisKey, json, expiry);
 233         }
 234 
 235         /// <summary>
 236         /// 获取一个对象(会进行反序列化)
 237         /// </summary>
 238         /// <param name="redisKey"></param>
 239         /// <param name="expiry"></param>
 240         /// <returns></returns>
 241         public async Task<T> StringGetAsync<T>(string redisKey, TimeSpan? expiry = null)
 242         {
 243             redisKey = AddKeyPrefix(redisKey);
 244             return Deserialize<T>(await _db.StringGetAsync(redisKey));
 245         }
 246 
 247         #endregion async
 248 
 249         #endregion String 操作
 250 
 251         #region Hash 操作
 252 
 253         /// <summary>
 254         /// 判断该字段是否存在 hash 中
 255         /// </summary>
 256         /// <param name="redisKey"></param>
 257         /// <param name="hashField"></param>
 258         /// <returns></returns>
 259         public bool HashExists(string redisKey, string hashField)
 260         {
 261             redisKey = AddKeyPrefix(redisKey);
 262             return _db.HashExists(redisKey, hashField);
 263         }
 264 
 265         /// <summary>
 266         /// 从 hash 中移除指定字段
 267         /// </summary>
 268         /// <param name="redisKey"></param>
 269         /// <param name="hashField"></param>
 270         /// <returns></returns>
 271         public bool HashDelete(string redisKey, string hashField)
 272         {
 273             redisKey = AddKeyPrefix(redisKey);
 274             return _db.HashDelete(redisKey, hashField);
 275         }
 276 
 277         /// <summary>
 278         /// 从 hash 中移除指定字段
 279         /// </summary>
 280         /// <param name="redisKey"></param>
 281         /// <param name="hashField"></param>
 282         /// <returns></returns>
 283         public long HashDelete(string redisKey, IEnumerable<RedisValue> hashField)
 284         {
 285             redisKey = AddKeyPrefix(redisKey);
 286             return _db.HashDelete(redisKey, hashField.ToArray());
 287         }
 288 
 289         /// <summary>
 290         /// 在 hash 设定值
 291         /// </summary>
 292         /// <param name="redisKey"></param>
 293         /// <param name="hashField"></param>
 294         /// <param name="value"></param>
 295         /// <returns></returns>
 296         public bool HashSet(string redisKey, string hashField, string value)
 297         {
 298             redisKey = AddKeyPrefix(redisKey);
 299             return _db.HashSet(redisKey, hashField, value);
 300         }
 301 
 302         /// <summary>
 303         /// 在 hash 中设定值
 304         /// </summary>
 305         /// <param name="redisKey"></param>
 306         /// <param name="hashFields"></param>
 307         public void HashSet(string redisKey, IEnumerable<HashEntry> hashFields)
 308         {
 309             redisKey = AddKeyPrefix(redisKey);
 310             _db.HashSet(redisKey, hashFields.ToArray());
 311         }
 312 
 313         /// <summary>
 314         /// 在 hash 中获取值
 315         /// </summary>
 316         /// <param name="redisKey"></param>
 317         /// <param name="hashField"></param>
 318         /// <returns></returns>
 319         public RedisValue HashGet(string redisKey, string hashField)
 320         {
 321             redisKey = AddKeyPrefix(redisKey);
 322             return _db.HashGet(redisKey, hashField);
 323         }
 324 
 325         /// <summary>
 326         /// 在 hash 中获取值
 327         /// </summary>
 328         /// <param name="redisKey"></param>
 329         /// <param name="hashField"></param>
 330         /// <param name="value"></param>
 331         /// <returns></returns>
 332         public RedisValue[] HashGet(string redisKey, RedisValue[] hashField, string value)
 333         {
 334             redisKey = AddKeyPrefix(redisKey);
 335             return _db.HashGet(redisKey, hashField);
 336         }
 337 
 338         /// <summary>
 339         /// 从 hash 返回所有的字段值
 340         /// </summary>
 341         /// <param name="redisKey"></param>
 342         /// <returns></returns>
 343         public IEnumerable<RedisValue> HashKeys(string redisKey)
 344         {
 345             redisKey = AddKeyPrefix(redisKey);
 346             return _db.HashKeys(redisKey);
 347         }
 348 
 349         /// <summary>
 350         /// 返回 hash 中的所有值
 351         /// </summary>
 352         /// <param name="redisKey"></param>
 353         /// <returns></returns>
 354         public RedisValue[] HashValues(string redisKey)
 355         {
 356             redisKey = AddKeyPrefix(redisKey);
 357             return _db.HashValues(redisKey);
 358         }
 359 
 360         /// <summary>
 361         /// 在 hash 设定值(序列化)
 362         /// </summary>
 363         /// <param name="redisKey"></param>
 364         /// <param name="hashField"></param>
 365         /// <param name="value"></param>
 366         /// <returns></returns>
 367         public bool HashSet<T>(string redisKey, string hashField, T value)
 368         {
 369             redisKey = AddKeyPrefix(redisKey);
 370             var json = Serialize(value);
 371             return _db.HashSet(redisKey, hashField, json);
 372         }
 373 
 374         /// <summary>
 375         /// 在 hash 中获取值(反序列化)
 376         /// </summary>
 377         /// <param name="redisKey"></param>
 378         /// <param name="hashField"></param>
 379         /// <returns></returns>
 380         public T HashGet<T>(string redisKey, string hashField)
 381         {
 382             redisKey = AddKeyPrefix(redisKey);
 383             return Deserialize<T>(_db.HashGet(redisKey, hashField));
 384         }
 385 
 386         #region async
 387 
 388         /// <summary>
 389         /// 判断该字段是否存在 hash 中
 390         /// </summary>
 391         /// <param name="redisKey"></param>
 392         /// <param name="hashField"></param>
 393         /// <returns></returns>
 394         public async Task<bool> HashExistsAsync(string redisKey, string hashField)
 395         {
 396             redisKey = AddKeyPrefix(redisKey);
 397             return await _db.HashExistsAsync(redisKey, hashField);
 398         }
 399 
 400         /// <summary>
 401         /// 从 hash 中移除指定字段
 402         /// </summary>
 403         /// <param name="redisKey"></param>
 404         /// <param name="hashField"></param>
 405         /// <returns></returns>
 406         public async Task<bool> HashDeleteAsync(string redisKey, string hashField)
 407         {
 408             redisKey = AddKeyPrefix(redisKey);
 409             return await _db.HashDeleteAsync(redisKey, hashField);
 410         }
 411 
 412         /// <summary>
 413         /// 从 hash 中移除指定字段
 414         /// </summary>
 415         /// <param name="redisKey"></param>
 416         /// <param name="hashField"></param>
 417         /// <returns></returns>
 418         public async Task<long> HashDeleteAsync(string redisKey, IEnumerable<RedisValue> hashField)
 419         {
 420             redisKey = AddKeyPrefix(redisKey);
 421             return await _db.HashDeleteAsync(redisKey, hashField.ToArray());
 422         }
 423 
 424         /// <summary>
 425         /// 在 hash 设定值
 426         /// </summary>
 427         /// <param name="redisKey"></param>
 428         /// <param name="hashField"></param>
 429         /// <param name="value"></param>
 430         /// <returns></returns>
 431         public async Task<bool> HashSetAsync(string redisKey, string hashField, string value)
 432         {
 433             redisKey = AddKeyPrefix(redisKey);
 434             return await _db.HashSetAsync(redisKey, hashField, value);
 435         }
 436 
 437         /// <summary>
 438         /// 在 hash 中设定值
 439         /// </summary>
 440         /// <param name="redisKey"></param>
 441         /// <param name="hashFields"></param>
 442         public async Task HashSetAsync(string redisKey, IEnumerable<HashEntry> hashFields)
 443         {
 444             redisKey = AddKeyPrefix(redisKey);
 445             await _db.HashSetAsync(redisKey, hashFields.ToArray());
 446         }
 447 
 448         /// <summary>
 449         /// 在 hash 中获取值
 450         /// </summary>
 451         /// <param name="redisKey"></param>
 452         /// <param name="hashField"></param>
 453         /// <returns></returns>
 454         public async Task<RedisValue> HashGetAsync(string redisKey, string hashField)
 455         {
 456             redisKey = AddKeyPrefix(redisKey);
 457             return await _db.HashGetAsync(redisKey, hashField);
 458         }
 459 
 460         /// <summary>
 461         /// 在 hash 中获取值
 462         /// </summary>
 463         /// <param name="redisKey"></param>
 464         /// <param name="hashField"></param>
 465         /// <param name="value"></param>
 466         /// <returns></returns>
 467         public async Task<IEnumerable<RedisValue>> HashGetAsync(string redisKey, RedisValue[] hashField, string value)
 468         {
 469             redisKey = AddKeyPrefix(redisKey);
 470             return await _db.HashGetAsync(redisKey, hashField);
 471         }
 472 
 473         /// <summary>
 474         /// 从 hash 返回所有的字段值
 475         /// </summary>
 476         /// <param name="redisKey"></param>
 477         /// <returns></returns>
 478         public async Task<IEnumerable<RedisValue>> HashKeysAsync(string redisKey)
 479         {
 480             redisKey = AddKeyPrefix(redisKey);
 481             return await _db.HashKeysAsync(redisKey);
 482         }
 483 
 484         /// <summary>
 485         /// 返回 hash 中的所有值
 486         /// </summary>
 487         /// <param name="redisKey"></param>
 488         /// <returns></returns>
 489         public async Task<IEnumerable<RedisValue>> HashValuesAsync(string redisKey)
 490         {
 491             redisKey = AddKeyPrefix(redisKey);
 492             return await _db.HashValuesAsync(redisKey);
 493         }
 494 
 495         /// <summary>
 496         /// 在 hash 设定值(序列化)
 497         /// </summary>
 498         /// <param name="redisKey"></param>
 499         /// <param name="hashField"></param>
 500         /// <param name="value"></param>
 501         /// <returns></returns>
 502         public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value)
 503         {
 504             redisKey = AddKeyPrefix(redisKey);
 505             var json = Serialize(value);
 506             return await _db.HashSetAsync(redisKey, hashField, json);
 507         }
 508 
 509         /// <summary>
 510         /// 在 hash 中获取值(反序列化)
 511         /// </summary>
 512         /// <param name="redisKey"></param>
 513         /// <param name="hashField"></param>
 514         /// <returns></returns>
 515         public async Task<T> HashGetAsync<T>(string redisKey, string hashField)
 516         {
 517             redisKey = AddKeyPrefix(redisKey);
 518             return Deserialize<T>(await _db.HashGetAsync(redisKey, hashField));
 519         }
 520 
 521         #endregion async
 522 
 523         /// <summary>
 524         /// 在 hash 中获取值(反序列化)
 525         /// </summary>
 526         /// <param name="redisKey"></param>
 527         /// <param name="hashField"></param>
 528         /// <returns></returns>
 529         public HashEntry[] HashGetAll(string redisKey)
 530         {
 531             redisKey = AddKeyPrefix(redisKey);
 532             return _db.HashGetAll(redisKey);
 533         }
 534 
 535         #endregion Hash 操作
 536 
 537         #region List 操作
 538 
 539         /// <summary>
 540         /// 移除并返回存储在该键列表的第一个元素
 541         /// </summary>
 542         /// <param name="redisKey"></param>
 543         /// <returns></returns>
 544         public string ListLeftPop(string redisKey)
 545         {
 546             redisKey = AddKeyPrefix(redisKey);
 547             return _db.ListLeftPop(redisKey);
 548         }
 549 
 550         /// <summary>
 551         /// 移除并返回存储在该键列表的最后一个元素
 552         /// </summary>
 553         /// <param name="redisKey"></param>
 554         /// <returns></returns>
 555         public string ListRightPop(string redisKey)
 556         {
 557             redisKey = AddKeyPrefix(redisKey);
 558             return _db.ListRightPop(redisKey);
 559         }
 560 
 561         /// <summary>
 562         /// 移除列表指定键上与该值相同的元素
 563         /// </summary>
 564         /// <param name="redisKey"></param>
 565         /// <param name="redisValue"></param>
 566         /// <returns></returns>
 567         public long ListRemove(string redisKey, string redisValue)
 568         {
 569             redisKey = AddKeyPrefix(redisKey);
 570             return _db.ListRemove(redisKey, redisValue);
 571         }
 572 
 573         /// <summary>
 574         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 575         /// </summary>
 576         /// <param name="redisKey"></param>
 577         /// <param name="redisValue"></param>
 578         /// <returns></returns>
 579         public long ListRightPush(string redisKey, string redisValue)
 580         {
 581             redisKey = AddKeyPrefix(redisKey);
 582             return _db.ListRightPush(redisKey, redisValue);
 583         }
 584 
 585         /// <summary>
 586         /// 在列表头部插入值。如果键不存在,先创建再插入值
 587         /// </summary>
 588         /// <param name="redisKey"></param>
 589         /// <param name="redisValue"></param>
 590         /// <returns></returns>
 591         public long ListLeftPush(string redisKey, string redisValue)
 592         {
 593             redisKey = AddKeyPrefix(redisKey);
 594             return _db.ListLeftPush(redisKey, redisValue);
 595         }
 596 
 597         /// <summary>
 598         /// 返回列表上该键的长度,如果不存在,返回 0
 599         /// </summary>
 600         /// <param name="redisKey"></param>
 601         /// <returns></returns>
 602         public long ListLength(string redisKey)
 603         {
 604             redisKey = AddKeyPrefix(redisKey);
 605             return _db.ListLength(redisKey);
 606         }
 607 
 608         /// <summary>
 609         /// 返回在该列表上键所对应的元素
 610         /// </summary>
 611         /// <param name="redisKey"></param>
 612         /// <returns></returns>
 613         public IEnumerable<RedisValue> ListRange(string redisKey)
 614         {
 615             redisKey = AddKeyPrefix(redisKey);
 616             return _db.ListRange(redisKey);
 617         }
 618 
 619         /// <summary>
 620         /// 移除并返回存储在该键列表的第一个元素
 621         /// </summary>
 622         /// <param name="redisKey"></param>
 623         /// <returns></returns>
 624         public T ListLeftPop<T>(string redisKey)
 625         {
 626             redisKey = AddKeyPrefix(redisKey);
 627             return Deserialize<T>(_db.ListLeftPop(redisKey));
 628         }
 629 
 630         /// <summary>
 631         /// 移除并返回存储在该键列表的最后一个元素
 632         /// </summary>
 633         /// <param name="redisKey"></param>
 634         /// <returns></returns>
 635         public T ListRightPop<T>(string redisKey)
 636         {
 637             redisKey = AddKeyPrefix(redisKey);
 638             return Deserialize<T>(_db.ListRightPop(redisKey));
 639         }
 640 
 641         /// <summary>
 642         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 643         /// </summary>
 644         /// <param name="redisKey"></param>
 645         /// <param name="redisValue"></param>
 646         /// <returns></returns>
 647         public long ListRightPush<T>(string redisKey, T redisValue)
 648         {
 649             redisKey = AddKeyPrefix(redisKey);
 650             return _db.ListRightPush(redisKey, Serialize(redisValue));
 651         }
 652 
 653         /// <summary>
 654         /// 在列表头部插入值。如果键不存在,先创建再插入值
 655         /// </summary>
 656         /// <param name="redisKey"></param>
 657         /// <param name="redisValue"></param>
 658         /// <returns></returns>
 659         public long ListLeftPush<T>(string redisKey, T redisValue)
 660         {
 661             redisKey = AddKeyPrefix(redisKey);
 662             return _db.ListLeftPush(redisKey, Serialize(redisValue));
 663         }
 664 
 665         #region List-async
 666 
 667         /// <summary>
 668         /// 移除并返回存储在该键列表的第一个元素
 669         /// </summary>
 670         /// <param name="redisKey"></param>
 671         /// <returns></returns>
 672         public async Task<string> ListLeftPopAsync(string redisKey)
 673         {
 674             redisKey = AddKeyPrefix(redisKey);
 675             return await _db.ListLeftPopAsync(redisKey);
 676         }
 677 
 678         /// <summary>
 679         /// 移除并返回存储在该键列表的最后一个元素
 680         /// </summary>
 681         /// <param name="redisKey"></param>
 682         /// <returns></returns>
 683         public async Task<string> ListRightPopAsync(string redisKey)
 684         {
 685             redisKey = AddKeyPrefix(redisKey);
 686             return await _db.ListRightPopAsync(redisKey);
 687         }
 688 
 689         /// <summary>
 690         /// 移除列表指定键上与该值相同的元素
 691         /// </summary>
 692         /// <param name="redisKey"></param>
 693         /// <param name="redisValue"></param>
 694         /// <returns></returns>
 695         public async Task<long> ListRemoveAsync(string redisKey, string redisValue)
 696         {
 697             redisKey = AddKeyPrefix(redisKey);
 698             return await _db.ListRemoveAsync(redisKey, redisValue);
 699         }
 700 
 701         /// <summary>
 702         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 703         /// </summary>
 704         /// <param name="redisKey"></param>
 705         /// <param name="redisValue"></param>
 706         /// <returns></returns>
 707         public async Task<long> ListRightPushAsync(string redisKey, string redisValue)
 708         {
 709             redisKey = AddKeyPrefix(redisKey);
 710             return await _db.ListRightPushAsync(redisKey, redisValue);
 711         }
 712 
 713         /// <summary>
 714         /// 在列表头部插入值。如果键不存在,先创建再插入值
 715         /// </summary>
 716         /// <param name="redisKey"></param>
 717         /// <param name="redisValue"></param>
 718         /// <returns></returns>
 719         public async Task<long> ListLeftPushAsync(string redisKey, string redisValue)
 720         {
 721             redisKey = AddKeyPrefix(redisKey);
 722             return await _db.ListLeftPushAsync(redisKey, redisValue);
 723         }
 724 
 725         /// <summary>
 726         /// 返回列表上该键的长度,如果不存在,返回 0
 727         /// </summary>
 728         /// <param name="redisKey"></param>
 729         /// <returns></returns>
 730         public async Task<long> ListLengthAsync(string redisKey)
 731         {
 732             redisKey = AddKeyPrefix(redisKey);
 733             return await _db.ListLengthAsync(redisKey);
 734         }
 735 
 736         /// <summary>
 737         /// 返回在该列表上键所对应的元素
 738         /// </summary>
 739         /// <param name="redisKey"></param>
 740         /// <returns></returns>
 741         public async Task<IEnumerable<RedisValue>> ListRangeAsync(string redisKey)
 742         {
 743             redisKey = AddKeyPrefix(redisKey);
 744             return await _db.ListRangeAsync(redisKey);
 745         }
 746 
 747         /// <summary>
 748         /// 移除并返回存储在该键列表的第一个元素
 749         /// </summary>
 750         /// <param name="redisKey"></param>
 751         /// <returns></returns>
 752         public async Task<T> ListLeftPopAsync<T>(string redisKey)
 753         {
 754             redisKey = AddKeyPrefix(redisKey);
 755             return Deserialize<T>(await _db.ListLeftPopAsync(redisKey));
 756         }
 757 
 758         /// <summary>
 759         /// 移除并返回存储在该键列表的最后一个元素
 760         /// </summary>
 761         /// <param name="redisKey"></param>
 762         /// <returns></returns>
 763         public async Task<T> ListRightPopAsync<T>(string redisKey)
 764         {
 765             redisKey = AddKeyPrefix(redisKey);
 766             return Deserialize<T>(await _db.ListRightPopAsync(redisKey));
 767         }
 768 
 769         /// <summary>
 770         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 771         /// </summary>
 772         /// <param name="redisKey"></param>
 773         /// <param name="redisValue"></param>
 774         /// <returns></returns>
 775         public async Task<long> ListRightPushAsync<T>(string redisKey, T redisValue)
 776         {
 777             redisKey = AddKeyPrefix(redisKey);
 778             return await _db.ListRightPushAsync(redisKey, Serialize(redisValue));
 779         }
 780 
 781         /// <summary>
 782         /// 在列表头部插入值。如果键不存在,先创建再插入值
 783         /// </summary>
 784         /// <param name="redisKey"></param>
 785         /// <param name="redisValue"></param>
 786         /// <returns></returns>
 787         public async Task<long> ListLeftPushAsync<T>(string redisKey, T redisValue)
 788         {
 789             redisKey = AddKeyPrefix(redisKey);
 790             return await _db.ListLeftPushAsync(redisKey, Serialize(redisValue));
 791         }
 792 
 793         #endregion List-async
 794 
 795         #endregion List 操作
 796 
 797         #region SortedSet 操作
 798 
 799         /// <summary>
 800         /// SortedSet 新增
 801         /// </summary>
 802         /// <param name="redisKey"></param>
 803         /// <param name="member"></param>
 804         /// <param name="score"></param>
 805         /// <returns></returns>
 806         public bool SortedSetAdd(string redisKey, string member, double score)
 807         {
 808             redisKey = AddKeyPrefix(redisKey);
 809             return _db.SortedSetAdd(redisKey, member, score);
 810         }
 811 
 812         /// <summary>
 813         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
 814         /// </summary>
 815         /// <param name="redisKey"></param>
 816         /// <returns></returns>
 817         public IEnumerable<RedisValue> SortedSetRangeByRank(string redisKey)
 818         {
 819             redisKey = AddKeyPrefix(redisKey);
 820             return _db.SortedSetRangeByRank(redisKey);
 821         }
 822 
 823         /// <summary>
 824         /// 返回有序集合的元素个数
 825         /// </summary>
 826         /// <param name="redisKey"></param>
 827         /// <returns></returns>
 828         public long SortedSetLength(string redisKey)
 829         {
 830             redisKey = AddKeyPrefix(redisKey);
 831             return _db.SortedSetLength(redisKey);
 832         }
 833 
 834         /// <summary>
 835         /// 返回有序集合的元素个数
 836         /// </summary>
 837         /// <param name="redisKey"></param>
 838         /// <param name="memebr"></param>
 839         /// <returns></returns>
 840         public bool SortedSetLength(string redisKey, string memebr)
 841         {
 842             redisKey = AddKeyPrefix(redisKey);
 843             return _db.SortedSetRemove(redisKey, memebr);
 844         }
 845 
 846         /// <summary>
 847         /// SortedSet 新增
 848         /// </summary>
 849         /// <param name="redisKey"></param>
 850         /// <param name="member"></param>
 851         /// <param name="score"></param>
 852         /// <returns></returns>
 853         public bool SortedSetAdd<T>(string redisKey, T member, double score)
 854         {
 855             redisKey = AddKeyPrefix(redisKey);
 856             var json = Serialize(member);
 857 
 858             return _db.SortedSetAdd(redisKey, json, score);
 859         }
 860 
 861         #region SortedSet-Async
 862 
 863         /// <summary>
 864         /// SortedSet 新增
 865         /// </summary>
 866         /// <param name="redisKey"></param>
 867         /// <param name="member"></param>
 868         /// <param name="score"></param>
 869         /// <returns></returns>
 870         public async Task<bool> SortedSetAddAsync(string redisKey, string member, double score)
 871         {
 872             redisKey = AddKeyPrefix(redisKey);
 873             return await _db.SortedSetAddAsync(redisKey, member, score);
 874         }
 875 
 876         /// <summary>
 877         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
 878         /// </summary>
 879         /// <param name="redisKey"></param>
 880         /// <returns></returns>
 881         public async Task<IEnumerable<RedisValue>> SortedSetRangeByRankAsync(string redisKey)
 882         {
 883             redisKey = AddKeyPrefix(redisKey);
 884             return await _db.SortedSetRangeByRankAsync(redisKey);
 885         }
 886 
 887         /// <summary>
 888         /// 返回有序集合的元素个数
 889         /// </summary>
 890         /// <param name="redisKey"></param>
 891         /// <returns></returns>
 892         public async Task<long> SortedSetLengthAsync(string redisKey)
 893         {
 894             redisKey = AddKeyPrefix(redisKey);
 895             return await _db.SortedSetLengthAsync(redisKey);
 896         }
 897 
 898         /// <summary>
 899         /// 返回有序集合的元素个数
 900         /// </summary>
 901         /// <param name="redisKey"></param>
 902         /// <param name="memebr"></param>
 903         /// <returns></returns>
 904         public async Task<bool> SortedSetRemoveAsync(string redisKey, string memebr)
 905         {
 906             redisKey = AddKeyPrefix(redisKey);
 907             return await _db.SortedSetRemoveAsync(redisKey, memebr);
 908         }
 909 
 910         /// <summary>
 911         /// SortedSet 新增
 912         /// </summary>
 913         /// <param name="redisKey"></param>
 914         /// <param name="member"></param>
 915         /// <param name="score"></param>
 916         /// <returns></returns>
 917         public async Task<bool> SortedSetAddAsync<T>(string redisKey, T member, double score)
 918         {
 919             redisKey = AddKeyPrefix(redisKey);
 920             var json = Serialize(member);
 921 
 922             return await _db.SortedSetAddAsync(redisKey, json, score);
 923         }
 924 
 925         #endregion SortedSet-Async
 926 
 927         #endregion SortedSet 操作
 928 
 929         #region key 操作
 930 
 931         /// <summary>
 932         /// 移除指定 Key
 933         /// </summary>
 934         /// <param name="redisKey"></param>
 935         /// <returns></returns>
 936         public bool KeyDelete(string redisKey)
 937         {
 938             redisKey = AddKeyPrefix(redisKey);
 939             return _db.KeyDelete(redisKey);
 940         }
 941 
 942         /// <summary>
 943         /// 移除指定 Key
 944         /// </summary>
 945         /// <param name="redisKeys"></param>
 946         /// <returns></returns>
 947         public long KeyDelete(IEnumerable<string> redisKeys)
 948         {
 949             var keys = redisKeys.Select(x => (RedisKey)AddKeyPrefix(x));
 950             return _db.KeyDelete(keys.ToArray());
 951         }
 952 
 953         /// <summary>
 954         /// 校验 Key 是否存在
 955         /// </summary>
 956         /// <param name="redisKey"></param>
 957         /// <returns></returns>
 958         public bool KeyExists(string redisKey)
 959         {
 960             redisKey = AddKeyPrefix(redisKey);
 961             return _db.KeyExists(redisKey);
 962         }
 963 
 964         /// <summary>
 965         /// 重命名 Key
 966         /// </summary>
 967         /// <param name="redisKey"></param>
 968         /// <param name="redisNewKey"></param>
 969         /// <returns></returns>
 970         public bool KeyRename(string redisKey, string redisNewKey)
 971         {
 972             redisKey = AddKeyPrefix(redisKey);
 973             return _db.KeyRename(redisKey, redisNewKey);
 974         }
 975 
 976         /// <summary>
 977         /// 设置 Key 的时间
 978         /// </summary>
 979         /// <param name="redisKey"></param>
 980         /// <param name="expiry"></param>
 981         /// <returns></returns>
 982         public bool KeyExpire(string redisKey, TimeSpan? expiry)
 983         {
 984             redisKey = AddKeyPrefix(redisKey);
 985             return _db.KeyExpire(redisKey, expiry);
 986         }
 987 
 988         /// <summary>
 989         /// Get all keys by wildcard
 990         /// </summary>
 991         /// <param name="pattern"></param>
 992         /// <returns></returns>
 993         public List<string> Keys(string pattern)
 994         {
 995             //var endPoint = _connMultiplexer.GetEndPoints()[0];
 996             //IServer _server = _connMultiplexer.GetServer(endPoint); //默认一个服务器
 997             //var keys = _server.Keys(database: _db.Database, pattern: pattern); //StackExchange.Redis 会根据redis版本决定用keys还是 scan
 998             //return keys;
 999             pattern = AddKeyPrefix(pattern);
1000             var redisResult = _db.ScriptEvaluate(LuaScript.Prepare(
1001                 " local res=redis.call('KEYS',@keypattern) " +
1002                 " return res "), new { @keypattern = pattern });
1003             if (redisResult == null) return null;
1004 
1005             var keys = (string[])redisResult;//Morningstar.Appointment.Dev:CSM:WDA-07171
1006             var list = new List<string>();
1007             foreach (var item in keys)
1008             {
1009                 list.Add(item.Split(DefaultKey + ":")[1]);
1010             }
1011             return list;
1012         }
1013 
1014         #region key-async
1015 
1016         /// <summary>
1017         /// 移除指定 Key
1018         /// </summary>
1019         /// <param name="redisKey"></param>
1020         /// <returns></returns>
1021         public async Task<bool> KeyDeleteAsync(string redisKey)
1022         {
1023             redisKey = AddKeyPrefix(redisKey);
1024             return await _db.KeyDeleteAsync(redisKey);
1025         }
1026 
1027         /// <summary>
1028         /// 移除指定 Key
1029         /// </summary>
1030         /// <param name="redisKeys"></param>
1031         /// <returns></returns>
1032         public async Task<long> KeyDeleteAsync(IEnumerable<string> redisKeys)
1033         {
1034             var keys = redisKeys.Select(x => (RedisKey)AddKeyPrefix(x));
1035             return await _db.KeyDeleteAsync(keys.ToArray());
1036         }
1037 
1038         /// <summary>
1039         /// 校验 Key 是否存在
1040         /// </summary>
1041         /// <param name="redisKey"></param>
1042         /// <returns></returns>
1043         public async Task<bool> KeyExistsAsync(string redisKey)
1044         {
1045             redisKey = AddKeyPrefix(redisKey);
1046             return await _db.KeyExistsAsync(redisKey);
1047         }
1048 
1049         /// <summary>
1050         /// 重命名 Key
1051         /// </summary>
1052         /// <param name="redisKey"></param>
1053         /// <param name="redisNewKey"></param>
1054         /// <returns></returns>
1055         public async Task<bool> KeyRenameAsync(string redisKey, string redisNewKey)
1056         {
1057             redisKey = AddKeyPrefix(redisKey);
1058             return await _db.KeyRenameAsync(redisKey, redisNewKey);
1059         }
1060 
1061         /// <summary>
1062         /// 设置 Key 的时间
1063         /// </summary>
1064         /// <param name="redisKey"></param>
1065         /// <param name="expiry"></param>
1066         /// <returns></returns>
1067         public async Task<bool> KeyExpireAsync(string redisKey, TimeSpan? expiry)
1068         {
1069             redisKey = AddKeyPrefix(redisKey);
1070             return await _db.KeyExpireAsync(redisKey, expiry);
1071         }
1072 
1073         #endregion key-async
1074 
1075         #endregion key 操作
1076 
1077         #region 发布订阅
1078 
1079         /// <summary>
1080         /// 订阅
1081         /// </summary>
1082         /// <param name="channel"></param>
1083         /// <param name="handle"></param>
1084         public void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
1085         {
1086             var sub = _connMultiplexer.GetSubscriber();
1087             sub.Subscribe(channel, handle);
1088         }
1089 
1090         /// <summary>
1091         /// 发布
1092         /// </summary>
1093         /// <param name="channel"></param>
1094         /// <param name="message"></param>
1095         /// <returns></returns>
1096         public long Publish(RedisChannel channel, RedisValue message)
1097         {
1098             var sub = _connMultiplexer.GetSubscriber();
1099             return sub.Publish(channel, message);
1100         }
1101 
1102         /// <summary>
1103         /// 发布(使用序列化)
1104         /// </summary>
1105         /// <typeparam name="T"></typeparam>
1106         /// <param name="channel"></param>
1107         /// <param name="message"></param>
1108         /// <returns></returns>
1109         public long Publish<T>(RedisChannel channel, T message)
1110         {
1111             var sub = _connMultiplexer.GetSubscriber();
1112             return sub.Publish(channel, Serialize(message));
1113         }
1114 
1115         #region 发布订阅-async
1116 
1117         /// <summary>
1118         /// 订阅
1119         /// </summary>
1120         /// <param name="channel"></param>
1121         /// <param name="handle"></param>
1122         public async Task SubscribeAsync(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
1123         {
1124             var sub = _connMultiplexer.GetSubscriber();
1125             await sub.SubscribeAsync(channel, handle);
1126         }
1127 
1128         /// <summary>
1129         /// 发布
1130         /// </summary>
1131         /// <param name="channel"></param>
1132         /// <param name="message"></param>
1133         /// <returns></returns>
1134         public async Task<long> PublishAsync(RedisChannel channel, RedisValue message)
1135         {
1136             var sub = _connMultiplexer.GetSubscriber();
1137             return await sub.PublishAsync(channel, message);
1138         }
1139 
1140         /// <summary>
1141         /// 发布(使用序列化)
1142         /// </summary>
1143         /// <typeparam name="T"></typeparam>
1144         /// <param name="channel"></param>
1145         /// <param name="message"></param>
1146         /// <returns></returns>
1147         public async Task<long> PublishAsync<T>(RedisChannel channel, T message)
1148         {
1149             var sub = _connMultiplexer.GetSubscriber();
1150             return await sub.PublishAsync(channel, Serialize(message));
1151         }
1152 
1153         #endregion 发布订阅-async
1154 
1155         #endregion 发布订阅
1156 
1157         #region private method
1158 
1159         /// <summary>
1160         /// 添加 Key 的前缀
1161         /// </summary>
1162         /// <param name="key"></param>
1163         /// <returns></returns>
1164         private static string AddKeyPrefix(string key)
1165         {
1166             return $"{DefaultKey}:{key}";
1167         }
1168 
1169         #region 注册事件
1170 
1171         /// <summary>
1172         /// 添加注册事件
1173         /// </summary>
1174         private static void AddRegisterEvent()
1175         {
1176             _connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
1177             _connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
1178             _connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
1179             _connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
1180             _connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
1181             _connMultiplexer.InternalError += ConnMultiplexer_InternalError;
1182             _connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
1183         }
1184 
1185         /// <summary>
1186         /// 重新配置广播时(通常意味着主从同步更改)
1187         /// </summary>
1188         /// <param name="sender"></param>
1189         /// <param name="e"></param>
1190         private static void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
1191         {
1192             Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
1193         }
1194 
1195         /// <summary>
1196         /// 发生内部错误时(主要用于调试)
1197         /// </summary>
1198         /// <param name="sender"></param>
1199         /// <param name="e"></param>
1200         private static void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
1201         {
1202             Console.WriteLine($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
1203         }
1204 
1205         /// <summary>
1206         /// 更改集群时
1207         /// </summary>
1208         /// <param name="sender"></param>
1209         /// <param name="e"></param>
1210         private static void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
1211         {
1212             Console.WriteLine(
1213                 $"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");
1214         }
1215 
1216         /// <summary>
1217         /// 配置更改时
1218         /// </summary>
1219         /// <param name="sender"></param>
1220         /// <param name="e"></param>
1221         private static void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
1222         {
1223             Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
1224         }
1225 
1226         /// <summary>
1227         /// 发生错误时
1228         /// </summary>
1229         /// <param name="sender"></param>
1230         /// <param name="e"></param>
1231         private static void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
1232         {
1233             Console.WriteLine($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
1234         }
1235 
1236         /// <summary>
1237         /// 物理连接失败时
1238         /// </summary>
1239         /// <param name="sender"></param>
1240         /// <param name="e"></param>
1241         private static void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
1242         {
1243             Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
1244         }
1245 
1246         /// <summary>
1247         /// 建立物理连接时
1248         /// </summary>
1249         /// <param name="sender"></param>
1250         /// <param name="e"></param>
1251         private static void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
1252         {
1253             Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
1254         }
1255 
1256         #endregion 注册事件
1257 
1258         /// <summary>
1259         /// 序列化
1260         /// </summary>
1261         /// <param name="obj"></param>
1262         /// <returns></returns>
1263         private static byte[] Serialize(object obj)
1264         {
1265             if (obj == null)
1266                 return null;
1267 
1268             var binaryFormatter = new BinaryFormatter();
1269             using (var memoryStream = new MemoryStream())
1270             {
1271                 binaryFormatter.Serialize(memoryStream, obj);
1272                 var data = memoryStream.ToArray();
1273                 return data;
1274             }
1275         }
1276 
1277         /// <summary>
1278         /// 反序列化
1279         /// </summary>
1280         /// <typeparam name="T"></typeparam>
1281         /// <param name="data"></param>
1282         /// <returns></returns>
1283         private static T Deserialize<T>(byte[] data)
1284         {
1285             if (data == null)
1286                 return default(T);
1287 
1288             var binaryFormatter = new BinaryFormatter();
1289             using (var memoryStream = new MemoryStream(data))
1290             {
1291                 var result = (T)binaryFormatter.Deserialize(memoryStream);
1292                 return result;
1293             }
1294         }
1295 
1296         #endregion private method
1297     }
1298 }
RedisHelper.cs

   2,appsettings.json

Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第11张Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第12张
 1 {
 2   "Redis": {
 3     "ConnectionStrings": "127.0.0.1:6379,password=ms.corpqa.interviewscheduling",
 4     "DefaultKey": "Morningstar.InterviewScheduling.Dev",
 5     "ServiceName": "mymaster",
 6     "Password": "ms.corpqa.interviewscheduling",
 7     "Sentinel": [
 8       "127.0.0.1:26379",
 9       "127.0.0.1:26380",
10       "127.0.0.1:26381"
11     ]
12   },
13   "ExpireDays": 7, //the unit is day
14   "HttpProxyConfig": {
15     "UseProxy": "true",
16     "ProxyHost": "172.28.104.174",
17     "ProxyPort": "8080"
18   }
19 }
appsettings.json

  注:StackExchange.Redis请使用最新版本,以上代码使用的是2.2.4版本。

三,.NET Core 项目中使用

  Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第13张

 Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵第14张

免责声明:文章转载自《Windows下Redis哨兵模式配置以及在.NetCore中使用StackExchange.Redis连接哨兵》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OpenGL_棋盘Essential Grid for ASP.NET MVC表格控件详细介绍及下载下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

redis-事务

redis 事务 redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中...

Django之缓存、信号和图片验证码、ORM性能

一、 缓存 1、 介绍 缓存通俗来说:就是把数据先保存在某个地方,下次再读取的时候不用再去原位置读取,让访问速度更快。 缓存机制图解 2、Django中提供了6种缓存方式   1. 开发调试   2. 内存   3. 文件   4. 数据库   5. Memcache缓存(python-memcached模块)   6. Memcache缓存(pyl...

Redis构建全局并发锁

Redis构建全局并发锁 https://www.cnblogs.com/FG123/p/9990336.html 谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓存,但是使用Redis仅仅作为缓存未免太大材小用了。深究Redis的原理后你会发现它有很多用途,在很多场景下能够使用它快速地解决问题。常见的用途有:分布式锁控...

使用Python操作Redis详解

之前的五天,过了个愉快的周末,然后将公司AbaseDump的调度部分代码看懂并且在此之上完成了OnlyDump的功能代码,代码不可以公开,今天完工,明天测试,晚上来总结一下这几天学到的一点应用。 使用Python操作Redis详解 ---------------------------------------------------------------...

.NET插件技术-应用程序热升级

今天说一说.NET 中的插件技术,即 应用程序热升级。在很多情况下、我们希望用户对应用程序的升级是无感知的,并且尽可能不打断用户操作的。 虽然在Web 或者 WebAPI上,由于多点的存在可以逐个停用单点进行系统升级,而不影响整个服务。但是 客户端却不能这样做,毕竟用户一直在使用着。 那么有没有一种方式,可以在用户无感知的情况下(即、不停止进程的情况下)对...

C# Xml序列化与反序列化

Xml文本的序列化与反序列化: public static class XmlSerializeHelper { // 序列化:对象 -> Xml文本 public static string SerializeToXmlString(object obj) {...