redis 获取不到_你不知道的redis:第三方jar无封装命令我们该怎么执行?

推荐学习

  • 缓存架构技术:Redis+MongDB,阿里P7面试必跳的坑
  • Redis让我凉在美团一面,摸爬滚打3个月,二战逆袭成功斩获Offer

redis的基本操作指令就不多说了,今天对redis的进阶操作给大家介绍一下,以及对于jedis和redisTemplate等工具包没有封装的命令我们该如何使用?相信大家读了本篇对redis的整体会有更深的认知。

一、Pipelin模式介绍

1.1 redis的通常使用方式

大多数情况下,我们都会通过请求-相应机制去操作redis。使用这种模式的步骤为

  1. 获得jedis实例
  2. 发送redis命令
  3. 由于redis是单线程的,所以处理完上一个指令之后才会进行执行该命令。

整个交互流程如下

98e3a7d914458a74c43d7819ee5504f5.png

1.2 Pipeline模式

然而使用Pipeline 模式,客户端可以一次性的发送多个命令,无需等待服务端返回。这样就大大的减少了网络往返时间,提高了系统性能。

pipeline是多条命令的组合,使用PIPELINE 可以解决网络开销的问题,原理也非常简单,流程如下, 将多个指令打包后,一次性提交到Redis, 网络通信只有一次

02c2368637624fe79cfb15bf1f1bcaa1.png

1.3 性能对比

00755817b7a39d1806c2c18d97081d92.png

可以看到,redis的延迟主要出现在网络请求的IO次数上,因此我们在使用redis的时候,尽量减少网络IO次数,通过pipeline的方式将多个指令封装在一个命令里执行。

二、Redis事物

redis的简单事务是将一组需要一起执行的命令放到multi和exec两个命令之间,其中multi代表事务开始,exec代表事务结束

6507f9d4cc96e297bea5233b70d22ec0.png

2.1 事务命令

multi:事务开始

exec:提交事务

watch:事务监控

WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到

discard:停止事务

在执行exec之前执行该命令,提交事务会失败,执行的命令会进行回滚

127.0.0.1:6379> multi     //开始事务 OK 127.0.0.1:6379> sadd tt 1   //业务操作 QUEUED 127.0.0.1:6379> DISCARD   //停止事务 OK 127.0.0.1:6379> exec   //提交事务 (error) ERR EXEC without MULTI   //报不存在事务异常 127.0.0.1:6379> get tt  //获取不到对象 (nil) 127.0.0.1:6379>

2.2 事务异常

redis支持事务,但他属于弱事务,中间的一些异常可能会导致事务失效。

1、命令错误,语法不正确,导致事务不能正常结束

127.0.0.1:6379> multi   //开始事务 OK 127.0.0.1:6379> set aa 123  //业务操作 QUEUED 127.0.0.1:6379> sett bb 124  //命令错误 (error) ERR unknown command 'sett' 127.0.0.1:6379> exec  (error) EXECABORT Transaction discarded because of  previous errors.  //提交事务异常 127.0.0.1:6379> get aa  //查询不到数据 (nil) 127.0.0.1:6379>

2、运行错误,语法正确,但类型错误,事务可以正常结束

127.0.0.1:6379> multi OK 127.0.0.1:6379> set t 1   //业务操作1 QUEUED 127.0.0.1:6379> sadd t 1  //业务操作2 QUEUED 127.0.0.1:6379> set t 2  //业务操作3 QUEUED 127.0.0.1:6379> exec 1) OK 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value  //类型异常 3) OK 127.0.0.1:6379> get t  //可以获取到t "2" 127.0.0.1:6379>

三、redis发布与订阅

redis提供了“发布、订阅”模式的消息机制,其中消息订阅者与发布者不直接通信,发布者向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以接收到消息

b337ca0466ce0f9979ad41055c3dfce0.png

3.1 Redis发布订阅常用命令

1726d98101ee80032970efeae3b5c227.png

3.2 性能测试

3.3 应用场景

redis主要提供发布消息、订阅频道、取消订阅以及按照模式订阅和取消订阅,和很多专业的消息队列(kafka rabbitmq),redis的发布订阅显得很lower, 比如无法实现消息规程和回溯, 但就是简单,如果能满足应用场景,用这个也可以

  1. 订阅号、公众号、微博关注、邮件订阅系统等
  2. 即使通信系统
  3. 群聊部落系统(微信群)

四、键的迁移

键迁移大家可能用的不是很多,因为一般都是使用redis主从同步。不过对于我们做数据统计分析使用的时候,可能会使用到,比如用户标签。为了避免key批量删除导致的redis雪崩,一般都是通过一个计算使用的redis和一个最终业务使用的redis,通过将计算时用的redis里的键值通过迁移的方式一个一个的更新到业务redis中,使其对业务冲击最小化。

4.1 move

move指令将redis一个库中的数据迁移到另外一个库中。

move key db  //reids有16个库, 编号为0-15set name DK;  move name 5 //迁移到第6个库elect 5 ;//数据库切换到第6个库,get name  可以取到james1

如果key在目标数据库中已存在,那么什么也不会发生。这种模式不建议在生产环境使用,在同一个reids里可以玩

4.2 dump

Redis DUMP 命令用于将key给序列化 ,并返回被序列化的值。用于导入到其他服务中

一般通过dump命令导出,使用restore命令导入。

1,在A服务器上

set name james;dump name;       //  得到"x00x05jamesbx001x82;f"DhJ"

2,在B服务器上

restore name 0 "x00x05jamesbx001x82;f"DhJ"    //0代表没有过期时间get name           //返回james

4.3 migrate

migrate用于在Redis实例间进行数据迁移,实际上migrate命令是将dump、restore、del三个命令进行组合,从而简化了操作流程。

migrate命令具有原子性,从Redis 3.0.6版本后已经支持迁移多个键的功能。migrate命令的数据传输直接在源Redis和目标Redis上完成,目标Redis完成restore后会发送OK给源Redis。

ecf7fc9f7790691b5122a7a0cde2916d.png

比如:把111上的name键值迁移到112上的redis

192.168.42.111:6379> migrate 192.168.42.112 6379 name 0 1000 copy

五、自定义命令封装

当我们使用jedis或者jdbctemplate时,想执行键迁移的指令的时候,发现根本没有给我们封装相关指令,这个时候我们该怎么办呢?除了框架帮我们封装的方法外,我们自己也可以通过反射的方式进行命令的封装,主要步骤如下

  1. 建立Connection链接,使用Connection连接Redis
  2. 通过反射获取Connection中的sendCommand方法(protected Connection sendCommand(Command cmd, String... args))。
  3. 调用connection的sendCommand方法,第二个参数为执行的命令(比如set,get,client等),第三个参数为命令的参数。可以看到ProtocolCommand这个枚举对象包含了redis的所有指令,即所有的指令都可以通过这个对象获取到。并封装执行
  4. 执行invoke方法,并且按照redis的指令封装参数
  5. 获取Redis的命令执行结果
package com.james.cache.jedis; import redis.clients.jedis.Connection;import redis.clients.jedis.Protocol; import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method; /** * @Auther: DK * @Date: 2020/10/11 23:17 * @Description: */public class RedisKeyMove {     public static void main(String[] args) throws IOException {        //1.使用Connection连接Redis        try (Connection connection = new Connection("10.1.253.188", 6379)) {            // 2. 通过反射获取Connection中的sendCommand方法(protected Connection sendCommand(Command cmd, String... args))。            Method method = Connection.class.getDeclaredMethod("sendCommand", Protocol.Command.class, String[].class);            method.setAccessible(true); // 设置可以访问private和protected方法            // 3. 调用connection的sendCommand方法,第二个参数为执行的命令(比如set,get,client等),第三个参数为命令的参数。            // 3.1 该命令最终对应redis中为: set test-key test-value            method.invoke(connection, Protocol.Command.MIGRATE,                    new String[] {"10.1.253.69", "6379", "name", "0", "1000", "copy"});            // 4.获取Redis的命令执行结果            System.out.println(connection.getBulkReply());        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }    }}

六、键全量遍历

6.1 keys

4859b4e9e611b42f798df77b22ce73b5.png

考虑到是单线程,使用改命令会阻塞线程, 在生产环境不建议使用,键多可能会阻塞。

6.2 渐进式遍历 scan

1,初始化数据

mset n1 1 n2 2 n3 3 n4 4 n5 5 n6 6 n7 7 n8 8 n9 9 n10 10 n11 11 n12 12 n13 13

2,遍历匹配

scan 0 match n* count 5    匹配以n开头的键,最大是取5条,第一次scan 0开始

第二次从游标4096开始取20个以n开头的键,相当于一页一页的取当最后返回0时,键被取完。

6.3 scan 和keys对比

  1. 通过游标分布进行的,不会阻塞线程;
  2. 提供 limit 参数,可以控制每次返回结果的最大条数,limit 不准,返回的结果可多可少;
  3. 同 keys 一样,Scan也提供模式匹配功能;
  4. 服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;
  5. scan返回的结果可能会有重复,需要客户端去重复;
  6. scan遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的;
  7. 单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零;

6.4 其他遍历命令

SCAN 命令用于迭代当前数据库中的数据库键。

SSCAN 命令用于迭代集合键中的元素。

HSCAN 命令用于迭代哈希键中的键值对。

ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。

用法和scan一样

作者:ark_King_

原文链接:https://blog.csdn.net/b379685397/article/details/109015852

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot,可以很方便地将Redis与应用程序结合起来。以下是在Spring Boot使用Redis的步骤: 1. 添加Redis的依赖Jar到项目。可以在项目的pom.xml文件添加以下代码来引入Redis依赖: ```xml <!-- Redis依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>${spring-boot.version}</version> </dependency> ``` 这样就可以通过Maven下载并引入相关的依赖。 2. 在配置文件application.properties或application.yml配置Redis连接信息。可以根据具体情况修改以下配置项: ```properties # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=200 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池的最大空闲连接 spring.redis.pool.max-idle=10 # 连接池的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=1000 ``` 根据实际情况修改以上配置项的值,使其与你的Redis服务器连接信息匹配。 3. 可以通过自定义注入bean组件来配置Redis相关的操作。根据具体需求,可以创建一个RedisService类来封装Redis的操作方法,比如获取、设置、删除等操作。在这个类,可以使用@Autowired注解将RedisTemplate注入进来,以便进行操作。 综上所述,在Spring Boot结合Redis的具体步骤包括添加Redis依赖、配置Redis连接信息和自定义注入bean组件来操作Redis。通过这些步骤,你可以在Spring Boot项目轻松使用Redis数据库。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [springboot整合Redis详解完整篇](https://blog.csdn.net/weixin_43978695/article/details/111054363)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [详解springboot配置多个redis连接](https://download.csdn.net/download/weixin_38598213/12782095)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值