• 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从

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

    发现程序正常运行:

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

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

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

  • 相关阅读:
    13 原型链_继承_this大总结_函数一定是对象,对象不一定是函数
    12 贪吃蛇游戏
    实现wiki访问
    11 第三个阶段js高级_原型
    JZOJ.5257【NOIP2017模拟8.11】小X的佛光
    模板——权值线段树(逆序对)
    LCA模板
    笛卡尔树——神奇的“二叉搜索堆”
    JZOJ.5246【NOIP2017模拟8.8】Trip
    JZOJ.5236【NOIP2017模拟8.7】利普希茨
  • 原文地址:https://www.cnblogs.com/peterzhang123/p/12524701.html
Copyright © 2020-2023  润新知