Cache和NoSql、Redis

ServiceStack.Redis

下面额代码类均是通过 ServiceStack.Redis 来对Redis进行各种操作

redis 文件配置类

    /// <summary>
/// redis配置文件信息
/// 也可以放到配置文件去
/// </summary>
public sealed class RedisConfigInfo
{
/// <summary>
/// 可写的Redis链接地址
/// format:ip1,ip2
///
/// 默认6379端口
/// </summary>
public string WriteServerList = "127.0.0.1:6379";
/// <summary>
/// 可读的Redis链接地址
/// format:ip1,ip2
/// </summary>
public string ReadServerList = "127.0.0.1:6379";
/// <summary>
/// 最大写链接数
/// </summary>
public int MaxWritePoolSize = 60;
/// <summary>
/// 最大读链接数
/// </summary>
public int MaxReadPoolSize = 60;
/// <summary>
/// 本地缓存到期时间,单位:秒
/// </summary>
public int LocalCacheTime = 180;
/// <summary>
/// 自动重启
/// </summary>
public bool AutoStart = true;
/// <summary>
/// 是否记录日志,该设置仅用于排查redis运行时出现的问题,
/// 如redis工作正常,请关闭该项
/// </summary>
public bool RecordeLog = false;
}

redis操作的基类

 /// <summary>
/// RedisBase类,是redis操作的基类,继承自IDisposable接口,主要用于释放内存
/// </summary>
public abstract class RedisBase : IDisposable
{
public IRedisClient iClient { get; private set; }
/// <summary>
/// 构造时完成链接的打开
/// </summary>
public RedisBase()
{
iClient = RedisManager.GetClient();
} //public static IRedisClient iClient { get; private set; }
//static RedisBase()
//{
// iClient = RedisManager.GetClient();
//} private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
iClient.Dispose();
iClient = null;
}
}
this._disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} public void Transcation()
{
using (IRedisTransaction irt = this.iClient.CreateTransaction())
{
try
{
irt.QueueCommand(r => r.Set("key", 20));
irt.QueueCommand(r => r.Increment("key", 1));
irt.Commit(); // 提交事务
}
catch (Exception ex)
{
irt.Rollback();
throw ex;
}
}
} /// <summary>
/// 清除全部数据 请小心
/// </summary>
public virtual void FlushAll()
{
iClient.FlushAll();
} /// <summary>
/// 保存数据DB文件到硬盘
/// </summary>
public void Save()
{
iClient.Save();//阻塞式save
} /// <summary>
/// 异步保存数据DB文件到硬盘
/// </summary>
public void SaveAsync()
{
iClient.SaveAsync();//异步save
}
}

Redis管理中心

 /// <summary>
/// Redis管理中心
/// </summary>
public class RedisManager
{
/// <summary>
/// redis配置文件信息
/// </summary>
private static RedisConfigInfo RedisConfigInfo = new RedisConfigInfo(); /// <summary>
/// Redis客户端池化管理
/// </summary>
private static PooledRedisClientManager prcManager; /// <summary>
/// 静态构造方法,初始化链接池管理对象
/// </summary>
static RedisManager()
{
CreateManager();
} /// <summary>
/// 创建链接池管理对象
/// </summary>
private static void CreateManager()
{
string[] WriteServerConStr = RedisConfigInfo.WriteServerList.Split(',');
string[] ReadServerConStr = RedisConfigInfo.ReadServerList.Split(',');
prcManager = new PooledRedisClientManager(ReadServerConStr, WriteServerConStr,
new RedisClientManagerConfig
{
MaxWritePoolSize = RedisConfigInfo.MaxWritePoolSize,
MaxReadPoolSize = RedisConfigInfo.MaxReadPoolSize,
AutoStart = RedisConfigInfo.AutoStart,
});
} /// <summary>
/// 客户端缓存操作对象
/// </summary>
public static IRedisClient GetClient()
{
return prcManager.GetClient();
}
}

String

redis 的string类型操作类

    /// <summary>
/// key-value 键值对:value可以是序列化的数据
/// </summary>
public class RedisStringService : RedisBase
{
#region 赋值
/// <summary>
/// 设置key的value
/// </summary>
public bool Set<T>(string key, T value)
{
return base.iClient.Set<T>(key, value);
}
/// <summary>
/// 设置key的value并设置过期时间
/// </summary>
public bool Set<T>(string key, T value, DateTime dt)
{
return base.iClient.Set<T>(key, value, dt);
}
/// <summary>
/// 设置key的value并设置过期时间
/// </summary>
public bool Set<T>(string key, T value, TimeSpan sp)
{
return base.iClient.Set<T>(key, value, sp);
}
/// <summary>
/// 设置多个key/value
/// </summary>
public void Set(Dictionary<string, string> dic)
{
base.iClient.SetAll(dic);
} #endregion #region 追加
/// <summary>
/// 在原有key的value值之后追加value,没有就新增一项
/// </summary>
public long Append(string key, string value)
{
return base.iClient.AppendToValue(key, value);
}
#endregion #region 获取值
/// <summary>
/// 获取key的value值
/// </summary>
public string Get(string key)
{
return base.iClient.GetValue(key);
}
/// <summary>
/// 获取多个key的value值
/// </summary>
public List<string> Get(List<string> keys)
{
return base.iClient.GetValues(keys);
}
/// <summary>
/// 获取多个key的value值
/// </summary>
public List<T> Get<T>(List<string> keys)
{
return base.iClient.GetValues<T>(keys);
}
#endregion #region 获取旧值赋上新值
/// <summary>
/// 获取旧值赋上新值
/// </summary>
public string GetAndSetValue(string key, string value)
{
return base.iClient.GetAndSetValue(key, value);
}
#endregion #region 辅助方法
/// <summary>
/// 获取值的长度
/// </summary>
public long GetLength(string key)
{
return base.iClient.GetStringCount(key);
}
/// <summary>
/// 自增1,返回自增后的值
/// </summary>
public long Incr(string key)
{
return base.iClient.IncrementValue(key);
}
/// <summary>
/// 自增count,返回自增后的值
/// </summary>
public long IncrBy(string key, int count)
{
return base.iClient.IncrementValueBy(key, count);
}
/// <summary>
/// 自减1,返回自减后的值
/// </summary>
public long Decr(string key)
{
return base.iClient.DecrementValue(key);
}
/// <summary>
/// 自减count ,返回自减后的值
/// </summary>
/// <param name="key"></param>
/// <param name="count"></param>
/// <returns></returns>
public long DecrBy(string key, int count)
{
return base.iClient.DecrementValueBy(key, count);
}
#endregion
}

使用

                using (RedisStringService service = new RedisStringService())
{
service.Set<string>("student1", "梦的翅膀");
Console.WriteLine(service.Get("student1")); service.Append("student1", "20180802");
Console.WriteLine(service.Get("student1")); Console.WriteLine(service.GetAndSetValue("student1", "程序错误"));
Console.WriteLine(service.Get("student1")); service.Set<string>("student2", "王", DateTime.Now.AddSeconds(5));
Thread.Sleep(5100);
Console.WriteLine(service.Get("student2")); service.Set<int>("Age", 32);
Console.WriteLine(service.Incr("Age"));
Console.WriteLine(service.IncrBy("Age", 3));
Console.WriteLine(service.Decr("Age"));
Console.WriteLine(service.DecrBy("Age", 3));
}

超卖

    /// <summary>
/// 超卖:订单数超过商品
///
///数据库:秒杀的时候,10件商品,100个人想买,假定大家一瞬间都来了,
///A 查询还有没有--有---1更新
///B 查询还有没有--有---1更新
///C 查询还有没有--有---1更新
///可能会卖出12 12甚至20件商品
///
/// 微服务也有超卖的问题,异步队列
///
///
/// Redis原子性操作--保证一个数值只出现一次--防止一个商品卖给多个人
///
///
/// Redis是单线程,程序怎么又多线程操作Redis呢? 这个是可以的,
/// 打开多个链接,去提交任务,对程序而言,Redis是并发
///
/// 假如redis命令是拼装的,Decr---1 获取值 2 程序减1 3 再save结果回去
/// 程序多线程并发一下, A线程 1 2 3 初始值是10
/// B线程 1 2 3 结果是9,减了2次但是结果是9
///
/// 组合命令,Decr Redis线程直接完成当前值-1并返回结果,原子性操作
/// 程序多线程并发一下,A线程 123 初始值10
/// B线程 123
/// C线程 123 得到3个结果,9/8/7
///
/// 假如库存只有1个(数据库),三个人同时来下单,一检测>0,都会成功--超卖
/// 三个人同时来,lock/开启事务
/// 只有一个人能去检测>0 -1 save
/// 然后第二个人来,==0 返回失败
/// 然后第三个人来,==0 返回失败
/// 因为这个等于是数据库单线程了,其他都要阻塞,各种超时
/// -1的时候除了操作库存,还得增加订单,等支付。。
/// 10个商品秒杀,一次只能进一个? 违背了业务
///
/// 所以用上了Redis,一方面保证绝对不会超卖,
/// 另一方面没有效率影响,数据库是可以为成功的人并发的
/// 还有撤单的时候增加库存,可以继续秒杀,
/// 限制秒杀的库存是放在redis,不是数据库,不会造成数据的不一致性
///
/// Redis能够拦截无效的请求,如果没有这一层,所有的请求压力都到数据库
///
/// 缓存击穿/穿透---缓存down掉,请求全部到数据库
/// 缓存预热功能---缓存重启,数据丢失,多了一个初始化缓存数据动作(写代码去把数据读出来放入缓存)

模拟超卖现象

  public class OversellField
{
private static bool IsGoOn = true;//秒杀活动是否结束
private static int Stock = 0;
public static void Show()
{
Stock = 10; for (int i = 0; i < 5000; i++)
{
int k = i;
Task.Run(() =>//每个线程就是一个用户请求
{
if (IsGoOn)
{
long index = Stock;//-1并且返回 去数据库查一下当前的库存
Thread.Sleep(100); if (index >= 1)
{
Stock = Stock - 1;//更新库存
Console.WriteLine($"{k.ToString("000")}秒杀成功,秒杀商品索引为{index}");
//可以分队列,去数据库操作
}
else
{
if (IsGoOn)
{
IsGoOn = false;
}
Console.WriteLine($"{k.ToString("000")}秒杀失败,秒杀商品索引为{index}");
}
}
else
{
Console.WriteLine($"{k.ToString("000")}秒杀停止......");
}
});
}
Console.Read();
}
}

利用redis解决超卖问题

public class OversellTest
{
private static bool IsGoOn = true;//秒杀活动是否结束
public static void Show()
{
using (RedisStringService service = new RedisStringService())
{
service.Set<int>("Stock", 10);//是库存
} for (int i = 0; i < 5000; i++)
{
int k = i;
Task.Run(() =>//每个线程就是一个用户请求
{
using (RedisStringService service = new RedisStringService())
{
if (IsGoOn)
{
long index = service.Decr("Stock");//-1并且返回
if (index >= 0)
{
Console.WriteLine($"{k.ToString("000")}秒杀成功,秒杀商品索引为{index}");
//service.Incr("Stock");//+1
//可以分队列,去数据库操作
}
else
{
if (IsGoOn)
{
IsGoOn = false;
}
Console.WriteLine($"{k.ToString("000")}秒杀失败,秒杀商品索引为{index}");
}
}
else
{
Console.WriteLine($"{k.ToString("000")}秒杀停止......");
}
}
});
}
Console.Read();
}
}

 

Hashtable

redis 的Hash类型操作类

    /// <summary>
/// Hash:类似dictionary,通过索引快速定位到指定元素的,耗时均等,跟string的区别在于不用反序列化,直接修改某个字段
/// string的话要么是 001:序列化整个实体
/// 要么是 001_name: 001_pwd: 多个key-value
/// Hash的话,一个hashid-{key:value;key:value;key:value;}
/// 可以一次性查找实体,也可以单个,还可以单个修改
/// </summary>
public class RedisHashService : RedisBase
{
#region 添加
/// <summary>
/// 向hashid集合中添加key/value
/// </summary>
public bool SetEntryInHash(string hashid, string key, string value)
{
return base.iClient.SetEntryInHash(hashid, key, value);
}
/// <summary>
/// 如果hashid集合中存在key/value则不添加返回false,
/// 如果不存在在添加key/value,返回true
/// </summary>
public bool SetEntryInHashIfNotExists(string hashid, string key, string value)
{
return base.iClient.SetEntryInHashIfNotExists(hashid, key, value);
}
/// <summary>
/// 存储对象T t到hash集合中
/// 需要包含Id,然后用Id获取
/// </summary>
public void StoreAsHash<T>(T t)
{
base.iClient.StoreAsHash<T>(t);
}
#endregion #region 获取
/// <summary>
/// 获取对象T中ID为id的数据。
/// </summary>
public T GetFromHash<T>(object id)
{
return base.iClient.GetFromHash<T>(id);
}
/// <summary>
/// 获取所有hashid数据集的key/value数据集合
/// </summary>
public Dictionary<string, string> GetAllEntriesFromHash(string hashid)
{
return base.iClient.GetAllEntriesFromHash(hashid);
}
/// <summary>
/// 获取hashid数据集中的数据总数
/// </summary>
public long GetHashCount(string hashid)
{
return base.iClient.GetHashCount(hashid);
}
/// <summary>
/// 获取hashid数据集中所有key的集合
/// </summary>
public List<string> GetHashKeys(string hashid)
{
return base.iClient.GetHashKeys(hashid);
}
/// <summary>
/// 获取hashid数据集中的所有value集合
/// </summary>
public List<string> GetHashValues(string hashid)
{
return base.iClient.GetHashValues(hashid);
}
/// <summary>
/// 获取hashid数据集中,key的value数据
/// </summary>
public string GetValueFromHash(string hashid, string key)
{
return base.iClient.GetValueFromHash(hashid, key);
}
/// <summary>
/// 获取hashid数据集中,多个keys的value集合
/// </summary>
public List<string> GetValuesFromHash(string hashid, string[] keys)
{
return base.iClient.GetValuesFromHash(hashid, keys);
}
#endregion #region 删除
/// <summary>
/// 删除hashid数据集中的key数据
/// </summary>
public bool RemoveEntryFromHash(string hashid, string key)
{
return base.iClient.RemoveEntryFromHash(hashid, key);
}
#endregion #region 其它
/// <summary>
/// 判断hashid数据集中是否存在key的数据
/// </summary>
public bool HashContainsEntry(string hashid, string key)
{
return base.iClient.HashContainsEntry(hashid, key);
}
/// <summary>
/// 给hashid数据集key的value加countby,返回相加后的数据
/// </summary>
public double IncrementValueInHash(string hashid, string key, double countBy)
{
return base.iClient.IncrementValueInHash(hashid, key, countBy);
}
#endregion
}

使用

Console.WriteLine("*****************************************");
{
using (RedisHashService service = new RedisHashService())
{
service.SetEntryInHash("student", "id", "123456");
service.SetEntryInHash("student", "name", "张xx");
service.SetEntryInHash("student", "remark", "高级班的学员"); var keys = service.GetHashKeys("student");
var values = service.GetHashValues("student");
var keyValues = service.GetAllEntriesFromHash("student");
Console.WriteLine(service.GetValueFromHash("student", "id")); service.SetEntryInHashIfNotExists("student", "name", "太子爷");
service.SetEntryInHashIfNotExists("student", "description", "高级班的学员2"); Console.WriteLine(service.GetValueFromHash("student", "name"));
Console.WriteLine(service.GetValueFromHash("student", "description"));
service.RemoveEntryFromHash("student", "description");
Console.WriteLine(service.GetValueFromHash("student", "description"));
}
}

Set

redis 的Set类型操作类

 /// <summary>
/// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据
/// 1.共同好友、二度好友
/// 2.利用唯一性,可以统计访问网站的所有独立 IP
/// </summary>
public class RedisSetService : RedisBase
{
#region 添加
/// <summary>
/// key集合中添加value值
/// </summary>
public void Add(string key, string value)
{
base.iClient.AddItemToSet(key, value);
}
/// <summary>
/// key集合中添加list集合
/// </summary>
public void Add(string key, List<string> list)
{
base.iClient.AddRangeToSet(key, list); }
#endregion #region 获取
/// <summary>
/// 随机获取key集合中的一个值
/// </summary>
public string GetRandomItemFromSet(string key)
{
return base.iClient.GetRandomItemFromSet(key);
}
/// <summary>
/// 获取key集合值的数量
/// </summary>
public long GetCount(string key)
{
return base.iClient.GetSetCount(key);
}
/// <summary>
/// 获取所有key集合的值
/// </summary>
public HashSet<string> GetAllItemsFromSet(string key)
{
return base.iClient.GetAllItemsFromSet(key);
}
#endregion #region 删除
/// <summary>
/// 随机删除key集合中的一个值
/// </summary>
public string RandomRemoveItemFromSet(string key)
{
return base.iClient.PopItemFromSet(key);
}
/// <summary>
/// 删除key集合中的value
/// </summary>
public void RemoveItemFromSet(string key, string value)
{
base.iClient.RemoveItemFromSet(key, value);
}
#endregion #region 其它
/// <summary>
/// 从fromkey集合中移除值为value的值,并把value添加到tokey集合中
/// </summary>
public void MoveBetweenSets(string fromkey, string tokey, string value)
{
base.iClient.MoveBetweenSets(fromkey, tokey, value);
}
/// <summary>
/// 返回keys多个集合中的并集,返还hashset
/// </summary>
public HashSet<string> GetUnionFromSets(params string[] keys)
{
return base.iClient.GetUnionFromSets(keys);
}
/// <summary>
/// 返回keys多个集合中的交集,返还hashset
/// </summary>
public HashSet<string> GetIntersectFromSets(params string[] keys)
{
return base.iClient.GetIntersectFromSets(keys);
}
/// <summary>
/// 返回keys多个集合中的差集,返还hashset
/// </summary>
/// <param name="fromKey">原集合</param>
/// <param name="keys">其他集合</param>
/// <returns>出现在原集合,但不包含在其他集合</returns>
public HashSet<string> GetDifferencesFromSet(string fromKey, params string[] keys)
{
return base.iClient.GetDifferencesFromSet(fromKey,keys);
}
/// <summary>
/// keys多个集合中的并集,放入newkey集合中
/// </summary>
public void StoreUnionFromSets(string newkey, string[] keys)
{
base.iClient.StoreUnionFromSets(newkey, keys);
}
/// <summary>
/// 把fromkey集合中的数据与keys集合中的数据对比,fromkey集合中不存在keys集合中,则把这些不存在的数据放入newkey集合中
/// </summary>
public void StoreDifferencesFromSet(string newkey, string fromkey, string[] keys)
{
base.iClient.StoreDifferencesFromSet(newkey, fromkey, keys);
}
#endregion
}

使用

  Console.WriteLine("*****************************************");
{
using (RedisSetService service = new RedisSetService())
{
service.FlushAll();//清理全部数据 service.Add("advanced", "111");
service.Add("advanced", "112");
service.Add("advanced", "114");
service.Add("advanced", "114");
service.Add("advanced", "115");
service.Add("advanced", "115");
service.Add("advanced", "113"); var result = service.GetAllItemsFromSet("advanced"); var random = service.GetRandomItemFromSet("advanced");//随机获取
service.GetCount("advanced");//独立的ip数
service.RemoveItemFromSet("advanced", "114"); {
service.Add("begin", "111");
service.Add("begin", "112");
service.Add("begin", "115"); service.Add("end", "111");
service.Add("end", "114");
service.Add("end", "113"); var result1 = service.GetIntersectFromSets("begin", "end");
var result2 = service.GetDifferencesFromSet("begin", "end");
var result3 = service.GetUnionFromSets("begin", "end");
//共同好友 共同关注
}
}
}

去重验证

删除Item验证

集合的交差并

ZSet

redis 的zset类型操作类

    /// <summary>
/// Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列
/// 1.带有权重的元素,比如一个游戏的用户得分排行榜
/// 2.比较复杂的数据结构,一般用到的场景不算太多
/// </summary>
public class RedisZSetService : RedisBase
{
#region 添加
/// <summary>
/// 添加key/value,默认分数是从1.多*10的9次方以此递增的,自带自增效果
/// </summary>
public bool Add(string key, string value)
{
return base.iClient.AddItemToSortedSet(key, value);
}
/// <summary>
/// 添加key/value,并设置value的分数
/// </summary>
public bool AddItemToSortedSet(string key, string value, double score)
{
return base.iClient.AddItemToSortedSet(key, value, score);
}
/// <summary>
/// 为key添加values集合,values集合中每个value的分数设置为score
/// </summary>
public bool AddRangeToSortedSet(string key, List<string> values, double score)
{
return base.iClient.AddRangeToSortedSet(key, values, score);
}
/// <summary>
/// 为key添加values集合,values集合中每个value的分数设置为score
/// </summary>
public bool AddRangeToSortedSet(string key, List<string> values, long score)
{
return base.iClient.AddRangeToSortedSet(key, values, score);
}
#endregion #region 获取
/// <summary>
/// 获取key的所有集合
/// </summary>
public List<string> GetAll(string key)
{
return base.iClient.GetAllItemsFromSortedSet(key);
}
/// <summary>
/// 获取key的所有集合,倒叙输出
/// </summary>
public List<string> GetAllDesc(string key)
{
return base.iClient.GetAllItemsFromSortedSetDesc(key);
}
/// <summary>
/// 获取集合,带分数
/// </summary>
public IDictionary<string, double> GetAllWithScoresFromSortedSet(string key)
{
return base.iClient.GetAllWithScoresFromSortedSet(key);
}
/// <summary>
/// 获取key为value的下标值
/// </summary>
public long GetItemIndexInSortedSet(string key, string value)
{
return base.iClient.GetItemIndexInSortedSet(key, value);
}
/// <summary>
/// 倒叙排列获取key为value的下标值
/// </summary>
public long GetItemIndexInSortedSetDesc(string key, string value)
{
return base.iClient.GetItemIndexInSortedSetDesc(key, value);
}
/// <summary>
/// 获取key为value的分数
/// </summary>
public double GetItemScoreInSortedSet(string key, string value)
{
return base.iClient.GetItemScoreInSortedSet(key, value);
}
/// <summary>
/// 获取key所有集合的数据总数
/// </summary>
public long GetSortedSetCount(string key)
{
return base.iClient.GetSortedSetCount(key);
}
/// <summary>
/// key集合数据从分数为fromscore到分数为toscore的数据总数
/// </summary>
public long GetSortedSetCount(string key, double fromScore, double toScore)
{
return base.iClient.GetSortedSetCount(key, fromScore, toScore);
}
/// <summary>
/// 获取key集合从高分到低分排序数据,分数从fromscore到分数为toscore的数据
/// </summary>
public List<string> GetRangeFromSortedSetByHighestScore(string key, double fromscore, double toscore)
{
return base.iClient.GetRangeFromSortedSetByHighestScore(key, fromscore, toscore);
}
/// <summary>
/// 获取key集合从低分到高分排序数据,分数从fromscore到分数为toscore的数据
/// </summary>
public List<string> GetRangeFromSortedSetByLowestScore(string key, double fromscore, double toscore)
{
return base.iClient.GetRangeFromSortedSetByLowestScore(key, fromscore, toscore);
}
/// <summary>
/// 获取key集合从高分到低分排序数据,分数从fromscore到分数为toscore的数据,带分数
/// </summary>
public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, double fromscore, double toscore)
{
return base.iClient.GetRangeWithScoresFromSortedSetByHighestScore(key, fromscore, toscore);
}
/// <summary>
/// 获取key集合从低分到高分排序数据,分数从fromscore到分数为toscore的数据,带分数
/// </summary>
public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, double fromscore, double toscore)
{
return base.iClient.GetRangeWithScoresFromSortedSetByLowestScore(key, fromscore, toscore);
}
/// <summary>
/// 获取key集合数据,下标从fromRank到分数为toRank的数据
/// </summary>
public List<string> GetRangeFromSortedSet(string key, int fromRank, int toRank)
{
return base.iClient.GetRangeFromSortedSet(key, fromRank, toRank);
}
/// <summary>
/// 获取key集合倒叙排列数据,下标从fromRank到分数为toRank的数据
/// </summary>
public List<string> GetRangeFromSortedSetDesc(string key, int fromRank, int toRank)
{
return base.iClient.GetRangeFromSortedSetDesc(key, fromRank, toRank);
}
/// <summary>
/// 获取key集合数据,下标从fromRank到分数为toRank的数据,带分数
/// </summary>
public IDictionary<string, double> GetRangeWithScoresFromSortedSet(string key, int fromRank, int toRank)
{
return base.iClient.GetRangeWithScoresFromSortedSet(key, fromRank, toRank);
}
/// <summary>
/// 获取key集合倒叙排列数据,下标从fromRank到分数为toRank的数据,带分数
/// </summary>
public IDictionary<string, double> GetRangeWithScoresFromSortedSetDesc(string key, int fromRank, int toRank)
{
return base.iClient.GetRangeWithScoresFromSortedSetDesc(key, fromRank, toRank);
}
#endregion #region 删除
/// <summary>
/// 删除key为value的数据
/// </summary>
public bool RemoveItemFromSortedSet(string key, string value)
{
return base.iClient.RemoveItemFromSortedSet(key, value);
}
/// <summary>
/// 删除下标从minRank到maxRank的key集合数据
/// </summary>
public long RemoveRangeFromSortedSet(string key, int minRank, int maxRank)
{
return base.iClient.RemoveRangeFromSortedSet(key, minRank, maxRank);
}
/// <summary>
/// 删除分数从fromscore到toscore的key集合数据
/// </summary>
public long RemoveRangeFromSortedSetByScore(string key, double fromscore, double toscore)
{
return base.iClient.RemoveRangeFromSortedSetByScore(key, fromscore, toscore);
}
/// <summary>
/// 删除key集合中分数最大的数据
/// </summary>
public string PopItemWithHighestScoreFromSortedSet(string key)
{
return base.iClient.PopItemWithHighestScoreFromSortedSet(key);
}
/// <summary>
/// 删除key集合中分数最小的数据
/// </summary>
public string PopItemWithLowestScoreFromSortedSet(string key)
{
return base.iClient.PopItemWithLowestScoreFromSortedSet(key);
}
#endregion #region 其它
/// <summary>
/// 判断key集合中是否存在value数据
/// </summary>
public bool SortedSetContainsItem(string key, string value)
{
return base.iClient.SortedSetContainsItem(key, value);
}
/// <summary>
/// 为key集合值为value的数据,分数加scoreby,返回相加后的分数
/// </summary>
public double IncrementItemInSortedSet(string key, string value, double scoreBy)
{
return base.iClient.IncrementItemInSortedSet(key, value, scoreBy);
}
/// <summary>
/// 获取keys多个集合的交集,并把交集添加的newkey集合中,返回交集数据的总数
/// </summary>
public long StoreIntersectFromSortedSets(string newkey, string[] keys)
{
return base.iClient.StoreIntersectFromSortedSets(newkey, keys);
}
/// <summary>
/// 获取keys多个集合的并集,并把并集数据添加到newkey集合中,返回并集数据的总数
/// </summary>
public long StoreUnionFromSortedSets(string newkey, string[] keys)
{
return base.iClient.StoreUnionFromSortedSets(newkey, keys);
}
#endregion
}

使用除了排序,其他与Set一样

 Console.WriteLine("*****************************************");
{
using (RedisZSetService service = new RedisZSetService())
{
service.FlushAll();//清理全部数据 service.Add("advanced", "1");
service.Add("advanced", "2");
service.Add("advanced", "5");
service.Add("advanced", "4");
service.Add("advanced", "7");
service.Add("advanced", "5");
service.Add("advanced", "9"); var result1 = service.GetAll("advanced");
var result2 = service.GetAllDesc("advanced"); service.AddItemToSortedSet("Sort", "BY", 123234);
service.AddItemToSortedSet("Sort", "走自己的路", 123);
service.AddItemToSortedSet("Sort", "redboy", 45);
service.AddItemToSortedSet("Sort", "大蛤蟆", 7567);
service.AddItemToSortedSet("Sort", "路人甲", 9879);
service.AddRangeToSortedSet("Sort", new List<string>() { "123", "花生", "加菲猫" }, 3232);
var result3 = service.GetAllWithScoresFromSortedSet("Sort"); //交叉并
}
}

排序值、及排序结果

场景(实时排行)

/// <summary>
/// 实时排行榜:刷个礼物
/// 维度很多,平台/房间/主播/日/周/月/年
/// A对B 刷个礼物,影响很多
/// 刷礼物只记录流水,不影响排行,凌晨24点跑任务更新
///
/// 实时排行榜
/// Redis-IncrementItemInSortedSet
/// 刷礼物时增加redis分数
/// 就可以实时获取最新的排行
/// (多个维度就是多个zSet,刷礼物的时候保存数据库并更新Redis)
/// </summary>
public class RankManager
{
private static List<string> UserList = new List<string>()
{
"Tenk","花生","Ray","阿莫西林","石昊","ywa"
};
public static void Show()
{
using (RedisZSetService service = new RedisZSetService())
{
service.FlushAll();//清理全部数据 Task.Run(() =>
{
while (true)
{
foreach (var user in UserList)
{
Thread.Sleep(10);
service.IncrementItemInSortedSet("陈一发儿", user, new Random().Next(1, 100));//表示在原来刷礼物的基础上增加礼物
}
Thread.Sleep(20 * 1000);
}
}); Task.Run(() =>
{
while (true)
{
Thread.Sleep(12 * 1000);
Console.WriteLine("**********当前排行************");
int i = 1; foreach (var item in service.GetAllWithScoresFromSortedSet("陈一发儿"))
{
Console.WriteLine($"第{i++}名 {item.Key} 分数{item.Value}");
}
//foreach (var item in service.GetAllDesc("陈一发儿"))
//{
// Console.WriteLine($"第{i++}名 {item}");
//}
}
}); Console.Read(); } }
}

List

redis 的List类型操作类

    /// <summary>
/// Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,
/// Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
/// </summary>
public class RedisListService : RedisBase
{
#region 赋值
/// <summary>
/// 从左侧向list中添加值
/// </summary>
public void LPush(string key, string value)
{
base.iClient.PushItemToList(key, value);
}
/// <summary>
/// 从左侧向list中添加值,并设置过期时间
/// </summary>
public void LPush(string key, string value, DateTime dt)
{ base.iClient.PushItemToList(key, value);
base.iClient.ExpireEntryAt(key, dt);
}
/// <summary>
/// 从左侧向list中添加值,设置过期时间
/// </summary>
public void LPush(string key, string value, TimeSpan sp)
{
base.iClient.PushItemToList(key, value);
base.iClient.ExpireEntryIn(key, sp);
}
/// <summary>
/// 从右侧向list中添加值
/// </summary>
public void RPush(string key, string value)
{
base.iClient.PrependItemToList(key, value);
}
/// <summary>
/// 从右侧向list中添加值,并设置过期时间
/// </summary>
public void RPush(string key, string value, DateTime dt)
{
base.iClient.PrependItemToList(key, value);
base.iClient.ExpireEntryAt(key, dt);
}
/// <summary>
/// 从右侧向list中添加值,并设置过期时间
/// </summary>
public void RPush(string key, string value, TimeSpan sp)
{
base.iClient.PrependItemToList(key, value);
base.iClient.ExpireEntryIn(key, sp);
}
/// <summary>
/// 添加key/value
/// </summary>
public void Add(string key, string value)
{
base.iClient.AddItemToList(key, value);
}
/// <summary>
/// 添加key/value ,并设置过期时间
/// </summary>
public void Add(string key, string value, DateTime dt)
{
base.iClient.AddItemToList(key, value);
base.iClient.ExpireEntryAt(key, dt);
}
/// <summary>
/// 添加key/value。并添加过期时间
/// </summary>
public void Add(string key, string value, TimeSpan sp)
{
base.iClient.AddItemToList(key, value);
base.iClient.ExpireEntryIn(key, sp);
}
/// <summary>
/// 为key添加多个值
/// </summary>
public void Add(string key, List<string> values)
{
base.iClient.AddRangeToList(key, values);
}
/// <summary>
/// 为key添加多个值,并设置过期时间
/// </summary>
public void Add(string key, List<string> values, DateTime dt)
{
base.iClient.AddRangeToList(key, values);
base.iClient.ExpireEntryAt(key, dt);
}
/// <summary>
/// 为key添加多个值,并设置过期时间
/// </summary>
public void Add(string key, List<string> values, TimeSpan sp)
{
base.iClient.AddRangeToList(key, values);
base.iClient.ExpireEntryIn(key, sp);
}
#endregion #region 获取值
/// <summary>
/// 获取list中key包含的数据数量
/// </summary>
public long Count(string key)
{
return base.iClient.GetListCount(key);
}
/// <summary>
/// 获取key包含的所有数据集合
/// </summary>
public List<string> Get(string key)
{
return base.iClient.GetAllItemsFromList(key);
}
/// <summary>
/// 获取key中下标为star到end的值集合
/// </summary>
public List<string> Get(string key, int star, int end)
{
return base.iClient.GetRangeFromList(key, star, end);
}
#endregion #region 阻塞命令
/// <summary>
/// 阻塞命令:从list为key的尾部移除一个值,并返回移除的值,阻塞时间为sp
/// </summary>
public string BlockingPopItemFromList(string key, TimeSpan? sp)
{
return base.iClient.BlockingPopItemFromList(key, sp);
}
/// <summary>
/// 阻塞命令:从多个list中尾部移除一个值,并返回移除的值&key,阻塞时间为sp
/// </summary>
public ItemRef BlockingPopItemFromLists(string[] keys, TimeSpan? sp)
{
return base.iClient.BlockingPopItemFromLists(keys, sp);
} /// <summary>
/// 阻塞命令:从list中keys的尾部移除一个值,并返回移除的值,阻塞时间为sp
/// </summary>
public string BlockingDequeueItemFromList(string key, TimeSpan? sp)
{
return base.iClient.BlockingDequeueItemFromList(key, sp);
} /// <summary>
/// 阻塞命令:从多个list中尾部移除一个值,并返回移除的值&key,阻塞时间为sp
/// </summary>
public ItemRef BlockingDequeueItemFromLists(string[] keys, TimeSpan? sp)
{
return base.iClient.BlockingDequeueItemFromLists(keys, sp);
} /// <summary>
/// 阻塞命令:从list中一个fromkey的尾部移除一个值,添加到另外一个tokey的头部,并返回移除的值,阻塞时间为sp
/// </summary>
public string BlockingPopAndPushItemBetweenLists(string fromkey, string tokey, TimeSpan? sp)
{
return base.iClient.BlockingPopAndPushItemBetweenLists(fromkey, tokey, sp);
}
#endregion #region 删除
/// <summary>
/// 从尾部移除数据,返回移除的数据
/// </summary>
public string PopItemFromList(string key)
{
var sa = base.iClient.CreateSubscription();
return base.iClient.PopItemFromList(key);
}
/// <summary>
/// 从尾部移除数据,返回移除的数据
/// </summary>
public string DequeueItemFromList(string key)
{
return base.iClient.DequeueItemFromList(key);
} /// <summary>
/// 移除list中,key/value,与参数相同的值,并返回移除的数量
/// </summary>
public long RemoveItemFromList(string key, string value)
{
return base.iClient.RemoveItemFromList(key, value);
}
/// <summary>
/// 从list的尾部移除一个数据,返回移除的数据
/// </summary>
public string RemoveEndFromList(string key)
{
return base.iClient.RemoveEndFromList(key);
}
/// <summary>
/// 从list的头部移除一个数据,返回移除的值
/// </summary>
public string RemoveStartFromList(string key)
{
return base.iClient.RemoveStartFromList(key);
}
#endregion #region 其它
/// <summary>
/// 从一个list的尾部移除一个数据,添加到另外一个list的头部,并返回移动的值
/// </summary>
public string PopAndPushItemBetweenLists(string fromKey, string toKey)
{
return base.iClient.PopAndPushItemBetweenLists(fromKey, toKey);
} public void TrimList(string key, int start, int end)
{
base.iClient.TrimList(key, start, end);
}
#endregion #region 发布订阅
public void Publish(string channel, string message)
{
base.iClient.PublishMessage(channel, message);
} public void Subscribe(string channel, Action<string, string, IRedisSubscription> actionOnMessage)
{
var subscription = base.iClient.CreateSubscription();
subscription.OnSubscribe = c =>
{
Console.WriteLine($"订阅频道{c}");
Console.WriteLine();
};
//取消订阅
subscription.OnUnSubscribe = c =>
{
Console.WriteLine($"取消订阅 {c}");
Console.WriteLine();
};
subscription.OnMessage += (c, s) =>
{
actionOnMessage(c, s, subscription);
};
Console.WriteLine($"开始启动监听 {channel}");
subscription.SubscribeToChannels(channel); //blocking
} public void UnSubscribeFromChannels(string channel)
{
var subscription = base.iClient.CreateSubscription();
subscription.UnSubscribeFromChannels(channel);
}
#endregion
}

 使用

              Console.WriteLine("*****************************************");
{
using (RedisListService service = new RedisListService())
{
service.FlushAll(); service.Add("article", "eleven1234");
service.Add("article", "kevin");
service.Add("article", "大叔");
service.Add("article", "C卡");
service.Add("article", "触不到的线");
service.Add("article", "程序错误"); var result1 = service.Get("article");
var result2 = service.Get("article", 0, 3); }

 后进先出(栈的效果)

                    service.FlushAll();

                    service.Add("article", "eleven1234");
service.Add("article", "kevin");
service.Add("article", "大叔");
service.Add("article", "C卡");
service.Add("article", "触不到的线");
service.Add("article", "程序错误"); for (int i = 0; i < 5; i++)
{
Console.WriteLine(service.PopItemFromList("article"));
var result1 = service.Get("article");
}

i=0 时

i=1时

i=2时

先进先出(队列的效果)

 // 队列:生产者消费者模型
service.FlushAll();
service.RPush("article", "eleven1234");
service.RPush("article", "kevin");
service.RPush("article", "大叔");
service.RPush("article", "C卡");
service.RPush("article", "触不到的线");
service.RPush("article", "程序错误"); for (int i = 0; i < 5; i++)
{
Console.WriteLine(service.PopItemFromList("article"));
var result1 = service.Get("article");
}
//分布式缓存,多服务器都可以访问到,多个生产者,多个消费者,任何产品只被消费一次

i=0时

i=1时

i=2时

生产者

 using (RedisListService service = new RedisListService())
{
List<string> stringList = new List<string>();
for (int i = 0; i < 10; i++)
{
stringList.Add(string.Format($"放入任务{i}"));
} service.Add("test", "这是一个学生Add1");
service.Add("test", "这是一个学生Add2");
service.Add("test", "这是一个学生Add3"); service.LPush("test", "这是一个学生LPush1");
service.LPush("test", "这是一个学生LPush2");
service.LPush("test", "这是一个学生LPush3");
service.LPush("test", "这是一个学生LPush4");
service.LPush("test", "这是一个学生LPush5");
service.LPush("test", "这是一个学生LPush6"); service.RPush("test", "这是一个学生RPush1");
service.RPush("test", "这是一个学生RPush2");
service.RPush("test", "这是一个学生RPush3");
service.RPush("test", "这是一个学生RPush4");
service.RPush("test", "这是一个学生RPush5");
service.RPush("test", "这是一个学生RPush6");
service.Add("task", stringList); Console.WriteLine(service.Count("test"));
Console.WriteLine(service.Count("task"));
var list = service.Get("test");
list = service.Get("task", 2, 4); Action act = new Action(() =>
{
while (true)
{
Console.WriteLine("************请输入数据**************");
string testTask = Console.ReadLine();
service.LPush("test", testTask);
}
});
act.EndInvoke(act.BeginInvoke(null, null));
}

消费者

    public class ServiceStackProcessor
{
public static void Show()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
string tag = path.Split('/', '\\').Last(s => !string.IsNullOrEmpty(s));
Console.WriteLine($"这里是 {tag} 启动了。。");
using (RedisListService service = new RedisListService())
{
Action act = new Action(() =>
{
while (true)
{
var result = service.BlockingPopItemFromLists(new string[] { "test", "task" }, TimeSpan.FromHours(3));
Thread.Sleep(100);
Console.WriteLine($"这里是 {tag} 队列获取的消息 {result.Id} {result.Item}");
}
});
act.EndInvoke(act.BeginInvoke(null, null));
}
} }

可以 一个生产者对应多个消费者,也可以一个消费者对应多个生产者,多对多也可以

下面是 一个生产者对应多个消费者的效果图

发布订阅

发布订阅:观察者,一个数据源,多个接受者,只要订阅了就可以收到的,能被多个数据源共享

      #region 发布订阅:观察者,一个数据源,多个接受者,只要订阅了就可以收到的,能被多个数据源共享
Task.Run(() =>
{
using (RedisListService service = new RedisListService())
{
//订阅频道
service.Subscribe("Eleven", (c, message, iRedisSubscription) =>
{
Console.WriteLine($"注册{1}{c}:{message},Dosomething else");
if (message.Equals("exit"))
iRedisSubscription.UnSubscribeFromChannels("Eleven");//取消订阅频道
});//blocking
}
});
Task.Run(() =>
{
using (RedisListService service = new RedisListService())
{
//订阅频道
service.Subscribe("Eleven", (c, message, iRedisSubscription) =>
{
Console.WriteLine($"注册{2}{c}:{message},Dosomething else");
if (message.Equals("exit"))
iRedisSubscription.UnSubscribeFromChannels("Eleven");//取消订阅频道
});//blocking
}
});
Task.Run(() =>
{
using (RedisListService service = new RedisListService())
{
//订阅频道
service.Subscribe("Twelve", (c, message, iRedisSubscription) =>
{
Console.WriteLine($"注册{3}{c}:{message},Dosomething else");
if (message.Equals("exit"))
iRedisSubscription.UnSubscribeFromChannels("Twelve");//取消订阅频道
});//blocking
}
});
using (RedisListService service = new RedisListService())
{
Thread.Sleep(1000);
//频道发布消息
service.Publish("Eleven", "Eleven123");
service.Publish("Eleven", "Eleven234");
service.Publish("Eleven", "Eleven345");
service.Publish("Eleven", "Eleven456");
//频道发布消息
service.Publish("Twelve", "Twelve123");
service.Publish("Twelve", "Twelve234");
service.Publish("Twelve", "Twelve345");
service.Publish("Twelve", "Twelve456");
Console.WriteLine("**********************************************");
//频道发布 封号退出消息
service.Publish("Eleven", "exit"); service.Publish("Eleven", "123Eleven");
service.Publish("Eleven", "234Eleven");
service.Publish("Eleven", "345Eleven");
service.Publish("Eleven", "456Eleven");
//频道发布 封号退出消息
service.Publish("Twelve", "exit");
service.Publish("Twelve", "123Twelve");
service.Publish("Twelve", "234Twelve");
service.Publish("Twelve", "345Twelve");
service.Publish("Twelve", "456Twelve");
}
#endregion

-----------------------------------------------------------------------------------------------------------------

StackExchange.Redis

下面额代码类均是通过 StackExchange.Redis 来对Redis进行各种操作

 Redis操作方法基础类

    /// <summary>
/// Redis操作方法基础类
/// </summary>
public abstract class RedisBase : IDisposable
{ #region 属性字段
/// <summary>
/// 网站Redis 系统自定义Key前缀
/// </summary>
protected string CustomKey = RedisManager.RedisSysCustomKey;
/// <summary>
/// 网站Redis 链接字符串
/// </summary>
protected readonly ConnectionMultiplexer _conn;
/// <summary>
/// Redis操作对象
/// </summary>
protected readonly IDatabase redis = null;
#endregion #region 构造函数
/// <summary>
/// 初始化Redis操作方法基础类
/// </summary>
/// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>
protected RedisBase(int? dbNum = null)
{
_conn = RedisManager.Instance;
if (_conn != null)
{
redis = _conn.GetDatabase(dbNum ?? RedisManager.RedisDataBaseIndex);
}
else
{
throw new ArgumentNullException("Redis连接初始化失败");
}
} private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
_conn.Dispose();
}
}
this._disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion 构造函数 #region 外部调用静态方法
/// <summary>
/// 获取Redis的String数据类型操作辅助方法类
/// </summary>
/// <returns></returns>
public static RedisStringService StringService => new RedisStringService();
/// <summary>
/// 获取Redis的Hash数据类型操作辅助方法类
/// </summary>
/// <returns></returns>
public static RedisHashService HashService => new RedisHashService();
/// <summary>
/// 获取Redis的List数据类型操作辅助方法类
/// </summary>
/// <returns></returns>
public static RedisListService ListService => new RedisListService();
/// <summary>
/// 获取Redis的Set无序集合数据类型操作辅助方法类
/// </summary>
/// <returns></returns>
public static RedisSetService SetService => new RedisSetService();
/// <summary>
/// 获取Redis的SortedSet(ZSet)有序集合数据类型操作辅助方法类
/// </summary>
/// <returns></returns>
public static RedisSortedSetService SortedSetService => new RedisSortedSetService(); #endregion #region 公共操作方法 #region 不建议公开这些方法,如果项目中用不到,建议注释或者删除
/// <summary>
/// 获取Redis事务对象
/// </summary>
/// <returns></returns>
public ITransaction CreateTransaction() => redis.CreateTransaction(); /// <summary>
/// 获取Redis服务和常用操作对象
/// </summary>
/// <returns></returns>
public IDatabase GetDatabase() => redis; /// <summary>
/// 获取Redis服务
/// </summary>
/// <param name="hostAndPort"></param>
/// <returns></returns>
public IServer GetServer(string hostAndPort) => _conn.GetServer(hostAndPort); /// <summary>
/// 执行Redis事务
/// </summary>
/// <param name="act"></param>
/// <returns></returns>
public bool RedisTransaction(Action<ITransaction> act)
{
var tran = redis.CreateTransaction();
act.Invoke(tran);
bool committed = tran.Execute();
return committed;
}
/// <summary>
/// Redis锁
/// </summary>
/// <param name="act"></param>
/// <param name="ts">锁住时间</param>
public void RedisLockTake(Action act, TimeSpan ts)
{
RedisValue token = Environment.MachineName;
string lockKey = "lock_LockTake";
if (redis.LockTake(lockKey, token, ts))
{
try
{
act();
}
finally
{
redis.LockRelease(lockKey, token);
}
}
}
#endregion 其他 #region 常用Key操作
/// <summary>
/// 设置前缀
/// </summary>
/// <param name="customKey"></param>
public void SetSysCustomKey(string customKey) => CustomKey = customKey; /// <summary>
/// 组合缓存Key名称
/// </summary>
/// <param name="oldKey"></param>
/// <returns></returns>
public string AddSysCustomKey(string oldKey) => $"{CustomKey}_{oldKey}"; #region 同步方法 /// <summary>
/// 删除单个key
/// </summary>
/// <param name="key">要删除的key</param>
/// <returns>是否删除成功</returns>
public bool KeyDelete(string key)
{
key = AddSysCustomKey(key);
return redis.KeyDelete(key);
} /// <summary>
/// 删除多个key
/// </summary>
/// <param name="keys">要删除的key集合</param>
/// <returns>成功删除的个数</returns>
public long KeyDelete(params string[] keys)
{
RedisKey[] newKeys = keys.Select(o => (RedisKey)AddSysCustomKey(o)).ToArray();
return redis.KeyDelete(newKeys);
} /// <summary>
/// 清空当前DataBase中所有Key
/// </summary>
public void KeyFulsh()
{
//直接执行清除命令
redis.Execute("FLUSHDB");
} /// <summary>
/// 判断key是否存在
/// </summary>
/// <param name="key">要判断的key</param>
/// <returns></returns>
public bool KeyExists(string key)
{
key = AddSysCustomKey(key);
return redis.KeyExists(key);
} /// <summary>
/// 重新命名key
/// </summary>
/// <param name="key">就的redis key</param>
/// <param name="newKey">新的redis key</param>
/// <returns></returns>
public bool KeyRename(string key, string newKey)
{
key = AddSysCustomKey(key);
newKey = AddSysCustomKey(newKey);
return redis.KeyRename(key, newKey);
} /// <summary>
/// 设置Key的过期时间
/// </summary>
/// <param name="key">redis key</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?))
{
key = AddSysCustomKey(key);
return redis.KeyExpire(key, expiry);
} #endregion #region 异步方法 /// <summary>
/// 删除单个key
/// </summary>
/// <param name="key">要删除的key</param>
/// <returns>是否删除成功</returns>
public async Task<bool> KeyDeleteAsync(string key)
{
key = AddSysCustomKey(key);
return await redis.KeyDeleteAsync(key);
} /// <summary>
/// 删除多个key
/// </summary>
/// <param name="keys">要删除的key集合</param>
/// <returns>成功删除的个数</returns>
public async Task<long> KeyDeleteAsync(params string[] keys)
{
RedisKey[] newKeys = keys.Select(o => (RedisKey)AddSysCustomKey(o)).ToArray();
return await redis.KeyDeleteAsync(newKeys);
} /// <summary>
/// 清空当前DataBase中所有Key
/// </summary>
public async Task KeyFulshAsync()
{
//直接执行清除命令
await redis.ExecuteAsync("FLUSHDB");
} /// <summary>
/// 判断key是否存在
/// </summary>
/// <param name="key">要判断的key</param>
/// <returns></returns>
public async Task<bool> KeyExistsAsync(string key)
{
key = AddSysCustomKey(key);
return await redis.KeyExistsAsync(key);
} /// <summary>
/// 重新命名key
/// </summary>
/// <param name="key">就的redis key</param>
/// <param name="newKey">新的redis key</param>
/// <returns></returns>
public async Task<bool> KeyRenameAsync(string key, string newKey)
{
key = AddSysCustomKey(key);
newKey = AddSysCustomKey(newKey);
return await redis.KeyRenameAsync(key, newKey);
} /// <summary>
/// 设置Key的过期时间
/// </summary>
/// <param name="key">redis key</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry = default(TimeSpan?))
{
key = AddSysCustomKey(key);
return await redis.KeyExpireAsync(key, expiry);
}
#endregion #endregion #endregion #region 辅助方法 /// <summary>
/// 将对象转换成string字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
protected string ConvertJson<T>(T value)
{
string result = value is string ? value.ToString() :
JsonConvert.SerializeObject(value, Formatting.None);
return result;
}
/// <summary>
/// 将值反系列化成对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
protected T ConvertObj<T>(RedisValue value)
{
return value.IsNullOrEmpty ? default(T) : JsonConvert.DeserializeObject<T>(value);
} /// <summary>
/// 将值反系列化成对象集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="values"></param>
/// <returns></returns>
protected List<T> ConvetList<T>(RedisValue[] values)
{
List<T> result = new List<T>();
foreach (var item in values)
{
var model = ConvertObj<T>(item);
result.Add(model);
}
return result;
}
/// <summary>
/// 将string类型的Key转换成 <see cref="RedisKey"/> 型的Key
/// </summary>
/// <param name="redisKeys"></param>
/// <returns></returns>
protected RedisKey[] ConvertRedisKeys(List<string> redisKeys) => redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); /// <summary>
/// 将string类型的Key转换成 <see cref="RedisKey"/> 型的Key
/// </summary>
/// <param name="redisKeys"></param>
/// <returns></returns>
protected RedisKey[] ConvertRedisKeys(params string[] redisKeys) => redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); /// <summary>
/// 将string类型的Key转换成 <see cref="RedisKey"/> 型的Key,并添加前缀字符串
/// </summary>
/// <param name="redisKeys"></param>
/// <returns></returns>
protected RedisKey[] ConvertRedisKeysAddSysCustomKey(params string[] redisKeys) => redisKeys.Select(redisKey => (RedisKey)AddSysCustomKey(redisKey)).ToArray();
/// <summary>
/// 将值集合转换成RedisValue集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisValues"></param>
/// <returns></returns>
protected RedisValue[] ConvertRedisValue<T>(params T[] redisValues) => redisValues.Select(o => (RedisValue)ConvertJson<T>(o)).ToArray();
#endregion 辅助方法 }

Redis基本信息初始化辅助类

    /// <summary>
/// Redis基本信息初始化辅助类
/// </summary>
internal class RedisManager
{
//private static LogHelper log = LogHelper.LogInterface<RedisManager>();
private static readonly object Locker = new object();
private static ConnectionMultiplexer _instance;
private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>();
/// <summary>
/// Redis保存的Key前缀,会自动添加到指定的Key名称前
/// </summary>
internal static readonly string RedisSysCustomKey = ConfigurationManager.AppSettings["RedisSysCustomKey"];
/// <summary>
/// 当前连接的Redis中的DataBase索引,默认0-16,可以在service.conf配置,最高64
/// </summary>
internal static readonly int RedisDataBaseIndex = int.Parse(ConfigurationManager.AppSettings["RedisDataBaseIndex"]);
/// <summary>
/// 当前连接的Redis中连接字符串,格式为:127.0.0.1:6379,allowadmin=true,passowrd=pwd
/// </summary>
internal static readonly string RedisHostConnection = ConfigurationManager.AppSettings["RedisHostConnection"]; /// <summary>
/// 单例获取
/// </summary>
public static ConnectionMultiplexer Instance
{
get
{
if (_instance == null)
{
lock (Locker)
{
if (_instance == null || !_instance.IsConnected)
{
_instance = GetManager();
}
}
}
return _instance;
}
} /// <summary>
/// 缓存获取
/// </summary>
/// <param name="connectionString"></param>
/// <returns></returns>
public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
{
if (!ConnectionCache.ContainsKey(connectionString))
{
ConnectionCache[connectionString] = GetManager(connectionString);
}
return ConnectionCache[connectionString];
} /// <summary>
/// 内部方法,获取Redis连接
/// </summary>
/// <param name="connectionString"></param>
/// <returns></returns>
private static ConnectionMultiplexer GetManager(string connectionString = null)
{
connectionString = connectionString ?? RedisHostConnection;
var connect = ConnectionMultiplexer.Connect(connectionString); //注册如下事件
connect.ConnectionFailed += MuxerConnectionFailed;
connect.ConnectionRestored += MuxerConnectionRestored;
connect.ErrorMessage += MuxerErrorMessage;
connect.ConfigurationChanged += MuxerConfigurationChanged;
connect.HashSlotMoved += MuxerHashSlotMoved;
connect.InternalError += MuxerInternalError; return connect;
} #region 事件 /// <summary>
/// 配置更改时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
{
//log.InfoAsync($"Configuration changed: {e.EndPoint}");
} /// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
{
//log.InfoAsync($"ErrorMessage: {e.Message}");
} /// <summary>
/// 重新建立连接之前的错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
//log.InfoAsync($"ConnectionRestored: {e.EndPoint}");
} /// <summary>
/// 连接失败 , 如果重新连接成功你将不会收到这个通知
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
//log.InfoAsync($"重新连接:Endpoint failed: {e.EndPoint}, {e.FailureType} , {(e.Exception == null ? "" : e.Exception.Message)}");
} /// <summary>
/// 更改集群
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
//log.InfoAsync($"HashSlotMoved:NewEndPoint{e.NewEndPoint}, OldEndPoint{e.OldEndPoint}");
} /// <summary>
/// redis类库错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
{
//log.InfoAsync($"InternalError:Message{ e.Exception.Message}");
} #endregion 事件
}

String

redis 的string类型操作类

 /// <summary>
/// key-value 键值对:value可以是序列化的数据
/// </summary>
public class RedisStringService : RedisBase
{
#region 构造函数 /// <summary>
/// 初始化Redis的String数据结构操作
/// </summary>
/// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>
public RedisStringService(int? dbNum = null) :
base(dbNum)
{ }
#endregion #region 同步方法
/// <summary>
/// 添加单个key value
/// </summary>
/// <param name="key">Redis Key</param>
/// <param name="value">保存的值</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?))
{
key = AddSysCustomKey(key);
return base.redis.StringSet(key, value, expiry);
} /// <summary>
/// 添加多个key/value
/// </summary>
/// <param name="valueList">key/value集合</param>
/// <returns></returns>
public bool StringSet(Dictionary<string, string> valueList)
{
var newkeyValues = valueList.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToArray();
return base.redis.StringSet(newkeyValues);
} /// <summary>
/// 保存一个对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="key">保存的Key名称</param>
/// <param name="value">对象实体</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public bool StringSet<T>(string key, T value, TimeSpan? expiry = default(TimeSpan?))
{
key = AddSysCustomKey(key);
string jsonValue = ConvertJson(value);
return base.redis.StringSet(key, jsonValue, expiry);
} /// <summary>
/// 在原有key的value值之后追加value
/// </summary>
/// <param name="key">追加的Key名称</param>
/// <param name="value">追加的值</param>
/// <returns></returns>
public long StringAppend(string key, string value)
{
key = AddSysCustomKey(key);
return base.redis.StringAppend(key, value);
} /// <summary>
/// 获取单个key的值
/// </summary>
/// <param name="key">要读取的Key名称</param>
/// <returns></returns>
public string StringGet(string key)
{
key = AddSysCustomKey(key);
return base.redis.StringGet(key);
} /// <summary>
/// 获取多个key的value值
/// </summary>
/// <param name="keys">要获取值的Key集合</param>
/// <returns></returns>
public List<string> StringGet(params string[] keys)
{
var newKeys = ConvertRedisKeysAddSysCustomKey(keys);
var values = base.redis.StringGet(newKeys);
return values.Select(o => o.ToString()).ToList();
} /// <summary>
/// 获取单个key的value值
/// </summary>
/// <typeparam name="T">返回数据类型</typeparam>
/// <param name="key">要获取值的Key集合</param>
/// <returns></returns>
public T StringGet<T>(string key)
{
key = AddSysCustomKey(key);
var values = base.redis.StringGet(key);
return ConvertObj<T>(values);
} /// <summary>
/// 获取多个key的value值
/// </summary>
/// <typeparam name="T">返回数据类型</typeparam>
/// <param name="keys">要获取值的Key集合</param>
/// <returns></returns>
public List<T> StringGet<T>(params string[] keys)
{
var newKeys = ConvertRedisKeysAddSysCustomKey(keys);
var values = base.redis.StringGet(newKeys);
return ConvetList<T>(values);
} /// <summary>
/// 获取旧值赋上新值
/// </summary>
/// <param name="key">Key名称</param>
/// <param name="value">新值</param>
/// <returns></returns>
public string StringGetSet(string key, string value)
{
key = AddSysCustomKey(key);
return base.redis.StringGetSet(key, value);
} /// <summary>
/// 获取旧值赋上新值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key">Key名称</param>
/// <param name="value">新值</param>
/// <returns></returns>
public T StringGetSet<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jsonValue = ConvertJson(value);
var oValue = base.redis.StringGetSet(key, jsonValue);
return ConvertObj<T>(oValue);
} /// <summary>
/// 获取值的长度
/// </summary>
/// <param name="key">Key名称</param>
/// <returns></returns>
public long StringGetLength(string key)
{
key = AddSysCustomKey(key);
return base.redis.StringLength(key);
} /// <summary>
/// 数字增长val,返回自增后的值
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负</param>
/// <returns>增长后的值</returns>
public double StringIncrement(string key, double val = 1)
{
key = AddSysCustomKey(key);
return base.redis.StringIncrement(key, val);
} /// <summary>
/// 数字减少val,返回自减少的值
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负</param>
/// <returns>减少后的值</returns>
public double StringDecrement(string key, double val = 1)
{
key = AddSysCustomKey(key);
return base.redis.StringDecrement(key, val);
} #endregion #region 异步方法
/// <summary>
/// 异步方法 保存单个key value
/// </summary>
/// <param name="key">Redis Key</param>
/// <param name="value">保存的值</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?))
{
key = AddSysCustomKey(key);
return await base.redis.StringSetAsync(key, value, expiry);
}
/// <summary>
/// 异步方法 添加多个key/value
/// </summary>
/// <param name="valueList">key/value集合</param>
/// <returns></returns>
public async Task<bool> StringSetAsync(Dictionary<string, string> valueList)
{
var newkeyValues = valueList.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToArray();
return await base.redis.StringSetAsync(newkeyValues);
} /// <summary>
/// 异步方法 保存一个对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="key">保存的Key名称</param>
/// <param name="obj">对象实体</param>
/// <param name="expiry">过期时间</param>
/// <returns></returns>
public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
{
key = AddSysCustomKey(key);
string jsonValue = ConvertJson(obj);
return await base.redis.StringSetAsync(key, jsonValue, expiry);
} /// <summary>
/// 异步方法 在原有key的value值之后追加value
/// </summary>
/// <param name="key">追加的Key名称</param>
/// <param name="value">追加的值</param>
/// <returns></returns>
public async Task<long> StringAppendAsync(string key, string value)
{
key = AddSysCustomKey(key);
return await base.redis.StringAppendAsync(key, value);
} /// <summary>
/// 异步方法 获取单个key的值
/// </summary>
/// <param name="key">要读取的Key名称</param>
/// <returns></returns>
public async Task<string> StringGetAsync(string key)
{
key = AddSysCustomKey(key);
return await base.redis.StringGetAsync(key);
} /// <summary>
/// 异步方法 获取多个key的value值
/// </summary>
/// <param name="keys">要获取值的Key集合</param>
/// <returns></returns>
public async Task<List<string>> StringGetAsync(params string[] keys)
{
var newKeys = ConvertRedisKeysAddSysCustomKey(keys);
var values = await base.redis.StringGetAsync(newKeys);
return values.Select(o => o.ToString()).ToList();
} /// <summary>
/// 异步方法 获取单个key的value值
/// </summary>
/// <typeparam name="T">返回数据类型</typeparam>
/// <param name="key">要获取值的Key集合</param>
/// <returns></returns>
public async Task<T> StringGetAsync<T>(string key)
{
key = AddSysCustomKey(key);
var values = await base.redis.StringGetAsync(key);
return ConvertObj<T>(values);
} /// <summary>
/// 异步方法 获取多个key的value值
/// </summary>
/// <typeparam name="T">返回数据类型</typeparam>
/// <param name="keys">要获取值的Key集合</param>
/// <returns></returns>
public async Task<List<T>> StringGetAsync<T>(params string[] keys)
{
var newKeys = ConvertRedisKeysAddSysCustomKey(keys);
var values = await base.redis.StringGetAsync(newKeys);
return ConvetList<T>(values);
} /// <summary>
/// 异步方法 获取旧值赋上新值
/// </summary>
/// <param name="key">Key名称</param>
/// <param name="value">新值</param>
/// <returns></returns>
public async Task<string> StringGetSetAsync(string key, string value)
{
key = AddSysCustomKey(key);
return await base.redis.StringGetSetAsync(key, value);
} /// <summary>
/// 异步方法 获取旧值赋上新值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key">Key名称</param>
/// <param name="value">新值</param>
/// <returns></returns>
public async Task<T> StringGetSetAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jsonValue = ConvertJson(value);
var oValue = await base.redis.StringGetSetAsync(key, jsonValue);
return ConvertObj<T>(oValue);
} /// <summary>
/// 异步方法 获取值的长度
/// </summary>
/// <param name="key">Key名称</param>
/// <returns></returns>
public async Task<long> StringGetLengthAsync(string key)
{
key = AddSysCustomKey(key);
return await base.redis.StringLengthAsync(key);
} /// <summary>
/// 异步方法 数字增长val,返回自增后的值
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负</param>
/// <returns>增长后的值</returns>
public async Task<double> StringIncrementAsync(string key, double val = 1)
{
key = AddSysCustomKey(key);
return await base.redis.StringIncrementAsync(key, val);
} /// <summary>
/// 异步方法 数字减少val,返回自减少的值
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负</param>
/// <returns>减少后的值</returns>
public async Task<double> StringDecrementAsync(string key, double val = 1)
{
key = AddSysCustomKey(key);
return await base.redis.StringDecrementAsync(key, val);
} #endregion
}

使用

 Console.WriteLine("*****************************************");
{
//key value 都是string 假如是个对象呢?序列化一下
//假如要修改某一个属性的值 读--反序列化--修改--序列化 memcached
using (RedisStringService service = new RedisStringService())
{
service.KeyFulsh();
service.StringSet("RedisStringService_key1", "RedisStringService_value1");
Console.WriteLine(service.StringGet("RedisStringService_key1"));
Console.WriteLine(service.StringGetSet("RedisStringService_key1", "RedisStringService_value2"));
Console.WriteLine(service.StringGet("RedisStringService_key1")); service.StringAppend("RedisStringService_key1", "Append");
Console.WriteLine(service.StringGet("RedisStringService_key1"));
service.StringSet("RedisStringService_key1", "RedisStringService_value", new TimeSpan(0, 0, 0, 5));
Console.WriteLine(service.StringGet("RedisStringService_key1"));
Thread.Sleep(5000);
Console.WriteLine(service.StringGet("RedisStringService_key1"));
}
}

Hashtable

redis 的Hash类型操作类

    /// <summary>
/// Hash:类似dictionary,通过索引快速定位到指定元素的,耗时均等,跟string的区别在于不用反序列化,直接修改某个字段
/// string的话要么是 001:序列化整个实体
/// 要么是 001_name: 001_pwd: 多个key-value
/// Hash的话,一个hashid-{key:value;key:value;key:value;}
/// 可以一次性查找实体,也可以单个,还可以单个修改
/// </summary>
public class RedisHashService : RedisBase
{ #region 构造函数 /// <summary>
/// 初始化Redis的Hash数据结构操作
/// </summary>
/// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>
public RedisHashService(int? dbNum = null) :
base(dbNum)
{ }
#endregion #region 同步方法 /// <summary>
/// 判断某个数据是否已经被缓存
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <returns></returns>
public bool HashExists(string key, string dataKey)
{
key = AddSysCustomKey(key);
return base.redis.HashExists(key, dataKey);
} /// <summary>
/// 存储数据到hash表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <param name="t"></param>
/// <returns></returns>
public bool HashSet<T>(string key, string dataKey, T t)
{
key = AddSysCustomKey(key);
string json = ConvertJson(t);
return base.redis.HashSet(key, dataKey, json);
} /// <summary>
/// 移除hash中的某值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <returns></returns>
public bool HashDelete(string key, string dataKey)
{
key = AddSysCustomKey(key);
return base.redis.HashDelete(key, dataKey);
} /// <summary>
/// 移除hash中的多个值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKeys"></param>
/// <returns></returns>
public long HashDelete(string key, params string[] dataKeys)
{
key = AddSysCustomKey(key);
var newValues = dataKeys.Select(o => (RedisValue)o).ToArray();
return base.redis.HashDelete(key, newValues);
} /// <summary>
/// 从hash表获取数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <returns></returns>
public T HashGet<T>(string key, string dataKey)
{
key = AddSysCustomKey(key);
string value = base.redis.HashGet(key, dataKey);
return ConvertObj<T>(value);
} /// <summary>
/// 数字增长val,返回自增后的值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <param name="val">可以为负</param>
/// <returns>增长后的值</returns>
public double HashIncrement(string key, string dataKey, double val = 1)
{
key = AddSysCustomKey(key);
return base.redis.HashIncrement(key, dataKey, val);
} /// <summary>
/// 数字减少val,返回自减少的值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <param name="val">可以为负</param>
/// <returns>减少后的值</returns>
public double HashDecrement(string key, string dataKey, double val = 1)
{
key = AddSysCustomKey(key);
return base.redis.HashDecrement(key, dataKey, val);
} /// <summary>
/// 获取hashkey所有key名称
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string[] HashKeys(string key)
{
key = AddSysCustomKey(key);
RedisValue[] values = base.redis.HashKeys(key);
return values.Select(o=>o.ToString()).ToArray();
} /// <summary>
/// 获取hashkey所有key与值,必须保证Key内的所有数据类型一致
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public Dictionary<string, T> HashGetAll<T>(string key)
{
key = AddSysCustomKey(key);
var query = base.redis.HashGetAll(key);
Dictionary<string, T> dic = new Dictionary<string, T>();
foreach (var item in query)
{
dic.Add(item.Name, ConvertObj<T>(item.Value));
}
return dic;
} #endregion 同步方法 #region 异步方法 /// <summary>
/// 异步方法 判断某个数据是否已经被缓存
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <returns></returns>
public async Task<bool> HashExistsAsync(string key, string dataKey)
{
key = AddSysCustomKey(key);
return await base.redis.HashExistsAsync(key, dataKey);
} /// <summary>
/// 异步方法 存储数据到hash表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <param name="t"></param>
/// <returns></returns>
public async Task<bool> HashSetAsync<T>(string key, string dataKey, T t)
{
key = AddSysCustomKey(key);
string json = ConvertJson(t);
return await base.redis.HashSetAsync(key, dataKey, json);
} /// <summary>
/// 异步方法 移除hash中的某值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <returns></returns>
public async Task<bool> HashDeleteAsync(string key, string dataKey)
{
key = AddSysCustomKey(key);
return await base.redis.HashDeleteAsync(key, dataKey);
} /// <summary>
/// 异步方法 移除hash中的多个值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKeys"></param>
/// <returns></returns>
public async Task<long> HashDeleteAsync(string key, params string[] dataKeys)
{
key = AddSysCustomKey(key);
var newValues = dataKeys.Select(o => (RedisValue)o).ToArray();
return await base.redis.HashDeleteAsync(key, newValues);
} /// <summary>
/// 异步方法 从hash表获取数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <returns></returns>
public async Task<T> HashGetAsync<T>(string key, string dataKey)
{
key = AddSysCustomKey(key);
string value = await base.redis.HashGetAsync(key, dataKey);
return ConvertObj<T>(value);
} /// <summary>
/// 异步方法 数字增长val,返回自增后的值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <param name="val">可以为负</param>
/// <returns>增长后的值</returns>
public async Task<double> HashIncrementAsync(string key, string dataKey, double val = 1)
{
key = AddSysCustomKey(key);
return await base.redis.HashIncrementAsync(key, dataKey, val);
} /// <summary>
/// 异步方法 数字减少val,返回自减少的值
/// </summary>
/// <param name="key"></param>
/// <param name="dataKey"></param>
/// <param name="val">可以为负</param>
/// <returns>减少后的值</returns>
public async Task<double> HashDecrementAsync(string key, string dataKey, double val = 1)
{
key = AddSysCustomKey(key);
return await base.redis.HashDecrementAsync(key, dataKey, val);
} /// <summary>
/// 异步方法 获取hashkey所有key名称
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<string[]> HashKeysAsync(string key)
{
key = AddSysCustomKey(key);
RedisValue[] values = await base.redis.HashKeysAsync(key);
return values.Select(o => o.ToString()).ToArray();
} /// <summary>
/// 获取hashkey所有key与值,必须保证Key内的所有数据类型一致
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<Dictionary<string, T>> HashGetAllAsync<T>(string key)
{
key = AddSysCustomKey(key);
var query = await base.redis.HashGetAllAsync(key);
Dictionary<string, T> dic = new Dictionary<string, T>();
foreach (var item in query)
{
dic.Add(item.Name, ConvertObj<T>(item.Value));
}
return dic;
} #endregion 异步方法 }

Set

redis 的Set类型操作类

    /// <summary>
/// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据
/// 1.共同好友、二度好友
/// 2.利用唯一性,可以统计访问网站的所有独立 IP
/// </summary>
public class RedisSetService : RedisBase
{
#region 构造函数 /// <summary>
/// 初始化Redis的Set无序数据结构操作
/// </summary>
/// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>
public RedisSetService(int? dbNum = null) :
base(dbNum)
{ }
#endregion #region 同步方法
/// <summary>
/// 在Key集合中添加一个value值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key">Key名称</param>
/// <param name="value">值</param>
/// <returns></returns>
public bool SetAdd<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return base.redis.SetAdd(key, jValue);
}
/// <summary>
/// 在Key集合中添加多个value值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key">Key名称</param>
/// <param name="value">值列表</param>
/// <returns></returns>
public long SetAdd<T>(string key, List<T> value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());
return base.redis.SetAdd(key, valueList);
} /// <summary>
/// 获取key集合值的数量
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public long SetLength(string key)
{
key = AddSysCustomKey(key);
return base.redis.SetLength(key);
} /// <summary>
/// 判断Key集合中是否包含指定的值
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="key"></param>
/// <param name="value">要判断是值</param>
/// <returns></returns>
public bool SetContains<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return base.redis.SetContains(key, jValue);
} /// <summary>
/// 随机获取key集合中的一个值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T SetRandomMember<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = base.redis.SetRandomMember(key);
return ConvertObj<T>(rValue);
} /// <summary>
/// 获取key所有值的集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public List<T> SetMembers<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = base.redis.SetMembers(key);
return ConvetList<T>(rValue);
} /// <summary>
/// 删除key集合中指定的value
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long SetRemove<T>(string key, params T[] value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value);
return base.redis.SetRemove(key, valueList);
} /// <summary>
/// 随机删除key集合中的一个值,并返回该值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T SetPop<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = base.redis.SetPop(key);
return ConvertObj<T>(rValue);
} /// <summary>
/// 获取几个集合的并集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public List<T> SetCombineUnion<T>(params string[] keys)
{
return _SetCombine<T>(SetOperation.Union, keys);
}
/// <summary>
/// 获取几个集合的交集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public List<T> SetCombineIntersect<T>(params string[] keys)
{
return _SetCombine<T>(SetOperation.Intersect, keys);
}
/// <summary>
/// 获取几个集合的差集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public List<T> SetCombineDifference<T>(params string[] keys)
{
return _SetCombine<T>(SetOperation.Difference, keys);
} /// <summary>
/// 获取几个集合的并集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public long SetCombineUnionAndStore(string destination, params string[] keys)
{
return _SetCombineAndStore(SetOperation.Union, destination, keys);
}
/// <summary>
/// 获取几个集合的交集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public long SetCombineIntersectAndStore(string destination, params string[] keys)
{
return _SetCombineAndStore(SetOperation.Intersect, destination, keys);
}
/// <summary>
/// 获取几个集合的差集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public long SetCombineDifferenceAndStore(string destination, params string[] keys)
{
return _SetCombineAndStore(SetOperation.Difference, destination, keys);
}
#endregion #region 异步方法
/// <summary>
/// 在Key集合中添加一个value值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key">Key名称</param>
/// <param name="value">值</param>
/// <returns></returns>
public async Task<bool> SetAddAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return await base.redis.SetAddAsync(key, jValue);
}
/// <summary>
/// 在Key集合中添加多个value值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key">Key名称</param>
/// <param name="value">值列表</param>
/// <returns></returns>
public async Task<long> SetAddAsync<T>(string key, List<T> value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());
return await base.redis.SetAddAsync(key, valueList);
} /// <summary>
/// 获取key集合值的数量
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<long> SetLengthAsync(string key)
{
key = AddSysCustomKey(key);
return await base.redis.SetLengthAsync(key);
} /// <summary>
/// 判断Key集合中是否包含指定的值
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="key"></param>
/// <param name="value">要判断是值</param>
/// <returns></returns>
public async Task<bool> SetContainsAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return await base.redis.SetContainsAsync(key, jValue);
} /// <summary>
/// 随机获取key集合中的一个值
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> SetRandomMemberAsync<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.SetRandomMemberAsync(key);
return ConvertObj<T>(rValue);
} /// <summary>
/// 获取key所有值的集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<List<T>> SetMembersAsync<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.SetMembersAsync(key);
return ConvetList<T>(rValue);
} /// <summary>
/// 删除key集合中指定的value
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> SetRemoveAsync<T>(string key, params T[] value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value);
return await base.redis.SetRemoveAsync(key, valueList);
} /// <summary>
/// 随机删除key集合中的一个值,并返回该值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> SetPopAsync<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.SetPopAsync(key);
return ConvertObj<T>(rValue);
} /// <summary>
/// 获取几个集合的并集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<List<T>> SetCombineUnionAsync<T>(params string[] keys)
{
return await _SetCombineAsync<T>(SetOperation.Union, keys);
}
/// <summary>
/// 获取几个集合的交集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<List<T>> SetCombineIntersectAsync<T>(params string[] keys)
{
return await _SetCombineAsync<T>(SetOperation.Intersect, keys);
}
/// <summary>
/// 获取几个集合的差集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<List<T>> SetCombineDifferenceAsync<T>(params string[] keys)
{
return await _SetCombineAsync<T>(SetOperation.Difference, keys);
} /// <summary>
/// 获取几个集合的并集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<long> SetCombineUnionAndStoreAsync(string destination, params string[] keys)
{
return await _SetCombineAndStoreAsync(SetOperation.Union, destination, keys);
}
/// <summary>
/// 获取几个集合的交集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<long> SetCombineIntersectAndStoreAsync(string destination, params string[] keys)
{
return await _SetCombineAndStoreAsync(SetOperation.Intersect, destination, keys);
}
/// <summary>
/// 获取几个集合的差集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<long> SetCombineDifferenceAndStoreAsync(string destination, params string[] keys)
{
return await _SetCombineAndStoreAsync(SetOperation.Difference, destination, keys);
} #endregion #region 内部辅助方法
/// <summary>
/// 获取几个集合的交叉并集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="operation">Union:并集 Intersect:交集 Difference:差集 详见 <see cref="SetOperation"/></param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
private List<T> _SetCombine<T>(SetOperation operation, params string[] keys)
{
RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);
var rValue = base.redis.SetCombine(operation, keyList);
return ConvetList<T>(rValue);
} /// <summary>
/// 获取几个集合的交叉并集合,并保存到一个新Key中
/// </summary>
/// <param name="operation">Union:并集 Intersect:交集 Difference:差集 详见 <see cref="SetOperation"/></param>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
private long _SetCombineAndStore(SetOperation operation, string destination, params string[] keys)
{
destination = AddSysCustomKey(destination);
RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);
return base.redis.SetCombineAndStore(operation, destination, keyList);
}
/// <summary>
/// 获取几个集合的交叉并集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="operation">Union:并集 Intersect:交集 Difference:差集 详见 <see cref="SetOperation"/></param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
private async Task<List<T>> _SetCombineAsync<T>(SetOperation operation, params string[] keys)
{
RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);
var rValue = await base.redis.SetCombineAsync(operation, keyList);
return ConvetList<T>(rValue);
}
/// <summary>
/// 获取几个集合的交叉并集合,并保存到一个新Key中
/// </summary>
/// <param name="operation">Union:并集 Intersect:交集 Difference:差集 详见 <see cref="SetOperation"/></param>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
private async Task<long> _SetCombineAndStoreAsync(SetOperation operation, string destination, params string[] keys)
{
destination = AddSysCustomKey(destination);
RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);
return await base.redis.SetCombineAndStoreAsync(operation, destination, keyList);
} #endregion }

ZSet

redis 的zset类型操作类

    /// <summary>
/// Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列
/// 1.带有权重的元素,比如一个游戏的用户得分排行榜
/// 2.比较复杂的数据结构,一般用到的场景不算太多
/// </summary>
public class RedisSortedSetService : RedisBase
{
#region 构造函数 /// <summary>
/// 初始化Redis的SortedSet有序数据结构操作
/// </summary>
/// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>
public RedisSortedSetService(int? dbNum = null) :
base(dbNum)
{ }
#endregion #region 同步方法 /// <summary>
/// 添加一个值到Key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="score">排序分数,为空将获取集合中最大score加1</param>
/// <returns></returns>
public bool SortedSetAdd<T>(string key, T value, double? score = null)
{
key = AddSysCustomKey(key);
double scoreNum = score ?? _GetScore(key);
return base.redis.SortedSetAdd(key, ConvertJson<T>(value), scoreNum);
} /// <summary>
/// 添加一个集合到Key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="score">排序分数,为空将获取集合中最大score加1</param>
/// <returns></returns>
public long SortedSetAdd<T>(string key, List<T> value, double? score = null)
{
key = AddSysCustomKey(key);
double scoreNum = score ?? _GetScore(key);
SortedSetEntry[] rValue = value.Select(o => new SortedSetEntry(ConvertJson<T>(o), scoreNum++)).ToArray();
return base.redis.SortedSetAdd(key, rValue);
} /// <summary>
/// 获取集合中的数量
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public long SortedSetLength(string key)
{
key = AddSysCustomKey(key);
return redis.SortedSetLength(key);
} /// <summary>
/// 获取指定起始值到结束值的集合数量
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="startValue">起始值</param>
/// <param name="endValue">结束值</param>
/// <returns></returns>
public long SortedSetLengthByValue<T>(string key, T startValue, T endValue)
{
key = AddSysCustomKey(key);
var sValue = ConvertJson<T>(startValue);
var eValue = ConvertJson<T>(endValue);
return redis.SortedSetLengthByValue(key, sValue, eValue);
} /// <summary>
/// 获取指定Key的排序Score值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public double? SortedSetScore<T>(string key, T value)
{
key = AddSysCustomKey(key);
var rValue = ConvertJson<T>(value);
return redis.SortedSetScore(key, rValue);
} /// <summary>
/// 获取指定Key中最小Score值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public double SortedSetMinScore(string key)
{
key = AddSysCustomKey(key);
double dValue = 0;
var rValue = base.redis.SortedSetRangeByRankWithScores(key, 0, 0, Order.Ascending).FirstOrDefault();
dValue = rValue != null ? rValue.Score : 0;
return dValue;
} /// <summary>
/// 获取指定Key中最大Score值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public double SortedSetMaxScore(string key)
{
key = AddSysCustomKey(key);
double dValue = 0;
var rValue = base.redis.SortedSetRangeByRankWithScores(key, 0, 0, Order.Descending).FirstOrDefault();
dValue = rValue != null ? rValue.Score : 0;
return dValue;
} /// <summary>
/// 删除Key中指定的值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public long SortedSetRemove<T>(string key, params T[] value)
{
key = AddSysCustomKey(key);
var rValue = ConvertRedisValue<T>(value);
return base.redis.SortedSetRemove(key, rValue);
} /// <summary>
/// 删除指定起始值到结束值的数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="startValue">起始值</param>
/// <param name="endValue">结束值</param>
/// <returns></returns>
public long SortedSetRemoveRangeByValue<T>(string key, T startValue, T endValue)
{
key = AddSysCustomKey(key);
var sValue = ConvertJson<T>(startValue);
var eValue = ConvertJson<T>(endValue);
return base.redis.SortedSetRemoveRangeByValue(key, sValue, eValue);
} /// <summary>
/// 删除 从 start 开始的 stop 条数据
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <returns></returns>
public long SortedSetRemoveRangeByRank(string key, long start, long stop)
{
key = AddSysCustomKey(key);
return base.redis.SortedSetRemoveRangeByRank(key, start, stop);
} /// <summary>
/// 根据排序分数Score,删除从 start 开始的 stop 条数据
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <returns></returns>
public long SortedSetRemoveRangeByScore(string key, double start, double stop)
{
key = AddSysCustomKey(key);
return base.redis.SortedSetRemoveRangeByScore(key, start, stop);
} /// <summary>
/// 获取从 start 开始的 stop 条数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public List<T> SortedSetRangeByRank<T>(string key, long start = 0, long stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = base.redis.SortedSetRangeByRank(key, start, stop, orderBy);
return ConvetList<T>(rValue);
} /// <summary>
/// 获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public Dictionary<T, double> SortedSetRangeByRankWithScores<T>(string key, long start = 0, long stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = base.redis.SortedSetRangeByRankWithScores(key, start, stop, orderBy);
Dictionary<T, double> dicList = new Dictionary<T, double>();
foreach (var item in rValue)
{
dicList.Add(ConvertObj<T>(item.Element), item.Score);
}
return dicList;
} /// <summary>
/// 根据Score排序 获取从 start 开始的 stop 条数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public List<T> SortedSetRangeByScore<T>(string key, double start = 0, double stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = base.redis.SortedSetRangeByScore(key, start, stop, Exclude.None, orderBy);
return ConvetList<T>(rValue);
} /// <summary>
/// 根据Score排序 获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public Dictionary<T, double> SortedSetRangeByScoreWithScores<T>(string key, double start = 0, double stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = base.redis.SortedSetRangeByScoreWithScores(key, start, stop, Exclude.None, orderBy);
Dictionary<T, double> dicList = new Dictionary<T, double>();
foreach (var item in rValue)
{
dicList.Add(ConvertObj<T>(item.Element), item.Score);
}
return dicList;
} /// <summary>
/// 获取指定起始值到结束值的数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="startValue">起始值</param>
/// <param name="endValue">结束值</param>
/// <returns></returns>
public List<T> SortedSetRangeByValue<T>(string key, T startValue, T endValue)
{
key = AddSysCustomKey(key);
var sValue = ConvertJson<T>(startValue);
var eValue = ConvertJson<T>(endValue);
var rValue = base.redis.SortedSetRangeByValue(key, sValue, eValue);
return ConvetList<T>(rValue);
} /// <summary>
/// 获取几个集合的并集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public long SortedSetCombineUnionAndStore(string destination, params string[] keys)
{
return _SortedSetCombineAndStore(SetOperation.Union, destination, keys);
} /// <summary>
/// 获取几个集合的交集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public long SortedSetCombineIntersectAndStore(string destination, params string[] keys)
{
return _SortedSetCombineAndStore(SetOperation.Intersect, destination, keys);
} //交集似乎并不支持
///// <summary>
///// 获取几个集合的差集,并保存到一个新Key中
///// </summary>
///// <param name="destination">保存的新Key名称</param>
///// <param name="keys">要操作的Key集合</param>
///// <returns></returns>
//public long SortedSetCombineDifferenceAndStore(string destination, params string[] keys)
//{
// return _SortedSetCombineAndStore(SetOperation.Difference, destination, keys);
//} /// <summary>
/// 修改指定Key和值的Scores在原值上减去scores,并返回最终Scores
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="scores"></param>
/// <returns></returns>
public double SortedSetDecrement<T>(string key, T value, double scores)
{
key = AddSysCustomKey(key);
var rValue = ConvertJson<T>(value);
return redis.SortedSetDecrement(key, rValue, scores);
} /// <summary>
/// 修改指定Key和值的Scores在原值上增加scores,并返回最终Scores
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="scores"></param>
/// <returns></returns>
public double SortedSetIncrement<T>(string key, T value, double scores)
{
key = AddSysCustomKey(key);
var rValue = ConvertJson<T>(value);
return redis.SortedSetIncrement(key, rValue, scores);
} #endregion #region 异步方法 /// <summary>
/// 添加一个值到Key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="score">排序分数,为空将获取集合中最大score加1</param>
/// <returns></returns>
public async Task<bool> SortedSetAddAsync<T>(string key, T value, double? score = null)
{
key = AddSysCustomKey(key);
double scoreNum = score ?? _GetScore(key);
return await base.redis.SortedSetAddAsync(key, ConvertJson<T>(value), scoreNum);
} /// <summary>
/// 添加一个集合到Key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="score">排序分数,为空将获取集合中最大score加1</param>
/// <returns></returns>
public async Task<long> SortedSetAddAsync<T>(string key, List<T> value, double? score = null)
{
key = AddSysCustomKey(key);
double scoreNum = score ?? _GetScore(key);
SortedSetEntry[] rValue = value.Select(o => new SortedSetEntry(ConvertJson<T>(o), scoreNum++)).ToArray();
return await base.redis.SortedSetAddAsync(key, rValue);
} /// <summary>
/// 获取集合中的数量
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<long> SortedSetLengthAsync(string key)
{
key = AddSysCustomKey(key);
return await redis.SortedSetLengthAsync(key);
} /// <summary>
/// 获取指定起始值到结束值的集合数量
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="startValue">起始值</param>
/// <param name="endValue">结束值</param>
/// <returns></returns>
public async Task<long> SortedSetLengthByValueAsync<T>(string key, T startValue, T endValue)
{
key = AddSysCustomKey(key);
var sValue = ConvertJson<T>(startValue);
var eValue = ConvertJson<T>(endValue);
return await redis.SortedSetLengthByValueAsync(key, sValue, eValue);
} /// <summary>
/// 获取指定Key的排序Score值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<double?> SortedSetScoreAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
var rValue = ConvertJson<T>(value);
return await redis.SortedSetScoreAsync(key, rValue);
} /// <summary>
/// 获取指定Key中最小Score值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<double> SortedSetMinScoreAsync(string key)
{
key = AddSysCustomKey(key);
double dValue = 0;
var rValue = (await base.redis.SortedSetRangeByRankWithScoresAsync(key, 0, 0, Order.Ascending)).FirstOrDefault();
dValue = rValue != null ? rValue.Score : 0;
return dValue;
} /// <summary>
/// 获取指定Key中最大Score值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<double> SortedSetMaxScoreAsync(string key)
{
key = AddSysCustomKey(key);
double dValue = 0;
var rValue = (await base.redis.SortedSetRangeByRankWithScoresAsync(key, 0, 0, Order.Descending)).FirstOrDefault();
dValue = rValue != null ? rValue.Score : 0;
return dValue;
} /// <summary>
/// 删除Key中指定的值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public async Task<long> SortedSetRemoveAsync<T>(string key, params T[] value)
{
key = AddSysCustomKey(key);
var rValue = ConvertRedisValue<T>(value);
return await base.redis.SortedSetRemoveAsync(key, rValue);
} /// <summary>
/// 删除指定起始值到结束值的数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="startValue">起始值</param>
/// <param name="endValue">结束值</param>
/// <returns></returns>
public async Task<long> SortedSetRemoveRangeByValueAsync<T>(string key, T startValue, T endValue)
{
key = AddSysCustomKey(key);
var sValue = ConvertJson<T>(startValue);
var eValue = ConvertJson<T>(endValue);
return await base.redis.SortedSetRemoveRangeByValueAsync(key, sValue, eValue);
} /// <summary>
/// 删除 从 start 开始的 stop 条数据
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <returns></returns>
public async Task<long> SortedSetRemoveRangeByRankAsync(string key, long start, long stop)
{
key = AddSysCustomKey(key);
return await base.redis.SortedSetRemoveRangeByRankAsync(key, start, stop);
} /// <summary>
/// 根据排序分数Score,删除从 start 开始的 stop 条数据
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <returns></returns>
public async Task<long> SortedSetRemoveRangeByScoreAsync(string key, double start, double stop)
{
key = AddSysCustomKey(key);
return await base.redis.SortedSetRemoveRangeByScoreAsync(key, start, stop);
} /// <summary>
/// 获取从 start 开始的 stop 条数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = await base.redis.SortedSetRangeByRankAsync(key, start, stop, orderBy);
return ConvetList<T>(rValue);
} /// <summary>
/// 获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public async Task<Dictionary<T, double>> SortedSetRangeByRankWithScoresAsync<T>(string key, long start = 0, long stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = await base.redis.SortedSetRangeByRankWithScoresAsync(key, start, stop, orderBy);
Dictionary<T, double> dicList = new Dictionary<T, double>();
foreach (var item in rValue)
{
dicList.Add(ConvertObj<T>(item.Element), item.Score);
}
return dicList;
} /// <summary>
/// 根据Score排序 获取从 start 开始的 stop 条数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public async Task<List<T>> SortedSetRangeByScoreAsync<T>(string key, double start = 0, double stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = await base.redis.SortedSetRangeByScoreAsync(key, start, stop, Exclude.None, orderBy);
return ConvetList<T>(rValue);
} /// <summary>
/// 根据Score排序 获取从 start 开始的 stop 条数据包含Score,返回数据格式:Key=值,Value = Score
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="start">起始数</param>
/// <param name="stop">-1表示到结束,0为1条</param>
/// <param name="desc">是否按降序排列</param>
/// <returns></returns>
public async Task<Dictionary<T, double>> SortedSetRangeByScoreWithScoresAsync<T>(string key, double start = 0, double stop = -1, bool desc = false)
{
key = AddSysCustomKey(key);
Order orderBy = desc ? Order.Descending : Order.Ascending;
var rValue = await base.redis.SortedSetRangeByScoreWithScoresAsync(key, start, stop, Exclude.None, orderBy);
Dictionary<T, double> dicList = new Dictionary<T, double>();
foreach (var item in rValue)
{
dicList.Add(ConvertObj<T>(item.Element), item.Score);
}
return dicList;
} /// <summary>
/// 获取指定起始值到结束值的数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="startValue">起始值</param>
/// <param name="endValue">结束值</param>
/// <returns></returns>
public async Task<List<T>> SortedSetRangeByValueAsync<T>(string key, T startValue, T endValue)
{
key = AddSysCustomKey(key);
var sValue = ConvertJson<T>(startValue);
var eValue = ConvertJson<T>(endValue);
var rValue = await base.redis.SortedSetRangeByValueAsync(key, sValue, eValue);
return ConvetList<T>(rValue);
} /// <summary>
/// 获取几个集合的并集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<long> SortedSetCombineUnionAndStoreAsync(string destination, params string[] keys)
{
return await _SortedSetCombineAndStoreAsync(SetOperation.Union, destination, keys);
} /// <summary>
/// 获取几个集合的交集,并保存到一个新Key中
/// </summary>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
public async Task<long> SortedSetCombineIntersectAndStoreAsync(string destination, params string[] keys)
{
return await _SortedSetCombineAndStoreAsync(SetOperation.Intersect, destination, keys);
} ///// <summary>
///// 获取几个集合的差集,并保存到一个新Key中
///// </summary>
///// <param name="destination">保存的新Key名称</param>
///// <param name="keys">要操作的Key集合</param>
///// <returns></returns>
//public async Task<long> SortedSetCombineDifferenceAndStoreAsync(string destination, params string[] keys)
//{
// return await _SortedSetCombineAndStoreAsync(SetOperation.Difference, destination, keys);
//} /// <summary>
/// 修改指定Key和值的Scores在原值上减去scores,并返回最终Scores
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="scores"></param>
/// <returns></returns>
public async Task<double> SortedSetDecrementAsync<T>(string key, T value, double scores)
{
key = AddSysCustomKey(key);
var rValue = ConvertJson<T>(value);
return await base.redis.SortedSetDecrementAsync(key, rValue, scores);
} /// <summary>
/// 修改指定Key和值的Scores在原值上增加scores,并返回最终Scores
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="scores"></param>
/// <returns></returns>
public async Task<double> SortedSetIncrementAsync<T>(string key, T value, double scores)
{
key = AddSysCustomKey(key);
var rValue = ConvertJson<T>(value);
return await base.redis.SortedSetIncrementAsync(key, rValue, scores);
} #endregion #region 内部辅助方法
/// <summary>
/// 获取指定Key中最大Score值,
/// </summary>
/// <param name="key">key名称,注意要先添加上Key前缀</param>
/// <returns></returns>
private double _GetScore(string key)
{
double dValue = 0;
var rValue = base.redis.SortedSetRangeByRankWithScores(key, 0, 0, Order.Descending).FirstOrDefault();
dValue = rValue != null ? rValue.Score : 0;
return dValue + 1;
} /// <summary>
/// 获取几个集合的交叉并集合,并保存到一个新Key中
/// </summary>
/// <param name="operation">Union:并集 Intersect:交集 Difference:差集 详见 <see cref="SetOperation"/></param>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
private long _SortedSetCombineAndStore(SetOperation operation, string destination, params string[] keys)
{
#region 查看源码,似乎并不支持Difference
//RedisCommand command;
//if (operation != SetOperation.Union)
//{
// if (operation != SetOperation.Intersect)
// {
// throw new ArgumentOutOfRangeException("operation");
// }
// command = RedisCommand.ZINTERSTORE;
//}
//else
//{
// command = RedisCommand.ZUNIONSTORE;
//}
#endregion destination = AddSysCustomKey(destination);
RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);
var rValue = base.redis.SortedSetCombineAndStore(operation, destination, keyList);
return rValue; } /// <summary>
/// 获取几个集合的交叉并集合,并保存到一个新Key中
/// </summary>
/// <param name="operation">Union:并集 Intersect:交集 Difference:差集 详见 <see cref="SetOperation"/></param>
/// <param name="destination">保存的新Key名称</param>
/// <param name="keys">要操作的Key集合</param>
/// <returns></returns>
private async Task<long> _SortedSetCombineAndStoreAsync(SetOperation operation, string destination, params string[] keys)
{
destination = AddSysCustomKey(destination);
RedisKey[] keyList = base.ConvertRedisKeysAddSysCustomKey(keys);
var rValue = await base.redis.SortedSetCombineAndStoreAsync(operation, destination, keyList);
return rValue;
} #endregion
}

List

redis 的List类型操作类

    /// <summary>
/// Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,
/// Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
/// 一般是左进右出或者右进左出
/// </summary>
public class RedisListService : RedisBase
{
#region 构造函数 /// <summary>
/// 初始化Redis的List数据结构操作
/// </summary>
/// <param name="dbNum">操作的数据库索引0-64(需要在conf文件中配置)</param>
public RedisListService(int? dbNum = null) :
base(dbNum)
{ }
#endregion #region 同步方法
/// <summary>
/// 从左侧向list中添加一个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListLeftPush<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return base.redis.ListLeftPush(key, jValue);
} /// <summary>
/// 从左侧向list中添加多个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListLeftPush<T>(string key, List<T> value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());
return base.redis.ListLeftPush(key, valueList);
} /// <summary>
/// 从右侧向list中添加一个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListRightPush<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return base.redis.ListRightPush(key, jValue);
} /// <summary>
/// 从右侧向list中添加多个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListRightPush<T>(string key, List<T> value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());
return base.redis.ListRightPush(key, valueList);
} /// <summary>
/// 从左侧向list中取出一个值并从list中删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T ListLeftPop<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = base.redis.ListLeftPop(key);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 从右侧向list中取出一个值并从list中删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T ListRightPop<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = base.redis.ListRightPop(key);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 从key的List中右侧取出一个值,并从左侧添加到destination集合中,且返回该数据对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">要取出数据的List名称</param>
/// <param name="destination">要添加到的List名称</param>
/// <returns></returns>
public T ListRightPopLeftPush<T>(string key, string destination)
{
key = AddSysCustomKey(key);
destination = AddSysCustomKey(destination);
var rValue = base.redis.ListRightPopLeftPush(key, destination);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 在key的List指定值pivot之后插入value,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="pivot">索引值</param>
/// <param name="value">要插入的值</param>
/// <returns></returns>
public long ListInsertAfter<T>(string key, T pivot, T value)
{
key = AddSysCustomKey(key);
string pValue = ConvertJson(pivot);
string jValue = ConvertJson(value);
return base.redis.ListInsertAfter(key, pValue, jValue);
} /// <summary>
/// 在key的List指定值pivot之前插入value,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="pivot">索引值</param>
/// <param name="value">要插入的值</param>
/// <returns></returns>
public long ListInsertBefore<T>(string key, T pivot, T value)
{
key = AddSysCustomKey(key);
string pValue = ConvertJson(pivot);
string jValue = ConvertJson(value);
return base.redis.ListInsertBefore(key, pValue, jValue);
} /// <summary>
/// 从key的list中取出所有数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public List<T> ListRange<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = base.redis.ListRange(key);
return base.ConvetList<T>(rValue);
} /// <summary>
/// 从key的List获取指定索引的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="index"></param>
/// <returns></returns>
public T ListGetByIndex<T>(string key, long index)
{
key = AddSysCustomKey(key);
var rValue = base.redis.ListGetByIndex(key, index);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 获取key的list中数据个数
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public long ListLength(string key)
{
key = AddSysCustomKey(key);
return base.redis.ListLength(key);
} /// <summary>
/// 从key的List中移除指定的值,返回删除个数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListRemove<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return base.redis.ListRemove(key, jValue);
}
#endregion #region 异步方法
/// <summary>
/// 从左侧向list中添加一个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListLeftPushAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return await base.redis.ListLeftPushAsync(key, jValue);
} /// <summary>
/// 从左侧向list中添加多个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListLeftPushAsync<T>(string key, List<T> value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());
return await base.redis.ListLeftPushAsync(key, valueList);
} /// <summary>
/// 从右侧向list中添加一个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListRightPushAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return await base.redis.ListRightPushAsync(key, jValue);
} /// <summary>
/// 从右侧向list中添加多个值,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListRightPushAsync<T>(string key, List<T> value)
{
key = AddSysCustomKey(key);
RedisValue[] valueList = base.ConvertRedisValue(value.ToArray());
return await base.redis.ListRightPushAsync(key, valueList);
} /// <summary>
/// 从左侧向list中取出一个值并从list中删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> ListLeftPopAsync<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.ListLeftPopAsync(key);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 从右侧向list中取出一个值并从list中删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> ListRightPopAsync<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.ListRightPopAsync(key);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 从key的List中右侧取出一个值,并从左侧添加到destination集合中,且返回该数据对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">要取出数据的List名称</param>
/// <param name="destination">要添加到的List名称</param>
/// <returns></returns>
public async Task<T> ListRightPopLeftPushAsync<T>(string key, string destination)
{
key = AddSysCustomKey(key);
destination = AddSysCustomKey(destination);
var rValue = await base.redis.ListRightPopLeftPushAsync(key, destination);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 在key的List指定值pivot之后插入value,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="pivot">索引值</param>
/// <param name="value">要插入的值</param>
/// <returns></returns>
public async Task<long> ListInsertAfterAsync<T>(string key, T pivot, T value)
{
key = AddSysCustomKey(key);
string pValue = ConvertJson(pivot);
string jValue = ConvertJson(value);
return await base.redis.ListInsertAfterAsync(key, pValue, jValue);
} /// <summary>
/// 在key的List指定值pivot之前插入value,返回集合总数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="pivot">索引值</param>
/// <param name="value">要插入的值</param>
/// <returns></returns>
public async Task<long> ListInsertBeforeAsync<T>(string key, T pivot, T value)
{
key = AddSysCustomKey(key);
string pValue = ConvertJson(pivot);
string jValue = ConvertJson(value);
return await base.redis.ListInsertBeforeAsync(key, pValue, jValue);
} /// <summary>
/// 从key的list中取出所有数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public async Task<List<T>> ListRangeAsync<T>(string key)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.ListRangeAsync(key);
return base.ConvetList<T>(rValue);
} /// <summary>
/// 从key的List获取指定索引的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="index"></param>
/// <returns></returns>
public async Task<T> ListGetByIndexAsync<T>(string key, long index)
{
key = AddSysCustomKey(key);
var rValue = await base.redis.ListGetByIndexAsync(key, index);
return base.ConvertObj<T>(rValue);
} /// <summary>
/// 获取key的list中数据个数
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<long> ListLengthAsync(string key)
{
key = AddSysCustomKey(key);
return await base.redis.ListLengthAsync(key);
} /// <summary>
/// 从key的List中移除指定的值,返回删除个数
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListRemoveAsync<T>(string key, T value)
{
key = AddSysCustomKey(key);
string jValue = ConvertJson(value);
return await base.redis.ListRemoveAsync(key, jValue);
}
#endregion
}

使用

 Console.WriteLine("*****************************************");
{
using (RedisListService service = new RedisListService())
{
service.KeyFulsh(); List<string> stringList = new List<string>();
for (int i = 0; i < 10; i++)
{
stringList.Add(string.Format($"放入任务{i}"));
} service.ListLeftPush("test", "这是一个学生1");
service.ListLeftPush("test", "这是一个学生2");
service.ListLeftPush("test", "这是一个学生3");
service.ListLeftPush("test", "这是一个学生4");
service.ListLeftPush("test", "这是一个学生5");
service.ListLeftPush("test", "这是一个学生6"); service.ListLeftPush("task", stringList); Console.WriteLine(service.ListLength("test"));
Console.WriteLine(service.ListLength("task"));
var list = service.ListRange<string>("test"); Action act = new Action(() =>
{
while (true)
{
Console.WriteLine("************请输入数据**************");
string testTask = Console.ReadLine();
service.ListLeftPush("test", testTask);
}
});
act.EndInvoke(act.BeginInvoke(null, null));
}
}

C# Redis的五大数据结构相关操作及应用场景的更多相关文章

  1. (一)REDIS之常见数据结构及操作

    (一)基本数据结构 1.1 String结构: String底层结构是动态字符串,可修改指定位置数据,通过预分配冗余空间减少内存的频繁分配,实际分配的空间capacity一般要高于实际字符串长度len ...

  2. 二:redis 的hash类型相关操作

    =====================二种:hash类型================== 介绍:redis -> hash是一个string类型的field和value的映射表 hash ...

  3. 三:redis的List类型相关操作

    </pre><pre name="code" class="php" style="font-size: 14px;"&g ...

  4. 一:redis 的string类型 - 相关操作

    *redisclient使用: =============一类:string的方法================ 介绍:string是redis的最简单类型,一个key相应一个value,strin ...

  5. 四:redis的sets类型 - 相关操作(有序和无序集合)

    ================四十五种(有序和无序集合):sets种类(它是一个集)=============      简介:  set它代表的集合.加入是随意添加----->无序集合    ...

  6. python redis的连接及相关操作

    1.redis连接.及存取值 import redis r = redis.Redis(host='192.168.2.22',port=6379,db=2,password= 'redis') r. ...

  7. redis 五大数据结构__常用命令

    linux 下下载redis数据库 apt install redis 如果提示权限不够的话, 直接提权: sudo apt install redis-server linux启用.停止服务 ser ...

  8. redis对sorted_set进行的相关操作

    redis对sorted_set(有序集合)类型操作的相关命令以及如何在python使用这些命令 redis对sorted_set(有序集合)类型操作的命令: 命令 语法 概述 返回值 Redis Z ...

  9. redis对list进行的相关操作

    redis对list类型进行的相关操作以及如何在python使用 redis对list类型操作的命令: 命令 语法 概述 返回值 Redis Blpop 命令 BLPOP key1 [key2 ] t ...

  10. redis对hash进行的相关操作

    redis对hash类型操作的相关命令以及如何在python使用这些命令 redis对hash类型操作的命令: 命令 语法 概述 返回值 Redis Hdel 命令 hdel key field [f ...

随机推荐

  1. 基于DotNetty实现自动发布 - 实现一键打包发布

    前言 上一篇,我只实现了一键检测代码变化,本篇才是真正的实现了一键打包发布 效果图 客户端打包待发布文件 /// <summary> /// 把多个文件添加到压缩包 (保留文件夹层级关系) ...

  2. [UOJ#748] [UNR#6 1B] 机器人表演

    在这个科技发达的年代,真人表演已经落伍了.参加完 UOI 后,hehe 蚤去到了下山市大剧院,观看下山市最火爆的机器人表演. 机器人有时比人类更能抓住事情的本质.所谓表演,其实也就是开场有若干个机器人 ...

  3. CICD实践1:环境安装篇

    一.CICD技术选型 配置管理工具 工具 需求管理工具 使用禅道 代码管理工具 使用Gitlab 编译构建工具 搭建Jenkins,使用Jenkinsfile 制品库工具 nexus 文档管理工具 C ...

  4. SpringBoot项目整合微信登录

    一.开通微信登录 去微信开发者平台 1.注册 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5.创建网站应用 6.提交审核,7个工作日审批 7.熟悉 ...

  5. CENTOS docker拉取私服镜像

    概述 docker的应用越来越多,安装部署越来越方便,批量自动化的镜像生成和发布都需要docker镜像的拉取. centos6版本太老,docker的使用过程中问题较多,centos7相对简单容易. ...

  6. CUDA驱动深度学习发展 - 技术全解与实战

    全面介绍CUDA与pytorch cuda实战 关注TechLead,分享AI全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云 ...

  7. Ubuntu20.04 安装shutter

    1 sudo add-apt-repository ppa:linuxuprising/shutter 2 3 sudo apt install shutter 4 5 卸载 6 sudo apt-g ...

  8. 【OpenVINO 】在 MacOS 上编译 OpenVINO C++ 项目

    前言 英特尔公司发行的模型部署工具OpenVINO模型部署套件,可以实现在不同系统环境下运行,且发布的OpenVINO 2023最新版目前已经支持MacOS系统并同时支持在苹果M系列芯片上部署模型.在 ...

  9. Asp .Net Core系列:AutoMapper自动映射框架介绍、使用

    1.介绍 AutoMapper是一个对象-对象映射器.对象-对象映射通过将一种类型的输入对象转换为另一种类型的输出对象来工作.使AutoMapper变得有趣的是,它提供了一些有趣的约定,以免去搞清楚如 ...

  10. 基于Llama2模型的开源模型

      2023年7月18日Meta开源了Llama2,在2万亿个Token上训练,可用于商业和研究,包括从7B到70B模型权重.预训练和微调的代码.相比Llama1,Llama2有较多提升,评估结果如下 ...