在分佈式緩存的應用中,會遇到多個客戶端同時爭用的問題。這個時候,須要用到分佈式鎖,獲得鎖的客戶端纔有操做權限redis
using ServiceStack.Redis; namespace Redis.AcquireLock { public class RedisHelper { //實例化Client public RedisClient client = new RedisClient("192.168.100.152", 6901); /// <summary> /// 根據key存儲T對象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public bool Set<T>(string key, T value) { var result = client.Set<T>(key, value); return result; } /// <summary> /// 根據key存儲T對象,而且設置過時時間 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="timeOut"></param> /// <returns></returns> public bool Set<T>(string key, T value, TimeSpan timeOut) { var result = client.Set<T>(key, value, timeOut); return result; } /// <summary> /// 根據key存儲T對象,而且設置過時時間 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="timeOut"></param> /// <returns></returns> public bool Set<T>(string key, T value, DateTime timeOut) { var result = client.Set<T>(key, value, timeOut); return result; } /// <summary> /// 根據key設置過時時間 /// </summary> /// <param name="key"></param> /// <param name="timeOut"></param> /// <returns></returns> public bool ExpireTime(string key, TimeSpan timeOut) { var result = client.ExpireEntryIn(key, timeOut); return result; } /// <summary> /// 根據key設置過時時間 /// </summary> /// <param name="key"></param> /// <param name="timeOut"></param> /// <returns></returns> public bool ExpireTime(string key, DateTime timeOut) { var result = client.ExpireEntryAt(key, timeOut); return result; } /// <summary> /// 根據key獲取對應的對象T /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public T Get<T>(string key) { var result = client.Get<T>(key); return result; } /// <summary> /// 移除/刪除對應key /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Remove(string key) { return client.Remove(key); } /// <summary> /// 刪除對應key(返回被刪除 key 的數量) /// </summary> /// <param name="key"></param> /// <returns></returns> public long Delete(string key) { return client.Del(key); } /// <summary> /// 判斷key是否存在,存在返回1,不存在返回0 /// </summary> /// <param name="key"></param> /// <returns></returns> public long Exists(string key) { return client.Exists(key); } /// <summary> /// 判斷key是否存在,存在返回true,不存在返回false /// </summary> /// <param name="key"></param> /// <returns></returns> public bool ContainsKey(string key) { return client.ContainsKey(key); } /// <summary> /// Redis分佈式鎖 /// </summary> /// <param name="key"></param> /// <returns></returns> public IDisposable AcquireLock(string key) { return client.AcquireLock(key); } /// <summary> /// Redis分佈式鎖,而且設置過時時間 /// </summary> /// <param name="key"></param> /// <param name="timeOut"></param> /// <returns></returns> public IDisposable AcquireLock(string key, TimeSpan timeOut) { return client.AcquireLock(key, timeOut); } } }
控制檯程序: 緩存
namespace Redis.AcquireLock { /// <summary> /// Redis分佈式鎖簡單實例 /// </summary> public class Program { public static void Main(string[] args) { RedisHelper redis = new RedisHelper(); Console.WriteLine("線程開始前,輸出" + redis.Get<int>("redisKey")); Console.WriteLine("線程開始前,輸出" + redis.Remove("redisKey")); Console.WriteLine("線程開始前,輸出" + redis.Delete("redisKey")); redis.Set<int>("redisKey", 0); //定義兩個線程 Thread myThread1 = new Thread(new ParameterizedThreadStart(AddVal)); Thread myThread2 = new Thread(AddVal); myThread1.Start("1"); myThread2.Start(); Console.WriteLine("等待兩個線程結束"); Console.ReadKey(); } public static void AddVal(object num) { RedisHelper redis = new RedisHelper(); for (int i = 0; i < 500; i++) { //int result = redis.Get<int>("redisKey"); //redis.Set<int>("redisKey", result + 1); //返回的是IDisposable,證實咱們須要手動釋放資源,因此這裏使用了using完過後自動釋放資源 //若是1秒不釋放鎖 自動釋放,避免死鎖 using (redis.AcquireLock("redis_lock", TimeSpan.FromSeconds(1))) { int result = redis.Get<int>("redisKey"); redis.Set<int>("redisKey", result + 1); } } Console.WriteLine("線程" + num + "結束,輸出" + redis.Get<int>("redisKey")); //設置緩存過時時間 redis.ExpireTime("redisKey", TimeSpan.FromSeconds(10)); } } }
運行結果效果圖說明:分佈式