/* * 由SharpDevelop创建。 * 用户: Administrator * 日期: 2018-09-14 * 时间: 15:16 * * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件 */ using System; using StackExchange.Redis; using System.Collections.Generic; using MrWu.Debug; using System.Linq; using GameData; using Server.Config; namespace Server.DB.Redis { /// /// 数据库类型 /// public enum DbStyle { /// /// 主库 /// main, /// /// 比赛 /// bisai } /// /// redis数据库管理 /// public class redisManager { /* redis 命令大全 * del key 删除键 * dump key 序列化key 返回序列化的值 * exists key 检查key是否存在 * exipire key seconds 设置过期的时间 * pexipire key milliseconds 设置过期时间毫秒 * keys keyspattem 查找给定格式的key * move key db 将key移动到给定数据库db中 * persist key 移除key的过期时间 * pttl key 返回剩余过期时间以毫秒计 * ttl key 返回剩余的过期时间以秒计 * randomkey 随机返回一个key * rename key newkey 修改key的名称 * renamenx key newkey 仅当newkey不存在时,将key改名为newkey * type key 返回key所存储的值类型 * * 字符串类型的命令 * set key value 设置key 字符串值 * get key 获取key的字符串值 * getrange key start end 获取key的字符串一段值 * getset key value 从新设置key的值 并返回原来的值 * getbit key offset ------ * strlen key 返回key存储的字符串长度 * mset key1 value1 key2 value2 设置一个或多个字符串的值 * msetnx key1 value1 key2 value2 设置一个活多个字符串的值不如果存在key则不设置 * setex key seconds value 将值value关联到key,并将key的过期时间设为seconds秒 * psetex key millseconds value 将value关联到key,并将key的过期时间设为milliseconds毫秒 * incr key 将key中存储的数字值增一 只能value是整数才能使用 并返回存储后的值 * incrby key increment 将key中存储的数字值增加increment 并返回存储后的值 * incrbyfloat key increment 将key中存储的数字值增加increment的浮点值 并返回存储后的值 存在误差 * decr key 将key中存储的数字减一 只有value是数字型的时候才能使用 并返回存储后的值 * decrby key decrement 将key中存储的数字值减少decrement 并返回存储后的值 * append key value 如果key已经存在并且是一个字符串 append 命令将指定的value追加到key原来的值的末尾 并返回追加后的字符串长度 * * hash类型的命令 * hmset key hashkey1 value1 hashkey2 vlaue2 将新的hash字段插入到hash表中 * hget key hashkey 获取hash中的key * hdel key hashkey1 hashkey2 删除一个或多个hash字段 * hexists key filed 查询哈希表中是否存在filed * hgetall key 获取在哈希表中指定的key的所有字段和值 * hincrby key field increment 为哈希表中key 的值增加1 * hincrbyfloat key field increment 为哈希表中key 的值浮点值增量 * hkeys key 获取所有的哈希表中key值 * hlen key 获取哈希表中字段的数量 * hmget key field1 field2 获取给定字段的值 * hset key field vlaue 如果hash表中存在key则 修改key的值 如果不存在则添加 * hsernx key filed value 只有在hash表中不存在field字段时才设置值 * hvals key 获取hash表中的所有值 * * List 列表类型命令 * lpush key value1 value2 将值插入到key列表中的头部 * blpop key key1 timeout 优先取key中的值如果key中有值返回第一个值 如果key中没有值取key1中的值 如果key1也没有值 则会等待timeout后超时 * brpop key key1 timeout 获取最后一个值 * brpoplpush source destination timeout 从source 中取出一个值并插入到destination 中 如果没有值知道timeout才停止 * lindex key index 通过索引获取表中的元素 * linsert key before value * lpop key 移出并获取列表中的第一个元素 * lpush key value1 value2 将值插入到已存在key列表中的头部 * lpushx key value 将一个值插入到已存在key表中的头部 * lrange key start end 获取列表中指定范围的内的元素 * lrem key count value count>0表示从头向尾搜索,移除value相等的元素 数量为count count<0表示从尾巴向头搜索,移除value相等的元素 数量为count的绝对值 count = 0 时移除列表中所有的value相等的元素 * lset key index value 设置列表index上的值 * ltrim key satrt stop 指定列表保留的元素区间,不在区间内的元素将会被删除 * rpop key 移除并获取列表中的最后一个元素\ * rpoplpush source destination 移除source中的最后一个元素并将该元素添加到destination表中 * rpush key value1 value2 将值插入到列表的尾部 * rpushx key value 向已存在的表中添加值 * * Set 集合命令 * sadd key menber1 menber2 向集合中添加一个或多个成员 * scard key 获取集合中的成员数量 * sdiff key key1 返回所有集合的差集 * sdiffstore destination key key1 返回给定所有集合的差集 并存储到destination 中 * sinter key key1 缩回所有集合的交集 * sindterstore destination key key1 返回所有集合的交集 并存储到destination中 * sismember key member 判断member元素是否是集合key的成员 * smemers key 返回集合中的所有成员 * smove source destination member 将member元素从source集合移动到destination集合中 * spop key 移除并返回集合中的一个随机元素 * srandmember key count 返回集合中的一个或多个随机元素 * serm key member member1 移除集合中的一个或多个成员 * sunion key key1 返回所有给定集合的并集 * sunionstore destination key1 key2 返回所有给定集合的并集并存储在destination集合中 * 迭代集合中的元素xxxx * * 有序集合 * zadd key score member1 socre1 member2 向有序集合添加一个或多个成员,或者更新已存在的成员的分数 * zcard key 获取有序集合的成员数量 * zcount key min max 计算在有序集合中指定区间分数的成员数 * zincrby key increment member 有序集合中对指定成员的分数加增量increment * ---zinterstore destination numkeys key key1 * --zlexcount key min max 在有序集合中计算指定字典区间内成员数量 * * * * * * */ /** * 通配符 * 表示任意一个或多个字符 * ? 表示任意字符 * [abc] 表示方括号中任意一个字母 * * */ private redisManager() { } /// /// 主redis 数据库连接 /// private static RedisConnectionHelp mainDBConnection; /// /// 比赛redis 数据库连接 /// private static RedisConnectionHelp bisaiDBConnection; private static volatile bool isStart = false; /// /// redis操作数据库代理_逻辑数据库处理 /// public static IDatabaseProxy db { get { if (isStart) { return new IDatabaseProxy(mainDBConnection.Instance.GetDatabase()); } return null; } } /// /// redis 操作数据库代理_逻辑数据库处理 /// /// /// public static IDatabaseProxy Getdb(int idx) { if (isStart) return new IDatabaseProxy(mainDBConnection.Instance.GetDatabase(idx)); return null; } /// /// 获取比赛数据库处理 /// /// /// public static IDatabaseProxy GetBiSaidb(int idx = -1) { if (isStart) return new IDatabaseProxy(bisaiDBConnection.Instance.GetDatabase(idx)); return null; } /// /// 获取数据库操作 /// /// public static IDatabase GetDataBase(DbStyle sty = DbStyle.main, int idx = -1) { ConnectionMultiplexer cm = null; switch (sty) { case DbStyle.main: cm = mainDBConnection.Instance; break; case DbStyle.bisai: cm = bisaiDBConnection.Instance; break; } if (cm == null) return null; return cm.GetDatabase(idx); } public static List Keys(string pattern, int dbidx, int pageSize = 1000, DbStyle sty = DbStyle.main) { if (!isStart) return null; ConnectionMultiplexer cm = null; switch (sty) { case DbStyle.main: cm = mainDBConnection.Instance; break; case DbStyle.bisai: cm = bisaiDBConnection.Instance; break; } if (cm == null) return null; List allkeys = new List(); try { var points = cm.GetEndPoints(); if (points.Length < 1) { Debug.Error("redis 没有任何连接!"); return null; } IServer server = cm.GetServer(points[0]); if (points.Length > 1) { ClusterConfiguration clusternodes = server.ClusterNodes(); foreach (var item in clusternodes.Nodes) { if (!item.IsSlave) { IServer temp = cm.GetServer(item.EndPoint); IEnumerable rks = temp.Keys(dbidx, pattern,pageSize); foreach (RedisKey rk in rks) { allkeys.Add(rk); } } } } else { var rks = server.Keys(dbidx, pattern, pageSize); foreach (var key in rks) { allkeys.Add(key); } } } catch (Exception e) { Debug.Error("查询错误asdsahdjk" + e.ToString()); return allkeys; } return allkeys; } /// /// 启动redis 服务器 /// /// 管理员模式 public static void Start(bool AllowAdmin = false) { for (int i = 0; i < RedisConfigCategory.Instance.DataList.Count; i++) { var item = RedisConfigCategory.Instance.DataList[i]; switch (item.Name) { case "main": mainDBConnection = new RedisConnectionHelp(); mainDBConnection.Start(item, AllowAdmin); break; case "bisai": bisaiDBConnection = new RedisConnectionHelp(); bisaiDBConnection.Start(item, AllowAdmin); break; } } isStart = true; } } /// /// ConnectionMultiplexer对象管理帮助类__单例换多例 /// public class RedisConnectionHelp { private readonly object Locker = new object(); private ConnectionMultiplexer _instance; /// /// 单例获取 /// public ConnectionMultiplexer Instance { get { if (_instance == null) { lock (Locker) { if (_instance == null || !_instance.IsConnected) { //Debug.Error("获取新的实例!!!!"); _instance = GetManager(); } } } return _instance; } } RedisConfig redisConfig; bool AllowAdmin; /// /// 启动redis /// /// /// public void Start(RedisConfig redisConfig_, bool AllowAdmin_ = false) { redisConfig = redisConfig_; AllowAdmin = AllowAdmin_; } private ConnectionMultiplexer GetManager(string connectionString = null) { ConfigurationOptions options = new ConfigurationOptions(); options.ConnectTimeout = redisConfig.ConnectTimeOut; options.AllowAdmin = AllowAdmin; options.AbortOnConnectFail = false; //true 表示连接失败将不会创建链接实例 options.ConnectRetry = 5; //失败尝试重新链接的次数 options.EndPoints.Add(redisConfig.Host, redisConfig.Port); ConnectionMultiplexer cml = ConnectionMultiplexer.Connect(options); //redisPool.TimeoutMilliseconds = 3000; cml.ConnectionFailed += MuxerConnectionFailed; cml.ConnectionRestored += MuxerConnectionRestored; cml.ErrorMessage += MuxerErrorMessage; cml.ConfigurationChanged += MuxerConfigurationChanged; cml.HashSlotMoved += MuxerHashSlotMoved; cml.InternalError += MuxerInternalError; return cml; } #region 事件 /// /// 配置更改时 /// /// /// private void MuxerConfigurationChanged(object sender, EndPointEventArgs e) { Debug.Fatal("Configuration changed: " + e.EndPoint); } /// /// 发生错误时 /// /// /// private void MuxerErrorMessage(object sender, RedisErrorEventArgs e) { Debug.Fatal("ErrorMessage: " + e.Message); } /// /// 重新建立连接之前的错误 /// /// /// private void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) { Debug.Fatal("ConnectionRestored: " + e.EndPoint); } /// /// 连接失败 , 如果重新连接成功你将不会收到这个通知 /// /// /// private void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e) { Debug.Fatal("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message))); } /// /// 更改集群 /// /// /// private void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e) { Debug.Fatal("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint); } /// /// redis类库错误 /// /// /// private void MuxerInternalError(object sender, InternalErrorEventArgs e) { Debug.Fatal("InternalError:Message" + e.Exception.Message); } #endregion 事件 } }