您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息

RedisRepository 分享和纠错

2024/3/28 22:56:22发布5次查看
一.   写在前面
毕业工作后,今天终于能回家了,回想了一些这半年来所做的内容,总是觉得还停留在那么基础的水平 ,在解决各种问题的过程中,自己的创新思路比较少,靠搜索来的比较多 。不想做16年的总结了 ,希望17年能学更多的我爱的技术,看更多的开源代码,能学到更多的设计思想和代码思路,能再更新这两年来对代码的理解。
这篇分享,主要是弥补我之前redisrepository的不足。
半年前由于我stackexchange.redis文档阅读不足,所分享的redisrepository有所错误。下面列举我的主要错误:
错误1,没有单例化connectionmultiplexer redis连接对象,并且我天真的以为给单例对象加锁,在并发情况下,会限制了redis的性能。
错误2,在主从情况下,我以为在发生手动切换的时候,我们要订阅切换事件,并在事件发生后,动态改变连接对象指向的endpoint。
当我再一次仔细阅读文档时,才明白我的错误,这是一篇迟到的修正,但是我自用的repository自我感觉还是有很多不足之处,所以我真的需要老司机的指点和建议。
修正1,redis连接对象创建的代价很大,并且单例加锁并不会影响redis性能,因为在发生网络请求的期间,连接对象并没有在等待中。
修正2,redis主从时,在哨兵切换主从关系后,stackexchange.redis会为我们识别新的主从,不需要我们做任何操作。
目前为止我还有两个疑问。
疑问1,在看文档后没有明确结果。当做主从读写分离时,  我们在endpoint collection集合中添加多个节点就会自动读写分离?还是说需要 我们在读取命令的方法中指定commandflags.preferslave?  我认为是后者吧?所以我在我所有的读取方法都指定了preferslave。    老司机们怎么说?
疑问2,我使用luascript.prepare(lua)后再load出来,执行lua总是无效果,并且luascript.getcachedscriptcount()为0. 不过我直接使用scriptevaluateasync却是好用的,老司机如果有好的例子,希望老司机给些指导或者分享。
二.   代码结构,仅供参考
结构大概就是这样,redisasynchelper下的所有类都是部分类,他们的类名称是redishelper。他们共同实现了iredishelper的接口,并且留下了详细的注释。
同步版本和异步版本的目录结构是一样的。
三.   预备阶段
commonhelper中的两个帮助类:
redisinnertypehelper.cs
using stackexchange.redis; using system.collections.generic; using system.linq; namespace fantasy.redisrepository.commonhelper { internal class redisinnertypehelper { public static list<t> redisvaluestogenericlist<t>(redisvalue[] redisvalues) { var result = new list<t>(); redisvalues.tolist().foreach(r => result.add(serializehelper.deserialize<t>(r))); return result; } public static redisvalue[] genericlisttoredisvalues<t>(list<t> values) { var redisvalues = new list<redisvalue>(); values.foreach(v => redisvalues.add(serializehelper.serialize(values))); return redisvalues.toarray(); } public static rediskey[] genericlisttorediskeys(list<string> keys) { var rediskeys = new list<rediskey>(); keys.foreach(k => rediskeys.add(k)); return rediskeys.toarray(); } } }
serializehelper.cs
using system.io; using system.runtime.serialization.formatters.binary; namespace fantasy.redisrepository.commonhelper { internal static class serializehelper { /// <summary> /// 字节数组序列化 /// </summary> /// <param name="o"></param> /// <returns></returns> internal static byte[] serialize(object o) { if (o == null) { return null; } binaryformatter binaryformatter = new binaryformatter(); using (memorystream memorystream = new memorystream()) { binaryformatter.serialize(memorystream, o); byte[] objectdataasstream = memorystream.toarray(); return objectdataasstream; } } /// <summary> /// 字节数组反序列化 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="stream"></param> /// <returns></returns> internal static t deserialize<t>(byte[] stream) { if (stream == null) { return default(t); } binaryformatter binaryformatter = new binaryformatter(); using (memorystream memorystream = new memorystream(stream)) { t result = (t)binaryformatter.deserialize(memorystream); return result; } } } }
config中的配置类:
confighelper.csusing system; using system.configuration; namespace fantasy.redisrepository.config { internal class confighelper { internal static t get<t>(string appsettingskey, t defaultvalue) { string text = configurationmanager.appsettings[appsettingskey]; if (string.isnullorwhitespace(text)) return defaultvalue; try { var value = convert.changetype(text, typeof(t)); return (t)value; } catch { return defaultvalue; } } } }
redisclientconfig.cs
namespace fantasy.redisrepository.config { internal class redisclientconfig { private static string _server = confighelper.get("redisserver", "115.xx.xx.31"); /// <summary> /// 节点ip /// </summary> public static string server { get { return _server; } set { _server = value; } } private static int _port = confighelper.get("redisport", 6380); /// <summary> /// 节点端口 /// </summary> public static int port { get { return _port; } set { _port = value; } } private static string _slaveserver = confighelper.get("slaveserver", "115.xx.xx.31"); /// <summary> /// 节点ip /// </summary> public static string slaveserver { get { return _slaveserver; } set { _slaveserver = value; } } private static int _slaveport = confighelper.get("slaveport", 6381); /// <summary> /// 节点端口 /// </summary> public static int slaveport { get { return _slaveport; } set { _slaveport = value; } } private static string _auth = confighelper.get("redisauth", "fantasy.."); /// <summary> /// 节点密码 /// </summary> public static string redisauth { get { return _auth; } set { _auth = value; } } private static int _defaultdatabase = confighelper.get("redisdatabase", 0); /// <summary> /// redis默认0号库 /// </summary> public static int defaultdatabase { get { return _defaultdatabase; } set { _defaultdatabase = value; } } private static int _connecttimeout = 10000; public static int connecttimeout { get { return _connecttimeout; } set { _connecttimeout = value; } } private static int _connectretry = 3; public static int connectretry { get { return _connectretry; } set { _connectretry = value; } } private static bool _preserveasyncorder = false; public static bool preserveasyncorder { get { return _preserveasyncorder; } set { _preserveasyncorder = value; } } } }
redisconnection.cs
using fantasy.redisrepository.config; using stackexchange.redis; namespace fantasy.redisrepository { /// <summary> /// redis连接类 /// </summary> public static class redisconnection { private static connectionmultiplexer _connection; private static readonly object syncobject = new object(); /// <summary> /// redis连接对象,单例加锁不影响性能 /// </summary> public static connectionmultiplexer generateconnection { get { if (_connection == null || !_connection.isconnected) { lock (syncobject) { var configurationoptions = new configurationoptions() { password = redisclientconfig.redisauth, endpoints = { {redisclientconfig.server, redisclientconfig.port}, {redisclientconfig.slaveserver, redisclientconfig.slaveport} } }; _connection = connectionmultiplexer.connect(configurationoptions); } } return _connection; } } } }
四. redishelper
实际上就是做了层序列化包装而已。
iredishelper:
using system; using stackexchange.redis; using system.collections.generic; using system.threading.tasks; namespace fantasy.redisrepository.redishelpers { /// <summary> /// 异步方法接口 --author 吴双 www.cnblogs.com/tdws /// 存入数据均为方法内部序列化后的byte,所以取数据的时候需要反序列化时,请指定正确的数据类型 /// </summary> public partial interface iredishelper { #region redis数据类型—string /// <summary> /// 将任何数据以redis string存储 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="timeout"></param> /// <returns></returns> task<bool> stringsetasync<t>(string key, t value, timespan? timeout = null); /// <summary> /// 对数值进行减法操作,默认-1 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns>操作后的结果</returns> task<long> stringdecrementasync(string key, long value = 1l); /// <summary> /// 对数值进行加法操作,默认+1 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns>操作后的结果</returns> task<long> stringincrementasync(string key, long value = 1l); /// <summary> /// 从redis string中以指定类型取出 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<t> stringgetasync<t>(string key); #endregion #region redis数据类型—hash /// <summary> /// 向hash key中存储任意类型任意值 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="field"></param> /// <param name="value"></param> /// <returns>是否成功</returns> task<bool> hashsetasync<t>(string key, string field, t value); /// <summary> /// 批量 向hash key中存储任意类型任意值 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="hashfields"></param> /// <returns>无返回值</returns> task hashmultisetasync<t>(string key, dictionary<string, t> hashfields); /// <summary> /// 对指定hash key中制定field做数量增加操作 默认自增1 /// 如果此操作前key不存在 则创建。 如果此操作前该field不存在或者非数字 则先被置0,再被继续操作 /// </summary> /// <param name="key"></param> /// <param name="field"></param> /// <param name="incrcount"></param> /// <returns>操作后的结果</returns> task<long> hashincrementasync(string key, string field, long incrcount = 1); /// <summary> /// 对指定hash key中制定field做数量增加操作 默认自减1 /// 如果此操作前key不存在 则创建。 如果此操作前该field不存在或者非数字 则先被置0,再被继续操作 /// </summary> /// <param name="key"></param> /// <param name="field"></param> /// <param name="decrcount"></param> /// <returns>操作后的结果</returns> task<long> hashdecrementasync(string key, string field, long decrcount = 1); /// <summary> /// 从指定hash中 删除指定field /// 如果key或者field不存在,则false /// </summary> /// <param name="key"></param> /// <param name="field"></param> /// <returns>是否成功</returns> task<bool> hashdeletefieldasync(string key, string field); /// <summary> /// 从指定hash key中 批量删除指定field /// 如果key或者field不存在,则false /// </summary> /// <param name="key"></param> /// <param name="fields"></param> /// <returns>移除数量</returns> task<long> hashmultideletefieldasync(string key, list<string> fields); /// <summary> /// 从指定hash key中获取指定field值 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="field"></param> /// <returns></returns> task<t> hashgetasync<t>(string key, string field); /// <summary> /// 从指定hash key中判断field是否存在 /// </summary> /// <param name="key"></param> /// <param name="field"></param> /// <returns></returns> task<bool> hashfieldexistasync(string key, string field); /// <summary> /// 获取指定hash key中的所有field的值 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<list<t>> hashvaluesasync<t>(string key); /// <summary> /// 获取指定hash key中所有 field名称及其value /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<dictionary<string, t>> hashgetallasync<t>(string key); /// <summary> /// 获取指定hash key中所有field /// </summary> /// <param name="key"></param> /// <returns></returns> task<list<string>> hashfieldsasync(string key); #endregion #region redis数据类型—list /// <summary> /// 在指定pivot后插入value, 如果pivot不存在,则返回-1, 如果key不存在,则返回0 /// 如果存在多个相同指定的的pivot,则插入第一个指定pivot后面. /// 即链表从左向右查找,遇到指定pivot,则确定位置 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="pivot">list中的一个值</param> /// <param name="value"></param> /// <returns></returns> task<long> listinsertafterasync<t>(string key, string pivot, t value); /// <summary> /// 在指定pivot前插入value, 如果pivot不存在,则返回-1, 如果key不存在,则返回0 /// 如果存在多个相同指定的的pivot,则插入第一个指定pivot前面. /// 即链表从左向右查找,遇到指定pivot,则确定位置 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="pivot"></param> /// <param name="value"></param> /// <returns></returns> task<long> listinsertbeforeasync<t>(string key, string pivot, t value); /// <summary> /// 从链表左侧弹出第一个元素(弹出能获取到该元素并且被删除) /// 如果key不存在 或者链表为空 则为null /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<t> listleftpopasync<t>(string key); /// <summary> /// 从链表左侧增加一个元素,key不存在则被创建 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns>返回操作后的链表长度</returns> task<long> listleftpushasync<t>(string key, t value); /// <summary> /// 从链表左侧批量增加元素,如果 a b c 则c会在链表左侧第一位 b第二位 a第三位 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="values"></param> /// <returns>返回操作后的链表长度</returns> task<long> listleftmultipushasync<t>(string key, list<t> values); /// <summary> /// 获取链表长度,不存在key则为0 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<long> listlengthasync<t>(string key); /// <summary> /// 获取链表中所有数据,从左侧start开始到stop结束,从0—-1则认为获取全部,默认获取全部 /// start为负数则代表从链表右侧开始,-1为右侧第一位,-2为右侧第二位 /// start要小于stop,否则返回null /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="start"></param> /// <param name="stop"></param> /// <returns></returns> task<list<t>> listrangeasync<t>(string key, long start = 0l, long stop = -1l); /// <summary> /// 从链表中一处count数量的value. count大于0则从左至右,count小于0则从右至左,count=0则移除全部 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="count"></param> /// <returns></returns> task<long> listremoveasync<t>(string key, t value, long count = 0l); /// <summary> /// 从右侧弹出第一个元素(弹出能获取到该元素并且被删除) /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<t> listrightpopasync<t>(string key); /// <summary> /// 从链表右侧加入元素,如果 rpush a b c 则c为右侧第一位 b第二位 c第三位 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> task<long> listrightpushasync<t>(string key, t value); /// <summary> /// 从右侧批量插入,和左侧相反 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="values"></param> /// <returns></returns> task<long> listrightmultipushasync<t>(string key, list<t> values); /// <summary> /// 在链表指定索引处,插入元素 /// 正数索引从0开始,代表左侧。负数从-1开始 代表从右侧。-1为右侧第一位 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="index"></param> /// <param name="value"></param> /// <returns></returns> task listsetbyindexasync<t>(string key, int index, t value); /// <summary> /// 留下start到stop之间的数据。负数代表从右侧寻找 -1为右侧第一位 /// </summary> /// <param name="key"></param> /// <param name="start"></param> /// <param name="stop"></param> /// <returns></returns> task listtrimasync(string key, long start, long stop); /// <summary> /// 获取指定index的值,负数代表从右侧寻找 -1为右侧第一位 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="index"></param> /// <returns></returns> task<t> listgetbyindexasync<t>(string key, long index); #endregion #region redis数据类型—set /// <summary> /// 向指定集合中增加一个元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> task<bool> setaddasync<t>(string key, t value); /// <summary> /// 指定集合计算操作operation枚举,指定计算结果将存的目标destkey,指定需要参与计算的多个key /// </summary> /// <param name="operation"></param> /// <param name="destkey"></param> /// <param name="combinekeys"></param> /// <returns></returns> task<long> setcombineandstoreasync(setoperation operation, string destkey, list<string> combinekeys); /// <summary> /// 指定集合计算操作operation枚举,指定需要参与计算的多个key /// </summary> /// <typeparam name="t"></typeparam> /// <param name="operation"></param> /// <param name="combinekeys"></param> /// <returns></returns> task<list<t>> setcombineasync<t>(setoperation operation, list<string> combinekeys); /// <summary> /// 指定值是否存在于指定集合中 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> task<bool> setcontainsasync<t>(string key, t value); /// <summary> /// 获取指定集合中元素个数 /// </summary> /// <param name="key"></param> /// <returns></returns> task<long> setlengthasync(string key); /// <summary> /// 获取指定集合中的所有元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> task<list<t>> setmembersasync<t>(string key, t value); /// <summary> /// 从sourcekey移除指定value到目标distkey集合当中 /// 如果sourcekey存在指定value则返回true,否则不做任何操作返回false /// </summary> /// <typeparam name="t"></typeparam> /// <param name="sourcekey"></param> /// <param name="distkey"></param> /// <param name="value"></param> /// <returns></returns> task<bool> setmoveasync<t>(string sourcekey, string distkey, t value); /// <summary> /// 从指定集合当中随机取出一个元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<t> setrandommemberasync<t>(string key); /// <summary> /// 从指定集合随机弹出(删除并获取)一个元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<t> setpopasync<t>(string key); /// <summary> /// 从集合中随机弹出(删除并获取)多个元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> task<list<t>> setrandommembersasync<t>(string key); /// <summary> /// 从集合中移除指定元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> task<bool> setremoveasync<t>(string key, t value); /// <summary> /// 从集合中批量移除元素 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="values"></param> /// <returns></returns> task<long> setmultiremoveasync<t>(string key, list<t> values); #endregion #region redis数据类型—sortset #endregion #region redis key操作 /// <summary> /// 删除指定key /// </summary> /// <param name="key"></param> /// <returns></returns> task<bool> keydeleteasync(string key); /// <summary> /// 设置key过期时间具体datetime /// </summary> /// <param name="key"></param> /// <param name="expireat"></param> /// <returns></returns> task<bool> keyexpireatasync(string key, datetime expireat); /// <summary> /// 设置key在将来的timeout后过期(timespan) /// </summary> /// <param name="key"></param> /// <param name="timeout"></param> /// <returns></returns> task<bool> keyexpireinasync(string key, timespan timeout); /// <summary> /// key重命名 /// </summary> /// <param name="key"></param> /// <param name="newkey"></param> /// <returns></returns> task<bool> keyrenameasync(string key, string newkey); /// <summary> /// 判断key是否已存在 /// </summary> /// <param name="key"></param> /// <returns></returns> task<bool> keyexistsasync(string key); #endregion #region redis transcation /// <summary> /// 在事务中执行一系列redis命令。注意:在委托中的一系列命令的所有 值 都需要进行字节数组序列化 /// </summary> /// <param name="ranoperations"></param> /// <returns></returns> task<bool> dointranscationasync(action<itransaction> ranoperations); #endregion task<redisresult> test(); } }
redishelper部分类redisstringhelperasync.cs
using system; using fantasy.redisrepository.commonhelper; using stackexchange.redis; using system.threading.tasks; namespace fantasy.redisrepository.redishelpers { /// <summary> /// redis异步操作类 string部分类 /// </summary> internal partial class redishelper// : iredishelper { private static idatabase _client; internal redishelper() { _client = redisconnection.generateconnection.getdatabase(); } #region string 写操作 /// <summary> /// 将任何数据添加到redis中 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="timeout"></param> /// <returns></returns> public async task<bool> stringsetasync<t>(string key, t value, timespan? timeout = null) { return await _client.stringsetasync(key, serializehelper.serialize(value), timeout); } public async task<long> stringdecrementasync(string key, long value = 1l) { return await _client.stringdecrementasync(key, value); } public async task<long> stringincrementasync(string key, long value = 1l) { return await _client.stringincrementasync(key, value); } #endregion #region string 读操作 /// <summary> /// 根据key获取指定类型数据 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> public async task<t> stringgetasync<t>(string key) { return serializehelper.deserialize<t>(await _client.stringgetasync(key, commandflags.preferslave)); } #endregion } }
redishelper部分类redishashhelperasync.cs
using fantasy.redisrepository.commonhelper; using stackexchange.redis; using system.collections.generic; using system.linq; using system.threading.tasks; namespace fantasy.redisrepository.redishelpers { /// <summary> /// redis异步操作类 hash部分类 /// </summary> internal partial class redishelper { #region hash 写操作 public async task<bool> hashsetasync<t>(string key, string field, t value) { return await _client.hashsetasync(key, field, serializehelper.serialize(value)); } public async task hashmultisetasync<t>(string key, dictionary<string, t> hashfields) { list<hashentry> entries = new list<hashentry>(); hashfields.tolist().foreach(d => entries.add(new hashentry(d.key, serializehelper.serialize(d.value)))); await _client.hashsetasync(key, entries.toarray()); } public async task<long> hashincrementasync(string key, string field, long incrcount = 1) { return await _client.hashincrementasync(key, field, incrcount); } public async task<long> hashdecrementasync(string key, string field, long decrcount = 1) { return await _client.hashdecrementasync(key, field, decrcount); } public async task<bool> hashdeletefieldasync(string key, string field) { return await _client.hashdeleteasync(key, field); } public async task<long> hashmultideletefieldasync(string key, list<string> fields) { list<redisvalue> values = new list<redisvalue>(); fields.foreach(f => values.add(f)); return await _client.hashdeleteasync(key, values.toarray()); } #endregion #region hash 读操作 /// <summary> /// redis 指定hash类型key中field是否存在 /// </summary> /// <param name="key"></param> /// <param name="field"></param> /// <returns></returns> public async task<bool> hashfieldexistasync(string key, string field) { return await _client.hashexistsasync(key, field, commandflags.preferslave); } public async task<list<string>> hashfieldsasync(string key) { redisvalue[] values = await _client.hashkeysasync(key, commandflags.preferslave); return redisinnertypehelper.redisvaluestogenericlist<string>(values); } public async task<list<t>> hashvaluesasync<t>(string key) { var values = await _client.hashvaluesasync(key, commandflags.preferslave); return redisinnertypehelper.redisvaluestogenericlist<t>(values); } public async task<t> hashgetasync<t>(string key, string field) { return serializehelper.deserialize<t>(await _client.hashgetasync(key, field, commandflags.preferslave)); } public async task<dictionary<string, t>> hashgetallasync<t>(string key) { hashentry[] entries = await _client.hashgetallasync(key, commandflags.preferslave); dictionary<string, t> dic = new dictionary<string, t>(); entries.tolist().foreach(e => dic.add(e.name, serializehelper.deserialize<t>(e.value))); return dic; } #endregion } }
redishelper部分类redislisthelperasync.cs
using fantasy.redisrepository.commonhelper; using stackexchange.redis; using system.collections.generic; using system.linq; using system.threading.tasks; namespace fantasy.redisrepository.redishelpers { /// <summary> /// redis异步操作类 hash部分类 /// </summary> internal partial class redishelper { #region hash 写操作 public async task<bool> hashsetasync<t>(string key, string field, t value) { return await _client.hashsetasync(key, field, serializehelper.serialize(value)); } public async task hashmultisetasync<t>(string key, dictionary<string, t> hashfields) { list<hashentry> entries = new list<hashentry>(); hashfields.tolist().foreach(d => entries.add(new hashentry(d.key, serializehelper.serialize(d.value)))); await _client.hashsetasync(key, entries.toarray()); } public async task<long> hashincrementasync(string key, string field, long incrcount = 1) { return await _client.hashincrementasync(key, field, incrcount); } public async task<long> hashdecrementasync(string key, string field, long decrcount = 1) { return await _client.hashdecrementasync(key, field, decrcount); } public async task<bool> hashdeletefieldasync(string key, string field) { return await _client.hashdeleteasync(key, field); } public async task<long> hashmultideletefieldasync(string key, list<string> fields) { list<redisvalue> values = new list<redisvalue>(); fields.foreach(f => values.add(f)); return await _client.hashdeleteasync(key, values.toarray()); } #endregion #region hash 读操作 /// <summary> /// redis 指定hash类型key中field是否存在 /// </summary> /// <param name="key"></param> /// <param name="field"></param> /// <returns></returns> public async task<bool> hashfieldexistasync(string key, string field) { return await _client.hashexistsasync(key, field, commandflags.preferslave); } public async task<list<string>> hashfieldsasync(string key) { redisvalue[] values = await _client.hashkeysasync(key, commandflags.preferslave); return redisinnertypehelper.redisvaluestogenericlist<string>(values); } public async task<list<t>> hashvaluesasync<t>(string key) { var values = await _client.hashvaluesasync(key, commandflags.preferslave); return redisinnertypehelper.redisvaluestogenericlist<t>(values); } public async task<t> hashgetasync<t>(string key, string field) { return serializehelper.deserialize<t>(await _client.hashgetasync(key, field, commandflags.preferslave)); } public async task<dictionary<string, t>> hashgetallasync<t>(string key) { hashentry[] entries = await _client.hashgetallasync(key, commandflags.preferslave); dictionary<string, t> dic = new dictionary<string, t>(); entries.tolist().foreach(e => dic.add(e.name, serializehelper.deserialize<t>(e.value))); return dic; } #endregion } }
redisluahelper.cs 这里打算装一些功能行lua脚本, 外部依然是传key一类的参数,这个不完整,只是个实例。
using stackexchange.redis; using system.threading.tasks; namespace fantasy.redisrepository.redishelpers { internal partial class redishelper { public async task<redisresult> luamutilgethash() { string lua = @"local result={} for i, v in ipairs(keys) do result[i] = redis.call('hgetall',v) end return result"; var res = await _client.scriptevaluateasync(lua, new rediskey[] { "people:1", "people:2", "people:3" }); var res1= luascript.getcachedscriptcount(); return res; } } }
关于transcation的封装,我个人没有什么好的方法,提供了这样一个方法
public async task<bool> dointranscationasync(action<itransaction> runoperations) { var tran = redisconnection.generateconnection.getdatabase().createtransaction(); runoperations(tran); return await tran.executeasync(); }
redisfactory.cs
using fantasy.redisrepository.redishelpers; namespace fantasy.redisrepository { public class redisfactory { /// <summary> /// 外部访问redis入口,暂时只暴露异步方法 /// </summary> /// <returns></returns> public static iredishelper createredisrepository() { return new redishelper(); } } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
更多redisrepository 分享和纠错。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录