標籤:沒有 html gif ber png linu mem ase 代理
redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value類型相對更多,包括string(字串)、list(鏈表)、set(集合)和zset(有序集合)。這些資料類型都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是緩衝在記憶體中。區別的是redis會周期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。
主要用於資料存放區(緩衝)、發布訂閱、訊息佇列以及分布式鎖等。
1.redis安裝 可以使用 window安裝 還有 linux安裝 以及docker安裝
官網 https://redis.io/
中文 http://www.redis.cn/
2.視覺化檢視
RedisDesktopManager
3. c# 驅動
比較知名的c#驅動是 ServiceStack.Redis 和 StackExchange.Redis
由於ServiceStack.Redis,提供了預設的線程池是收費的,主要是需要付費解除並發數量的限制,
而StackExchange.Redis沒有提供預設的線程池沒有並發量的限制,是免費的。
StackExchange.Redis封裝類 方便使用。
public class RedisManager { /// <summary> /// 鎖對象 /// </summary> private static object _locker = new object(); /// <summary> /// StackExchange.Redis對象 /// </summary> private static ConnectionMultiplexer _redis; /// <summary> /// 代理類型 /// None = 0, /// Twemproxy = 1, /// </summary> private static int proxy = int.Parse(ConfigurationManager.AppSettings["Redis_Proxy"] ?? "0"); /// <summary> /// 是否為sentinel伺服器 /// yes=1, /// no=0, /// </summary> private static int issentinel = int.Parse(ConfigurationManager.AppSettings["Redis_RedisIssentinel"] ?? "0"); /// <summary> /// sentinel模式下,redis主要資料伺服器的密碼 /// </summary> private static string authPassword = ConfigurationManager.AppSettings["Redis_RedisIssentinel"]; /// <summary> /// serverName /// </summary> private static string serviceName = ConfigurationManager.AppSettings["Redis_ServiceName"]; /// <summary> /// 得到StackExchange.Redis單例對象 /// </summary> public static ConnectionMultiplexer Instance { get { if (_redis == null || !_redis.IsConnected) { lock (_locker) { if (_redis == null || !_redis.IsConnected) { _redis = GetManager(); return _redis; } } } return _redis; } } /// <summary> /// 構建連結 /// </summary> /// <param name="connectionString"></param> /// <returns></returns> private static ConnectionMultiplexer GetManager() { return GetCurrentRedis(); } /// <summary> /// 每個串連串用逗號分開,sentinel不支援密碼 /// </summary> /// <returns></returns> static ConnectionMultiplexer GetCurrentRedis() { var connectionString = ConfigurationManager.AppSettings["Redis_Host"]; ConnectionMultiplexer conn; var option = new ConfigurationOptions(); option.Proxy = (Proxy)proxy;//代理模式,目前支援TW //sentinel模式下自動連接主redis if (issentinel == 1) { var configArr = connectionString.Split(new char[] { ‘,‘ }, StringSplitOptions.RemoveEmptyEntries); configArr.ToList().ForEach(i => { option.EndPoints.Add(i); }); option.TieBreaker = "";//這行在sentinel模式必須加上 option.CommandMap = CommandMap.Sentinel; conn = ConnectionMultiplexer.Connect(option); for (int i = 0; i < option.EndPoints.Count; i++) { try { connectionString = conn.GetServer(option.EndPoints[i]).SentinelGetMasterAddressByName(serviceName).ToString(); Console.WriteLine("當前主master[{0}]:{1}", i, connectionString); break; } catch (RedisConnectionException ex)//逾時 { continue; } catch (Exception ex) { continue; } } } return ConnectionMultiplexer.Connect(connectionString + ",password=" + authPassword); } }
View Code
訊息佇列:
入隊
/// <summary> /// 訊息佇列-入隊 /// </summary> static void ListLeftPush() { while (true) { string msg = $"{DateTime.Now:HH:mm}-{globaxId}-{Thread.CurrentThread.ManagedThreadId}-{StringExtend.GetRanString(8)}"; RedisManager.Instance.GetDatabase(RedisConfig.DemoDb).ListLeftPush(RedisConfig.DemoKey, msg); globaxId++; Console.WriteLine($"LeftPush:{msg}"); Task.Delay(500); Thread.Sleep(500); } }
View Code
出隊:
/// <summary> /// 訊息佇列-出隊 /// </summary> static void ListLeftPush() { while (true) { //ListLeftPush var msg = RedisManager.Instance.GetDatabase(RedisConfig.DemoDb).ListLeftPop(RedisConfig.DemoKey); if (!msg.IsNullOrEmpty) { Console.WriteLine($"出隊:{msg}"); Task.Delay(200); } else { Thread.Sleep(1000); } } }
View Code
效果:
4.2發布訂閱:
發布
/// <summary> /// 發布 /// </summary> static void Publish() { while (true) { lock (lockObj) { string msg = $"{DateTime.Now:HH:mm}-{globaxId}-{StringExtend.GetRanString(8)}"; var sub = RedisManager.Instance.GetSubscriber(); sub.Publish(RedisConfig.DemoChannel1, msg); Console.WriteLine($"Publish:{msg}"); globaxId++; } Task.Delay(200); Thread.Sleep(500); } }
View Code訂閱
/// <summary> /// 訂閱 /// </summary> static void Subscribe() { while (true) { lock (lockObj) { // string msg = $"Publish:{DateTime.Now:HH:mm}-{globaxId}-{StringExtend.GetRanString(8)}"; var sub = RedisManager.Instance.GetSubscriber(); sub.Subscribe(RedisConfig.DemoChannel1, SubHandel); } Task.Delay(200); Thread.Sleep(500); } } static void SubHandel(RedisChannel cnl, RedisValue val) { if (!val.IsNullOrEmpty) { Console.WriteLine($"Subscribe{val},線程:{Thread.CurrentThread.ManagedThreadId},是否線程池:{Thread.CurrentThread.IsThreadPoolThread}"); } else { Thread.Sleep(1000); } }
View Code
c#redis使用