.NET Redis简单使用
1 static void Main(string[] args) 2 { 3 var redis = new Redis(); 4 Console.WriteLine("-----------单个设置缓存开始-----------"); 5 redis.Set("a", "123"); 6 Console.WriteLine("a = 123"); 7 redis.Set("b", "456"); 8 Console.WriteLine("b = 456"); 9 redis.Set("c", "789"); 10 Console.WriteLine("c = 789"); 11 Console.WriteLine("-----------单个设置缓存结束-----------"); 12 13 Thread.Sleep(3000); 14 15 Console.WriteLine(); 16 17 Console.WriteLine("-----------单个读取缓存开始-----------"); 18 Console.WriteLine($"a = {redis.Get<string>("a")}"); 19 Console.WriteLine($"b = {redis.Get<string>("b")}"); 20 Console.WriteLine($"c = {redis.Get<string>("c")}"); 21 Console.WriteLine("-----------单个读取缓存结束-----------"); 22 23 Console.WriteLine(); 24 25 Console.WriteLine("-----------批量读取缓存开始-----------"); 26 var arr = new string[] { "a", "b", "c" }; 27 var value = redis.BatchGet<string>(arr); 28 for (int i = 0; i < value.Count; i++) 29 { 30 Console.WriteLine(arr[i] + " = " + value[i]); 31 } 32 Console.WriteLine("-----------批量读取缓存结束-----------"); 33 34 Console.WriteLine(); 35 36 Console.WriteLine("-----------批量设置缓存开始-----------"); 37 var modelList = new List<BatchSetModel> 38 { 39 new BatchSetModel { key = "a", value = "147" }, 40 new BatchSetModel { key = "b", value = "258" }, 41 new BatchSetModel { key = "c", value = "369" } 42 }; 43 redis.BatchSet(modelList); 44 45 //redis.Set("a", "147"); 46 //redis.Set("b", "258"); 47 //redis.Set("c", "369"); 48 49 Console.WriteLine("a = 147"); 50 Console.WriteLine("b = 258"); 51 Console.WriteLine("c = 369"); 52 Console.WriteLine("-----------批量设置缓存结束-----------"); 53 54 Console.WriteLine(); 55 Thread.Sleep(3000); 56 Console.WriteLine("-----------批量读取缓存开始-----------"); 57 arr = new string[] { "a", "b", "c" }; 58 value = redis.BatchGet<string>(arr); 59 for (int i = 0; i < value.Count; i++) 60 { 61 Console.WriteLine(arr[i] + " = " + value[i]); 62 } 63 Console.WriteLine("-----------批量读取缓存结束-----------"); 64 65 }
<add key="Connection_Redis" value="127.0.0.1:6379,password=123456,abortConnect=false" />
<add key="Connection_Redis_Prefix" value="Test:" />
public class Redis { public Redis() { ConnectionString = ConfigurationManager.AppSettings["Connection_Redis"]; KeyPrefix = ConfigurationManager.AppSettings["Connection_Redis_Prefix"]; } private string ConnectionString { get; set; } private string KeyPrefix { get; set; } /// <summary> /// 并发锁 /// </summary> private static object locker = new object(); private ConnectionMultiplexer multiplexer = null; private ConnectionMultiplexer ConnMultiplexer { get { if (multiplexer == null) { lock (locker) { multiplexer = CreateMultiplexer(); multiplexer.ConnectionFailed += Multiplexer_ConnectionFailed; multiplexer.ConnectionRestored += Multiplexer_ConnectionRestored; multiplexer.ErrorMessage += Multiplexer_ErrorMessage; multiplexer.ConfigurationChanged += Multiplexer_ConfigurationChanged; multiplexer.HashSlotMoved += Multiplexer_HashSlotMoved; multiplexer.InternalError += Multiplexer_InternalError; } } return multiplexer; } } /// <summary> /// 创建连接 /// </summary> /// <returns></returns> protected virtual ConnectionMultiplexer CreateMultiplexer() { ConfigurationOptions config = ConfigurationOptions.Parse(ConnectionString); config.ConnectTimeout = 15000; config.SyncTimeout = 15000; config.AbortOnConnectFail = false; //失败自动重连 return ConnectionMultiplexer.Connect(config); } /// <summary> /// 获取内存数据库,从 GetDatabase 方法返回的对象是一个轻量级直通对象,不需要进行存储。 /// </summary> /// <returns></returns> private IDatabase GetDatabase() { return ConnMultiplexer.GetDatabase(); }
#region 注册事件 /// <summary> /// 连接失败时触发,如果重新连接成功你将不会收到这个通知 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void Multiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e) { //LogHelper.Error("Redis连接失败", e.Exception); } /// <summary> /// 重新连接时通知 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void Multiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e) { //LogHelper.Error("Redis重新连接成功"); } /// <summary> /// 服务端返回错误消息时触发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void Multiplexer_ErrorMessage(object sender, RedisErrorEventArgs e) { //LogHelper.Error($"Redis服务端返回错误:{e.Message}"); } /// <summary> /// 配置更改时触发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void Multiplexer_ConfigurationChanged(object sender, EndPointEventArgs e) { //LogHelper.Error($"Redis连接配置更改"); } /// <summary> /// 更改集群时触发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void Multiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e) { //LogHelper.Error($"Redis集群更改更改"); } /// <summary> /// 发生内部错误时触发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void Multiplexer_InternalError(object sender, InternalErrorEventArgs e) { //LogHelper.Error("Redis发生内部错误", e.Exception); } #endregion
#region 普通类型 /// <summary> /// 根据key获取缓存对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="key">关键字</param> /// <returns></returns> public virtual T Get<T>(string key) { return Deserialize<T>(GetDatabase().StringGet(MergeKey(key))); } /// <summary> /// 根据多个关键字获取多个缓存对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="keys">关键字数组</param> /// <returns></returns> public virtual List<T> Get<T>(string[] keys) { if (keys == null || keys.Length == 0) { return null; } List<RedisKey> keyList = new List<RedisKey>(); foreach (string key in keys) { keyList.Add(MergeKey(key)); } return Deserialize<T>(GetDatabase().StringGet(keyList.ToArray())); } /// <summary> /// 根据多个关键字批量缓存对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="keys">关键字数组</param> /// <returns></returns> public virtual List<T> BatchGet<T>(string[] keys) { if (keys == null || keys.Length == 0) { return null; } var batch = GetDatabase().CreateBatch(); //批量读 List<Task<RedisValue>> taskList = new List<Task<RedisValue>>(); foreach (string key in keys) { Task<RedisValue> tres = batch.StringGetAsync(MergeKey(key)); taskList.Add(tres); } batch.Execute(); List<RedisValue> valueList = new List<RedisValue>(); foreach (var redisValue in taskList) { valueList.Add(redisValue.Result);//取出对应的value值 } return Deserialize<T>(valueList.ToArray()); } /// <summary> /// 设置缓存 /// </summary> /// <param name="key">关键字</param> /// <param name="value">值对象</param> /// <param name="expiry">留空则默认保留3天</param> /// <returns>设置是否成功</returns> public virtual bool Set<T>(string key, T value, TimeSpan? expiry = null) { if (expiry == null) { expiry = TimeSpan.FromDays(3); } return GetDatabase().StringSet(MergeKey(key), Serialize(value), expiry); } /// <summary> /// 批量设置缓存 /// </summary> public virtual void BatchSet(List<BatchSetModel> model) { var batch = GetDatabase().CreateBatch(); List<Task<bool>> taskList = new List<Task<bool>>(); //批量写 foreach (var item in model) { taskList.Add(batch.StringSetAsync(MergeKey(item.key), Serialize(item.value), item.expiry)); } batch.Execute(); Task.WaitAll(taskList.ToArray()); } public class BatchSetModel { public string key { get; set; } public RedisValue value { get; set; } public TimeSpan? expiry { get; set; } } /// <summary> /// 为数字增长val /// </summary> /// <param name="key">关键字</param> /// <param name="val">增长的值,可以为负</param> /// <returns>增长后的值</returns> public long Increment(string key, long val = 1) { return GetDatabase().StringIncrement(MergeKey(key), val); } /// <summary> /// 为数字减少val /// </summary> /// <param name="key">关键字</param> /// <param name="val">减少的值,可以为负</param> /// <returns>减少后的值</returns> public long StringDecrement(string key, long val = 1) { return GetDatabase().StringDecrement(MergeKey(key), val); } #endregion 普通类型
#region List类型 /// <summary> /// 移除指定ListId的内部List的值 /// </summary> /// <param name="key">关键字</param> /// <param name="value">列表内部的值</param> /// <returns>移除的个数</returns> public long ListRemove<T>(string key, T value) { return GetDatabase().ListRemove(MergeKey(key), Serialize(value)); } /// <summary> /// 获取指定key的List /// </summary> /// <param name="key">关键字</param> /// <returns></returns> public List<T> ListRange<T>(string key) { List<T> result = new List<T>(); var values = GetDatabase().ListRange(MergeKey(key)); return Deserialize<T>(values); } /// <summary> /// 入队 /// </summary> /// <param name="key">关键字</param> /// <param name="value">值</param> /// <returns>入队后的队列长度</returns> public long ListRightPush<T>(string key, T value) { return GetDatabase().ListRightPush(MergeKey(key), Serialize(value)); } /// <summary> /// 出队/出栈 /// </summary> /// <param name="key">关键字</param> /// <returns>出队/队栈的对象,如果key不存在,返回null</returns> public T ListLeftPop<T>(string key) { var value = GetDatabase().ListLeftPop(MergeKey(key)); return Deserialize<T>(value); } /// <summary> /// 入栈 /// </summary> /// <param name="key">关键字</param> /// <param name="value">值</param> /// <returns>入栈后的队列长度</returns> public long ListLeftPush<T>(string key, T value) { return GetDatabase().ListLeftPush(MergeKey(key), Serialize(value)); } /// <summary> /// 获取集合中的数量 /// </summary> /// <param name="key">关键字</param> /// <returns></returns> public long ListLength(string key) { return GetDatabase().ListLength(MergeKey(key)); } #endregion List类型
#region Hash类型 /// <summary> /// 判断某个数据是否已经被缓存 /// </summary> /// <param name="key">关键字</param> /// <param name="dataKey">数据关键字</param> /// <returns></returns> public bool HashExists(string key, string dataKey) { return GetDatabase().HashExists(MergeKey(key), dataKey); } /// <summary> /// 存储数据到hash表 /// </summary> /// <param name="key">关键字</param> /// <param name="dataKey">数据关键字</param> /// <param name="value">值</param> /// <returns></returns> public bool HashSet<T>(string key, string dataKey, T value) { return GetDatabase().HashSet(MergeKey(key), dataKey, Serialize(value)); } /// <summary> /// 移除hash中的某值 /// </summary> /// <param name="key">关键字</param> /// <param name="dataKey">数据关键字</param> /// <returns></returns> public bool HashDelete(string key, string dataKey) { return GetDatabase().HashDelete(MergeKey(key), dataKey); } /// <summary> /// 移除hash中的多个值 /// </summary> /// <param name="key">关键字</param> /// <param name="dataKeys">数据关键字集合</param> /// <returns></returns> public long HashDelete(string key, List<string> dataKeys) { return GetDatabase().HashDelete(MergeKey(key), dataKeys.Select(f => (RedisValue)f).ToArray()); } /// <summary> /// 从hash表获取数据 /// </summary> /// <param name="key">关键字</param> /// <param name="dataKey">数据关键字</param> /// <returns></returns> public T HashGet<T>(string key, string dataKey) { var value = GetDatabase().HashGet(MergeKey(key), dataKey); return Deserialize<T>(value); } /// <summary> /// 从hash表批量获取数据 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key">关键字</param> /// <param name="dataKeys">数据关键字集合</param> /// <returns></returns> public List<T> HashGet<T>(string key, string[] dataKeys) { if (dataKeys == null || dataKeys.Length == 0) { return null; } List<RedisValue> keyList = new List<RedisValue>(); foreach (string item in dataKeys) { keyList.Add(item); } return Deserialize<T>(GetDatabase().HashGet(MergeKey(key), keyList.ToArray())); } /// <summary> /// 为数字增长val /// </summary> /// <param name="key">关键字</param> /// <param name="dataKey">数据关键字</param> /// <param name="val">可以为负</param> /// <returns>增长后的值</returns> public long HashIncrement(string key, string dataKey, long val = 1) { return GetDatabase().HashIncrement(MergeKey(key), dataKey, val); } /// <summary> /// 为数字减少val /// </summary> /// <param name="key">关键字</param> /// <param name="dataKey">数据关键字</param> /// <param name="val">可以为负</param> /// <returns>减少后的值</returns> public long HashDecrement(string key, string dataKey, long val = 1) { return GetDatabase().HashDecrement(MergeKey(key), dataKey, val); } /// <summary> /// 获取hash表所有key /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key">关键字</param> /// <returns></returns> public List<T> HashKeys<T>(string key) { RedisValue[] values = GetDatabase().HashKeys(MergeKey(key)); return Deserialize<T>(values); } #endregion Hash类型
#region 发布/订阅 /// <summary> /// 订阅(客户端连接可使用KeepAlive=60来发送心跳包保持socket接口活跃) /// </summary> /// <param name="subChannel"></param> /// <param name="handler"></param> public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null) { ISubscriber sub = ConnMultiplexer.GetSubscriber(); sub.Subscribe(subChannel, (channel, message) => { if (handler == null) { Console.WriteLine(subChannel + " 订阅收到消息:" + message); } else { handler(channel, message); } }); } /// <summary> /// 发布 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="channel"></param> /// <param name="msg"></param> /// <returns></returns> public long Publish<T>(string channel, T msg) { ISubscriber sub = ConnMultiplexer.GetSubscriber(); return sub.Publish(channel, JsonConvert.SerializeObject(msg)); } /// <summary> /// 取消订阅 /// </summary> /// <param name="channel"></param> public void Unsubscribe(string channel) { ISubscriber sub = ConnMultiplexer.GetSubscriber(); sub.Unsubscribe(channel); } /// <summary> /// 取消全部订阅 /// </summary> public void UnsubscribeAll() { ISubscriber sub = ConnMultiplexer.GetSubscriber(); sub.UnsubscribeAll(); } #endregion 发布/订阅
#region Key管理 /// <summary> /// 拼接Key前缀,可多系统使用同一库 /// </summary> /// <param name="key">关键字</param> /// <returns></returns> private string MergeKey(string key) { if (string.IsNullOrEmpty(KeyPrefix)) { return key; } return KeyPrefix + key; } /// <summary> /// 判断在缓存中是否存在该key的缓存数据 /// </summary> /// <param name="key">关键字</param> /// <returns>关键字是否存在</returns> public virtual bool Exists(string key) { return GetDatabase().KeyExists(MergeKey(key)); //可直接调用 } /// <summary> /// 移除指定key的缓存 /// </summary> /// <param name="key">关键字</param> /// <returns>是否移除成功</returns> public virtual bool Remove(string key) { return GetDatabase().KeyDelete(MergeKey(key)); } /// <summary> /// 移除指定key的缓存 /// </summary> /// <param name="keys">关键字数组</param> /// <returns>移除的缓存数</returns> public virtual long Remove(string[] keys) { RedisKey[] redisKeys = keys.Select(f => (RedisKey)MergeKey(f)).ToArray(); return GetDatabase().KeyDelete(redisKeys); } /// <summary> /// 设置Key的时间 /// </summary> /// <param name="key">关键字</param> /// <param name="expiry">留空则默认保留3天</param> /// <returns></returns> public virtual bool SetExpire(string key, TimeSpan? expiry = null) { if (expiry == null) { expiry = TimeSpan.FromDays(3); } return GetDatabase().KeyExpire(MergeKey(key), expiry); } #endregion Key管理
#region 序列/反序列 /// <summary> /// 序列化对象 /// </summary> /// <param name="value"></param> /// <returns></returns> private string Serialize<T>(T value) { return JsonConvert.SerializeObject(value); } /// <summary> /// 反序列化对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">值</param> /// <returns></returns> private static T Deserialize<T>(RedisValue value) { if (value.HasValue) { return JsonConvert.DeserializeObject<T>(value); } return default; } /// <summary> /// 反序列化对象(返回值可能为null,需要根据数据类型判空) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="values">值</param> /// <returns></returns> private static List<T> Deserialize<T>(RedisValue[] values) { List<T> result = new List<T>(); foreach (var item in values) { var model = Deserialize<T>(item); result.Add(model); } return result; } #endregion 序列/反序列
}
https://www.cnblogs.com/cang12138/p/8884362.html 这边稍微简短点