/*
* 由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 事件
}
}