Redis中Hash结构数据分批获取 您所在的位置:网站首页 redis中的hash数据类型 Redis中Hash结构数据分批获取

Redis中Hash结构数据分批获取

2023-10-18 05:15| 来源: 网络整理| 查看: 265

分批获取Redis中 采用Hash结构存储的数据 写在前面

本文是想记录一下自己在工作之中,使用Redis的HASH来存储数据时,并全分批量获取时遇到的问题。这个问题其实也不应该算是一个问题,说到底也就是一个命令的事情。其实是因为自己才疏学浅,还没有及时观看官方文档,导致没有想到方案。所以在此记录一下自己的愚蠢以及获取到新知识的喜悦。

问题的由来

当时整个在设计的时候,就想着把大量的数据存入Redis,然后将数据库中查询到的数据,与Redis中的数据进行对比,相当于是取两个数据的交集。然后又不想让KEY泛滥成灾,加上当时的我只知道HASH 和 String 两种数据结构😂 所以就使用了HASH结构。可是突然有一天发现需要 全量获取所有数据。(嗯…幸好使用了HASH结构,不然这全量的数据,还获取不了了。果然多接触点东西不会错。)其实现在想想看,既然想要分页获取全量数据,并且还要判断需要的东西在不在里面,完全可以考虑用Set的。但是现在后悔不了了,已经有了历史数据,历史数据变换类型的割接会非常的麻烦,况且想要割接也得把原来存储的所有数据都得获取下来才能转移,所以归根结底还是需要遍历出原来HASH 中的全量数据。

问题描述

那问题就清楚了需要将Redis中的全量数据获取出来,但由于自己使用的是HASH结构存储了大量的数据,一个 KEY 下面大约有上百万的数据。但是此时由于业务需求,需要获取HASH中的全量数据。如果数量少的话,也就可以直接获取了,但是百万的数据真的不敢一下获取出来。所以就想能不能分页获取某个KEY下的所有HASH呢?

「今でもゎたはれたしの光」 “时至今日你仍然是我的光芒”—— 米津玄师 《lemon》

解决过程

可能是像我这种奇葩设计的人,真的太少了。我在搜索的时候,搜到的东西真的廖廖无几。有的说可以使用pipline有的说可以使用脚本 但是看了看好像都不太符合我的需要。终于~不知道找了多久,也忘记了换了什么关键字,终于我搜到了一个命令HSCAN。

看到这个命令宛如碰到了救星一般,开始疯狂搜索这个命令的博客。却忘记了应该去官网看一下这个命令(只怪自己太蠢,没有这个习惯。) 不过也确实搜到一些不错的,还是比较有帮助。但是还是建议去看官网教程。虽然这里也没写什么,都是使用帮助。

安装Redis-Cli客户端

那看到这里当然要先试用一下这个命令,所以需要使用Redis的客户端redis-cli 。MAC 安装redis-cil 可以看看这篇文章。但是需要使用brew命令。如果提示brew 不是内部命令,推荐使用这个脚本安装。当时选择清华超时了,选择中国科学技术大学镜像挺快的。不过安装过程需还是要持续挺久的… 安装完毕一定要执行一下这个命令source /Users/xxxx/.bash_profile 才能继续安装redis-cli

连接Redis集群

可以使用命令redis-cli -h 10.19.25.12 -p 41500 -a 1234!QAZ -c --raw 来连接到Redis集群

-h 主机-p 端口-a 密码-c 集群模式–raw 解决乱码问题

尝试一下命令,确实如愿了。心里别提多开心了。 在这里插入图片描述 可以看到返回1个数字,还有10行记录。起初不知道最上面的数字是什么意思,也不懂为什么返回了10条。后来了解到最上面的数组是返回的***偏移量***,而10条记录实际上是5条记录,不过返回的是一对一对的HASH和Value。当偏移量返回0的时候,代表迭代结束了。

但是到这里还有个特殊情况。当我在hash中存入其他的四组数据,并且想要一个一个取出来的时候,却发现并不能如愿。并不是一个一个返回,而是一次性全部返回了。 在这里插入图片描述 这样的结果让我一度怀疑🤨,这个方法到底能不能真的按照我的预想去工作。看到这个现象有两个想法冒出来:

这个方法会不会觉得我的数据太少了?就一次性返回了?对这个方法一无所知,其实并不能满足我的要求。

那无论是哪一种,都需要查一下资料。这里推荐一下这篇文章,写的非常详细。或者可以直接看看官网文档,让我了解到其中的奥秘。实际上就是第一个猜想那样,也算是Redis的一种优化机制。

如果Value的长度超过某个限制,count属性生效如果数据量超过某个限制,count 属性生效

我喜欢那些闪光的东西,比如冬日的雪花,天上的星星,还有你的眼睛。

现在终于确认了,这个的确可以用来迭代HASH 中的所有KEY,那现在就是需要使用java来实现了。好在jedis的命令与redis的hscan方法名字是一致的。但是可惜公司封装的jedis客户端没有暴露出来这个hscan的方法。所以无奈之下,只好自己连接Redis集群。部分代码如下:

private GenericObjectPoolConfig configSelf; private String[] hostsSelf; private String pwdSelf; private JedisCluster jcSelf; private boolean needAuth = false; private int connectionTimeout = 20000; private int soTimeout = 20000; private int maxAttempts = 3; /** * 获取Jedis集群客户端 * 使用完毕,一定要记得关闭客户端 * * @return Jedis客户端实例 */ public JedisCluster getClusterClient() { logger.info("-----------------------create Self Jedis Cluster Pool------------------------begin---"); GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxTotal(500); genericObjectPoolConfig.setMaxIdle(10); genericObjectPoolConfig.setMinIdle(5); genericObjectPoolConfig.setTestOnBorrow(true); Set jedisClusterNodes = new HashSet(); try { if (null != jcSelf) jcSelf.close(); for (String address : hostsSelf) { String[] ipAndPort = address.split(":"); jedisClusterNodes.add(new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]))); logger.debug(address); } if (configSelf.getMaxWaitMillis()


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有