Redis使用详解(超详细运用实践 + springboot集成)

Redis简介

数据库分类

关系型数据库 MySQL 、oracle

NoSQL数据库 非关系型数据库 分类

键值存储 查找速度快 数据无结构化

列存储数据库 查找速度快、可拓展性强,容易进行分布式扩展 功能相对局限

文档型数据库 数据结构要求不严格,表结构可变,不需要预定义表结构 查询性能不高,缺乏统一的查询语法

图形数据库 利用图结构相关算法,不好做分布式的集群方案

非关系型数据库特点

1.数据模型简单

2.需要灵活性更强的应用系统

3.对数据库性能要求较高

4.不需要高度的数据一致性

5.对于给定key,比较容易映射复杂值的环境.

Redis优缺点

优点: 对数据高并发读写(直接是内存中进行读写的) 对海量数据的高效率存储和访问 对数据的可拓展性和高可用性. 单线程操作,每个操作都是原子操作,没有并发相关问题(redis 6)

缺点: redis(ACID处理非常简单) 无法做太复杂的关系数据库模型

redis定位是缓存, 提高数据读写速度, 减轻对数据库存储与访问压力

一旦涉及到缓存,首要的候选方案:Redis

数据类型

redis命令格式:

类型命令 + key + 参数数据

String类型:

Map<String, String> map

set key value 存入键值对

get key 根据键取出值

incr key 把值递增1

decr key 把值递减1

del key 根据键删除尖子对

setex key timeout value 存入键值对 timeout表示失效时间 单位s

ttl key 可以查询当前的key还剩多长时间过期

setnx key value 如果可任意已经操作 不作操作,否则直接添加

hash类型

Map<string, Map<string, ?>> map

hset key hashkey hashvalue 存入一个hash对象

hget key hashkey 根据hash对象键取值

hexists key hashkey -> 判断hash对象是含有某个键

hdel key hashkey -> 根据hashkey删除hash对象键值对

list类型

Map<String, List>

rpush key value -> 往列表右边添加数据

lrange key start end -> 范围显示列表数据,全显示则设置0 -1

lpush key value -> 往列表左边添加数据

lpop key -> 弹出列表最左边的数据

rpop key -> 弹出列表最右边的数据

llen key -> 获取列表长度

set类型

Set集合是string类型的无序集合,set是通过hashtable实现的,对集合我们可以取交集,并集,差集.

sadd key value -> 往set集合中添加元素 smembers key -> 列出set集合中的元素 srem key value -> 删除set集合中的元素 spop key count -> 随机弹出集合中的元素

sdiff key1 key2 -> 返回key1中特有元素(差集)

sdiffstore var key1 key2 -> 返回key1中特有元素存入另一个set集合

sinter key1 key2 -> 返回两个set集合的交集

sinterstore var key1 key2 -> 返回两个set集合的交集存入另一个set集合

sunion key1 key2 -> 返回两个set集合的并集

sunionstore var key1 key2 -> 返回两个set集合的并集存入另一个set集合

smove key1 key2 value -> 把key1中的某元素移入key2中

scard key -> 返回set集合中元素个数

sismember key value -> 判断集合是否包含某个值

srandmember key count -> 随机获取set集合中元素

sorted_set类型

zadd key score column -> 存入分数和名称

zincrby key score column -> 偏移名称对应的分数

zrange key start end -> 按照分数升序输出名称

zrevrange key start end -> 按照分数降序输出名称

zrank key name -> 升序返回排名

zrevrank key name -> 降序返回排名

zcard key -> 返回元素个数

类型选用

value选用

1>如果要排序选用zset

2>如果数据是多个且允许重复选用list

3>如果数据是多个且不允许重复选用set

4>如果数据是对象,选用hash,或者String

5>剩下的使用string

key设计

1.唯一性 一般使用数据的主键保证唯一

2.可读性 加上一些能描述key作用的前缀

一般前缀: 项目_模块_可读性前缀:主键

3.灵活性

4.时效性

redis进阶

redis高级命令

keys * 返回满足的所有键 (可以模糊查询)

exists 是否存在指定key

expire 设置某个key的过期时间,使用ttl查看剩余时间

persist 取消过期时间

flushdb 清空当前数据库

flushall 清空所有数据库

select 选择数据库

rename 重命名key

redis安全性

在redis.config进行密码修改

用redis-cli -a[密码]启动

redis事务

Redis事务可以—次执行多个命令,并且带有以下三个重要的保证:

1.批量操作在发送EXEC命令前被放入队列缓存。

2.收到EXEC命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。

3.在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

执行事务的三个阶段

1.开始事务

2.命令入队

3.执行事务

单个Redis 命令的执行是原子性的,但Redis 没有在事务上增加任何维持原子性的机制,所以Redis事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批是指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

redis持久化机制

redis是一个支持持久化的内存数据库,也就是说redis经常将内存中的数据同步到硬盘保证持久化

redis持久化有两种方式

RDB方式

snapshotting快照,默认方式,将内存中以快照的方式写入到二进制文件中,默认为dump.rbd,可以自动配置设置自动做快照持久化方式,可以自定义配置

snapshotting

save 900 1 900秒内如果超过1个key被修改则发起快照保存

save 300 10 300秒捏如果超过10个jey被修改则发起快照保存

save 60 10000

AOF方式

append-only-file

redis会将一个收到的写命令都通过write函数追加到命令中,当redis重新启动是会执行文件中保存的写命令来在内存中重建这个数据库的内容,这个文件在bin目录下:appendonly.aof

aof不是立即写到硬盘中,可以通过配置文件修改强制写到硬盘中

appendonly yes //启动aof持久化方式有三种修改方式

#appendsync always收到命令就立即写到磁盘,效率最慢,但能保证完全的持久化

#appendsync everysec 每秒写入磁盘一次,在性能和持久化方面做了很好地折中

#appendsync no 完全以依赖os,性能最好,但持久化没保证

根据数据量、数据重要性选用

redis内存淘汰机制及过期key处理

内存淘汰机制

1.LRU 最近最少使用

2.LFU 最不经常使用

3.TTL 优先淘汰即将过期的数据

4.random 随机淘汰

volatile-lru/lfu/random/ttl 对以设置过期时间的数据集进行处理

allkeys-lru/lfu/random 对所有数据集处理

no-envictio 什么都不做

过期key处理

惰性删除,当访问时判断是否过期,过期再删除

定时删除:设置键的过期时间的同时,创建一个定时器,当到达过期时间点立即执行删除操作

定期删除,每隔一段时间,对数据进行一次检查,删除里面的过期key(优先选用)

实际运用

Jedis基本使用

配置依赖

创建Jedis连接池

从连接池获取对象

执行操作(redis的命令就是Jedis的方法)

关闭资源

String类型

        JedisPool pool = new JedisPool("localhost",6379);Jedis jedis = pool.getResource();jedis.set("name","jqy");                                //存入键值对jedis.set("age","18");System.out.println(jedis.get("name"));                  //根据键取出值System.out.println(jedis.get("age"));jedis.incr("age");                                  //把值递增1System.out.println(jedis.get("age"));jedis.decr("age");                                  //把值递减1System.out.println(jedis.get("age"));jedis.del("name");                                  //根据键删除值jedis.setnx("name","lye");                              //如果key存在不作操作否则直接添加System.out.println(jedis.get("name"));                  //根据键取出值
​jedis.setex("hobby",10,"lye");        //存入键值对,并设置生命周期System.out.println(jedis.ttl("hobby"));             //查看剩余时间
​jedis.close();pool.destroy();
​

Hash类型

 JedisPool pool = new JedisPool("localhost", 6379);Jedis jedis = pool.getResource();jedis.hset("user","name","jqy");                //存入一个hash对象jedis.hset("user","age","18");System.out.println(jedis.hget("user", "name"));       //  根据hash对象键取值System.out.println(jedis.hexists("user","age"));        //判断hash对象是含有某个键jedis.hdel("user","age");                               //根据hashkey删除hash对象键值System.out.println(jedis.hget("user", "age"));
​
​jedis.close();pool.destroy();
​

list类型

JedisPool pool = new JedisPool("localhost", 6379);Jedis jedis = pool.getResource();
​jedis.rpush("hobby","java","C","C++","lye");            // 往列表右边添加数据System.out.println(jedis.lrange("hobby", 0, -1));       //范围显示列表数据,全显示则设置0 -1jedis.lpush("hobby","zakuha");                          //往列表左边添加数据System.out.println(jedis.lpop("hobby"));                        //弹出列表最左边的数据System.out.println(jedis.rpop("hobby"));                        //弹出列表最右边的数据System.out.println(jedis.llen("hobby"));                        //获取列表长度
​jedis.close();pool.destroy();

set类型

 JedisPool pool = new JedisPool("localhost", 6379);Jedis jedis = pool.getResource();
​jedis.sadd("jqy","a","b","c","d","e");          // 往set集合中添加元素jedis.sadd("lye","e","f","c","d");System.out.println(jedis.smembers("jqy"));                  //列出set集合中的元素jedis.srem("jqy","e");                          //删除set集合中的元素System.out.println(jedis.smembers("jqy"));                  //列出set集合中的元素
//        Set<String> jqy = jedis.spop("jqy", 1);                       //随机弹出集合中的元素System.out.println(jedis.sdiff("jqy", "lye"));          //返回key1中特有元素(差集)System.out.println(jedis.sinter("jqy","lye"));          //返回两个set集合的交集System.out.println(jedis.sunion("jqy","lye"));          // 返回两个set集合的并集jedis.smove("jqy","lye","a");           //把key1中的某元素移入key2中System.out.println(jedis.scard("jqy"));                     //返回set集合中元素个数
​
​jedis.close();pool.destroy();

sorted-set类型

 JedisPool pool = new JedisPool("localhost", 6379);Jedis jedis = pool.getResource();
​jedis.zadd("players",3000,"a");                         //存入分数和名称jedis.zadd("players",3000,"b");jedis.zadd("players",3000,"c");jedis.zadd("players",3000,"d");jedis.zincrby("players",2000,"b");                  //偏移名称对应的分数jedis.zincrby("players",4000,"c");System.out.println(jedis.zrange("players", 0, -1));         //按照分数升序输出名称System.out.println(jedis.zrevrange("players", 0, -1));      //按照分数降序输出名称System.out.println(jedis.zrank("players", "b"));                //升序返回排名   从0开始System.out.println(jedis.zrevrank("players", "b"));             //降序返回排名    从0开始System.out.println(jedis.zcard("players"));//返回元素个数
​jedis.close();pool.destroy();

集成springboot

导入依赖

配置文件

获取(RedisTemplate<>对象 )StringRedisTemplate对象

进行操作

redis命令的全称就是spring-data-redis的方法

redis的全局命令在template对象中

String类型

   redisTemplate.opsForValue().set("name","jqy");                               //存入键值对redisTemplate.opsForValue().set("age","18");System.out.println(redisTemplate.opsForValue().get("name"));                  //根据键取出值System.out.println(redisTemplate.opsForValue().get("age"));redisTemplate.opsForValue().increment("age");                                  //把值递增1System.out.println(redisTemplate.opsForValue().get("age"));redisTemplate.opsForValue().decrement("age");                                  //把值递减1System.out.println(redisTemplate.opsForValue().get("age"));redisTemplate.delete("name")      ;                            //根据键删除值redisTemplate.opsForValue().setIfAbsent("name","lye");                    //如果key存在不作操作否则直接添加System.out.println(redisTemplate.opsForValue().get("name"));                  //根据键取出值
​redisTemplate.opsForValue().set("hobby","lye",Duration.ofSeconds(10));        //存入键值对,并设置生命周期System.out.println(redisTemplate.getExpire("hobby", TimeUnit.SECONDS));             //查看剩余时间
​

hash类型

   redisTemplate.opsForList().rightPushAll("hobby","java","C","C++","lye");            // 往列表右边添加数据System.out.println(redisTemplate.opsForList().range("hobby", 0, -1));       //范围显示列表数据,全显示则设置0 -1redisTemplate.opsForList().leftPush("hobby","zakuha");                          //往列表左边添加数据System.out.println(redisTemplate.opsForList().leftPop("hobby"));                        //弹出列表最左边的数据System.out.println(redisTemplate.opsForList().rightPop("hobby"));                        //弹出列表最右边的数据System.out.println(redisTemplate.opsForList().size("hobby"));                        //获取列表长度
​

set类型

​redisTemplate.opsForSet().add("jqy","a","b","c","d","e");          // 往set集合中添加元素redisTemplate.opsForSet().add("lye","e","f","c","d");System.out.println(redisTemplate.opsForSet().members("jqy"));                  //列出set集合中的元素redisTemplate.opsForSet().remove("jqy","e");                          //删除set集合中的元素System.out.println(redisTemplate.opsForSet().members("jqy"));                  //列出set集合中的元素
//        List<String> jqy = redisTemplate.opsForSet().pop("jqy", 1);                       //随机弹出集合中的元素System.out.println(redisTemplate.opsForSet().difference("jqy", "lye"));          //返回key1中特有元素(差集)System.out.println(redisTemplate.opsForSet().intersect("jqy","lye"));          //返回两个set集合的交集System.out.println(redisTemplate.opsForSet().union("jqy","lye"));          // 返回两个set集合的并集System.out.println(redisTemplate.opsForSet().move("jqy", "a", "lye"));System.out.println(redisTemplate.opsForSet().size("jqy"));                     //返回set集合中元素个数
​
​

sorted-set类型

​redisTemplate.opsForZSet().add("players","a",3000);                         //存入分数和名称redisTemplate.opsForZSet().add("players","b",3000);                         //存入分数和名称redisTemplate.opsForZSet().add("players","c",3000);                         //存入分数和名称redisTemplate.opsForZSet().add("players","d",3000);                         //存入分数和名称redisTemplate.opsForZSet().incrementScore("players","b",2000);                  //偏移名称对应的分数redisTemplate.opsForZSet().incrementScore("players","c",4000);System.out.println(redisTemplate.opsForZSet().range("players", 0, -1));         //按照分数升序输出名称System.out.println(redisTemplate.opsForZSet().reverseRange("players", 0, -1));      //按照分数降序输出名称System.out.println(redisTemplate.opsForZSet().rank("players", "b"));                //升序返回排名   从0开始System.out.println(redisTemplate.opsForZSet().reverseRank("players", "b"));             //降序返回排名    从0开始System.out.println(redisTemplate.opsForZSet().size("players"));//返回元素个数
​

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Rosetta 一:手把手教你用Linux安装Rosetta(全网最简洁)

文章目录 1. Rosetta 介绍2.下载2. Rosetta 安装3. 验证安装 1. Rosetta 介绍 很久很久之前就对Rosetta有所耳闻&#xff0c;有一篇文章叫做denovo protein design&#xff0c;说的就是用rosetta来设计蛋白质。 rosetta是david baker团队设计的软件&#xff0c;早期只是一个蛋…

【Godot4.3】胶囊形的偏移获取法

概述 之前用半圆弧拼接的方式求过胶囊形&#xff0c;在逐渐熟练使用Geometry2D的过程中&#xff0c;发现通过线段求端点是圆角类型的偏移多边形&#xff0c;获得的就是胶囊形。 所以我们有了第二种胶囊形求法。 测试代码 tool extends Node2D## 横向宽度 export var width:…

【工具】Windows|两款开源桌面窗口管理小工具Deskpins和WindowTop

总结 Deskpins 功能单一&#xff0c;拖到窗口上窗口就可以置顶并且标记钉子标签&#xff0c;大小 104 KB&#xff0c;开源位置&#xff1a;https://github.com/thewhitegrizzli/DeskPins/releases WindowTop 功能完善全面强大&#xff0c;包括透明度、置顶、选区置顶等一系列功…

SQL server学习01-SQL server环境配置

目录 一&#xff0c;手动下载及安装 microsoft .net framework 3.5 1&#xff0c;下载 2&#xff0c;安装 二&#xff0c;安装SQL server2014 1&#xff0c;下载 2&#xff0c;安装 3&#xff0c;启动SQL server服务 三&#xff0c;下载及安装Microsoft SQL Server…

C Prime Plus 第6章习题

你该逆袭了 红色标注的是&#xff1a;错误的答案 蓝色标注的是&#xff1a;正确的答案 绿色标注的是&#xff1a;做题时有疑问的地方 橙色标注的是&#xff1a;答案中需要着重注意的地方 练习题 一、复习题1、2、3、4、5、我的答案&#xff1a;错误正确答案&#xff1a; 6、7、…

ubuntu 安装minikube,并拉取k8s镜像

不要使用最新版&#xff0c;重要的事情说三遍&#xff0c;刚开始也是最求新一点的版本&#xff0c;但问题很多&#xff0c;主要是版本之间的依赖问题&#xff0c;不是某个依赖的版本不支持某些功能&#xff0c;就是依赖之间的版本不能对应上&#xff0c;所以就降低几个版本&…

行业人工智能研究-Python自监督方式学习图像表示算法

学术界人工智能研究落后于工业界 摘要 行业或工业界在人工智能研究上超出学术界&#xff0c;并占据着大量的计算力&#xff0c;数据集和人才诱人的薪水和明朗的预期吸引大量人才离开学术界&#xff0c;涌入行业或工业界即使&#xff0c;比如Meta开源其人工智能模型&#xff0…

实验:WLAN无线综合实验

无线综合实验的概述&#xff1a; WLAN无线综合实验是一种针对无线网络技术的综合性实验&#xff0c;旨在通过实践操作加深对无线局域网&#xff08;WLAN&#xff09;技术的理解和应用能力。以下是对该实验的详细概述&#xff1a; 实验目的 掌握认证AP上线的配置方法&#xff…

[SAP ABAP] 创建域

我们可以使用事务码SE11创建域 输入要创建的域的名称&#xff0c;然后点击创建 输入简短描述&#xff0c;选择数据类型和输入字符数 激活并保存域&#xff0c;创建的域才能够生效

pg入门18—如何使用pg gis

1. 下载postgre gis镜像 2. 运行镜像 docker run -p 15432:5432 -d -e POSTGRES_PASSWORDAb123456! postgis/postgis:12-3.4-alpine 3. 使用gis # 进入容器&#xff0c;登录pgdocker exec -it bash# 登录数据库psql -U postgres# 创建数据库CREATE DATABASE mygeotest;# 使用…

Spring Boot 入门:解锁 Spring 全家桶

前言 Spring 全家桶是现代 Java 开发者不可或缺的工具集&#xff0c;它提供了从轻量级的框架到微服务架构的完整支持。本文将带你快速了解 Spring 框架、核心概念如 IoC&#xff08;控制反转&#xff09;和 AOP&#xff08;面向切面编程&#xff09;&#xff0c;并深入介绍 Sp…

YOLOv10多模态 结合Transformer与NMS-Free 融合可见光+红外光(RGB+IR)双输入【附代码】

文章目录 前言视频效果代码获取文章概述必要环境一、模型训练1、 定义数据1.1、数据集结构1.2、定义data.yaml 2、 运行方法运行效果 二、模型验证运行方法运行效果 三、模型推理3.1. 推理图像1. 参数定义2. 运行方法运行效果 3.2. 推理视频1. 参数定义2. 运行方法运行效果 四、…

构建高可用和高防御力的云服务架构第一部分:深入解析DDoS高防(1/5)

引言 在数字化时代&#xff0c;网络安全已成为全球关注的焦点。随着互联网技术的快速发展和应用的广泛深入&#xff0c;网络安全形势日益严峻。特别是分布式拒绝服务&#xff08;DDoS&#xff09;攻击&#xff0c;以其破坏性强、难以防范的特点&#xff0c;对个人、企业乃至国…

Go-知识-定时器

Go-知识-定时器 1. 介绍2. Timer使用场景2.1 设定超时时间2.2 延迟执行某个方法 3. Timer 对外接口3.1 创建定时器3.2 停止定时器3.3 重置定时器3.4 After3.5 AfterFunc 4. Timer 的实现原理4.1 Timer数据结构4.1.1 Timer4.1.2 runtimeTimer 4.2 Timer 实现原理4.2.1 创建Timer…

Type-C 诱骗取电快充协议芯片,支持取电电压5V、9V、12V、15V、20V

‌XSP01A快充协议芯片‌是一款集成USB Power Delivery(PD) 2.0/3.0快充协议的USB-C/Type-C多功能取电芯片 它支持从手机充电器、车充等电源上取电给产品供电。这款芯片的优势在于其价格便宜&#xff0c;同时能够实现快充&#xff0c;对于不需要支持太多协议的设备来说&#x…

DRV8825步进电机驱动详细说明书————含接线图

最近玩步进电机时候&#xff0c;发现步进电机驱动种类多&#xff1b;A4988&#xff0c;drv8825,tb6600,lv8731……&#xff1b;tb6600驱动电流可达4A&#xff0c;1600细分&#xff0c;十分强大&#xff0c;但是体积大&#xff0c;用在平衡车上不太合适。 drv8825加散热器驱动电…

安装SQL Server遇到的问题

出现了一和二的问题&#xff0c;最后还是通过三完全卸载sqlserver安装成功了 一.安装过程中依次报错 1.MOF编译器无法连接WMI服务器。原因可能是语义错误(例如&#xff0c;与现有WMI知识库不兼容)或实际错误(例如WMI服务器启动失败)。 2.PerfLib 2.0计数器removal失败&#xf…

HarmonyOS鸿蒙开发实战(5.0)表情图片聊天案例实践

鸿蒙HarmonyOS NEXT开发实战往期文章必看&#xff08;持续更新......&#xff09; HarmonyOS NEXT应用开发性能实践总结 HarmonyOS NEXT应用开发案例实践总结合集 最新版&#xff01;“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门…

混合开发-JSBridge

1.1 什么是混合开发? 混合开发是一种融合了原生开发和Web开发优势的移动应用开发方式。 具体来说&#xff0c;混合开发通常指的是利用一种框架或平台来创建应用程序&#xff0c;这种程序结合了原生应用的一些功能和特性&#xff08;比如访问设备的摄像头、相册、GPS、蓝牙等…

DAMODEL——Llama3.1的部署与使用指南

Llama3.1的部署与使用指南 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;大模型&#xff08;LLM&#xff09;是基于深度学习算法训练而成的重要工具&#xff0c;应用范围包括自然语言理解和生成。随着技术的发展&#xff0c;开源的LLM不断涌现&#xff0c;涵盖了…