You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

427 lines
13 KiB

/*
作用: redis操作类
时间: 2023.06.09
作者: evangeyu
说明:
导出所有redis相关操作
使用约束:
1. 不允许大key,key命名包含唯一id: 数据库功能:类型:唯一id1 : 唯一id2:.... = 数据 如:AccountInfo:string:accountType:accountType = "xxx"
2. key禁止包含特殊字符,如空格、换行、单双引号以及其他转义字符
3. 如果是String类型,单个value大小控制10k以内
4. hash、list、set、zset类型,元素个数一般不超过5000
*/
using System;
using StackExchange.Redis;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sog
{
public class RedisDB
{
private string m_dbName;
private string m_ip;
private static ConfigurationOptions m_connectConfig = null;
private static ConnectionMultiplexer m_redisConn = null;
private IDatabase m_redisDB
{
get
{
return m_redisConn.GetDatabase();
}
}
public RedisDB(string dbname, string ip, string password)
{
m_ip = ip;
m_dbName = dbname;
m_connectConfig = ConfigurationOptions.Parse(string.Format("{0},password={1}", ip, password));
m_connectConfig.CommandMap = CommandMap.Create(new HashSet<string> { "SUBSCRIBE" }, false); // 禁用订阅功能
try
{
m_redisConn = ConnectionMultiplexer.Connect(m_connectConfig);
RegisterEvent();
}
catch (Exception ex)
{
TraceLog.Error("connect redis ip {0} error!", m_ip);
TraceLog.Exception(ex);
TraceLog.Error("Inner exception:");
TraceLog.Exception(ex.InnerException);
}
}
public void Dispose()
{
if (m_redisConn != null)
{
m_redisConn.Close(true);
m_redisConn.Dispose();
m_redisConn = null;
}
}
public TimeSpan Ping()
{
return m_redisDB.Ping();
}
public string CreateKey(string name, params string[] ids)
{
if (ids == null)
{
return string.Format("{0}:{1}", m_dbName, name);;
}
return string.Format("{0}:{1}:{2}", m_dbName, name, string.Join(":", ids));
}
//----------------------------------------- 序列化
public static string ConvertToStr<T>(T value)
{
return value is string ? value.ToString() : JsonConvert.SerializeObject(value);
}
public static T ConvertToObj<T>(string value)
{
if (string.IsNullOrEmpty(value))
{
return default(T);
}
else
{
return JsonConvert.DeserializeObject<T>(value);
}
}
private static List<T> ConvetList<T>(RedisValue[] values)
{
List<T> result = new List<T>();
foreach (var item in values)
{
var model = ConvertToObj<T>(item);
if (model != null)
result.Add(model);
}
return result;
}
//----------------------------------------- String
public bool StringSet<T>(string redisKey, T obj)
{
return m_redisDB.StringSet(redisKey, ConvertToStr(obj));
}
public T StringGet<T>(string redisKey)
{
return ConvertToObj<T>(m_redisDB.StringGet(redisKey));
}
public long StringIncrement(string redisKey)
{
return m_redisDB.StringIncrement(redisKey);
}
public async Task<bool> StringSetAsync<T>(string redisKey, T obj)
{
return await m_redisDB.StringSetAsync(redisKey, ConvertToStr(obj));
}
public async Task<T> StringGetAsync<T>(string redisKey)
{
return ConvertToObj<T>(await m_redisDB.StringGetAsync(redisKey));
}
//----------------------------------------- Hash
public void HashSetPart(string redisKey, IEnumerable<HashEntry> hashFields)
{
m_redisDB.HashSet(redisKey, hashFields.ToArray());
}
public RedisValue[] HashGetPart(string redisKey, RedisValue[] hashField)
{
return m_redisDB.HashGet(redisKey, hashField);
}
public bool HashSet<T>(string redisKey, string hashField, T value)
{
return m_redisDB.HashSet(redisKey, hashField, ConvertToStr(value));
}
public T HashGet<T>(string redisKey, string hashField)
{
return ConvertToObj<T>(m_redisDB.HashGet(redisKey, hashField));
}
public HashEntry[] HashGetAll(string redisKey)
{
return m_redisDB.HashGetAll(redisKey);
}
public async Task<T> HashGetAsync<T>(string redisKey, string hashField)
{
return ConvertToObj<T>(await m_redisDB.HashGetAsync(redisKey, hashField));
}
public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value)
{
return await m_redisDB.HashSetAsync(redisKey, hashField, ConvertToStr(value));
}
//----------------------------------------- List
public string ListLeftPop(string redisKey)
{
return m_redisDB.ListLeftPop(redisKey);
}
public string ListRightPop(string redisKey)
{
return m_redisDB.ListRightPop(redisKey);
}
public long ListRemove(string redisKey, string redisValue, long count = 0)
{
return m_redisDB.ListRemove(redisKey, redisValue, count);
}
public void ListTrim(string redisKey, long start, long stop)
{
m_redisDB.ListTrim(redisKey, start, stop);
}
public void ListMaxLen(string redisKey, long maxLen)
{
ListTrim(redisKey, 0, maxLen > 0 ? (maxLen - 1) : -1);
}
public long ListRightPush(string redisKey, string redisValue)
{
return m_redisDB.ListRightPush(redisKey, redisValue);
}
public long ListLeftPush(string redisKey, string redisValue)
{
return m_redisDB.ListLeftPush(redisKey, redisValue);
}
public long ListLength(string redisKey)
{
return m_redisDB.ListLength(redisKey);
}
public IEnumerable<RedisValue> ListRange(string redisKey, int startRow=0, int endRow=-1)
{
return m_redisDB.ListRange(redisKey, startRow, endRow);
}
public long ListRightPush<T>(string redisKey, T value)
{
return m_redisDB.ListRightPush(redisKey, ConvertToStr(value));
}
public long ListLeftPush<T>(string redisKey, T value)
{
return m_redisDB.ListLeftPush(redisKey, ConvertToStr(value));
}
public List<T> ListRange<T>(string redisKey, int startRow=0, int endRow=-1)
{
return ConvetList<T>(ListRange(redisKey, startRow, endRow).ToArray());
}
//----------------------------------------- Set
public bool SetAdd(string redisKey, string member)
{
return m_redisDB.SetAdd(redisKey, member);
}
public long SetAdd(string redisKey, RedisValue[] members)
{
return m_redisDB.SetAdd(redisKey, members);
}
public long SetLength(string redisKey)
{
return m_redisDB.SetLength(redisKey);
}
public bool SetRemove(string redisKey, string memebr)
{
return m_redisDB.SetRemove(redisKey, memebr);
}
public bool SetAdd<T>(string redisKey, T member)
{
return m_redisDB.SetAdd(redisKey, ConvertToStr(member));
}
public RedisValue[] SetMembers(string redisKey)
{
return m_redisDB.SetMembers(redisKey);
}
//----------------------------------------- SortedSet
public bool ZSetAdd(string redisKey, string member, double score)
{
return m_redisDB.SortedSetAdd(redisKey, member, score);
}
public IEnumerable<RedisValue> ZSetRangeByRank(string redisKey)
{
return m_redisDB.SortedSetRangeByRank(redisKey);
}
public long ZSetLength(string redisKey)
{
return m_redisDB.SortedSetLength(redisKey);
}
public bool ZSetRemove(string redisKey, string memebr)
{
return m_redisDB.SortedSetRemove(redisKey, memebr);
}
public bool ZSetAdd<T>(string redisKey, T member, double score)
{
return m_redisDB.SortedSetAdd(redisKey, ConvertToStr(member), score);
}
public IEnumerable<SortedSetEntry> ZSetScan(string redisKey, string pattern, int pageSize = 250, long cursor = 0, int pageOffset = 0)
{
return m_redisDB.SortedSetScan(redisKey, pattern, pageSize, cursor, pageOffset);
}
//----------------------------------------- 操作key
public bool KeyDelete(string redisKey)
{
return m_redisDB.KeyDelete(redisKey);
}
public long KeyDelete(IEnumerable<string> redisKeys)
{
var keys = redisKeys.Select(x => (RedisKey)x);
return m_redisDB.KeyDelete(keys.ToArray());
}
public bool KeyExists(string redisKey)
{
return m_redisDB.KeyExists(redisKey);
}
public bool KeyRename(string redisKey, string redisNewKey)
{
return m_redisDB.KeyRename(redisKey, redisNewKey);
}
public bool KeyExpire(string redisKey, TimeSpan? expiry)
{
return m_redisDB.KeyExpire(redisKey, expiry);
}
//----------------------------------------- keys scan
// 注意:这个底层可能使用了keys 和 scan两种命令
// pattern : 支持通配符 (*:任意字符;?:单个任意字符;[ab]:指定范围内的字符)
public IEnumerable<RedisKey> Keys(RedisValue _pattern = default)
{
var server = m_redisConn.GetServer(m_ip);
return server.Keys(pattern: _pattern);
}
// pattern : 支持通配符 (*:任意字符;?:单个任意字符;[ab]:指定范围内的字符)
public long Scan(ref IEnumerable<RedisKey> result, string _pattern, long cursor = 0, int count = 100)
{
var redisResults = (RedisResult[])m_redisDB.Execute("scan", cursor, "MATCH", _pattern, "COUNT", count);
result = (RedisKey[])redisResults[1];
return (long)redisResults[0];
}
//----------------------------------------- pipleline 批处理
public IBatch CreateBatch()
{
return m_redisDB.CreateBatch();
}
//----------------------------------------- redis相关事件
private static void RegisterEvent()
{
m_redisConn.ConfigurationChangedBroadcast += OnConfigurationChangedBroadcast;
m_redisConn.HashSlotMoved += OnHashSlotMoved;
m_redisConn.ConfigurationChanged += OnConfigurationChanged;
m_redisConn.ConnectionRestored += OnConnectionRestored;
m_redisConn.ConnectionFailed += OnConnectionFailed;
m_redisConn.ErrorMessage += OnErrorMessage;
m_redisConn.InternalError += OnInternalError;
}
// 重新配置广播-主从同步更改
private static void OnConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
{
TraceLog.Trace($"{nameof(OnConfigurationChangedBroadcast)}: {e.EndPoint}");
}
// 更改集群
private static void OnHashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
TraceLog.Error(
$"{nameof(OnHashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");
}
// 更改配置
private static void OnConfigurationChanged(object sender, EndPointEventArgs e)
{
TraceLog.Error($"{nameof(OnConfigurationChanged)}: {e.EndPoint}");
}
// 连接失败
private static void OnConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
TraceLog.Error($"{nameof(OnConnectionFailed)}: {e.Exception}");
}
// 重新连接
private static void OnConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
TraceLog.Error($"{nameof(OnConnectionRestored)}: {e.Exception}");
}
// 发生错误
private static void OnErrorMessage(object sender, RedisErrorEventArgs e)
{
TraceLog.Error($"{nameof(OnErrorMessage)}: {e.Message}");
}
// 内部错误
private static void OnInternalError(object sender, InternalErrorEventArgs e)
{
TraceLog.Error($"{nameof(OnInternalError)}: {e.Exception}");
}
}
}