zoukankan      html  css  js  c++  java
  • Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍

    Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍

    目录

    • 简介
    • 安装
    • 入门指令
    • GUI 工具
    • C# 驱动介绍

    简介

      ANSI C 编写,开源,基于内存,可持久化,一个键值对的数据库,用法简单。

      支持的类型:字符串、散列、列表、集合和有序集合。

      因为 Redis 默认将所有数据都存储到内存中,并且内存的读写速度远远高于硬盘,因此,比其他基于硬盘存储的数据库在性能上体现的优势非常明显。不过这样也引发了一个数据安全性的问题,程序异常或退出后数据会出现丢失的情形,现在新的版本已经提供了数据持久化(RDB + AOF)的支持,即可以将内存中的数据异步写入到硬盘上,同时不会影响其它功能的运行。

      redis 可以为每个键设置生存时间,到期自动删除,也就是说可以作为缓存系统(这也是企业主要的运用场景)进行使用。

      相对于 Memcached,简单的说:Redis 单线程模型,Memcached 支持多线程,但 Redis 支持的功能和数据类型更多,更简单易用,并且 redis 的性能在绝大部分场合下都不会成为系统瓶颈,不过在多核服务器上使用的情况下,理论上 Memcached 比 redis 性能更高。所以,在新项目中,建议使用 redis 代替 Memcached。

      Redis 还可以限定数据占用的最大内存空间,在数据达到空间限制后按一定规则自动淘汰不需要的键;也支持构建高性能的队列(不过很多企业会选择第三方的 MQ,如:RabbitMQ)。

    安装

      它的约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版(如 v2.8,v3.0)。

      为了减少学习成本,我们直接使用 windows 版本的就可以,想学习 Linux 部署的,先搜搜别人的文章吧。

      redis-windows-3.0(搜索了一下,最新的正式版是 3.2):下载地址

      文件简单说明:

    入门指令

      1.启动 CMD:

    $ redis-server
    
    $ redis-server --port 6380 //自定义端口

      2.停止:

    $ redis-cli SHUTDOWN

      3.PING 命令:

      测试与 redis 的连接是否正常,正常返回 PONG

    $ redis-cli PING   

    GUI 工具

      Redis Client:一个基于Java SWT 和 Jedis 编写的 redis 客户端 GUI 工具。可从 https://github.com/caoxinyu/RedisClient 下载。

      从图可知,redis 包含了 16 个数据库。上面的每个数据库默认从 0 开始的递增数字命名。

      因为该程序打包后的压缩包 >10 M,无法上传到 cnblogs,如有需要的童鞋请加群在群文件中下载压缩包。

      补充一下园友(心态要好)推荐的其它 GUI 工具 RedisDeskTopManager:https://redisdesktop.com/download

    C# 驱动

      之前在 《使用 StackExchange.Redis 封装属于自己的 RedisHelper》 曾经发布了一篇使用 StackExchange.Redis 进行了简单封装的 RedisHelper,你可以选择查看之前的文章,从中借鉴一些思想或者给出一些建议。

      这里是更新后的 Helper 代码(直接展开即可),代码的后续更新在 GitHub 上。

       1 #region
       2 
       3 using System;
       4 using System.Collections.Generic;
       5 using System.Configuration;
       6 using System.IO;
       7 using System.Linq;
       8 using System.Runtime.Serialization.Formatters.Binary;
       9 using System.Threading.Tasks;
      10 using StackExchange.Redis;
      11 
      12 #endregion
      13 
      14 namespace Wen.Helpers.Common.Redis
      15 {
      16     /// <summary>
      17     /// Redis 助手
      18     /// </summary>
      19     public class RedisHelper
      20     {
      21         /// <summary>
      22         /// 获取 Redis 连接对象
      23         /// </summary>
      24         /// <returns></returns>
      25         public IConnectionMultiplexer GetConnectionRedisMultiplexer()
      26         {
      27             if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
      28                 lock (Locker)
      29                 {
      30                     if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
      31                         _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
      32                 }
      33 
      34             return _connMultiplexer;
      35         }
      36 
      37         #region 其它
      38 
      39         public ITransaction GetTransaction()
      40         {
      41             return _db.CreateTransaction();
      42         }
      43 
      44         #endregion 其它
      45 
      46         #region private field
      47 
      48         /// <summary>
      49         /// 连接字符串
      50         /// </summary>
      51         private static readonly string ConnectionString;
      52 
      53         /// <summary>
      54         /// redis 连接对象
      55         /// </summary>
      56         private static IConnectionMultiplexer _connMultiplexer;
      57 
      58         /// <summary>
      59         /// 默认的 Key 值(用来当作 RedisKey 的前缀)
      60         /// </summary>
      61         private static readonly string DefaultKey;
      62 
      63         /// <summary>
      64         ///  65         /// </summary>
      66         private static readonly object Locker = new object();
      67 
      68         /// <summary>
      69         /// 数据库
      70         /// </summary>
      71         private readonly IDatabase _db;
      72 
      73         #endregion private field
      74 
      75         #region 构造函数
      76 
      77         static RedisHelper()
      78         {
      79             ConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString;
      80             _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
      81             DefaultKey = ConfigurationManager.AppSettings["Redis.DefaultKey"];
      82             AddRegisterEvent();
      83         }
      84 
      85         public RedisHelper(int db = 0)
      86         {
      87             _db = _connMultiplexer.GetDatabase(db);
      88         }
      89 
      90         #endregion 构造函数
      91 
      92         #region String 操作
      93 
      94         /// <summary>
      95         /// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)
      96         /// </summary>
      97         /// <param name="key"></param>
      98         /// <param name="value"></param>
      99         /// <param name="expiry"></param>
     100         /// <returns></returns>
     101         public bool StringSet(string key, string value, TimeSpan? expiry = null)
     102         {
     103             key = AddKeyPrefix(key);
     104             return _db.StringSet(key, value, expiry);
     105         }
     106 
     107         /// <summary>
     108         /// 保存多个 Key-value
     109         /// </summary>
     110         /// <param name="keyValuePairs"></param>
     111         /// <returns></returns>
     112         public bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
     113         {
     114             var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
     115             return _db.StringSet(pairs.ToArray());
     116         }
     117 
     118         /// <summary>
     119         /// 获取字符串
     120         /// </summary>
     121         /// <param name="redisKey"></param>
     122         /// <param name="expiry"></param>
     123         /// <returns></returns>
     124         public string StringGet(string redisKey)
     125         {
     126             redisKey = AddKeyPrefix(redisKey);
     127             return _db.StringGet(redisKey);
     128         }
     129 
     130         /// <summary>
     131         /// 存储一个对象(该对象会被序列化保存)
     132         /// </summary>
     133         /// <param name="key"></param>
     134         /// <param name="value"></param>
     135         /// <param name="expiry"></param>
     136         /// <returns></returns>
     137         public bool StringSet<T>(string key, T value, TimeSpan? expiry = null)
     138         {
     139             key = AddKeyPrefix(key);
     140             var json = Serialize(value);
     141 
     142             return _db.StringSet(key, json, expiry);
     143         }
     144 
     145         /// <summary>
     146         /// 获取一个对象(会进行反序列化)
     147         /// </summary>
     148         /// <param name="key"></param>
     149         /// <param name="expiry"></param>
     150         /// <returns></returns>
     151         public T StringGet<T>(string key, TimeSpan? expiry = null)
     152         {
     153             key = AddKeyPrefix(key);
     154             return Deserialize<T>(_db.StringGet(key));
     155         }
     156 
     157         /// <summary>
     158         /// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
     159         /// </summary>
     160         /// <param name="key"></param>
     161         /// <param name="value"></param>
     162         /// <returns></returns>
     163         public double StringIncrement(string key, double value = 1)
     164         {
     165             key = AddKeyPrefix(key);
     166             return _db.StringIncrement(key, value);
     167         }
     168 
     169         /// <summary>
     170         /// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
     171         /// </summary>
     172         /// <param name="key"></param>
     173         /// <param name="value"></param>
     174         /// <returns></returns>
     175         public double StringDecrement(string key, double value = 1)
     176         {
     177             key = AddKeyPrefix(key);
     178             return _db.StringDecrement(key, value);
     179         }
     180 
     181         #region async
     182 
     183         /// <summary>
     184         /// 保存一个字符串值
     185         /// </summary>
     186         /// <param name="key"></param>
     187         /// <param name="value"></param>
     188         /// <param name="expiry"></param>
     189         /// <returns></returns>
     190         public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = null)
     191         {
     192             key = AddKeyPrefix(key);
     193             return await _db.StringSetAsync(key, value, expiry);
     194         }
     195 
     196         /// <summary>
     197         /// 保存一组字符串值
     198         /// </summary>
     199         /// <param name="keyValuePairs"></param>
     200         /// <returns></returns>
     201         public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
     202         {
     203             var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
     204             return await _db.StringSetAsync(pairs.ToArray());
     205         }
     206 
     207         /// <summary>
     208         /// 获取单个值
     209         /// </summary>
     210         /// <param name="key"></param>
     211         /// <param name="value"></param>
     212         /// <param name="expiry"></param>
     213         /// <returns></returns>
     214         public async Task<string> StringGetAsync(string key, string value, TimeSpan? expiry = null)
     215         {
     216             key = AddKeyPrefix(key);
     217             return await _db.StringGetAsync(key);
     218         }
     219 
     220         /// <summary>
     221         /// 存储一个对象(该对象会被序列化保存)
     222         /// </summary>
     223         /// <param name="key"></param>
     224         /// <param name="value"></param>
     225         /// <param name="expiry"></param>
     226         /// <returns></returns>
     227         public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
     228         {
     229             key = AddKeyPrefix(key);
     230             var json = Serialize(value);
     231             return await _db.StringSetAsync(key, json, expiry);
     232         }
     233 
     234         /// <summary>
     235         /// 获取一个对象(会进行反序列化)
     236         /// </summary>
     237         /// <param name="key"></param>
     238         /// <param name="expiry"></param>
     239         /// <returns></returns>
     240         public async Task<T> StringGetAsync<T>(string key, TimeSpan? expiry = null)
     241         {
     242             key = AddKeyPrefix(key);
     243             return Deserialize<T>(await _db.StringGetAsync(key));
     244         }
     245 
     246         /// <summary>
     247         /// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
     248         /// </summary>
     249         /// <param name="key"></param>
     250         /// <param name="value"></param>
     251         /// <returns></returns>
     252         public async Task<double> StringIncrementAsync(string key, double value = 1)
     253         {
     254             key = AddKeyPrefix(key);
     255             return await _db.StringIncrementAsync(key, value);
     256         }
     257 
     258         /// <summary>
     259         /// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
     260         /// </summary>
     261         /// <param name="key"></param>
     262         /// <param name="value"></param>
     263         /// <returns></returns>
     264         public async Task<double> StringDecrementAsync(string key, double value = 1)
     265         {
     266             key = AddKeyPrefix(key);
     267             return await _db.StringDecrementAsync(key, value);
     268         }
     269 
     270         #endregion async
     271 
     272         #endregion String 操作
     273 
     274         #region Hash 操作
     275 
     276         /// <summary>
     277         /// 判断该字段是否存在 hash 中
     278         /// </summary>
     279         /// <param name="key"></param>
     280         /// <param name="hashField"></param>
     281         /// <returns></returns>
     282         public bool HashExists(string key, string hashField)
     283         {
     284             key = AddKeyPrefix(key);
     285             return _db.HashExists(key, hashField);
     286         }
     287 
     288         /// <summary>
     289         /// 从 hash 中移除指定字段
     290         /// </summary>
     291         /// <param name="key"></param>
     292         /// <param name="hashField"></param>
     293         /// <returns></returns>
     294         public bool HashDelete(string key, string hashField)
     295         {
     296             key = AddKeyPrefix(key);
     297             return _db.HashDelete(key, hashField);
     298         }
     299 
     300         /// <summary>
     301         /// 从 hash 中移除指定字段
     302         /// </summary>
     303         /// <param name="key"></param>
     304         /// <param name="hashFields"></param>
     305         /// <returns></returns>
     306         public long HashDelete(string key, IEnumerable<string> hashFields)
     307         {
     308             key = AddKeyPrefix(key);
     309             var fields = hashFields.Select(x => (RedisValue) x);
     310 
     311             return _db.HashDelete(key, fields.ToArray());
     312         }
     313 
     314         /// <summary>
     315         /// 在 hash 设定值
     316         /// </summary>
     317         /// <param name="key"></param>
     318         /// <param name="hashField"></param>
     319         /// <param name="value"></param>
     320         /// <returns></returns>
     321         public bool HashSet(string key, string hashField, string value)
     322         {
     323             key = AddKeyPrefix(key);
     324             return _db.HashSet(key, hashField, value);
     325         }
     326 
     327         /// <summary>
     328         /// 在 hash 中设定值
     329         /// </summary>
     330         /// <param name="key"></param>
     331         /// <param name="hashFields"></param>
     332         public void HashSet(string key, IEnumerable<KeyValuePair<string, string>> hashFields)
     333         {
     334             key = AddKeyPrefix(key);
     335             var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value));
     336 
     337             _db.HashSet(key, entries.ToArray());
     338         }
     339 
     340         /// <summary>
     341         /// 在 hash 中获取值
     342         /// </summary>
     343         /// <param name="key"></param>
     344         /// <param name="hashField"></param>
     345         /// <returns></returns>
     346         public string HashGet(string key, string hashField)
     347         {
     348             key = AddKeyPrefix(key);
     349             return _db.HashGet(key, hashField);
     350         }
     351 
     352         /// <summary>
     353         /// 在 hash 中获取值
     354         /// </summary>
     355         /// <param name="key"></param>
     356         /// <param name="hashFields"></param>
     357         /// <returns></returns>
     358         public IEnumerable<string> HashGet(string key, IEnumerable<string> hashFields)
     359         {
     360             key = AddKeyPrefix(key);
     361             var fields = hashFields.Select(x => (RedisValue) x);
     362 
     363             return ConvertStrings(_db.HashGet(key, fields.ToArray()));
     364         }
     365 
     366         /// <summary>
     367         /// 从 hash 返回所有的字段值
     368         /// </summary>
     369         /// <param name="key"></param>
     370         /// <returns></returns>
     371         public IEnumerable<string> HashKeys(string key)
     372         {
     373             key = AddKeyPrefix(key);
     374             return ConvertStrings(_db.HashKeys(key));
     375         }
     376 
     377         /// <summary>
     378         /// 返回 hash 中的所有值
     379         /// </summary>
     380         /// <param name="key"></param>
     381         /// <returns></returns>
     382         public IEnumerable<string> HashValues(string key)
     383         {
     384             key = AddKeyPrefix(key);
     385             return ConvertStrings(_db.HashValues(key));
     386         }
     387 
     388         /// <summary>
     389         /// 在 hash 设定值(序列化)
     390         /// </summary>
     391         /// <param name="key"></param>
     392         /// <param name="hashField"></param>
     393         /// <param name="redisValue"></param>
     394         /// <returns></returns>
     395         public bool HashSet<T>(string key, string hashField, T redisValue)
     396         {
     397             key = AddKeyPrefix(key);
     398             var json = Serialize(redisValue);
     399 
     400             return _db.HashSet(key, hashField, json);
     401         }
     402 
     403         /// <summary>
     404         /// 在 hash 中获取值(反序列化)
     405         /// </summary>
     406         /// <param name="key"></param>
     407         /// <param name="hashField"></param>
     408         /// <returns></returns>
     409         public T HashGet<T>(string key, string hashField)
     410         {
     411             key = AddKeyPrefix(key);
     412             return Deserialize<T>(_db.HashGet(key, hashField));
     413         }
     414 
     415         /// <summary>
     416         /// 指定键递增
     417         /// </summary>
     418         /// <param name="key"></param>
     419         /// <param name="hashField"></param>
     420         /// <param name="value"></param>
     421         /// <returns></returns>
     422         public double HashIncrement(string key, string hashField, double value = 1)
     423         {
     424             key = AddKeyPrefix(key);
     425             return _db.HashIncrement(key, hashField, value);
     426         }
     427 
     428         /// <summary>
     429         /// 指定键递减
     430         /// </summary>
     431         /// <param name="key"></param>
     432         /// <param name="hashField"></param>
     433         /// <param name="value"></param>
     434         /// <returns></returns>
     435         public double HashDecrement(string key, string hashField, double value = 1)
     436         {
     437             key = AddKeyPrefix(key);
     438             return _db.HashDecrement(key, hashField, value);
     439         }
     440 
     441         #region async
     442 
     443         /// <summary>
     444         /// 判断该字段是否存在 hash 中
     445         /// </summary>
     446         /// <param name="redisKey"></param>
     447         /// <param name="hashField"></param>
     448         /// <returns></returns>
     449         public async Task<bool> HashExistsAsync(string redisKey, string hashField)
     450         {
     451             redisKey = AddKeyPrefix(redisKey);
     452             return await _db.HashExistsAsync(redisKey, hashField);
     453         }
     454 
     455         /// <summary>
     456         /// 从 hash 中移除指定字段
     457         /// </summary>
     458         /// <param name="redisKey"></param>
     459         /// <param name="hashField"></param>
     460         /// <returns></returns>
     461         public async Task<bool> HashDeleteAsync(string redisKey, string hashField)
     462         {
     463             redisKey = AddKeyPrefix(redisKey);
     464             return await _db.HashDeleteAsync(redisKey, hashField);
     465         }
     466 
     467         /// <summary>
     468         /// 从 hash 中移除指定字段
     469         /// </summary>
     470         /// <param name="redisKey"></param>
     471         /// <param name="hashFields"></param>
     472         /// <returns></returns>
     473         public async Task<long> HashDeleteAsync(string redisKey, IEnumerable<string> hashFields)
     474         {
     475             redisKey = AddKeyPrefix(redisKey);
     476             var fields = hashFields.Select(x => (RedisValue) x);
     477 
     478             return await _db.HashDeleteAsync(redisKey, fields.ToArray());
     479         }
     480 
     481         /// <summary>
     482         /// 在 hash 设定值
     483         /// </summary>
     484         /// <param name="redisKey"></param>
     485         /// <param name="hashField"></param>
     486         /// <param name="value"></param>
     487         /// <returns></returns>
     488         public async Task<bool> HashSetAsync(string redisKey, string hashField, string value)
     489         {
     490             redisKey = AddKeyPrefix(redisKey);
     491             return await _db.HashSetAsync(redisKey, hashField, value);
     492         }
     493 
     494         /// <summary>
     495         /// 在 hash 中设定值
     496         /// </summary>
     497         /// <param name="redisKey"></param>
     498         /// <param name="hashFields"></param>
     499         public async Task HashSetAsync(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields)
     500         {
     501             redisKey = AddKeyPrefix(redisKey);
     502             var entries = hashFields.Select(x => new HashEntry(AddKeyPrefix(x.Key), x.Value));
     503             await _db.HashSetAsync(redisKey, entries.ToArray());
     504         }
     505 
     506         /// <summary>
     507         /// 在 hash 中获取值
     508         /// </summary>
     509         /// <param name="redisKey"></param>
     510         /// <param name="hashField"></param>
     511         /// <returns></returns>
     512         public async Task<string> HashGetAsync(string redisKey, string hashField)
     513         {
     514             redisKey = AddKeyPrefix(redisKey);
     515             return await _db.HashGetAsync(redisKey, hashField);
     516         }
     517 
     518         /// <summary>
     519         /// 在 hash 中获取值
     520         /// </summary>
     521         /// <param name="redisKey"></param>
     522         /// <param name="hashFields"></param>
     523         /// <param name="value"></param>
     524         /// <returns></returns>
     525         public async Task<IEnumerable<string>> HashGetAsync(string redisKey, IEnumerable<string> hashFields,
     526             string value)
     527         {
     528             redisKey = AddKeyPrefix(redisKey);
     529             var fields = hashFields.Select(x => (RedisValue) x);
     530 
     531             return ConvertStrings(await _db.HashGetAsync(redisKey, fields.ToArray()));
     532         }
     533 
     534         /// <summary>
     535         /// 从 hash 返回所有的字段值
     536         /// </summary>
     537         /// <param name="redisKey"></param>
     538         /// <returns></returns>
     539         public async Task<IEnumerable<string>> HashKeysAsync(string redisKey)
     540         {
     541             redisKey = AddKeyPrefix(redisKey);
     542             return ConvertStrings(await _db.HashKeysAsync(redisKey));
     543         }
     544 
     545         /// <summary>
     546         /// 返回 hash 中的所有值
     547         /// </summary>
     548         /// <param name="redisKey"></param>
     549         /// <returns></returns>
     550         public async Task<IEnumerable<string>> HashValuesAsync(string redisKey)
     551         {
     552             redisKey = AddKeyPrefix(redisKey);
     553             return ConvertStrings(await _db.HashValuesAsync(redisKey));
     554         }
     555 
     556         /// <summary>
     557         /// 在 hash 设定值(序列化)
     558         /// </summary>
     559         /// <param name="redisKey"></param>
     560         /// <param name="hashField"></param>
     561         /// <param name="value"></param>
     562         /// <returns></returns>
     563         public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value)
     564         {
     565             redisKey = AddKeyPrefix(redisKey);
     566             var json = Serialize(value);
     567             return await _db.HashSetAsync(redisKey, hashField, json);
     568         }
     569 
     570         /// <summary>
     571         /// 在 hash 中获取值(反序列化)
     572         /// </summary>
     573         /// <param name="redisKey"></param>
     574         /// <param name="hashField"></param>
     575         /// <returns></returns>
     576         public async Task<T> HashGetAsync<T>(string redisKey, string hashField)
     577         {
     578             redisKey = AddKeyPrefix(redisKey);
     579             return Deserialize<T>(await _db.HashGetAsync(redisKey, hashField));
     580         }
     581 
     582         /// <summary>
     583         /// 指定键递增
     584         /// </summary>
     585         /// <param name="key"></param>
     586         /// <param name="hashField"></param>
     587         /// <param name="value"></param>
     588         /// <returns></returns>
     589         public async Task<double> HashIncrementAsync(string key, string hashField, double value = 1)
     590         {
     591             key = AddKeyPrefix(key);
     592             return await _db.HashIncrementAsync(key, hashField, value);
     593         }
     594 
     595         /// <summary>
     596         /// 指定键递减
     597         /// </summary>
     598         /// <param name="key"></param>
     599         /// <param name="hashField"></param>
     600         /// <param name="value"></param>
     601         /// <returns></returns>
     602         public async Task<double> HashDecrementAsync(string key, string hashField, double value = 1)
     603         {
     604             key = AddKeyPrefix(key);
     605             return await _db.HashDecrementAsync(key, hashField, value);
     606         }
     607 
     608         #endregion async
     609 
     610         #endregion Hash 操作
     611 
     612         #region List 操作
     613 
     614         /// <summary>
     615         /// 移除并返回存储在该键列表的第一个元素
     616         /// </summary>
     617         /// <param name="key"></param>
     618         /// <returns></returns>
     619         public string ListLeftPop(string key)
     620         {
     621             key = AddKeyPrefix(key);
     622             return _db.ListLeftPop(key);
     623         }
     624 
     625         /// <summary>
     626         /// 出列,移除并返回存储在该键列表的最后一个元素
     627         /// </summary>
     628         /// <param name="key"></param>
     629         /// <returns></returns>
     630         public string ListRightPop(string key)
     631         {
     632             key = AddKeyPrefix(key);
     633             return _db.ListRightPop(key);
     634         }
     635 
     636         /// <summary>
     637         /// 移除列表指定键上与该值相同的元素
     638         /// </summary>
     639         /// <param name="key"></param>
     640         /// <param name="value"></param>
     641         /// <returns></returns>
     642         public long ListRemove(string key, string value)
     643         {
     644             key = AddKeyPrefix(key);
     645             return _db.ListRemove(key, value);
     646         }
     647 
     648         /// <summary>
     649         /// 入列,在列表尾部插入值。如果键不存在,先创建再插入值
     650         /// </summary>
     651         /// <param name="key"></param>
     652         /// <param name="value"></param>
     653         /// <returns></returns>
     654         public long ListRightPush(string key, string value)
     655         {
     656             key = AddKeyPrefix(key);
     657             return _db.ListRightPush(key, value);
     658         }
     659 
     660         /// <summary>
     661         /// 在列表头部插入值。如果键不存在,先创建再插入值
     662         /// </summary>
     663         /// <param name="key"></param>
     664         /// <param name="value"></param>
     665         /// <returns></returns>
     666         public long ListLeftPush(string key, string value)
     667         {
     668             key = AddKeyPrefix(key);
     669             return _db.ListLeftPush(key, value);
     670         }
     671 
     672         /// <summary>
     673         /// 返回列表上该键的长度,如果不存在,返回 0
     674         /// </summary>
     675         /// <param name="key"></param>
     676         /// <returns></returns>
     677         public long ListLength(string key)
     678         {
     679             key = AddKeyPrefix(key);
     680             return _db.ListLength(key);
     681         }
     682 
     683         /// <summary>
     684         /// 返回在该列表上键所对应的元素
     685         /// </summary>
     686         /// <param name="key"></param>
     687         /// <param name="start"></param>
     688         /// <param name="stop"></param>
     689         /// <returns></returns>
     690         public IEnumerable<string> ListRange(string key, long start = 0L, long stop = -1L)
     691         {
     692             key = AddKeyPrefix(key);
     693             return ConvertStrings(_db.ListRange(key, start, stop));
     694         }
     695 
     696         /// <summary>
     697         /// 移除并返回存储在该键列表的第一个元素
     698         /// </summary>
     699         /// <param name="key"></param>
     700         /// <returns></returns>
     701         public T ListLeftPop<T>(string key)
     702         {
     703             key = AddKeyPrefix(key);
     704             return Deserialize<T>(_db.ListLeftPop(key));
     705         }
     706 
     707         /// <summary>
     708         /// 出队,移除并返回存储在该键列表的最后一个元素
     709         /// </summary>
     710         /// <param name="key"></param>
     711         /// <returns></returns>
     712         public T ListRightPop<T>(string key)
     713         {
     714             key = AddKeyPrefix(key);
     715             return Deserialize<T>(_db.ListRightPop(key));
     716         }
     717 
     718         /// <summary>
     719         /// 入队,在列表尾部插入值。如果键不存在,先创建再插入值
     720         /// </summary>
     721         /// <param name="key"></param>
     722         /// <param name="value"></param>
     723         /// <returns></returns>
     724         public long ListRightPush<T>(string key, T value)
     725         {
     726             key = AddKeyPrefix(key);
     727             return _db.ListRightPush(key, Serialize(value));
     728         }
     729 
     730         /// <summary>
     731         /// 在列表头部插入值。如果键不存在,先创建再插入值
     732         /// </summary>
     733         /// <param name="key"></param>
     734         /// <param name="value"></param>
     735         /// <returns></returns>
     736         public long ListLeftPush<T>(string key, T value)
     737         {
     738             key = AddKeyPrefix(key);
     739             return _db.ListLeftPush(key, Serialize(value));
     740         }
     741 
     742         #region List-async
     743 
     744         /// <summary>
     745         /// 移除并返回存储在该键列表的第一个元素
     746         /// </summary>
     747         /// <param name="key"></param>
     748         /// <returns></returns>
     749         public async Task<string> ListLeftPopAsync(string key)
     750         {
     751             key = AddKeyPrefix(key);
     752             return await _db.ListLeftPopAsync(key);
     753         }
     754 
     755         /// <summary>
     756         /// 移除并返回存储在该键列表的最后一个元素
     757         /// </summary>
     758         /// <param name="key"></param>
     759         /// <returns></returns>
     760         public async Task<string> ListRightPopAsync(string key)
     761         {
     762             key = AddKeyPrefix(key);
     763             return await _db.ListRightPopAsync(key);
     764         }
     765 
     766         /// <summary>
     767         /// 移除列表指定键上与该值相同的元素
     768         /// </summary>
     769         /// <param name="key"></param>
     770         /// <param name="value"></param>
     771         /// <returns></returns>
     772         public async Task<long> ListRemoveAsync(string key, string value)
     773         {
     774             key = AddKeyPrefix(key);
     775             return await _db.ListRemoveAsync(key, value);
     776         }
     777 
     778         /// <summary>
     779         /// 在列表尾部插入值。如果键不存在,先创建再插入值
     780         /// </summary>
     781         /// <param name="key"></param>
     782         /// <param name="value"></param>
     783         /// <returns></returns>
     784         public async Task<long> ListRightPushAsync(string key, string value)
     785         {
     786             key = AddKeyPrefix(key);
     787             return await _db.ListRightPushAsync(key, value);
     788         }
     789 
     790         /// <summary>
     791         /// 在列表头部插入值。如果键不存在,先创建再插入值
     792         /// </summary>
     793         /// <param name="key"></param>
     794         /// <param name="value"></param>
     795         /// <returns></returns>
     796         public async Task<long> ListLeftPushAsync(string key, string value)
     797         {
     798             key = AddKeyPrefix(key);
     799             return await _db.ListLeftPushAsync(key, value);
     800         }
     801 
     802         /// <summary>
     803         /// 返回列表上该键的长度,如果不存在,返回 0
     804         /// </summary>
     805         /// <param name="key"></param>
     806         /// <returns></returns>
     807         public async Task<long> ListLengthAsync(string key)
     808         {
     809             key = AddKeyPrefix(key);
     810             return await _db.ListLengthAsync(key);
     811         }
     812 
     813         /// <summary>
     814         /// 返回在该列表上键所对应的元素
     815         /// </summary>
     816         /// <param name="key"></param>
     817         /// <param name="start"></param>
     818         /// <param name="stop"></param>
     819         /// <returns></returns>
     820         public async Task<IEnumerable<string>> ListRangeAsync(string key, long start = 0L, long stop = -1L)
     821         {
     822             key = AddKeyPrefix(key);
     823             var query = await _db.ListRangeAsync(key, start, stop);
     824             return query.Select(x => x.ToString());
     825         }
     826 
     827         /// <summary>
     828         /// 移除并返回存储在该键列表的第一个元素
     829         /// </summary>
     830         /// <param name="key"></param>
     831         /// <returns></returns>
     832         public async Task<T> ListLeftPopAsync<T>(string key)
     833         {
     834             key = AddKeyPrefix(key);
     835             return Deserialize<T>(await _db.ListLeftPopAsync(key));
     836         }
     837 
     838         /// <summary>
     839         /// 移除并返回存储在该键列表的最后一个元素
     840         /// </summary>
     841         /// <param name="key"></param>
     842         /// <returns></returns>
     843         public async Task<T> ListRightPopAsync<T>(string key)
     844         {
     845             key = AddKeyPrefix(key);
     846             return Deserialize<T>(await _db.ListRightPopAsync(key));
     847         }
     848 
     849         /// <summary>
     850         /// 在列表尾部插入值。如果键不存在,先创建再插入值
     851         /// </summary>
     852         /// <param name="key"></param>
     853         /// <param name="value"></param>
     854         /// <returns></returns>
     855         public async Task<long> ListRightPushAsync<T>(string key, T value)
     856         {
     857             key = AddKeyPrefix(key);
     858             return await _db.ListRightPushAsync(key, Serialize(value));
     859         }
     860 
     861         /// <summary>
     862         /// 在列表头部插入值。如果键不存在,先创建再插入值
     863         /// </summary>
     864         /// <param name="key"></param>
     865         /// <param name="value"></param>
     866         /// <returns></returns>
     867         public async Task<long> ListLeftPushAsync<T>(string key, T value)
     868         {
     869             key = AddKeyPrefix(key);
     870             return await _db.ListLeftPushAsync(key, Serialize(value));
     871         }
     872 
     873         #endregion List-async
     874 
     875         #endregion List 操作
     876 
     877         #region SortedSet 操作
     878 
     879         /// <summary>
     880         /// SortedSet 新增
     881         /// </summary>
     882         /// <param name="key"></param>
     883         /// <param name="member"></param>
     884         /// <param name="score"></param>
     885         /// <returns></returns>
     886         public bool SortedSetAdd(string key, string member, double score)
     887         {
     888             key = AddKeyPrefix(key);
     889             return _db.SortedSetAdd(key, member, score);
     890         }
     891 
     892         /// <summary>
     893         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
     894         /// </summary>
     895         /// <param name="key"></param>
     896         /// <param name="start"></param>
     897         /// <param name="stop"></param>
     898         /// <param name="order"></param>
     899         /// <returns></returns>
     900         public IEnumerable<string> SortedSetRangeByRank(string key, long start = 0L, long stop = -1L,
     901             OrderType order = OrderType.Ascending)
     902         {
     903             key = AddKeyPrefix(key);
     904             return _db.SortedSetRangeByRank(key, start, stop, (Order) order).Select(x => x.ToString());
     905         }
     906 
     907         /// <summary>
     908         /// 返回有序集合的元素个数
     909         /// </summary>
     910         /// <param name="key"></param>
     911         /// <returns></returns>
     912         public long SortedSetLength(string key)
     913         {
     914             key = AddKeyPrefix(key);
     915             return _db.SortedSetLength(key);
     916         }
     917 
     918         /// <summary>
     919         /// 返回有序集合的元素个数
     920         /// </summary>
     921         /// <param name="key"></param>
     922         /// <param name="memebr"></param>
     923         /// <returns></returns>
     924         public bool SortedSetRemove(string key, string memebr)
     925         {
     926             key = AddKeyPrefix(key);
     927             return _db.SortedSetRemove(key, memebr);
     928         }
     929 
     930         /// <summary>
     931         /// SortedSet 新增
     932         /// </summary>
     933         /// <param name="key"></param>
     934         /// <param name="member"></param>
     935         /// <param name="score"></param>
     936         /// <returns></returns>
     937         public bool SortedSetAdd<T>(string key, T member, double score)
     938         {
     939             key = AddKeyPrefix(key);
     940             var json = Serialize(member);
     941 
     942             return _db.SortedSetAdd(key, json, score);
     943         }
     944 
     945         /// <summary>
     946         /// 增量的得分排序的集合中的成员存储键值键按增量
     947         /// </summary>
     948         /// <param name="key"></param>
     949         /// <param name="member"></param>
     950         /// <param name="value"></param>
     951         /// <returns></returns>
     952         public double SortedSetIncrement(string key, string member, double value = 1)
     953         {
     954             key = AddKeyPrefix(key);
     955             return _db.SortedSetIncrement(key, member, value);
     956         }
     957 
     958         #region SortedSet-Async
     959 
     960         /// <summary>
     961         /// SortedSet 新增
     962         /// </summary>
     963         /// <param name="key"></param>
     964         /// <param name="member"></param>
     965         /// <param name="score"></param>
     966         /// <returns></returns>
     967         public async Task<bool> SortedSetAddAsync(string key, string member, double score)
     968         {
     969             key = AddKeyPrefix(key);
     970             return await _db.SortedSetAddAsync(key, member, score);
     971         }
     972 
     973         /// <summary>
     974         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
     975         /// </summary>
     976         /// <param name="key"></param>
     977         /// <returns></returns>
     978         public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string key)
     979         {
     980             key = AddKeyPrefix(key);
     981             return ConvertStrings(await _db.SortedSetRangeByRankAsync(key));
     982         }
     983 
     984         /// <summary>
     985         /// 返回有序集合的元素个数
     986         /// </summary>
     987         /// <param name="key"></param>
     988         /// <returns></returns>
     989         public async Task<long> SortedSetLengthAsync(string key)
     990         {
     991             key = AddKeyPrefix(key);
     992             return await _db.SortedSetLengthAsync(key);
     993         }
     994 
     995         /// <summary>
     996         /// 返回有序集合的元素个数
     997         /// </summary>
     998         /// <param name="key"></param>
     999         /// <param name="memebr"></param>
    1000         /// <returns></returns>
    1001         public async Task<bool> SortedSetRemoveAsync(string key, string memebr)
    1002         {
    1003             key = AddKeyPrefix(key);
    1004             return await _db.SortedSetRemoveAsync(key, memebr);
    1005         }
    1006 
    1007         /// <summary>
    1008         /// SortedSet 新增
    1009         /// </summary>
    1010         /// <param name="key"></param>
    1011         /// <param name="member"></param>
    1012         /// <param name="score"></param>
    1013         /// <returns></returns>
    1014         public async Task<bool> SortedSetAddAsync<T>(string key, T member, double score)
    1015         {
    1016             key = AddKeyPrefix(key);
    1017             var json = Serialize(member);
    1018 
    1019             return await _db.SortedSetAddAsync(key, json, score);
    1020         }
    1021 
    1022         /// <summary>
    1023         /// 增量的得分排序的集合中的成员存储键值键按增量
    1024         /// </summary>
    1025         /// <param name="key"></param>
    1026         /// <param name="member"></param>
    1027         /// <param name="value"></param>
    1028         /// <returns></returns>
    1029         public Task<double> SortedSetIncrementAsync(string key, string member, double value = 1)
    1030         {
    1031             key = AddKeyPrefix(key);
    1032             return _db.SortedSetIncrementAsync(key, member, value);
    1033         }
    1034 
    1035         #endregion SortedSet-Async
    1036 
    1037         #endregion SortedSet 操作
    1038 
    1039         #region key 操作
    1040 
    1041         /// <summary>
    1042         /// 移除指定 Key
    1043         /// </summary>
    1044         /// <param name="key"></param>
    1045         /// <returns></returns>
    1046         public bool KeyDelete(string key)
    1047         {
    1048             key = AddKeyPrefix(key);
    1049             return _db.KeyDelete(key);
    1050         }
    1051 
    1052         /// <summary>
    1053         /// 移除指定 Key
    1054         /// </summary>
    1055         /// <param name="keys"></param>
    1056         /// <returns></returns>
    1057         public long KeyDelete(IEnumerable<string> keys)
    1058         {
    1059             var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
    1060             return _db.KeyDelete(redisKeys.ToArray());
    1061         }
    1062 
    1063         /// <summary>
    1064         /// 校验 Key 是否存在
    1065         /// </summary>
    1066         /// <param name="key"></param>
    1067         /// <returns></returns>
    1068         public bool KeyExists(string key)
    1069         {
    1070             key = AddKeyPrefix(key);
    1071             return _db.KeyExists(key);
    1072         }
    1073 
    1074         /// <summary>
    1075         /// 重命名 Key
    1076         /// </summary>
    1077         /// <param name="key"></param>
    1078         /// <param name="newKey"></param>
    1079         /// <returns></returns>
    1080         public bool KeyRename(string key, string newKey)
    1081         {
    1082             key = AddKeyPrefix(key);
    1083             return _db.KeyRename(key, newKey);
    1084         }
    1085 
    1086         /// <summary>
    1087         /// 设置 Key 的时间
    1088         /// </summary>
    1089         /// <param name="key"></param>
    1090         /// <param name="expiry"></param>
    1091         /// <returns></returns>
    1092         public bool KeyExpire(string key, TimeSpan? expiry)
    1093         {
    1094             key = AddKeyPrefix(key);
    1095             return _db.KeyExpire(key, expiry);
    1096         }
    1097 
    1098         #region key-async
    1099 
    1100         /// <summary>
    1101         /// 移除指定 Key
    1102         /// </summary>
    1103         /// <param name="key"></param>
    1104         /// <returns></returns>
    1105         public async Task<bool> KeyDeleteAsync(string key)
    1106         {
    1107             key = AddKeyPrefix(key);
    1108             return await _db.KeyDeleteAsync(key);
    1109         }
    1110 
    1111         /// <summary>
    1112         /// 移除指定 Key
    1113         /// </summary>
    1114         /// <param name="keys"></param>
    1115         /// <returns></returns>
    1116         public async Task<long> KeyDeleteAsync(IEnumerable<string> keys)
    1117         {
    1118             var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
    1119             return await _db.KeyDeleteAsync(redisKeys.ToArray());
    1120         }
    1121 
    1122         /// <summary>
    1123         /// 校验 Key 是否存在
    1124         /// </summary>
    1125         /// <param name="key"></param>
    1126         /// <returns></returns>
    1127         public async Task<bool> KeyExistsAsync(string key)
    1128         {
    1129             key = AddKeyPrefix(key);
    1130             return await _db.KeyExistsAsync(key);
    1131         }
    1132 
    1133         /// <summary>
    1134         /// 重命名 Key
    1135         /// </summary>
    1136         /// <param name="key"></param>
    1137         /// <param name="newKey"></param>
    1138         /// <returns></returns>
    1139         public async Task<bool> KeyRenameAsync(string key, string newKey)
    1140         {
    1141             key = AddKeyPrefix(key);
    1142             return await _db.KeyRenameAsync(key, newKey);
    1143         }
    1144 
    1145         /// <summary>
    1146         /// 设置 Key 的时间
    1147         /// </summary>
    1148         /// <param name="key"></param>
    1149         /// <param name="expiry"></param>
    1150         /// <returns></returns>
    1151         public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry)
    1152         {
    1153             key = AddKeyPrefix(key);
    1154             return await _db.KeyExpireAsync(key, expiry);
    1155         }
    1156 
    1157         #endregion key-async
    1158 
    1159         #endregion key 操作
    1160 
    1161         #region 发布订阅
    1162 
    1163         /// <summary>
    1164         /// 订阅
    1165         /// </summary>
    1166         /// <param name="channel"></param>
    1167         /// <param name="handle"></param>
    1168         public void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
    1169         {
    1170             var sub = _connMultiplexer.GetSubscriber();
    1171             sub.Subscribe(channel, handle);
    1172         }
    1173 
    1174         /// <summary>
    1175         /// 发布
    1176         /// </summary>
    1177         /// <param name="channel"></param>
    1178         /// <param name="message"></param>
    1179         /// <returns></returns>
    1180         public long Publish(RedisChannel channel, RedisValue message)
    1181         {
    1182             var sub = _connMultiplexer.GetSubscriber();
    1183             return sub.Publish(channel, message);
    1184         }
    1185 
    1186         /// <summary>
    1187         /// 发布(使用序列化)
    1188         /// </summary>
    1189         /// <typeparam name="T"></typeparam>
    1190         /// <param name="channel"></param>
    1191         /// <param name="message"></param>
    1192         /// <returns></returns>
    1193         public long Publish<T>(RedisChannel channel, T message)
    1194         {
    1195             var sub = _connMultiplexer.GetSubscriber();
    1196             return sub.Publish(channel, Serialize(message));
    1197         }
    1198 
    1199         #region 发布订阅-async
    1200 
    1201         /// <summary>
    1202         /// 订阅
    1203         /// </summary>
    1204         /// <param name="channel"></param>
    1205         /// <param name="handle"></param>
    1206         public async Task SubscribeAsync(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
    1207         {
    1208             var sub = _connMultiplexer.GetSubscriber();
    1209             await sub.SubscribeAsync(channel, handle);
    1210         }
    1211 
    1212         /// <summary>
    1213         /// 发布
    1214         /// </summary>
    1215         /// <param name="channel"></param>
    1216         /// <param name="message"></param>
    1217         /// <returns></returns>
    1218         public async Task<long> PublishAsync(RedisChannel channel, RedisValue message)
    1219         {
    1220             var sub = _connMultiplexer.GetSubscriber();
    1221             return await sub.PublishAsync(channel, message);
    1222         }
    1223 
    1224         /// <summary>
    1225         /// 发布(使用序列化)
    1226         /// </summary>
    1227         /// <typeparam name="T"></typeparam>
    1228         /// <param name="channel"></param>
    1229         /// <param name="message"></param>
    1230         /// <returns></returns>
    1231         public async Task<long> PublishAsync<T>(RedisChannel channel, T message)
    1232         {
    1233             var sub = _connMultiplexer.GetSubscriber();
    1234             return await sub.PublishAsync(channel, Serialize(message));
    1235         }
    1236 
    1237         #endregion 发布订阅-async
    1238 
    1239         #endregion 发布订阅
    1240 
    1241         #region private method
    1242 
    1243         /// <summary>
    1244         /// 添加 Key 的前缀
    1245         /// </summary>
    1246         /// <param name="key"></param>
    1247         /// <returns></returns>
    1248         private static string AddKeyPrefix(string key)
    1249         {
    1250             return $"{DefaultKey}:{key}";
    1251         }
    1252 
    1253         /// <summary>
    1254         /// 转换为字符串
    1255         /// </summary>
    1256         /// <typeparam name="T"></typeparam>
    1257         /// <param name="list"></param>
    1258         /// <returns></returns>
    1259         private static IEnumerable<string> ConvertStrings<T>(IEnumerable<T> list) where T : struct
    1260         {
    1261             if (list == null) throw new ArgumentNullException(nameof(list));
    1262             return list.Select(x => x.ToString());
    1263         }
    1264 
    1265         #region 注册事件
    1266 
    1267         /// <summary>
    1268         /// 添加注册事件
    1269         /// </summary>
    1270         private static void AddRegisterEvent()
    1271         {
    1272             _connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
    1273             _connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
    1274             _connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
    1275             _connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
    1276             _connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
    1277             _connMultiplexer.InternalError += ConnMultiplexer_InternalError;
    1278             _connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
    1279         }
    1280 
    1281         /// <summary>
    1282         /// 重新配置广播时(通常意味着主从同步更改)
    1283         /// </summary>
    1284         /// <param name="sender"></param>
    1285         /// <param name="e"></param>
    1286         private static void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
    1287         {
    1288             Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
    1289         }
    1290 
    1291         /// <summary>
    1292         /// 发生内部错误时(主要用于调试)
    1293         /// </summary>
    1294         /// <param name="sender"></param>
    1295         /// <param name="e"></param>
    1296         private static void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
    1297         {
    1298             Console.WriteLine($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
    1299         }
    1300 
    1301         /// <summary>
    1302         /// 更改集群时
    1303         /// </summary>
    1304         /// <param name="sender"></param>
    1305         /// <param name="e"></param>
    1306         private static void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
    1307         {
    1308             Console.WriteLine(
    1309                 $"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");
    1310         }
    1311 
    1312         /// <summary>
    1313         /// 配置更改时
    1314         /// </summary>
    1315         /// <param name="sender"></param>
    1316         /// <param name="e"></param>
    1317         private static void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
    1318         {
    1319             Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
    1320         }
    1321 
    1322         /// <summary>
    1323         /// 发生错误时
    1324         /// </summary>
    1325         /// <param name="sender"></param>
    1326         /// <param name="e"></param>
    1327         private static void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
    1328         {
    1329             Console.WriteLine($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
    1330         }
    1331 
    1332         /// <summary>
    1333         /// 物理连接失败时
    1334         /// </summary>
    1335         /// <param name="sender"></param>
    1336         /// <param name="e"></param>
    1337         private static void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
    1338         {
    1339             Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
    1340         }
    1341 
    1342         /// <summary>
    1343         /// 建立物理连接时
    1344         /// </summary>
    1345         /// <param name="sender"></param>
    1346         /// <param name="e"></param>
    1347         private static void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
    1348         {
    1349             Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
    1350         }
    1351 
    1352         #endregion 注册事件
    1353 
    1354         /// <summary>
    1355         /// 序列化
    1356         /// </summary>
    1357         /// <param name="obj"></param>
    1358         /// <returns></returns>
    1359         private static byte[] Serialize(object obj)
    1360         {
    1361             if (obj == null)
    1362                 return null;
    1363 
    1364             var binaryFormatter = new BinaryFormatter();
    1365             using (var memoryStream = new MemoryStream())
    1366             {
    1367                 binaryFormatter.Serialize(memoryStream, obj);
    1368                 var data = memoryStream.ToArray();
    1369                 return data;
    1370             }
    1371         }
    1372 
    1373         /// <summary>
    1374         /// 反序列化
    1375         /// </summary>
    1376         /// <typeparam name="T"></typeparam>
    1377         /// <param name="data"></param>
    1378         /// <returns></returns>
    1379         private static T Deserialize<T>(byte[] data)
    1380         {
    1381             if (data == null)
    1382                 return default(T);
    1383 
    1384             var binaryFormatter = new BinaryFormatter();
    1385             using (var memoryStream = new MemoryStream(data))
    1386             {
    1387                 var result = (T) binaryFormatter.Deserialize(memoryStream);
    1388                 return result;
    1389             }
    1390         }
    1391 
    1392         #endregion private method
    1393     }
    1394 }
    RedisHelper.cs

      下期将分析 redis 的五大类型,及介绍他们常用的指令。   

    系列

      《Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍

      《Redis 小白指南(二)- 聊聊五大类型:字符串、散列、列表、集合和有序集合

      《Redis 小白指南(三)- 事务、过期、消息通知、管道、优化内存空间》

      《Redis 小白指南(四)- 数据的持久化保存


    【博主】反骨仔

    【原文】http://www.cnblogs.com/liqingwen/p/6917426.html 

    【GitHub】https://github.com/liqingwen2015/Wen.Helpers/blob/master/Wen.Helpers.Common/Redis/RedisHelper.cs

    【参考】《redis 入门指南》

  • 相关阅读:
    数据库MySQL常用命令复习
    09、C语言——构造类型
    06、C语言——数组
    08、C语言——指针
    11、排序【理论篇】
    01、C语言——基础知识
    16、自学——Linux的学习进度与任务【vim编辑器及文件测试】
    15、自学——Linux的学习进度与任务【bash编程之条件判断】
    05、自学——计算机网络学习任务与进度(数据链路层)
    14、自学——Linux的学习进度与任务【正则表达式】
  • 原文地址:https://www.cnblogs.com/liqingwen/p/6917426.html
Copyright © 2011-2022 走看看