StackExchange.Redis 的組件封裝示例網上有很多,自行百度搜索即可。 這裡只演示如何使用Hash類型操作數據: 1 // 在 hash 中存入或修改一個值 並設置order_hashkey有效期1分鐘,過期自動刪除;null為不過期 2 stopwatch.Start(); 3 va ...
StackExchange.Redis 的組件封裝示例網上有很多,自行百度搜索即可。
這裡只演示如何使用Hash類型操作數據:
1 // 在 hash 中存入或修改一個值 並設置order_hashkey有效期1分鐘,過期自動刪除;null為不過期 2 stopwatch.Start(); 3 var isok = RedisCacheHelper.Instance.HashSet("order_hashkey", "order_hashfield", "10", TimeSpan.FromMinutes(1)); 4 stopwatch.Stop(); 5 Console.WriteLine("在hash中存入一個值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
1 //判斷該欄位是否存在 hash 中 2 var isexists = RedisCacheHelper.Instance.HashExists("order_hashkey", "order_hashfield"); 3 Console.WriteLine("判斷該欄位是否存在hash中:" + isexists); //返回 True 或 False
//從hash中移除指定欄位 var isdel = RedisCacheHelper.Instance.HashDelete("order_hashkey", "order_hashfield"); Console.WriteLine("從hash中移除指定欄位:" + isdel); //返回 True 或 False
//從hash中遞增 預設按1遞增 var getincre = RedisCacheHelper.Instance.HashIncrement("order_hashkey", "order_hashfield"); Console.WriteLine("從hash中遞增:" + getincre); //返遞增後的值 11 //從hash中遞減 預設按1遞減 var getdecre = RedisCacheHelper.Instance.HashDecrement("order_hashkey", "order_hashfield"); Console.WriteLine("從hash中遞減:" + getdecre); //返遞減後的值 10
//保存一個字元串類型集合 string[] strarray = { "1", "2", "3", "4", "5" }; RedisCacheHelper.Instance.HashSetList("orderlist_hashkey", strarray, m => { return "hashfield_" + m.ToString(); }, new TimeSpan(0, 0, 50)); //從資料庫獲取10條數據 stopwatch.Start(); var getlist = TestRedis.GetOrderFormAll(10); stopwatch.Stop(); Console.WriteLine("從資料庫獲取10條數據消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); //保存多個對象集合 非序列化 stopwatch.Start(); RedisCacheHelper.Instance.HashSetObjectList("objlist_hashkey", getlist, r => { return r.ordercode.ToString(); }, 1); stopwatch.Stop(); Console.WriteLine("將10條數據存入HashRedis 消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
//保存或修改一個hash對象(序列化) 對key設置過期時間有時候起作用,有時候不起作用 stopwatch.Start(); RedisCacheHelper.Instance.HashSet<OrderForm>("orderform_hashkey", "orderform_hashfield", getlist.FirstOrDefault(), new TimeSpan(0, 0, 10), 2); stopwatch.Stop(); Console.WriteLine("保存或修改一個hash對象(序列化)消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); //保存Hash對象集合 序列化 對key設置過期時間可以起作用 stopwatch.Start(); RedisCacheHelper.Instance.HashSet<OrderForm>("orderformlist_hashkey", getlist, m=> { return m.ordercode.ToString(); }, new TimeSpan(0, 0, 30), 3); stopwatch.Stop(); Console.WriteLine("保存Hash對象集合(序列化)消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
//從Hash Redis獲取某一條訂單信息 反序列化 stopwatch.Start(); var getorderinfo = RedisCacheHelper.Instance.HashGet<OrderForm>("orderform_hashkey", "orderform_hashfield", 2); stopwatch.Stop(); Console.WriteLine("從Hash Redis獲取某一條訂單信息消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); Console.WriteLine(getorderinfo.ordercode); Console.WriteLine(getorderinfo.Area); Console.WriteLine(getorderinfo.City); Console.WriteLine(getorderinfo.Province); Console.WriteLine(getorderinfo.PostTime);
//根據hashkey 獲取所有的值 反序列化 stopwatch.Start(); var getorderlist = RedisCacheHelper.Instance.HashGetAll<OrderForm>("orderformlist_hashkey", 3); stopwatch.Stop(); Console.WriteLine("根據hashkey 獲取所有的值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getorderlist) { Console.WriteLine("獲取反序列化得到的ordercode: " + item.ordercode); }
//根據hashkey獲取單個欄位hashField的值 stopwatch.Start(); var getvalue = RedisCacheHelper.Instance.HashGet("objlist_hashkey1", "City", 1); stopwatch.Stop(); Console.WriteLine("獲取單個欄位hashField的值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); Console.WriteLine("獲取City: " + getvalue); Console.WriteLine("------------------"); Console.WriteLine(); //獲取多個欄位hashField的值 List<RedisValue> fieldlist = new List<RedisValue>() { "ordercode", "Province", "City", "Area" }; stopwatch.Start(); var getlist = RedisCacheHelper.Instance.HashGet("objlist_hashkey1", fieldlist.ToArray(), 1); stopwatch.Stop(); Console.WriteLine("獲取多個欄位hashField的值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getlist) { Console.WriteLine("獲取到的值: " + item); }
//根據hashkey返回所有的HashFiled stopwatch.Start(); var getkeylist = RedisCacheHelper.Instance.HashKeys("objlist_hashkey1", 1); stopwatch.Stop(); Console.WriteLine("消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getkeylist) { Console.WriteLine("獲取到的HashFiled: " + item); } //根據hashkey返回所有HashFiled值 stopwatch.Start(); var getvaluelist = RedisCacheHelper.Instance.HashValues("objlist_hashkey1", 1); stopwatch.Stop(); Console.WriteLine("消耗時間:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getvaluelist) { Console.WriteLine("獲取到的HashFiled值: " + item); }
//模擬併發場景 使用HashDecrement遞減功能 使用分散式鎖,但是線程線程排隊處理,有可能照成Redis超時
該示例會照成1個用戶搶多個
stopwatch.Start(); List<Task> taskList = new List<Task>(); for (int i = 1; i <= 100; i++) //模擬多個用戶同時請求 { var task = Task.Run(() => { try { //*************************開始**************** RedisValue token = Environment.MachineName; while (true) { if (RedisCacheHelper.Instance.LockAndDo("lock_key", token, () => { //在這裡處理併發邏輯 //先獲取庫存數 var getvalues = (int)RedisCacheHelper.Instance.HashGet("order_hashkey", "order_hashfield"); if (getvalues > 0) { //先自減,獲取自減後的值 int order_Num = (int)RedisCacheHelper.Instance.HashDecrement("order_hashkey", "order_hashfield", null); if (order_Num >= 0) { //下麵執行訂單邏輯(這裡不考慮業務出錯的情況) Console.WriteLine("我搶到了,還剩餘數量:" + order_Num); } else { Console.WriteLine("A商品已經被搶光了"); } return true; } else { Console.WriteLine("B商品已經被搶光了"); return true; } }, new TimeSpan(0, 0, 10))) { break; } } } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } }); taskList.Add(task); } Task.WaitAll(taskList.ToArray()); stopwatch.Stop(); Console.WriteLine("模擬併發場景消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
搶購前庫存30個
搶購後庫存0
這裡附上RedisHelp
/// <summary> /// 判斷該欄位是否存在 hash 中 /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <returns></returns> public bool HashExists(string redisKey, string hashField, int db = -1) { try { _db = GetDatabase(db); return _db.HashExists(redisKey, hashField); } catch (Exception) { throw; } } /// <summary> /// 從 hash 中移除指定欄位 /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <returns></returns> public bool HashDelete(string redisKey, string hashField, int db = -1) { try { _db = GetDatabase(db); return _db.HashDelete(redisKey, hashField); } catch (Exception) { throw; } } /// <summary> /// 從 hash 中移除多個指定欄位 /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <returns></returns> public long HashDelete(string redisKey, IEnumerable<RedisValue> hashField, int db = -1) { try { _db = GetDatabase(db); return _db.HashDelete(redisKey, hashField.ToArray()); } catch (Exception) { throw; } } /// <summary> /// 遞增 預設按1遞增 可用於計數 /// </summary> /// <param name="key"></param> /// <param name="span"></param> /// <param name="db"></param> /// <returns></returns> public long HashIncrement(string redisKey, string hashField, TimeSpan? span = null, int db = -1) { try { _db = GetDatabase(db); var result = _db.HashIncrement(redisKey, hashField); //設置過期時間 if (span != null) { this.KeyExpire(redisKey, span); } return result; } catch (Exception) { throw; } } /// <summary> /// 遞減 預設按1遞減 可用於搶購類的案例 /// </summary> /// <param name="key"></param> /// <param name="span"></param> /// <param name="db"></param> /// <returns></returns> public long HashDecrement(string redisKey, string hashField, TimeSpan? span = null, int db = -1) { try { _db = GetDatabase(db); var result = _db.HashDecrement(redisKey, hashField); //設置過期時間 if (span != null) { this.KeyExpire(redisKey, span); } return result; } catch (Exception) { throw; } } /// <summary> /// 在 hash 中保存或修改一個值 字元類型 /// set or update the HashValue for string key /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <param name="value"></param> /// <param name="span">過期時間,可空</param> /// <returns></returns> public bool HashSet(string redisKey, string hashField, string value, TimeSpan? span = null, int db = -1) { try { _db = GetDatabase(db); if (span != null) { //設置過期時間 this.KeyExpire(redisKey, span); } return _db.HashSet(redisKey, hashField, value); } catch (Exception) { throw; } } /// <summary> /// 保存一個字元串類型集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="redisKey">Redis Key</param> /// <param name="list">數據集合</param> /// <param name="getFiledKey">欄位key</param> public void HashSetList(string redisKey, IEnumerable<string> list, Func<string, string> getFiledKey, TimeSpan? span = null, int db = -1) { try { _db = GetDatabase(db); List<HashEntry> listHashEntry = new List<HashEntry>(); foreach (var item in list) { listHashEntry.Add(new HashEntry(getFiledKey(item), item)); } _db.HashSet(redisKey, listHashEntry.ToArray()); if (span != null) { //設置過期時間 this.KeyExpire(redisKey, span); } } catch (Exception ex) { throw; } } /// <summary> /// 保存多個對象集合 非序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tableName">表名首碼</param> /// <param name="list">數據集合</param> /// <param name="getModelId">欄位key</param> public void HashSetObjectList<T>(string tableName, IEnumerable<T> list, Func<T, string> getModelId, int db = -1) where T : class { try { _db = GetDatabase(db); foreach (var item in list) { List<HashEntry> listHashEntry = new List<HashEntry>(); Type t = item.GetType();//獲得該類的Type foreach (PropertyInfo pi in t.GetProperties()) { string name = pi.Name; //獲得屬性的名字,後面就可以根據名字判斷來進行些自己想要的操作 var value = pi.GetValue(item, null); //用pi.GetValue獲得值 listHashEntry.Add(new HashEntry(name, value.ToString())); } _db.HashSet(tableName + getModelId(item), listHashEntry.ToArray()); } } catch (Exception ex) { throw; } } /// <summary> /// 保存或修改一個hash對象(序列化) /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <param name="value"></param> /// <returns></returns> public bool HashSet<T>(string redisKey, string hashField, T value, TimeSpan? span = null, int db = -1) where T : class { try { _db = GetDatabase(db); var json = JsonConvert.SerializeObject(value); if (span != null) { //設置過期時間 this.KeyExpire(redisKey, span); } return _db.HashSet(redisKey, hashField, json); } catch (Exception) { throw; } } /// <summary> /// 保存Hash對象集合 序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="redisKey">Redis Key</param> /// <param name="list">數據集合</param> /// <param name="getModelId"></param> public void HashSet<T>(string redisKey, IEnumerable<T> list, Func<T, string> getModelId, TimeSpan? span = null, int db = -1) where T : class { try { _db = GetDatabase(db); List<HashEntry> listHashEntry = new List<HashEntry>(); foreach (var item in list) { string json = JsonConvert.SerializeObject(item); listHashEntry.Add(new HashEntry(getModelId(item), json)); } _db.HashSet(redisKey, listHashEntry.ToArray()); if (span != null) { //設置過期時間 this.KeyExpire(redisKey, span); } } catch (Exception ex) { throw; } } /// <summary> /// 從 hash 中獲取對象(反序列化) /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <returns></returns> public T HashGet<T>(string redisKey, string hashField, int db = -1) where T : class { try { _db = GetDatabase(db); return JsonConvert.DeserializeObject<T>(_db.HashGet(redisKey, hashField)); } catch (Exception) { throw; } } /// <summary> /// 根據hashkey獲取所有的值 序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="redisKey"></param> /// <param name="db"></param> /// <returns></returns> public List<T> HashGetAll<T>(string redisKey, int db = -1) where T : class { List<T> result = new List<T>(); try { _db = GetDatabase(db); HashEntry[] arr = _db.HashGetAll(redisKey); foreach (var item in arr) { if (!item.Value.IsNullOrEmpty) { var t = JsonConvert.DeserializeObject<T>(item.Value); if (t != null) { result.Add(t); } } } } catch (Exception) { throw; } return result; } /// <summary> /// 根據hashkey獲取所有的值 非序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="redisKey"></param> /// <param name="db"></param> /// <returns></returns> public IEnumerable<Dictionary<RedisValue, RedisValue>> HashGetAll(IEnumerable<string> redisKey, int db = -1) { List<Dictionary<RedisValue, RedisValue>> diclist = new List<Dictionary<RedisValue, RedisValue>>(); try { _db = GetDatabase(db); foreach (var item in redisKey) { HashEntry[] arr = _db.HashGetAll(item); foreach (var he in arr) { Dictionary<RedisValue, RedisValue> dic = new Dictionary<RedisValue, RedisValue>(); if (!he.Value.IsNullOrEmpty) { dic.Add(he.Name, he.Value); } diclist.Add(dic); } } } catch (Exception) { throw; } return diclist; } /// <summary> /// 根據hashkey獲取單個欄位hashField的值 /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <returns></returns> public RedisValue HashGet(string redisKey, string hashField, int db = -1) { try { _db = GetDatabase(db); return _db.HashGet(redisKey, hashField); } catch (Exception) { throw; } } /// <summary> /// 根據hashkey獲取多個欄位hashField的值 /// </summary> /// <param name="redisKey"></param> /// <param name="hashField"></param> /// <returns></returns> public RedisValue[] HashGet(string redisKey, RedisValue[] hashField, int db = -1) { _db = GetDatabase(db); return _db.HashGet(redisKey, hashField); } /// <summary> /// 根據hashkey返回所有的HashFiled /// </summary> /// <param name="redisKey"></param> /// <returns></returns> public IEnumerable<RedisValue> HashKeys(string redisKey, int db = -1) { _db = GetDatabase(db); return _db.HashKeys(redisKey); } /// <summary> /// 根據hashkey返回所有HashValue值 /// </summary> /// <param name="redisKey"></param> /// <returns></returns> public RedisValue[] HashValues(string redisKey, int db = -1) { _db = GetDatabase(db); return _db.HashValues(redisKey); }View Code