Redis Tool的开发历程

前言

基于git上的【RDM.dev GUI for Redis】工具总是崩溃和目前网络平台上比较流行的【HslRedisDesktop】在加载大批量数据时总是假性卡死(一般超过15000条数据需要缓冲10秒以上,数据量越多,时间越久,本人测试电脑的CPU是i5-9400,具体时间可能会根据电脑型号不一样而不一样)的情况下迫不得已自己动手使用核心库 StackExchange.Redis 开发一个在Windows电脑能使用并且扩展性强的【Redis Tool】。

该工具在界面上是基于【HslRedisDesktop】但是融合了【RDM.dev GUI for Redis】的风格,尽量做到工具更人性化。

在这感谢这两个工具的开发人员提供的帮助。

一、Redis数据库连接配置

Redis Tool的开发历程

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 Tool的开发历程

这个基础配置没有什么问题,知悉阅读官网上的资料,相信大家都会。

二、Redis核心库二次封装与使用

二次封装基本是基于redis数据库的连接, string、list、hash、set、zset的使用

1,RedisClient 封装

Redis Tool的开发历程

由于封装的代码太多,不宜全部展示,有兴趣的同学可以下载代码在 RedisClient 自行查看。

2,String使用界面

Redis Tool的开发历程

3,List使用界面

Redis Tool的开发历程

4,Hash使用界面

Redis Tool的开发历程

5,Set使用界面

Redis Tool的开发历程

6,Zset使用界面

Redis Tool的开发历程

以上界面的具体使用,大家都可以查看源码

三、使用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

Redis Tool的开发历程

 

 

上一篇:linux文件和目录权限rwxstST


下一篇:第五章 Linux系统中的权限管理