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

73fcbfe165b08c0dd39a854bf853ed4d.png

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

一、Pipelin模式介绍

1、redis的通常使用方式

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

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

整个交互流程如下

d3b3681aca996c37ce7a8c722ce04528.png

2、Pipeline模式

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

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

7ba34fd1d444a1799642c24e001d954e.png

3、性能对比

1b03eef775020812db2e58dc0b3f8f2c.png

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

二、Redis事物

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

14970a8b7a8fb67cddfdc4d79c4b7da2.png

1、事务命令

multi:事务开始

exec:提交事务

watch:事务监控

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

discard:停止事务

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

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

2、事务异常

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

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

127.0.0.1:6379> multi   //开始事务OK127.0.0.1:6379> set aa 123  //业务操作QUEUED127.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> multiOK127.0.0.1:6379> set t 1   //业务操作1QUEUED127.0.0.1:6379> sadd t 1  //业务操作2QUEUED127.0.0.1:6379> set t 2  //业务操作3QUEUED127.0.0.1:6379> exec1) OK2) (error) WRONGTYPE Operation against a key holding the wrong kind of value  //类型异常3) OK127.0.0.1:6379> get t  //可以获取到t"2"127.0.0.1:6379>

三、redis发布与订阅

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

edb897936beb8bf0faee3a4b9ab86b74.png

1、Redis发布订阅常用命令

命令含义
publish channel发布消息
subscribe channel订阅消息
pubsub numsub channel查看订阅数
unsubscribe channel取消订阅
psubscribe ch*按模式订阅和取消订阅

2、性能测试

3、应用场景

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

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

四、键的迁移

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

1、move

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

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

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

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

3、migrate

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

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

migrate192.168.42.1126379name01000copyreplace
指令要迁移的目标IP端口迁移键值目标库超时时间迁移后不删除原键不管目标库是不存在test键都迁移成功

比如:把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连接Redistry (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-valuemethod.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();}}
}

六、键全量遍历

1、keys

指令含义
keys *返回所有的键, *匹配任意字符多个字符
keys *y以结尾的键
keys n*e以n开头以e结尾,返回name
keys n?me?问号代表只匹配一个字符 返回name,全局匹配
keys n?m*返回name
keys [j,l]*返回以j l开头的所有键 keys [j]ames 全量匹配james

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

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时,键被取完。

3、scan 和keys对比

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

4、其他遍历命令

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

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

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

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

用法和scan一样

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502624.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云mysql 分布式_MySQL大型分布式集群

本套课程将通过分布式集群和分库分表两部分内容进行讲解1、主要解决针对大型网站架构中持久化部分中,大量数据存储以及高并发访问所带来是数据读写问题。分布式是将一个业务拆分为多个子业务,部署在不同的服务器上。集群是同一个业务,部署在多…

子窗体 记录选择_如何设计一个简单的Access登录窗体(1)

Access是一个对数据库新手相当友好的软件。Access的窗体功能确实是一种独一无二的前端设计平台,很多常见的人机交互用法,可以用Access的窗体来轻松实现,同时Access的查询和计算功能,也需要窗体的配合才能获得最佳的表达效果。 一、…

mysql 5.6.14 win32_mysql-5.6.14-win32为免安装解压缩版

mysql-5.6.14-win32为免安装解压缩版,安装版(http://dev.mysql.com/downloads/installer/5.5.html#downloads)存在很多弊端。mysql 5.6.14 win7 32位免安装版配置1.下载mysql 5.6.14;下载地址:http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.14-wi…

网页javascript加载不出_写给初学者的JavaScript异步编程和背后思想

导读:对于接触JavaScript这门编程语言没有多久的本菜鸡而言,在相当长的一段时间内,我都完全无法理解这门语言中的异步编程,不明白什么叫异步编程以及为什么需要异步编程。为什么顺序执行程序就不行了呢?非要使用异步回…

mysql 货币显示_在MySQL中以正确的格式显示USD货币记录

FORMAT()在MySQL中使用,以正确的格式显示USD货币记录。让我们首先创建一个表-mysql> create table DemoTable-> (-> Amount DECIMAL(15,4)-> );使用插入命令在表中插入一些记录-mysql> insert into DemoTable values(90948484);mysql> insert int…

js监听iframe关闭_Node.js文档NET[翻译]

Node.js v12.0.0 Documentation​nodejs.orgNet模块提供一个异步的网络API,这个API可以创建基于流的TCP,或者IPC服务器(net.createServer()),和客户端(net.createConnection())。它可以这样访问…

mysql 主键倒序查询速度慢_一亿条数据order by主键降序速度很慢

我用sysbench造了1亿条数据,mysql用了30分钟,tidb总共花了3个小时,感觉tidb在批量插入时比较慢,如果后面程序做分页查询会很慢的.count总数、降序排序也比mysql慢。tidb 执行时间,count 一亿条数据用了1分22秒多&#…

python切片逆序_Python 的逆序同时切片如何操作?

Python 的切片,语法是这样的a[[start]:[end][:[step]]]其中索引为 end 的元素不会被包括进来。start、end、step 和 step 前面的冒号都可以省略。这么多可以省略的,那么解释器是怎么设置默认值的呢?解释器对正序和逆序切片的默认值设置是不一…

camunda流程定义表无数据_创建流程实例时 act_ru_identitylink 表中没有出现相关的人员数据...

老师您好,我对流程实例有两个问题:创建流程实例的方法,视频中给出的是ProcessInstance processInstance runtimeService.startProcessInstanceByKey("Process_1", "business_id");请问这个方法和如下所示的方法有什么区…

静态网页托管_求职季,教你制作一份精美的在线网页简历,程序员必看!!

引言近期和学弟交流了一下找实习的相关的话题,谈到了简历这块。虽然近期没有找工作的打算,但还是会不定期的更新自己的简历。于是将自己的简历分享了一下,没想到得到了这样的评价,心里还是挺高兴的。简历的形式是一个在线的静态网…

mysql代码不熟_mysql存储过程的错误,语法不熟,找了好久没找到错误。。。

CREATEPROCEDUREupdate_pointer()begin/*done为1执行异常,停止执行*/DECLAREDoneINTDEFAULT0;DECLAREnowtimeINT;DECLAREyuefloat;DECLAREuidint;DECLAREyqmoneyfloat;DECLAREsummone...CREATE PROCEDURE update_pointer()begin/*done为1执行异常,停止执…

python axes_浅谈matplotlib.pyplot与axes的关系

最近在学习数据可视化,梳理一下其中一些诸如pandas绘图、matplotlib绘图、pyplot(plt)、axes等概念。重要的事情说三遍:axes不是axis!axes不是axis!axes不是axis!重要的事情说三遍:pyplot是接口不是对象&am…

protobuf2和3同时安装_安装protobuf可能遇到的问题

http://code.google.com/p/protobuf/downloads/list安装:unzip protobuf-2.3.0.zipcd protobuf-2.3.0./configuremakemake checkmake install1.每步在执行过程中注意权限问题,有的命令不sudo执行会出问题。./configuremakemake checkmake install2. 执行…

python制作考试系统_Python系统学习 - Pytest单元测试框架

哈咯,大家,我们今天来学习pytest单元测试框架,这个框架要比unittest更加易于使用,结构性也更加好,希望大家能够从中学习到有用的东西,然后在下一章,我们来使用pytest单元测试框架来搭建一个web自…

python分析推特_用Python关注者的关注者抓取Twitter数据的最快方法

我在用Python在Twitter上做一个关于用户社交关系的研究。在问题是“什么是最快的方式抓取某个用户的关注者信息”我搜索了很多信息,目前正在使用Tweepy:c tweepy.Cursor(api.followers_ids, idcentre, count5000).items()while True:try:followers_ids_…

python修复不了_如何修复Python代码?

当您将变量定义为str()时,就是将它们分配给一个空字符串(尝试在命令shell或IDLE中运行str(),然后查看其返回值)。在然后,使用input()函数,您将为某些字符串重新定义变量,并且在if语句中,您将使用这些比较运…

为什么不可以使用哈曼顿距离_K-means真的不能使用曼哈顿距离吗?

问题说到k-means聚类算法,想必大家已经对它很熟悉了,它是基于距离计算的经典无监督算法,但是有一次在我接受面试时,面试官问了我一个问题:“k-means为什么不能使用曼哈顿距离计算,而使用欧式距离进行计算&a…

linux 查看进程_Linux怎么查看和监控每个进程的实时流量

请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号**“智传网优”**直接开始自助**视频学习**1. 前言NetHogs是一个开源的命令行工具(类似于Linux的top命令),用来按进程或程序实时统计网络带宽使用率。来自NetH…

mysql修改密码1820_mysql5.7初始化密码报错ERROR1820(HY000):YoumustresetyourpasswordusingALTERUSERstateme...

1,mysql5.6是密码为空直接进入数据库的,但是mysql5.7就需要初始密码cat /var/log/mysqld.log | grep password或者:grep temporary password /var/log/mysqld.lo2,然后执行 mysql -uroot -p,输入上面的到的密码进入&am…

idea集成python_IDEA集成Python插件,SDK配置

(第一次写在博客园添加随笔, 会有些生硬,有不对的地方和描述错误之处希望可以指出)最近在学习一个新的知识点,涉及到Python的使用,因为第一次接触很多地方都不是很明白 ,好,废话不多说,现在直接…