欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Redis分布式队列和缓存更新

程序员文章站 2022-07-23 09:11:16
原文链接:https://www.cnblogs.com/hua66/p/9600085.html 在使用Redis中,我们可能会遇到以下场景: 例如: 某用户向服务器中发送一个请求,服务器将用户请求加入Redis任务队列,任务完成则移出队列。 以上场景有几点疑问: 解决方案: 以上解决方案都可以使 ......

  原文链接:

  在使用redis中,我们可能会遇到以下场景:

  例如:

  某用户向服务器中发送一个请求,服务器将用户请求加入redis任务队列,任务完成则移出队列。

  以上场景有几点疑问:

  1. redis队列中数据如果不仅仅来自于我们的应用程序,那么我们怎么把这个数据加入redis?
  2. 当redis队列中用户的请求达程序所能处理的峰值。那么我们该如何处理这些用户请求?

  解决方案:

  1.  对外提供接口,将请求数据添加至db。启动一个定时服务,在规定时间扫描db中的请求数据并添加至redis队列。
  2. 使用分布式异步队列。

  以上解决方案都可以使用插件来实现。

  1. 使用quartz.net
  2. 使用stackexchange.redis

  一、

  关于quartz.net可以通过上面链接获取官方api。它与sql server中的代理作业有着同样功能。

  代码示例:

  

Redis分布式队列和缓存更新
 1  /// <summary>
 2         /// 添加job并以周期的形式运行
 3         /// </summary>
 4         /// <typeparam name="t"></typeparam>
 5         /// <param name="jobname">job名称</param>
 6         /// <param name="jobgroupname">job组名称</param>
 7         /// <param name="replace">job是否可修改</param>
 8         /// <param name="triggername">job触发器的名称</param>
 9         /// <param name="minutes">job执行的时间间隔,以分为单位</param>
10         /// <returns></returns>
11         public datetimeoffset addjob<t>(string jobname, string jobgroupname, bool replace, string triggername, int minutes) where t : ijob
12         {
13             ijobdetail jobdetail = jobbuilder.create<t>().withidentity(jobname, jobgroupname).build();
14             _sched.addjob(jobdetail, replace);
15             itrigger trigger = triggerbuilder.create()
16               .withidentity(triggername, jobgroupname)
17               .startnow()
18               .withsimpleschedule(x => x
19                   .withintervalinminutes(minutes)//表示分钟的时间间隔
20                   .repeatforever())
21               .build();
22             return _sched.schedulejob(jobdetail, trigger).result;
23         }
view code

  以上的代码中是基于quartz封装一个添加了job的方法。这个方法依赖于 “ijobdetail” 和 “itrigger” 这两个对象。

  “ijobdetail” 表示job的身份信息,“itrigger” 则包含了job执行信息,它表示job该如何执行。

  以下为调用示例:

  

Redis分布式队列和缓存更新
1 quartzhelper quartzhelper = quartzhelper.createinstance();
2                 quartzhelper.addjob<testjob>("testjob", "testjob_group",false, "testjob_trigger",1*10);
view code

  上述实例中的 “testjob” 实现quartz.net中的 "ijob" 接口。这个接口只有一个方法 “execute”,并由quartz.net框架自行调用该方法。

  你可以在此方法中执行你的代码。并在添加该job制定你的执行策略 “itrigger” 对象。然后框架会根据你制定的策略进行调用。调用参数请参见上述封装。

 

  下面是向redis队列插入数据的示例job:

  

Redis分布式队列和缓存更新
 1 public class testjob : ijob
 2     {
 3         task ijob.execute(ijobexecutioncontext context)
 4         {
 5             //jobdatamap datamap = context.jobdetail.jobdatamap;
 6             task task = task.run(
 7                   () =>
 8                   {
 9                       console.writeline(string.format("{0}开始执行!当前系统时间{1}", this.gettype().name, datetime.now));
10                       try
11                       {
12                           string rediskey = this.gettype().name;
13                           redishelper redishelper = new redishelper();
14                           if (redishelper.keyexists(rediskey))
15                           {
16                               redishelper.keydelete(rediskey);
17                           };
18 
19                           for (int i = 1; i <= 10; i++)
20                           {
21                               user user = new user()
22                               {
23                                   id = i,
24                                   name = "user" + datetime.now.ticks +"_"+ i                                  
25                               };
26                               redishelper.listleftpush<user>(rediskey, user);//模拟db用户数据
27                           }
28                       }
29                       catch (exception ex)
30                       {
31                           console.writeline(string.format("{0}任务出现异常,异常信息:{1}!当前系统时间{2}", this.gettype().name, ex.message, datetime.now));
32                       }
33                   }
34                   );
35             return task;
36         }
37     }
view code

 

  上面的 “testjob” 模拟了从db加载用户请求数据至redis队列。至此我们已经解决了上面的第一个问题。

 

  二、

  在.net中redis的插件不多。比较流行有 "servicestack.redis" 和 "stackexchange.redis" 。

  "servicestack.redis" 为官方推出的插件。非开源插件,且普通版最高只支持 6000/s 读写。高级版是要收费的。为了后续扩展,这里我们采用 "stackexchange.redis" 。

  关于stackexchange.redis可以通过上面链接获取官方api,目前是开源的。

  在第一个问题中,已经通过定时job的方式向redis队列中填充数据。下面我们通过 "stackexchange.redis" 获取redis队列中的请求并处理这些请求。

 

  1.加载数据至redis:

  

Redis分布式队列和缓存更新
 1 using app_test.job;
 2 using common.quartz;
 3 using common.redis.stackexchange;
 4 using quartz;
 5 using system;
 6 using system.collections.generic;
 7 using system.linq;
 8 using system.text;
 9 using system.threading.tasks;
10 
11 namespace app_test
12 {
13     class program
14     {
15         static void main(string[] args)
16         {
17             {
18                 redishelper redishelpera = new redishelper();
19                 redishelper redishelperb = new redishelper();
20                 string stra = redishelpera.stringget("mykey");
21                 string strb = redishelperb.stringget("mykey");
22                 if (stra== strb)
23                 {
24                     console.writeline(string.format("***********{0}=={1}***********", stra, strb));
25                 }
26                 else
27                 {
28                     console.writeline(string.format("***********{0}!={1}***********", stra, strb));
29                 }
30             }
31 
32             {
33                 
34                 quartzhelper quartzhelper = quartzhelper.createinstance();
35                 quartzhelper.addjob<testjob>("testjob", "testjob_group",false, "testjob_trigger",1*10);//这里设置了以秒为单位
36             }
37 
38             console.readkey();
39         }
40         
41     }
42 }
view code

 

  Redis分布式队列和缓存更新

 

  可以看到上面代码执行的时间节点与我们所添加job中的 ”itrigger “ 的触发策略完全一致。至此,我们第一步已得到验证。

 

  2.启动处理redis队列中请求的程序。

  

Redis分布式队列和缓存更新
 1 using app_test.models;
 2 using common.redis.stackexchange;
 3 using system;
 4 using system.collections.generic;
 5 using system.linq;
 6 using system.text;
 7 using system.threading.tasks;
 8 
 9 namespace app_redisclienttest
10 {
11     class program
12     {
13         static void main(string[] args)
14         {
15             redishelper redishelper = new redishelper();
16             string rediskey = "testjob";
17             while (true)
18             {
19                 action action = new action(() =>
20                 {
21                     user user = redishelper.listleftpop<user>(rediskey);//获取请求数据并移出队列
22                     if (user!=null)
23                     {
24                         console.writeline(string.format("*******{0}*******", user.name));
25                     }                    
26                 }
27                     );
28                 action.endinvoke(action.begininvoke(null, null));
29             }
30             console.readkey();
31         }
32     }
33 }
view code

 

  Redis分布式队列和缓存更新

  上面我启动3个客户端实例,他们一起处理redis队列中的请求。每当job向redis队列中添加请求对象后就会立即被我们处理请求的程序获取并消费,每当一个请求被消费就会被移出redis队列。并且遵循先入先出的准则。按照上述,如果出现主程序请求量过高情形,我们只需要启动多个处理请求的辅助程序即可缓解主程序的压力。

  至此上面的两个问题已得到验证。

 

  如下附个人基于 "quartz.net" 和 "stackexchange.redis" 封装的帮助类

  

Redis分布式队列和缓存更新
  1 using system;
  2 using system.collections.generic;
  3 
  4 namespace common.quartz
  5 {
  6     using global::quartz;
  7     using global::quartz.impl;
  8     using global::quartz.impl.matchers;
  9 
 10     /// <summary>
 11     /// v:3.0.6.0
 12     /// </summary>
 13     public class quartzhelper
 14     {
 15         private readonly static object _obj = new object();//单例锁
 16 
 17         //private  ischedulerfactory _sf = null;
 18 
 19         private static ischeduler _sched = null;
 20         /// <summary>
 21         /// 提供ischeduler对象,访问异步方法
 22         /// </summary>
 23         public ischeduler scheduler { get { return _sched; } }
 24 
 25         private static quartzhelper _quartzhelper = null;//单例对象
 26 
 27         private quartzhelper()
 28         {
 29             //_sf = new stdschedulerfactory();
 30             //_sched = _sf.getscheduler().result;
 31             _sched = stdschedulerfactory.getdefaultscheduler().result;
 32             _sched.start();
 33         }
 34 
 35         /// <summary>
 36         /// 获取单例对象
 37         /// </summary>
 38         /// <returns></returns>
 39         public static quartzhelper createinstance()
 40         {
 41             if (_quartzhelper == null) //双if +lock
 42             {
 43                 lock (_obj)
 44                 {
 45                     if (_quartzhelper == null)
 46                     {
 47                         _quartzhelper = new quartzhelper();
 48                     }
 49                 }
 50             }
 51             return _quartzhelper;
 52         }
 53         public bool checkexists(triggerkey triggerkey)
 54         {
 55             return _sched.checkexists(triggerkey).result;
 56         }
 57         public bool checkexists(jobkey jobkey)
 58         {
 59             return _sched.checkexists(jobkey).result;
 60         }
 61         public ireadonlycollection<ijobexecutioncontext> getcurrentlyexecutingjobs()
 62         {
 63             return _sched.getcurrentlyexecutingjobs().result;
 64         }
 65 
 66         /// <summary>
 67         /// 添加job并以周期的形式运行
 68         /// </summary>
 69         /// <typeparam name="t"></typeparam>
 70         /// <param name="jobname">job名称</param>
 71         /// <param name="jobgroupname">job组名称</param>
 72         /// <param name="replace">job是否可修改</param>
 73         /// <param name="triggername">job触发器的名称</param>
 74         /// <param name="minutes">job执行的时间间隔,以分为单位</param>
 75         /// <returns></returns>
 76         public datetimeoffset addjob<t>(string jobname, string jobgroupname, bool replace, string triggername, int minutes) where t : ijob
 77         {
 78             ijobdetail jobdetail = jobbuilder.create<t>().withidentity(jobname, jobgroupname).build();
 79             _sched.addjob(jobdetail, replace);
 80             itrigger trigger = triggerbuilder.create()
 81               .withidentity(triggername, jobgroupname)
 82               .startnow()
 83               .withsimpleschedule(x => x
 84                   .withintervalinseconds(minutes)//seconds表示秒的时间间隔
 85                                                  //.withintervalinminutes(minutes)//表示分钟的时间间隔
 86                   .repeatforever())
 87               .build();
 88             return _sched.schedulejob(jobdetail, trigger).result;
 89         }
 90         public bool deletejobs(ireadonlycollection<jobkey> jobkeys)
 91         {
 92             return _sched.deletejobs(jobkeys).result;
 93         }
 94         public ijobdetail getjobdetail(jobkey jobkey)
 95         {
 96             return _sched.getjobdetail(jobkey).result;
 97         }
 98         public ireadonlycollection<string> getjobgroupnames()
 99         {
100             return _sched.getjobgroupnames().result;
101         }
102         public ireadonlycollection<jobkey> getjobkeys(groupmatcher<jobkey> matcher)
103         {
104             return _sched.getjobkeys(matcher).result;
105         }
106         public bool interrupt(jobkey jobkey)
107         {
108             return _sched.interrupt(jobkey).result;
109         }
110         public bool isjobgrouppaused(string groupname)
111         {
112             return _sched.isjobgrouppaused(groupname).result;
113         }
114         public itrigger gettrigger(triggerkey triggerkey)
115         {
116             return _sched.gettrigger(triggerkey).result;
117         }
118         public ireadonlycollection<string> gettriggergroupnames()
119         {
120             return _sched.gettriggergroupnames().result;
121         }
122         public ireadonlycollection<triggerkey> gettriggerkeys(groupmatcher<triggerkey> matcher)
123         {
124             return _sched.gettriggerkeys(matcher).result;
125         }
126         public ireadonlycollection<itrigger> gettriggersofjob(jobkey jobkey)
127         {
128             return _sched.gettriggersofjob(jobkey).result;
129         }
130         public triggerstate gettriggerstate(triggerkey triggerkey)
131         {
132             return _sched.gettriggerstate(triggerkey).result;
133         }
134         public ireadonlycollection<string> getpausedtriggergroups()
135         {
136             return _sched.getpausedtriggergroups().result;
137         }
138         public bool interrupt(string fireinstanceid)
139         {
140             return _sched.interrupt(fireinstanceid).result;
141         }
142         public bool istriggergrouppaused(string groupname)
143         {
144             return _sched.istriggergrouppaused(groupname).result;
145         }
146         public void pauseall()
147         {
148             _sched.pauseall();
149         }
150         public void pausejobs(groupmatcher<jobkey> matcher)
151         {
152             _sched.pausejobs(matcher);
153         }
154         public void pausetriggers(groupmatcher<triggerkey> matcher)
155         {
156             _sched.pausetriggers(matcher);
157         }
158         public void resumeall()
159         {
160             _sched.resumeall();
161         }
162         public void resumejobs(groupmatcher<jobkey> matcher)
163         {
164             _sched.resumejobs(matcher);
165         }
166         public void resumetriggers(groupmatcher<triggerkey> matcher)
167         {
168             _sched.resumetriggers(matcher);
169         }
170         public void schedulejobs(ireadonlydictionary<ijobdetail, ireadonlycollection<itrigger>> triggersandjobs, bool replace)
171         {
172             _sched.schedulejobs(triggersandjobs, replace);
173         }
174         public datetimeoffset? reschedulejob(triggerkey triggerkey, itrigger newtrigger)
175         {
176             return _sched.reschedulejob(triggerkey, newtrigger).result;
177         }
178         public void shutdown(bool waitforjobstocomplete)
179         {
180             _sched.shutdown(waitforjobstocomplete);
181         }
182         public void clear()
183         {
184             _sched.clear();
185         }
186 
187 
188     }
189 }
view code
Redis分布式队列和缓存更新
   1 using stackexchange.redis;
   2 using system;
   3 using system.collections.generic;
   4 using system.configuration;
   5 using system.io;
   6 using system.linq;
   7 using system.runtime.serialization.formatters.binary;
   8 using system.threading.tasks;
   9 using newtonsoft.json;
  10 
  11 namespace common.redis.stackexchange
  12 {
  13     /// <summary>
  14     /// v:1.2.6.0
  15     /// </summary>
  16     public class redishelper
  17     {
  18         #region private field
  19 
  20         /// <summary>
  21         /// 连接字符串
  22         /// </summary>
  23         private static readonly string connectionstring;
  24 
  25         /// <summary>
  26         /// redis 连接对象
  27         /// </summary>
  28         private static iconnectionmultiplexer _connmultiplexer;
  29 
  30         /// <summary>
  31         /// 默认的 key 值(用来当作 rediskey 的前缀)
  32         /// </summary>
  33         private static readonly string defaultkey;
  34 
  35         /// <summary>
  36         /// 锁
  37         /// </summary>
  38         private static readonly object locker = new object();
  39 
  40         /// <summary>
  41         /// 数据库
  42         /// </summary>
  43         private readonly idatabase _db;
  44 
  45         #endregion private field
  46 
  47         #region 构造函数
  48 
  49         static redishelper()
  50         {
  51             connectionstring = configurationmanager.connectionstrings["redisconnectionstring"].connectionstring;
  52             _connmultiplexer = connectionmultiplexer.connect(connectionstring);
  53             defaultkey = configurationmanager.appsettings["redis.defaultkey"];
  54             addregisterevent();
  55         }
  56 
  57         public redishelper(int db = 0)
  58         {
  59             _db = _connmultiplexer.getdatabase(db);
  60         }
  61 
  62         #endregion 构造函数
  63 
  64         #region 其它
  65 
  66         /// <summary>
  67         /// 获取 redis 连接对象
  68         /// </summary>
  69         /// <returns></returns>
  70         public iconnectionmultiplexer getconnectionredismultiplexer()
  71         {
  72             if (_connmultiplexer == null || !_connmultiplexer.isconnected)
  73                 lock (locker)
  74                 {
  75                     if (_connmultiplexer == null || !_connmultiplexer.isconnected)
  76                         _connmultiplexer = connectionmultiplexer.connect(connectionstring);
  77                 }
  78 
  79             return _connmultiplexer;
  80         }
  81 
  82         public itransaction gettransaction()
  83         {
  84             return _db.createtransaction();
  85         }
  86 
  87         #endregion 其它
  88 
  89         #region 类型封装
  90 
  91         #region string 操作
  92 
  93         /// <summary>
  94         /// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)
  95         /// </summary>
  96         /// <param name="rediskey"></param>
  97         /// <param name="redisvalue"></param>
  98         /// <param name="expiry"></param>
  99         /// <returns></returns>
 100         public bool stringset(string rediskey, string redisvalue, timespan? expiry = null)
 101         {
 102             rediskey = addkeyprefix(rediskey);
 103             return _db.stringset(rediskey, redisvalue, expiry);
 104         }
 105 
 106         /// <summary>
 107         /// 保存多个 key-value
 108         /// </summary>
 109         /// <param name="keyvaluepairs"></param>
 110         /// <returns></returns>
 111         public bool stringset(ienumerable<keyvaluepair<string, string>> keyvaluepairs)
 112         {
 113             var pairs = keyvaluepairs.select(x => new keyvaluepair<rediskey, redisvalue>(addkeyprefix(x.key), x.value));
 114             return _db.stringset(pairs.toarray());
 115         }
 116 
 117         /// <summary>
 118         /// 获取字符串
 119         /// </summary>
 120         /// <param name="rediskey"></param>
 121         /// <param name="expiry"></param>
 122         /// <returns></returns>
 123         public string stringget(string rediskey, timespan? expiry = null)
 124         {
 125             rediskey = addkeyprefix(rediskey);
 126             return _db.stringget(rediskey);
 127         }
 128 
 129         /// <summary>
 130         /// 存储一个对象(该对象会被序列化保存)
 131         /// </summary>
 132         /// <param name="rediskey"></param>
 133         /// <param name="redisvalue"></param>
 134         /// <param name="expiry"></param>
 135         /// <returns></returns>
 136         public bool stringset<t>(string rediskey, t redisvalue, timespan? expiry = null)
 137         {
 138             rediskey = addkeyprefix(rediskey);
 139             var json = serialize(redisvalue);
 140             return _db.stringset(rediskey, json, expiry);
 141         }
 142 
 143         /// <summary>
 144         /// 获取一个对象(会进行反序列化)
 145         /// </summary>
 146         /// <param name="rediskey"></param>
 147         /// <param name="expiry"></param>
 148         /// <returns></returns>
 149         public t stringget<t>(string rediskey, timespan? expiry = null)
 150         {
 151             rediskey = addkeyprefix(rediskey);
 152             return deserialize<t>(_db.stringget(rediskey));
 153         }
 154 
 155         #region async
 156 
 157         /// <summary>
 158         /// 保存一个字符串值
 159         /// </summary>
 160         /// <param name="rediskey"></param>
 161         /// <param name="redisvalue"></param>
 162         /// <param name="expiry"></param>
 163         /// <returns></returns>
 164         public async task<bool> stringsetasync(string rediskey, string redisvalue, timespan? expiry = null)
 165         {
 166             rediskey = addkeyprefix(rediskey);
 167             return await _db.stringsetasync(rediskey, redisvalue, expiry);
 168         }
 169 
 170         /// <summary>
 171         /// 保存一组字符串值
 172         /// </summary>
 173         /// <param name="keyvaluepairs"></param>
 174         /// <returns></returns>
 175         public async task<bool> stringsetasync(ienumerable<keyvaluepair<string, string>> keyvaluepairs)
 176         {
 177             var pairs = keyvaluepairs.select(x => new keyvaluepair<rediskey, redisvalue>(addkeyprefix(x.key), x.value));
 178             return await _db.stringsetasync(pairs.toarray());
 179         }
 180 
 181         /// <summary>
 182         /// 获取单个值
 183         /// </summary>
 184         /// <param name="rediskey"></param>
 185         /// <param name="redisvalue"></param>
 186         /// <param name="expiry"></param>
 187         /// <returns></returns>
 188         public async task<string> stringgetasync(string rediskey, string redisvalue, timespan? expiry = null)
 189         {
 190             rediskey = addkeyprefix(rediskey);
 191             return await _db.stringgetasync(rediskey);
 192         }
 193 
 194         /// <summary>
 195         /// 存储一个对象(该对象会被序列化保存)
 196         /// </summary>
 197         /// <param name="rediskey"></param>
 198         /// <param name="redisvalue"></param>
 199         /// <param name="expiry"></param>
 200         /// <returns></returns>
 201         public async task<bool> stringsetasync<t>(string rediskey, t redisvalue, timespan? expiry = null)
 202         {
 203             rediskey = addkeyprefix(rediskey);
 204             var json = serialize(redisvalue);
 205             return await _db.stringsetasync(rediskey, json, expiry);
 206         }
 207 
 208         /// <summary>
 209         /// 获取一个对象(会进行反序列化)
 210         /// </summary>
 211         /// <param name="rediskey"></param>
 212         /// <param name="expiry"></param>
 213         /// <returns></returns>
 214         public async task<t> stringgetasync<t>(string rediskey, timespan? expiry = null)
 215         {
 216             rediskey = addkeyprefix(rediskey);
 217             return deserialize<t>(await _db.stringgetasync(rediskey));
 218         }
 219 
 220         #endregion async
 221 
 222         #endregion string 操作
 223 
 224         #region hash 操作
 225 
 226         /// <summary>
 227         /// 判断该字段是否存在 hash 中
 228         /// </summary>
 229         /// <param name="rediskey"></param>
 230         /// <param name="hashfield"></param>
 231         /// <returns></returns>
 232         public bool hashexists(string rediskey, string hashfield)
 233         {
 234             rediskey = addkeyprefix(rediskey);
 235             return _db.hashexists(rediskey, hashfield);
 236         }
 237 
 238         /// <summary>
 239         /// 从 hash 中移除指定字段
 240         /// </summary>
 241         /// <param name="rediskey"></param>
 242         /// <param name="hashfield"></param>
 243         /// <returns></returns>
 244         public bool hashdelete(string rediskey, string hashfield)
 245         {
 246             rediskey = addkeyprefix(rediskey);
 247             return _db.hashdelete(rediskey, hashfield);
 248         }
 249 
 250         /// <summary>
 251         /// 从 hash 中移除指定字段
 252         /// </summary>
 253         /// <param name="rediskey"></param>
 254         /// <param name="hashfields"></param>
 255         /// <returns></returns>
 256         public long hashdelete(string rediskey, ienumerable<string> hashfields)
 257         {
 258             rediskey = addkeyprefix(rediskey);
 259             var fields = hashfields.select(x => (redisvalue)x);
 260 
 261             return _db.hashdelete(rediskey, fields.toarray());
 262         }
 263 
 264         /// <summary>
 265         /// 在 hash 设定值
 266         /// </summary>
 267         /// <param name="rediskey"></param>
 268         /// <param name="hashfield"></param>
 269         /// <param name="value"></param>
 270         /// <returns></returns>
 271         public bool hashset(string rediskey, string hashfield, string value)
 272         {
 273             rediskey = addkeyprefix(rediskey);
 274             return _db.hashset(rediskey, hashfield, value);
 275         }
 276 
 277         /// <summary>
 278         /// 在 hash 中设定值
 279         /// </summary>
 280         /// <param name="rediskey"></param>
 281         /// <param name="hashfields"></param>
 282         public void hashset(string rediskey, ienumerable<keyvaluepair<string, string>> hashfields)
 283         {
 284             rediskey = addkeyprefix(rediskey);
 285             var entries = hashfields.select(x => new hashentry(x.key, x.value));
 286 
 287             _db.hashset(rediskey, entries.toarray());
 288         }
 289 
 290         /// <summary>
 291         /// 在 hash 中获取值
 292         /// </summary>
 293         /// <param name="rediskey"></param>
 294         /// <param name="hashfield"></param>
 295         /// <returns></returns>
 296         public string hashget(string rediskey, string hashfield)
 297         {
 298             rediskey = addkeyprefix(rediskey);
 299             return _db.hashget(rediskey, hashfield);
 300         }
 301 
 302         /// <summary>
 303         /// 在 hash 中获取值
 304         /// </summary>
 305         /// <param name="rediskey"></param>
 306         /// <param name="hashfields"></param>
 307         /// <returns></returns>
 308         public ienumerable<string> hashget(string rediskey, ienumerable<string> hashfields)
 309         {
 310             rediskey = addkeyprefix(rediskey);
 311             var fields = hashfields.select(x => (redisvalue)x);
 312 
 313             return convertstrings(_db.hashget(rediskey, fields.toarray()));
 314         }
 315 
 316         /// <summary>
 317         /// 从 hash 返回所有的字段值
 318         /// </summary>
 319         /// <param name="rediskey"></param>
 320         /// <returns></returns>
 321         public ienumerable<string> hashkeys(string rediskey)
 322         {
 323             rediskey = addkeyprefix(rediskey);
 324             return convertstrings(_db.hashkeys(rediskey));
 325         }
 326 
 327         /// <summary>
 328         /// 返回 hash 中的所有值
 329         /// </summary>
 330         /// <param name="rediskey"></param>
 331         /// <returns></returns>
 332         public ienumerable<string> hashvalues(string rediskey)
 333         {
 334             rediskey = addkeyprefix(rediskey);
 335             return convertstrings(_db.hashvalues(rediskey));
 336         }
 337 
 338         /// <summary>
 339         /// 在 hash 设定值(序列化)
 340         /// </summary>
 341         /// <param name="rediskey"></param>
 342         /// <param name="hashfield"></param>
 343         /// <param name="redisvalue"></param>
 344         /// <returns></returns>
 345         public bool hashset<t>(string rediskey, string hashfield, t redisvalue)
 346         {
 347             rediskey = addkeyprefix(rediskey);
 348             var json = serialize(redisvalue);
 349 
 350             return _db.hashset(rediskey, hashfield, json);
 351         }
 352 
 353         /// <summary>
 354         /// 在 hash 中获取值(反序列化)
 355         /// </summary>
 356         /// <param name="rediskey"></param>
 357         /// <param name="hashfield"></param>
 358         /// <returns></returns>
 359         public t hashget<t>(string rediskey, string hashfield)
 360         {
 361             rediskey = addkeyprefix(rediskey);
 362 
 363             return deserialize<t>(_db.hashget(rediskey, hashfield));
 364         }
 365 
 366         #region async
 367 
 368         /// <summary>
 369         /// 判断该字段是否存在 hash 中
 370         /// </summary>
 371         /// <param name="rediskey"></param>
 372         /// <param name="hashfield"></param>
 373         /// <returns></returns>
 374         public async task<bool> hashexistsasync(string rediskey, string hashfield)
 375         {
 376             rediskey = addkeyprefix(rediskey);
 377             return await _db.hashexistsasync(rediskey, hashfield);
 378         }
 379 
 380         /// <summary>
 381         /// 从 hash 中移除指定字段
 382         /// </summary>
 383         /// <param name="rediskey"></param>
 384         /// <param name="hashfield"></param>
 385         /// <returns></returns>
 386         public async task<bool> hashdeleteasync(string rediskey, string hashfield)
 387         {
 388             rediskey = addkeyprefix(rediskey);
 389             return await _db.hashdeleteasync(rediskey, hashfield);
 390         }
 391 
 392         /// <summary>
 393         /// 从 hash 中移除指定字段
 394         /// </summary>
 395         /// <param name="rediskey"></param>
 396         /// <param name="hashfields"></param>
 397         /// <returns></returns>
 398         public async task<long> hashdeleteasync(string rediskey, ienumerable<string> hashfields)
 399         {
 400             rediskey = addkeyprefix(rediskey);
 401             var fields = hashfields.select(x => (redisvalue)x);
 402 
 403             return await _db.hashdeleteasync(rediskey, fields.toarray());
 404         }
 405 
 406         /// <summary>
 407         /// 在 hash 设定值
 408         /// </summary>
 409         /// <param name="rediskey"></param>
 410         /// <param name="hashfield"></param>
 411         /// <param name="value"></param>
 412         /// <returns></returns>
 413         public async task<bool> hashsetasync(string rediskey, string hashfield, string value)
 414         {
 415             rediskey = addkeyprefix(rediskey);
 416             return await _db.hashsetasync(rediskey, hashfield, value);
 417         }
 418 
 419         /// <summary>
 420         /// 在 hash 中设定值
 421         /// </summary>
 422         /// <param name="rediskey"></param>
 423         /// <param name="hashfields"></param>
 424         public async task hashsetasync(string rediskey, ienumerable<keyvaluepair<string, string>> hashfields)
 425         {
 426             rediskey = addkeyprefix(rediskey);
 427             var entries = hashfields.select(x => new hashentry(addkeyprefix(x.key), x.value));
 428             await _db.hashsetasync(rediskey, entries.toarray());
 429         }
 430 
 431         /// <summary>
 432         /// 在 hash 中获取值
 433         /// </summary>
 434         /// <param name="rediskey"></param>
 435         /// <param name="hashfield"></param>
 436         /// <returns></returns>
 437         public async task<string> hashgetasync(string rediskey, string hashfield)
 438         {
 439             rediskey = addkeyprefix(rediskey);
 440             return await _db.hashgetasync(rediskey, hashfield);
 441         }
 442 
 443         /// <summary>
 444         /// 在 hash 中获取值
 445         /// </summary>
 446         /// <param name="rediskey"></param>
 447         /// <param name="hashfields"></param>
 448         /// <param name="value"></param>
 449         /// <returns></returns>
 450         public async task<ienumerable<string>> hashgetasync(string rediskey, ienumerable<string> hashfields,
 451             string value)
 452         {
 453             rediskey = addkeyprefix(rediskey);
 454             var fields = hashfields.select(x => (redisvalue)x);
 455 
 456             return convertstrings(await _db.hashgetasync(rediskey, fields.toarray()));
 457         }
 458 
 459         /// <summary>
 460         /// 从 hash 返回所有的字段值
 461         /// </summary>
 462         /// <param name="rediskey"></param>
 463         /// <returns></returns>
 464         public async task<ienumerable<string>> hashkeysasync(string rediskey)
 465         {
 466             rediskey = addkeyprefix(rediskey);
 467             return convertstrings(await _db.hashkeysasync(rediskey));
 468         }
 469 
 470         /// <summary>
 471         /// 返回 hash 中的所有值
 472         /// </summary>
 473         /// <param name="rediskey"></param>
 474         /// <returns></returns>
 475         public async task<ienumerable<string>> hashvaluesasync(string rediskey)
 476         {
 477             rediskey = addkeyprefix(rediskey);
 478             return convertstrings(await _db.hashvaluesasync(rediskey));
 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<t>(string rediskey, string hashfield, t value)
 489         {
 490             rediskey = addkeyprefix(rediskey);
 491             var json = serialize(value);
 492             return await _db.hashsetasync(rediskey, hashfield, json);
 493         }
 494 
 495         /// <summary>
 496         /// 在 hash 中获取值(反序列化)
 497         /// </summary>
 498         /// <param name="rediskey"></param>
 499         /// <param name="hashfield"></param>
 500         /// <returns></returns>
 501         public async task<t> hashgetasync<t>(string rediskey, string hashfield)
 502         {
 503             rediskey = addkeyprefix(rediskey);
 504             return deserialize<t>(await _db.hashgetasync(rediskey, hashfield));
 505         }
 506 
 507         #endregion async
 508 
 509         #endregion hash 操作
 510 
 511         #region list 操作
 512 
 513         /// <summary>
 514         /// 移除并返回存储在该键列表的第一个元素
 515         /// </summary>
 516         /// <param name="rediskey"></param>
 517         /// <returns></returns>
 518         public string listleftpop(string rediskey)
 519         {
 520             rediskey = addkeyprefix(rediskey);
 521             return _db.listleftpop(rediskey);
 522         }
 523 
 524         /// <summary>
 525         /// 移除并返回存储在该键列表的最后一个元素
 526         /// </summary>
 527         /// <param name="rediskey"></param>
 528         /// <returns></returns>
 529         public string listrightpop(string rediskey)
 530         {
 531             rediskey = addkeyprefix(rediskey);
 532             return _db.listrightpop(rediskey);
 533         }
 534 
 535         /// <summary>
 536         /// 移除列表指定键上与该值相同的元素
 537         /// </summary>
 538         /// <param name="rediskey"></param>
 539         /// <param name="redisvalue"></param>
 540         /// <returns></returns>
 541         public long listremove(string rediskey, string redisvalue)
 542         {
 543             rediskey = addkeyprefix(rediskey);
 544             return _db.listremove(rediskey, redisvalue);
 545         }
 546 
 547         /// <summary>
 548         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 549         /// </summary>
 550         /// <param name="rediskey"></param>
 551         /// <param name="redisvalue"></param>
 552         /// <returns></returns>
 553         public long listrightpush(string rediskey, string redisvalue)
 554         {
 555             rediskey = addkeyprefix(rediskey);
 556             return _db.listrightpush(rediskey, redisvalue);
 557         }
 558 
 559         /// <summary>
 560         /// 在列表头部插入值。如果键不存在,先创建再插入值
 561         /// </summary>
 562         /// <param name="rediskey"></param>
 563         /// <param name="redisvalue"></param>
 564         /// <returns></returns>
 565         public long listleftpush(string rediskey, string redisvalue)
 566         {
 567             rediskey = addkeyprefix(rediskey);
 568             return _db.listleftpush(rediskey, redisvalue);
 569         }
 570 
 571         /// <summary>
 572         /// 返回列表上该键的长度,如果不存在,返回 0
 573         /// </summary>
 574         /// <param name="rediskey"></param>
 575         /// <returns></returns>
 576         public long listlength(string rediskey)
 577         {
 578             rediskey = addkeyprefix(rediskey);
 579             return _db.listlength(rediskey);
 580         }
 581 
 582         /// <summary>
 583         /// 返回在该列表上键所对应的元素
 584         /// </summary>
 585         /// <param name="rediskey"></param>
 586         /// <param name="start"></param>
 587         /// <param name="stop"></param>
 588         /// <returns></returns>
 589         public ienumerable<string> listrange(string rediskey, long start = 0l, long stop = -1l)
 590         {
 591             rediskey = addkeyprefix(rediskey);
 592             return convertstrings(_db.listrange(rediskey, start, stop));
 593         }
 594 
 595         /// <summary>
 596         /// 移除并返回存储在该键列表的第一个元素
 597         /// </summary>
 598         /// <param name="rediskey"></param>
 599         /// <returns></returns>
 600         public t listleftpop<t>(string rediskey)
 601         {
 602             rediskey = addkeyprefix(rediskey);
 603             return deserialize<t>(_db.listleftpop(rediskey));
 604         }
 605 
 606         /// <summary>
 607         /// 移除并返回存储在该键列表的最后一个元素
 608         /// </summary>
 609         /// <param name="rediskey"></param>
 610         /// <returns></returns>
 611         public t listrightpop<t>(string rediskey)
 612         {
 613             rediskey = addkeyprefix(rediskey);
 614             return deserialize<t>(_db.listrightpop(rediskey));
 615         }
 616 
 617         /// <summary>
 618         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 619         /// </summary>
 620         /// <param name="rediskey"></param>
 621         /// <param name="redisvalue"></param>
 622         /// <returns></returns>
 623         public long listrightpush<t>(string rediskey, t redisvalue)
 624         {
 625             rediskey = addkeyprefix(rediskey);
 626             return _db.listrightpush(rediskey, serialize(redisvalue));
 627         }
 628 
 629         /// <summary>
 630         /// 在列表头部插入值。如果键不存在,先创建再插入值
 631         /// </summary>
 632         /// <param name="rediskey"></param>
 633         /// <param name="redisvalue"></param>
 634         /// <returns></returns>
 635         public long listleftpush<t>(string rediskey, t redisvalue)
 636         {
 637             rediskey = addkeyprefix(rediskey);
 638             return _db.listleftpush(rediskey, serialize(redisvalue));
 639         }
 640 
 641         #region list-async
 642 
 643         /// <summary>
 644         /// 移除并返回存储在该键列表的第一个元素
 645         /// </summary>
 646         /// <param name="rediskey"></param>
 647         /// <returns></returns>
 648         public async task<string> listleftpopasync(string rediskey)
 649         {
 650             rediskey = addkeyprefix(rediskey);
 651             return await _db.listleftpopasync(rediskey);
 652         }
 653 
 654         /// <summary>
 655         /// 移除并返回存储在该键列表的最后一个元素
 656         /// </summary>
 657         /// <param name="rediskey"></param>
 658         /// <returns></returns>
 659         public async task<string> listrightpopasync(string rediskey)
 660         {
 661             rediskey = addkeyprefix(rediskey);
 662             return await _db.listrightpopasync(rediskey);
 663         }
 664 
 665         /// <summary>
 666         /// 移除列表指定键上与该值相同的元素
 667         /// </summary>
 668         /// <param name="rediskey"></param>
 669         /// <param name="redisvalue"></param>
 670         /// <returns></returns>
 671         public async task<long> listremoveasync(string rediskey, string redisvalue)
 672         {
 673             rediskey = addkeyprefix(rediskey);
 674             return await _db.listremoveasync(rediskey, redisvalue);
 675         }
 676 
 677         /// <summary>
 678         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 679         /// </summary>
 680         /// <param name="rediskey"></param>
 681         /// <param name="redisvalue"></param>
 682         /// <returns></returns>
 683         public async task<long> listrightpushasync(string rediskey, string redisvalue)
 684         {
 685             rediskey = addkeyprefix(rediskey);
 686             return await _db.listrightpushasync(rediskey, redisvalue);
 687         }
 688 
 689         /// <summary>
 690         /// 在列表头部插入值。如果键不存在,先创建再插入值
 691         /// </summary>
 692         /// <param name="rediskey"></param>
 693         /// <param name="redisvalue"></param>
 694         /// <returns></returns>
 695         public async task<long> listleftpushasync(string rediskey, string redisvalue)
 696         {
 697             rediskey = addkeyprefix(rediskey);
 698             return await _db.listleftpushasync(rediskey, redisvalue);
 699         }
 700 
 701         /// <summary>
 702         /// 返回列表上该键的长度,如果不存在,返回 0
 703         /// </summary>
 704         /// <param name="rediskey"></param>
 705         /// <returns></returns>
 706         public async task<long> listlengthasync(string rediskey)
 707         {
 708             rediskey = addkeyprefix(rediskey);
 709             return await _db.listlengthasync(rediskey);
 710         }
 711 
 712         /// <summary>
 713         /// 返回在该列表上键所对应的元素
 714         /// </summary>
 715         /// <param name="rediskey"></param>
 716         /// <param name="start"></param>
 717         /// <param name="stop"></param>
 718         /// <returns></returns>
 719         public async task<ienumerable<string>> listrangeasync(string rediskey, long start = 0l, long stop = -1l)
 720         {
 721             rediskey = addkeyprefix(rediskey);
 722             var query = await _db.listrangeasync(rediskey, start, stop);
 723             return query.select(x => x.tostring());
 724         }
 725 
 726         /// <summary>
 727         /// 移除并返回存储在该键列表的第一个元素
 728         /// </summary>
 729         /// <param name="rediskey"></param>
 730         /// <returns></returns>
 731         public async task<t> listleftpopasync<t>(string rediskey)
 732         {
 733             rediskey = addkeyprefix(rediskey);
 734             return deserialize<t>(await _db.listleftpopasync(rediskey));
 735         }
 736 
 737         /// <summary>
 738         /// 移除并返回存储在该键列表的最后一个元素
 739         /// </summary>
 740         /// <param name="rediskey"></param>
 741         /// <returns></returns>
 742         public async task<t> listrightpopasync<t>(string rediskey)
 743         {
 744             rediskey = addkeyprefix(rediskey);
 745             return deserialize<t>(await _db.listrightpopasync(rediskey));
 746         }
 747 
 748         /// <summary>
 749         /// 在列表尾部插入值。如果键不存在,先创建再插入值
 750         /// </summary>
 751         /// <param name="rediskey"></param>
 752         /// <param name="redisvalue"></param>
 753         /// <returns></returns>
 754         public async task<long> listrightpushasync<t>(string rediskey, t redisvalue)
 755         {
 756             rediskey = addkeyprefix(rediskey);
 757             return await _db.listrightpushasync(rediskey, serialize(redisvalue));
 758         }
 759 
 760         /// <summary>
 761         /// 在列表头部插入值。如果键不存在,先创建再插入值
 762         /// </summary>
 763         /// <param name="rediskey"></param>
 764         /// <param name="redisvalue"></param>
 765         /// <returns></returns>
 766         public async task<long> listleftpushasync<t>(string rediskey, t redisvalue)
 767         {
 768             rediskey = addkeyprefix(rediskey);
 769             return await _db.listleftpushasync(rediskey, serialize(redisvalue));
 770         }
 771 
 772         #endregion list-async
 773 
 774         #endregion list 操作
 775 
 776         #region sortedset 操作
 777 
 778         /// <summary>
 779         /// sortedset 新增
 780         /// </summary>
 781         /// <param name="rediskey"></param>
 782         /// <param name="member"></param>
 783         /// <param name="score"></param>
 784         /// <returns></returns>
 785         public bool sortedsetadd(string rediskey, string member, double score)
 786         {
 787             rediskey = addkeyprefix(rediskey);
 788             return _db.sortedsetadd(rediskey, member, score);
 789         }
 790 
 791         /// <summary>
 792         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
 793         /// </summary>
 794         /// <param name="rediskey"></param>
 795         /// <param name="start"></param>
 796         /// <param name="stop"></param>
 797         /// <param name="order"></param>
 798         /// <returns></returns>
 799         public ienumerable<string> sortedsetrangebyrank(string rediskey, long start = 0l, long stop = -1l,
 800             order order = order.ascending)
 801         {
 802             rediskey = addkeyprefix(rediskey);
 803             return _db.sortedsetrangebyrank(rediskey, start, stop, (order)order).select(x => x.tostring());
 804         }
 805 
 806         /// <summary>
 807         /// 返回有序集合的元素个数
 808         /// </summary>
 809         /// <param name="rediskey"></param>
 810         /// <returns></returns>
 811         public long sortedsetlength(string rediskey)
 812         {
 813             rediskey = addkeyprefix(rediskey);
 814             return _db.sortedsetlength(rediskey);
 815         }
 816 
 817         /// <summary>
 818         /// 返回有序集合的元素个数
 819         /// </summary>
 820         /// <param name="rediskey"></param>
 821         /// <param name="memebr"></param>
 822         /// <returns></returns>
 823         public bool sortedsetlength(string rediskey, string memebr)
 824         {
 825             rediskey = addkeyprefix(rediskey);
 826             return _db.sortedsetremove(rediskey, memebr);
 827         }
 828 
 829         /// <summary>
 830         /// sortedset 新增
 831         /// </summary>
 832         /// <param name="rediskey"></param>
 833         /// <param name="member"></param>
 834         /// <param name="score"></param>
 835         /// <returns></returns>
 836         public bool sortedsetadd<t>(string rediskey, t member, double score)
 837         {
 838             rediskey = addkeyprefix(rediskey);
 839             var json = serialize(member);
 840 
 841             return _db.sortedsetadd(rediskey, json, score);
 842         }
 843 
 844         /// <summary>
 845         /// 增量的得分排序的集合中的成员存储键值键按增量
 846         /// </summary>
 847         /// <param name="rediskey"></param>
 848         /// <param name="member"></param>
 849         /// <param name="value"></param>
 850         /// <returns></returns>
 851         public double sortedsetincrement(string rediskey, string member, double value = 1)
 852         {
 853             rediskey = addkeyprefix(rediskey);
 854             return _db.sortedsetincrement(rediskey, member, value);
 855         }
 856 
 857         #region sortedset-async
 858 
 859         /// <summary>
 860         /// sortedset 新增
 861         /// </summary>
 862         /// <param name="rediskey"></param>
 863         /// <param name="member"></param>
 864         /// <param name="score"></param>
 865         /// <returns></returns>
 866         public async task<bool> sortedsetaddasync(string rediskey, string member, double score)
 867         {
 868             rediskey = addkeyprefix(rediskey);
 869             return await _db.sortedsetaddasync(rediskey, member, score);
 870         }
 871 
 872         /// <summary>
 873         /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
 874         /// </summary>
 875         /// <param name="rediskey"></param>
 876         /// <returns></returns>
 877         public async task<ienumerable<string>> sortedsetrangebyrankasync(string rediskey)
 878         {
 879             rediskey = addkeyprefix(rediskey);
 880             return convertstrings(await _db.sortedsetrangebyrankasync(rediskey));
 881         }
 882 
 883         /// <summary>
 884         /// 返回有序集合的元素个数
 885         /// </summary>
 886         /// <param name="rediskey"></param>
 887         /// <returns></returns>
 888         public async task<long> sortedsetlengthasync(string rediskey)
 889         {
 890             rediskey = addkeyprefix(rediskey);
 891             return await _db.sortedsetlengthasync(rediskey);
 892         }
 893 
 894         /// <summary>
 895         /// 返回有序集合的元素个数
 896         /// </summary>
 897         /// <param name="rediskey"></param>
 898         /// <param name="memebr"></param>
 899         /// <returns></returns>
 900         public async task<bool> sortedsetremoveasync(string rediskey, string memebr)
 901         {
 902             rediskey = addkeyprefix(rediskey);
 903             return await _db.sortedsetremoveasync(rediskey, memebr);
 904         }
 905 
 906         /// <summary>
 907         /// sortedset 新增
 908         /// </summary>
 909         /// <param name="rediskey"></param>
 910         /// <param name="member"></param>
 911         /// <param name="score"></param>
 912         /// <returns></returns>
 913         public async task<bool> sortedsetaddasync<t>(string rediskey, t member, double score)
 914         {
 915             rediskey = addkeyprefix(rediskey);
 916             var json = serialize(member);
 917 
 918             return await _db.sortedsetaddasync(rediskey, json, score);
 919         }
 920 
 921         /// <summary>
 922         /// 增量的得分排序的集合中的成员存储键值键按增量
 923         /// </summary>
 924         /// <param name="rediskey"></param>
 925         /// <param name="member"></param>
 926         /// <param name="value"></param>
 927         /// <returns></returns>
 928         public task<double> sortedsetincrementasync(string rediskey, string member, double value = 1)
 929         {
 930             rediskey = addkeyprefix(rediskey);
 931             return _db.sortedsetincrementasync(rediskey, member, value);
 932         }
 933 
 934         #endregion sortedset-async
 935 
 936         #endregion sortedset 操作
 937 
 938         #endregion 类型封装
 939 
 940         #region 将object序列化读写
 941         public void listset<t>(string key, list<t> value)
 942         {
 943             foreach (var single in value)
 944             {
 945                 var jsonobj = jsonconvert.serializeobject(single); //序列化
 946                 this.listleftpush(key, jsonobj); //要一个个的插入
 947                 
 948             }
 949         }
 950         public list<t> listget<t>(string key)
 951         {
 952             var jsonarr = this.listrange(key);
 953             list<t> result = new list<t>();
 954             foreach (var item in jsonarr)
 955             {
 956                 var model = jsonconvert.deserializeobject<t>(item); //反序列化
 957                 result.add(model);
 958             }
 959             return result;
 960         }
 961         #endregion
 962 
 963         #region key 操作
 964 
 965         /// <summary>
 966         /// 删除单个key
 967         /// </summary>
 968         /// <param name="rediskey"></param>
 969         /// <returns>是否删除成功</returns>
 970         public bool keydelete(string rediskey)
 971         {
 972             rediskey = addkeyprefix(rediskey);
 973             return _db.keydelete(rediskey);
 974         }
 975 
 976         /// <summary>
 977         /// 删除多个key
 978         /// </summary>
 979         /// <param name="rediskeys"></param>
 980         /// <returns>成功删除的个数</returns>
 981         public long keydelete(ienumerable<string> rediskeys)
 982         {
 983             var keys = rediskeys.select(x => (rediskey)addkeyprefix(x));
 984             return _db.keydelete(keys.toarray());
 985         }
 986 
 987         /// <summary>
 988         /// 校验 key 是否存在
 989         /// </summary>
 990         /// <param name="rediskey"></param>
 991         /// <returns></returns>
 992         public bool keyexists(string rediskey)
 993         {
 994             rediskey = addkeyprefix(rediskey);
 995             return _db.keyexists(rediskey);
 996         }
 997 
 998         /// <summary>
 999         /// 重命名 key
1000         /// </summary>
1001         /// <param name="rediskey"></param>
1002         /// <param name="redisnewkey"></param>
1003         /// <returns></returns>
1004         public bool keyrename(string rediskey, string redisnewkey)
1005         {
1006             rediskey = addkeyprefix(rediskey);
1007             return _db.keyrename(rediskey, redisnewkey);
1008         }
1009 
1010         /// <summary>
1011         /// 设置 key 的时间
1012         /// </summary>
1013         /// <param name="rediskey"></param>
1014         /// <param name="expiry"></param>
1015         /// <returns></returns>
1016         public bool keyexpire(string rediskey, timespan? expiry)
1017         {
1018             rediskey = addkeyprefix(rediskey);
1019             return _db.keyexpire(rediskey, expiry);
1020         }

                    
                
(0)
打赏 Redis分布式队列和缓存更新 微信扫一扫

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

Redis分布式队列和缓存更新
验证码: Redis分布式队列和缓存更新