StackExchange.Redis 之 操作Redis链接字符串配置
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"
·
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
集群)。
public class RedisCacheHelper
{
private readonly Logger _log = LogManager.GetCurrentClassLogger();
/// <summary>
/// 连接字符串
/// </summary>
private static string _connectionString;
/// <summary>
/// redis 连接对象
/// </summary>
private static IConnectionMultiplexer _connMultiplexer;
/// <summary>
/// 实例化对象
/// </summary>
private static RedisCacheHelper _cacheHelper;
/// <summary>
/// 实例
/// </summary>
private static RedisCacheHelper _instance;
/// <summary>
/// 锁
/// </summary>
private static readonly object Locker = new object();
/// <summary>
/// 数据库
/// </summary>
private IDatabase _db;
/// <summary>
/// 默认链接实例
/// </summary>
private RedisCacheHelper()
{
_connectionString = ConfigurationManager.ConnectionStrings["Connection_Redis"].ConnectionString;
_connMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
//添加注册事件
AddRegisterEvent();
}
/// <summary>
/// 获取 Redis 连接对象
/// </summary>
private IConnectionMultiplexer Connnection
{
get
{
if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
{
lock (Locker)
{
if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
{
_connMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
}
}
}
return _connMultiplexer;
}
}
/// <summary>
/// 获取指定db,默认不指定
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
private IDatabase GetDatabase(int db = -1)
{
return Connnection.GetDatabase(db);
}
/// <summary>
/// 调用实例,通过该实例调用Redis
/// </summary>
public static RedisCacheHelper Instance
{
get
{
if (_cacheHelper != null) return _cacheHelper;
lock (Locker)
{
if (_cacheHelper != null) return _cacheHelper;
_cacheHelper = new RedisCacheHelper();
}
return _cacheHelper;
}
}
#region 注册事件
/// <summary>
/// 添加注册事件
/// </summary>
private void AddRegisterEvent()
{
_connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
_connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
_connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
_connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
_connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
_connMultiplexer.InternalError += ConnMultiplexer_InternalError;
_connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
}
/// <summary>
/// 重新配置广播时(通常意味着主从同步更改)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
{
_log.Info($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
}
/// <summary>
/// 发生内部错误时(主要用于调试)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
{
_log.Error($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
}
/// <summary>
/// 更改集群时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
_log.Info(
$"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}");
}
/// <summary>
/// 配置更改时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
{
_log.Info($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
}
/// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
{
_log.Error($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
}
/// <summary>
/// 物理连接失败时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
_log.Fatal($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
}
/// <summary>
/// 建立物理连接时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
_log.Info($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
}
#endregion
}
以上Redis
链接就配置好了,使用方式如下:首先在把集群中的主从服务都开启,3主、3从
然后在代码中进行操作验证,向缓存中插入一条数据,然后循环读写数据,循环的时候手动任意关闭Redis服务当中的 1~2个 服务器
while (true)
{
//设置age
RedisCacheHelper.Instance.Set("age", "10", new TimeSpan(0, 5, 0));
//获取age
var getage = RedisCacheHelper.Instance.Get("age");
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + ":" + getage);
Thread.Sleep(1000); // 等待1s
}
//设置name
RedisCacheHelper.Instance.Set("name", "李四", new TimeSpan(0, 2, 0));
RedisCacheHelper.Instance.Set("age", "10", new TimeSpan(0, 2, 0));
//获取name
var getname = RedisCacheHelper.Instance.Get("name");
Console.WriteLine(getname);
//获取age
var getage = RedisCacheHelper.Instance.Get("age");
Console.WriteLine(getage);
成功将缓存存入到服务器当中,运行效果如下:
此时查看Redis集群,发现主从实例都有数据了,接下来我们把其中任意1个 Redis实例关掉 (上边运行的循环代码程序不要关闭)
发现程序正常运行:
但是上边的步骤,我经过多次测试,在任意关闭某个实例的时候,偶尔会报如下错误:集群挂了
我们把写的方法注释掉,只保留读取的代码,同样会偶尔报异常。
但是大部分情况下,关掉其中一个实例,程序都正常运行:
更多推荐
已为社区贡献32条内容
所有评论(0)