有没有好的方法遍历redis里面的所有key

有没有好的方法遍历redis里面的所有key,第1张

这个就是官方内置命令(redis 的命令手册里面你的需求貌似只有这个命令了)。。性能方面的话,官方的警告(不知道你看了没。。)如果是很大的数据库(个人感觉应该是GB级别以上的数据库)就不要用这种。

key 是一个字符串,通过 key 获取 redis 中保存的数据,那么 key 通常存在以下的 *** 作

在本节,我们将介绍 key 的通用 *** 作

删除指定key

判定key是否存在

获取 key 的类型

为指定key设置有效期

获取key的有效时间

对于获取有效时间的指令,key 不存在返回 -2,key 存在但是没有关联超时时间返回 -1,如果key存在并且有关联时间,则返回具体的剩余时间秒或者毫秒。

切换key从实效性转为永久性

key可以使用正则表达式的方式进行查询,查询指令为

以下是常用的查询示例

将key改名

排序

对 list, set 或sorted set 中的元素进行排序输出,sort 指令功能比较多,在本文中我们暂且 指演示简单的用户

查看更多通用 *** 作

如果你是redis集群的话,在命令行输入 keys 只会返回其中一个redis实例上所有key,要想显示所有的key就要遍历每台实例,命令行中我不知道怎么做,但是代码中可以这么做:以JAVA为例:

public TreeSet<String> keys(String pattern) {

TreeSet<String> keys = new TreeSet<>();

// 遍历集群中每个节点,在每个节点实例上执行keys

Map<String, JedisPool> clusterNodes = jedisClustergetClusterNodes();

for (String k : clusterNodeskeySet()) {

JedisPool jp = clusterNodesget(k);

Jedis connection = jpgetResource();

try {

keysaddAll(connectionkeys(pattern));

} catch (Exception e) {

eprintStackTrace();

} finally {

connectionclose();

}

}

return keys;

}

通常指数据内存使用量非常大的数据,比如set里放了相当多的数据

ps:比如我们用set存储了单个用户的文章点赞数据,有个小伙伴天天无聊就在那给文章点赞,点了几百万,那set里就有了几百万数据,这个可能就是一个大key

业务方应尽量避免进行大key *** 作,如 hgetall 一次获取非常大的hash数据,用 hmset 一次设置非常多的value,用 lrange 一次取一个非常大的 list 或非常多的元素,如果客户端需要用到这些 *** 作对应的API,一次 *** 作的返回结果大小必须是在合理可控的范围内,防止导致节点通信超时、网络堵塞等严重后果。

40 以前 string,list,set,hash 不同数据类型的大 key,删除方式有所不同。一般有两种情况:del 命令删除单个很大的 key 和 del 批量删除 大 key。直接 del 命令粗暴的删大 key 容易造成 redis 线程阻塞。40 以前要优雅的删除就是针对不同的类型 写脚本,拆分链表,hash 表,分批删除。

在Redis集群中,每个节点都会保存槽信息,比如Redis集群默认有16384个槽,假设node0节点保存了0-4000槽数据,node1保存了4001-8000槽数据,node2 保存了80001-16383槽数据,则在每个节点中,都保存有当前节点处理哪些槽数据,哪些数据由其他节点处理,如node0保存了0-4000由node0处理,4001-8000由node1处理,80001-16383由node2处理。

当客户端请求过来。如果首先到达node0,当时这个key(假设计算出槽节点为10086)所在的槽并不在node0 节点上(假设node0通过自己保存结构查询出来处理key的节点为node1,地址为127001:7001),node0 会返回给客户端一个MOVED错误,结果类似如下

这样客户端就知道它应该去127001:7001再做请求

先如今我们想要自己搭建一套多redis节点/实例的集群,实现一套无主模型的集群

Redis 集群的数据分片

Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

我们先去到存放redi源码目录下,打开utils目录,会发现里面有个create-cluster文件夹,进入这个文件夹,会发现有如下两个文件:

我们先打开README文件看看里面是写了什么?

我们再来看看creat-cluster这个脚本文件里面装着什么药?

我们分析一下最前面的内容:

我们先把redis运行起来,执行以下指令后,会发现有启动了6个端口,代表着启动了6台redis

我们再这6台redis,进行搭建集群,“分赃”(是指分给每个master给一些槽位),执行以下指令后,会发现其中的30005跟随30001,其中的30006跟随30002,其中的30004跟随30003

我们看到,这个redis cluster为其中的3个master准备了一些槽位:

这个时候我们尝试连接其中一个master,随便哪个,我这里连接的是30001端口,然后做了一些 *** 作,你会发现下面的中,有两句指令是报错的,只有第一句指令是返回OK的,是什么原因呢?

redis-cli -p 30001

使用以下指令就可以重定向到对应映射值的端口上

我们尝试一下能不能使用事务,如下图,我们开启事务后,中间是有几次经过hash算法之后重定向到其他端口上面的,到最后我们执行exec之后报错。是因为我们在30001上开启的事务,由于hash值映射我们重定向到其他端口上了,其他端口并没有开启事务,所以报错!

我们可以将某些类似于相同hash值的key放在一块执行,这样就可以避免重定向,从而实现事务 *** 作

接下来我们换一种方式来进行实现redis cluster,用原始的命令来实现。我们先把启动的redis关掉,并把持久化文件删除,然后再启动

使用redis原生命令来启动,我们先查询help

输入指令原生指令,启动redis cluster,启动成功,和刚才的一模一样

我们再尝试连接客户端,进行一些 *** 作,和我们用脚本启动一模一样

解下来我们再了解一些reshard这个指令,给数据从新分片

输入指令后,redis会提示我们要移出多少个槽位,我们随便填个3000,然后回车

接下来,将接收方的节点id输入进去,目的是要把这3000个槽位移动给接收方

注意我们这里提示错误,原因是我们移动给了一个不是master的节点

我们给一个master的节点id重来一遍,接着要我们提供槽位来源,可以选一个或者多个槽位来源,比如我们要把3000个槽位移动给30002端口,我们可以从30001上移动也可以从30003上移动,我们直接在30001上移过来

输入yes回车

等待一会,我们看到3000个节点,从30001移动到30002端口上面了

我们可以查看槽位分布情况

原先是分布比较平均,都是5461个槽位,而我们从30001移动3000个到30002,发现原来的30001的只剩下2461个槽位的确少了3000个,并且30002的现在由8462个槽位多了3000个槽位!

种种现象我们看到,这完全就符合我们开头说的,用数据哈希槽的方式去分片数据,也就redis内部实现的预分区

以上就是关于有没有好的方法遍历redis里面的所有key全部的内容,包括:有没有好的方法遍历redis里面的所有key、redis中key的通用 *** 作、有没有人遇到过 redis keys 无法显示所有的key值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10122378.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存