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");                                  //把值递增1
        System.out.println(jedis.get("age"));
        jedis.decr("age");                                  //把值递减1
        System.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 -1
        jedis.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");                                  //把值递增1
        System.out.println(redisTemplate.opsForValue().get("age"));
        redisTemplate.opsForValue().decrement("age");                                  //把值递减1
        System.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 -1
        redisTemplate.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"));//返回元素个数
​
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值