前言
基于git上的【RDM.dev GUI for Redis】工具总是崩溃和目前网络平台上比较流行的【HslRedisDesktop】在加载大批量数据时总是假性卡死(一般超过15000条数据需要缓冲10秒以上,数据量越多,时间越久,本人测试电脑的CPU是i5-9400,具体时间可能会根据电脑型号不一样而不一样)的情况下迫不得已自己动手使用核心库 StackExchange.Redis 开发一个在Windows电脑能使用并且扩展性强的【Redis Tool】。
该工具在界面上是基于【HslRedisDesktop】但是融合了【RDM.dev GUI for Redis】的风格,尽量做到工具更人性化。
在这感谢这两个工具的开发人员提供的帮助。
一、Redis数据库连接配置
public OperateResult ConnectServer()
{
OperateResult operateResult = new OperateResult();
ConnectionString = string.Format(@"{0}:{1},synctimeout=15000,keepalive=60", ip, port);
_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
{
operateResult.IsSuccess = false;
}
else
{
operateResult.IsSuccess = true;
RegisterEvent();
}
return operateResult;
}
密码在程序里面默认为空,如果需要带密码,请参照
这个基础配置没有什么问题,知悉阅读官网上的资料,相信大家都会。
二、Redis核心库二次封装与使用
二次封装基本是基于redis数据库的连接, string、list、hash、set、zset的使用
1,RedisClient 封装
由于封装的代码太多,不宜全部展示,有兴趣的同学可以下载代码在 RedisClient 自行查看。
2,String使用界面
3,List使用界面
4,Hash使用界面
5,Set使用界面
6,Zset使用界面
以上界面的具体使用,大家都可以查看源码
三、使用LUA脚本
StackExchange.Redis提供了对LUA脚本的支持。通过 LuaScript
类可以获得更复杂的脚本。 LuaScript
类使得更容易准备和提交参数以及脚本,以及允许使用清理代码后变量名称。
如:StackExchange.Redis如果需要查询数据库中所有的键值,采用LUA脚本会是一个很好的方法,不然如果返回的数据量太大就可能导致服务器崩溃!!!
public OperateResult ReadAllKeys(string filter)
{
OperateResult<List<string>> operateResult = new OperateResult<List<string>>();
if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
{
operateResult.IsSuccess = false;
}
else
{
var result = (RedisResult[])_db.ScriptEvaluate(global, new { filter });
var values = new List<string>();
foreach (RedisValue point in result)
{
values.Add(point);
}
operateResult.Content = values;
operateResult.IsSuccess = true;
}
return operateResult;
}
--local为局部变量,没有local关键字,则视为全局变量
--redis.call是调用redis命令,下面使用了keys命令
--KEYS[1]为第1个参数,lua数组下标从1开始
local keys = redis.call('keys',@filter)
--下面通过mget获取所有key的值,call后面是可变长参数,unpack是将数组变成可变长参数
--local values = redis.call('mget', unpack(keys));
--定义返回结果
--local keyValuePairs = {}
--#keys是获取keys的长度,这里作了个for循环,将key与value对应起来
--lua中字符串拼接是用..
--for i = 1,#keys do
--keyValuePairs[i] = keys[i] .. '\t' .. values[i]
--keyValuePairs[i] = keys[i]
--end
--返回结果
--return keyValuePairs
return keys
四、TreeView的用法
由于Redis一般存储的数据量比较大,一次性把所有数据查询出来并且用递归的方法 绑定到TreeView上面,那肯定会导致界面卡死。一般这种情况有2种处理方式:
1,每次只查询自己关心的数据,使用Filter尽量减少查询的数据量,但是这种方式对于Redis大数据作用一般。
2,在采用第一种方式的基础上在结合TreeView的结构特点,首先只绑定TreeView的根结构,每次点击一层Node后只加载该层Node的子Node,而且也只加载一层。这样处理对于用户而言没有任何操作上的不适,又可解决TreeView的大数据加载问题。
private void AddTreeNode(TreeNode parent, RedisClient redisClient, string key, string infactKey)
{
int index = key.IndexOf(':');
if (index <= 0)
{
// 不存在冒号
TreeNode node = new TreeNode(infactKey);
node.Tag = infactKey;
// 读取类型 None = 0,String = 1,List = 2,Set = 3,SortedSet = 4,Hash = 5,Stream = 6,Unknown = 7
OperateResult<RedisType> type = (OperateResult<RedisType>)redisClient.ReadKeyType(infactKey);
switch (type.Content)
{
case RedisType.String:
node.ImageKey = "Enum_582";
node.SelectedImageKey = "Enum_582";
break;
case RedisType.List:
node.ImageKey = "brackets_Square_16xMD";
node.SelectedImageKey = "brackets_Square_16xMD";
break;
case RedisType.Hash:
node.ImageKey = "Table_748";
node.SelectedImageKey = "Table_748";
break;
case RedisType.Set:
node.ImageKey = "docview_xaml_on_16x16";
node.SelectedImageKey = "docview_xaml_on_16x16";
break;
case RedisType.SortedSet:
node.ImageKey = "zset";
node.SelectedImageKey = "zset";
break;
}
parent.Nodes.Add(node);
}
else
{
TreeNode parentNode = null;
for (int i = 0; i < parent.Nodes.Count; i++)
{
if (parent.Nodes[i].Text == key.Substring(0, index))
{
parentNode = parent.Nodes[i];
break;
}
}
if (parentNode == null)
{
parentNode = new TreeNode(key.Substring(0, index));
parentNode.ImageKey = "Class_489";
parentNode.SelectedImageKey = "Class_489";
parent.Nodes.Add(parentNode);
}
}
}
五、总结
时间有限,本次开发的持续时间也就是在3天左右,其中也遇到很多的坑。希望看过我博客和研究过我代码的同学都一一避过。
最后演示一下总体运行效果,有需要的同学可去下载。https://download.csdn.net/download/cao443647116/13640834