IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Redis学习笔记 -> 正文阅读

[大数据]Redis学习笔记

Redis

需要笔记的可以加群,这是我自己的群,一个月了就我一个人,希望能和一群人交流学习,无论你是高手还是糕手,到了这技术要学会,🐂也要吹上天

image-20211111220132185

1. Redis数据库相关指令

1.1 数据库操作指令

# 1.Redis中库说明
- 使用redis的默认配置器动redis服务后,默认会存在16个库,编号从0-15
- 可以使用select 库的编号 来选择一个redis的库

# 2.Redis中操作库的指令
- 清空当前的库  FLUSHDB
- 清空全部的库  FLUSHALL

# 3.redis客户端显示中文
-	./redis-cli  -p 7000 --raw

1.2 操作key相关指令

# 1.DEL指令
- 语法 :  DEL key [key ...] 
- 作用 :  删除给定的一个或多个key 。不存在的key 会被忽略。
- 可用版本: >= 1.0.0
- 返回值: 被删除key 的数量。 

# 2.EXISTS指令
- 语法:  EXISTS key
- 作用:  检查给定key 是否存在。
- 可用版本: >= 1.0.0
- 返回值: 若key 存在,返回1 ,否则返回0。

# 3.EXPIRE
- 语法:  EXPIRE key seconds
- 作用:  为给定key 设置生存时间,当key 过期时(生存时间为0 ),它会被自动删除。
- 可用版本: >= 1.0.0
- 时间复杂度: O(1)
- 返回值:设置成功返回1 。

# 4.KEYS
- 语法 :  KEYS pattern
- 作用 :  查找所有符合给定模式pattern 的key 。
- 语法:
	KEYS * 匹配数据库中所有key 。
	KEYS h?llo 匹配hello ,hallo 和hxllo 等。
	KEYS h*llo 匹配hllo 和heeeeello 等。
	KEYS h[ae]llo 匹配hello 和hallo ,但不匹配hillo 。特殊符号用 "\" 隔开
- 可用版本: >= 1.0.0
- 返回值: 符合给定模式的key 列表。

# 5.MOVE
- 语法 :  MOVE key db
- 作用 :  将当前数据库的key 移动到给定的数据库db 当中。
- 可用版本: >= 1.0.0
- 返回值: 移动成功返回1 ,失败则返回0 。

# 6.PEXPIRE
- 语法 :  PEXPIRE key milliseconds
- 作用 :  这个命令和EXPIRE 命令的作用类似,但是它以毫秒为单位设置key 的生存时间,而不像EXPIRE 命令那样,以秒为单位。
- 可用版本: >= 2.6.0
- 时间复杂度: O(1)
- 返回值:设置成功,返回1  key 不存在或设置失败,返回0

# 7.PEXPIREAT
- 语法 :  PEXPIREAT key milliseconds-timestamp
- 作用 :  这个命令和EXPIREAT 命令类似,但它以毫秒为单位设置key 的过期unix 时间戳,而不是像EXPIREAT那样,以秒为单位。
- 可用版本: >= 2.6.0
- 返回值:如果生存时间设置成功,返回1 。当key 不存在或没办法设置生存时间时,返回0 。(查看EXPIRE 命令获取更多信息)

# 8.TTL
- 语法 :   TTL key
- 作用 :   以秒为单位,返回给定key 的剩余生存时间(TTL, time to live)。
- 可用版本: >= 1.0.0
- 返回值:
	当key 不存在时,返回-2 。
	当key 存在但没有设置剩余生存时间时,返回-1 。
	否则,以秒为单位,返回key 的剩余生存时间。
- Note : 在Redis 2.8 以前,当key 不存在,或者key 没有设置剩余生存时间时,命令都返回-1 。

# 9.PTTL
- 语法 :  PTTL key
- 作用 :  这个命令类似于TTL 命令,但它以毫秒为单位返回key 的剩余生存时间,而不是像TTL 命令那样,以秒为单位。
- 可用版本: >= 2.6.0
- 返回值: 当key 不存在时,返回-2 。当key 存在但没有设置剩余生存时间时,返回-1 。
- 否则,以毫秒为单位,返回key 的剩余生存时间。
- 注意 : 在Redis 2.8 以前,当key 不存在,或者key 没有设置剩余生存时间时,命令都返回-1 。

# 10.RANDOMKEY
- 语法 :  RANDOMKEY
- 作用 :  从当前数据库中随机返回(不删除) 一个key 。
- 可用版本: >= 1.0.0
- 返回值:当数据库不为空时,返回一个key 。当数据库为空时,返回nil 。

# 11.RENAME
- 语法 :  RENAME key newkey
- 作用 :  将key 改名为newkey 。当key 和newkey 相同,或者key 不存在时,返回一个错误。当newkey 已经存在时,RENAME 命令将覆盖旧值。
- 可用版本: >= 1.0.0
- 返回值: 改名成功时提示OK ,失败时候返回一个错误。

# 12.TYPE
- 语法 :  TYPE key
- 作用 :  返回key 所储存的值的类型。
- 可用版本: >= 1.0.0
- 返回值:
	none (key 不存在)
	string (字符串)
	list (列表)
	set (集合)
	zset (有序集)
	hash (哈希表)

1.3 String类型

1. 内存存储模型

image-20211111154555963

2. 常用操作命令

命令说明
set设置一个key/value
get根据key获得对应的value
mset一次设置多个key value
mget一次获得多个key的value
getset获得原始key的值,同时设置新值
strlen获得对应key存储value的长度
append为对应key的value追加内容
getrange 索引0开始截取value的内容
setex设置一个key存活的有效期(秒)
psetex设置一个key存活的有效期(毫秒)
setnx存在不做任何操作,不存在添加
msetnx原子操作(只要有一个存在不做任何操作)可以同时设置多个key,只有有一个存在都不保存
decr进行数值类型的-1操作
decrby根据提供的数据进行减法操作
Incr进行数值类型的+1操作
incrby根据提供的数据进行加法操作
Incrbyfloat根据提供的数据加入浮点数

1.4 List类型

list 列表 相当于java中list 集合 特点 元素有序 且 可以重复

1.内存存储模型

image-20211111154621204

2.常用操作指令

命令说明
lpush将某个值加入到一个key列表头部
lpushx同lpush,但是必须要保证这个key存在
rpush将某个值加入到一个key列表末尾
rpushx同rpush,但是必须要保证这个key存在
lpop返回和移除列表左边的第一个元素
rpop返回和移除列表右边的第一个元素
lrange获取某一个下标区间内的元素
llen获取列表元素个数
lset设置某一个指定索引的值(索引必须存在)
lindex获取某一个指定索引位置的元素
lrem删除重复元素
ltrim保留列表中特定区间内的元素
linsert在某一个元素之前,之后插入新元素

1.5 Set类型

特点: Set类型 Set集合 元素无序 不可以重复

1.内存存储模型

image-20211111154639391

2.常用命令

命令说明
sadd为集合添加元素
smembers显示集合中所有元素 无序
scard返回集合中元素的个数
spop随机返回一个元素 并将元素在集合中删除
smove从一个集合中向另一个集合移动元素 必须是同一种类型
srem从集合中删除一个元素
sismember判断一个集合中是否含有这个元素
srandmember随机返回元素
sdiff去掉第一个集合中其它集合含有的相同元素
sinter求交集
sunion求和集

1.6 ZSet类型

特点: 可排序的set集合 排序 不可重复

ZSET 官方 可排序SET sortSet

1.内存模型

image-20211111154658014

2.常用命令

命令说明
zadd添加一个有序集合元素
zcard返回集合的元素个数
zrange 升序 zrevrange 降序返回一个范围内的元素
zrangebyscore按照分数查找一个范围内的元素
zrank返回排名
zrevrank倒序排名
zscore显示某一个元素的分数
zrem移除某一个元素
zincrby给某个特定元素加分

7.7 hash类型

特点: value 是一个map结构 存在key value key 无序的

1.内存模型

image-20211111154716102

2.常用命令

命令说明
hset设置一个key/value对
hget获得一个key对应的value
hgetall获得所有的key/value对
hdel删除某一个key/value对
hexists判断一个key是否存在
hkeys获得所有的key
hvals获得所有的value
hmset设置多个key/value
hmget获得多个key的value
hsetnx设置一个不存在的key的值
hincrby为value进行加法运算
hincrbyfloat为value加入浮点值

2.数据持久化

redis数据持久化分为两种:快照(rdb)、AOF(append only file)

当rdb和aof都开启时,redis在启动时会采用AOF来恢复数据

2.1 快照(RDB)

保存某一时刻的数据,redis默认使用的方式。它会生成.rdb后缀的文件(最后一次持久化的数据可能丢失)

生成快照文件的几种方式:

SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同:

SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。

Save是阻塞方式的;bgsave是非阻塞方式的。

  1. 客户端bgsave命令:调用fork创建一个子进程,子进程负责将快照写入到磁盘,主进程继续处理命令
  2. 客户端save命令:主进程负责快照生成,也就是说会导致redis无法对外服务,阻塞。
  3. 自动触发,当配置文件的条件满足时,触发快照生成:(执行bgsave命令)

image-20211111090713150

  1. 客户端shutdown命令:执行的是save命令

2.2 AOF(append only file)

将所有的写命命令记录到日志文件

要使用AOF,需开启,在配置文件中:

image-20211111092956254

日志追加频率: always、everysec、no

image-20211111093255232

always:来一个写命令就追加一次(以一个写命令为单位),虽然它可以保证数据不丢失,但是大量的写操作会极大降低redis运行效率。

everysec(推荐):以1s为单位,一秒追加一次,一秒内随便来多少个写命令,1s到了把1s内的写命令全部追加。可以看到这是redis默认使用的,redis可以保证,即使系统崩溃最多只会丢失1s的数据

no:不是不追加,而是把什么时候追加交给操作系统,操作系统需要的时候刷新即可

随着redis运行时间的增加,aof文件会越来越大,就会导致恢复数据越来越慢。所以为了压缩aof文件的大小,redis提供了AOF重写机制

2.3 AOF重写的两种方式

  1. 客户端命令:BGREWRITEAOF(bgrewriteaof)即后台重写,不会阻塞redis服务
  2. 配置自动触发

image-20211111101251176

这里有两个参数,解释下:

上面是一个百分比,这里是100%

下面是aof最小多少兆,这里是64

它两加起来就是这个意思:当aof文件达到64mb时,触发第一次重写,假如重写后为20mb;那么!下一次触发重写就是aof文件从20mb扩大了一倍(即100%的含义)为40mb时。你设置500%,下一次就是100mb触发重写

2.4 AOF重写原理

重写并不是在原有AOF文件的基础上进行压缩,而是将内存中的数据内容以命令的方式记录到一个临时的AOF文件中,然后将原来的替换掉,下面是我画的过程图:

image-20211111110444561

首先,我们应该弄明白怎么aof文件的体积就变小了?

举个例子,比如我对key为test的value(值为0)进行incr 1 ,加一操作,执行了1000次,aof中就记录了1000条记录,其实就只需要记录一条set test 1000不就是记录了test的值了吗。

它的过程我,描述一下:首先redis收到重写aof的命令时redis会调用fork()创建一个子进程,这个子进程会生成快照,然后将快照中的数据转变为写记录 写入临时的aof文件;与此同时,因为主线程还在工作,还会有新的写命令,主线程会将写命令继续追加到原来的文件(因为害怕子进程出现问题而导致后续的数据丢失),并将其缓存起来。当临时aof文件生成后,子进程会通知主进程,让主进程把缓存的写命令追加到临时文件。最后就将原来的文件替换掉,就完成了重写

3.SpringBoot 整合Redis

Spring Boot Data Redis提供了两个模板类:RedisTemplate和StringRedisTemplate。

RedisTemplate<Object,Object>,两个泛型都是Object类型,即key、value都是对象;但是Redis库中存储的都是String,所以RedisTemplate在存储时会自动将对象序列化,在取的时候会自动反序列化,这就要求使用的对象必须实现序列化接口(implements Serializable)!!!

而StringRedisTemplate<String,String>两个泛型都是String的,StringRedisTemplate是RedsiTemplate的子类

3.1 创建springboot项目

使用快速构建,你可以勾选上:lombok、web、redis

image-20211111170359494

这里也提供一下pom:

<dependencies>
    <!--redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <!--单元测试-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3.2 编写配置

#redis地址
spring.redis.host=127.0.0.1
#redis端口号
spring.redis.port=6379
#使用哪个库
spring.redis.database=0

3.3 编写测试类(以StringRedisTemple为介绍)

我们需要注入StringRedisTemplate(它和RedisTemplate都交给了Spring容器管理)

@SpringBootTest
class RedisApplicationTests {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //StringRedisTemple测试类
    @Test
    void redis() {
        
    }

}

api介绍:

image-20211111171229582

测试方法:

@SpringBootTest
class RedisApplicationTests {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //StringRedisTemple测试类
    @Test
    void redis() {
        //往redis中存一个key为name,值为xiaoxiang的数据
        stringRedisTemplate.opsForValue().set("name","xiaoxiang");
        
        //取出name的值
        String value = stringRedisTemplate.opsForValue().get("name");
        System.out.println(value);
    }

}

结果:

image-20211111174054023

Redis库中也有该条数据:

image-20211111174318307

对key的操作:

//对key的操作:

//删除key
stringRedisTemplate.delete("name");
//设置key过期时间
stringRedisTemplate.expire("name", 10 , TimeUnit.DAYS);
//获取过期时间
stringRedisTemplate.getExpire("name");
//获取指定key的value是什么数据类型
stringRedisTemplate.type("name");

==对String类型的操作:==不能一一介绍,大家根据api字面意思对照前面的操作命令就能知道是干啥的了,可以自己玩一玩。其它类型的数据的使用和string差不多,api不同大家可自行体会就不介绍了

image-20211111175051311

 //hash相关操作 opsForHash
    @Test
    public void testHash(){
        stringRedisTemplate.opsForHash().put("maps","name","小黑");
        Object o = stringRedisTemplate.opsForHash().get("maps", "name");
        System.out.println(o);
    }
//zset相关操作 opsForZSet
@Test
public void testZSet(){
    stringRedisTemplate.opsForZSet().add("zsets","小黑",10);
    Set<String> zsets = stringRedisTemplate.opsForZSet().range("zsets", 0, -1);
    zsets.forEach(value-> System.out.println(value));
}

//set相关操作 opsForSet
@Test
public void testSet(){
    stringRedisTemplate.opsForSet().add("sets","xiaosan","xiaosi","xiaowu");
    Set<String> sets = stringRedisTemplate.opsForSet().members("sets");
    sets.forEach(value-> System.out.println(value));
}

//list相关的操作opsForList
@Test
public void testList(){
    // stringRedisTemplate.opsForList().leftPushAll("lists","张三","李四","王五");
    List<String> lists = stringRedisTemplate.opsForList().range("lists", 0, -1);
    lists.forEach(key -> System.out.println(key));
}


//String相关的操作 opsForValue
@Test
public void testString(){
    //stringRedisTemplate.opsForValue().set("166","好同学");
    String s = stringRedisTemplate.opsForValue().get("166");
    System.out.println(s);
    Long size = stringRedisTemplate.opsForValue().size("166");
    System.out.println(size);
}


//key相关的操作
@Test
public void test(){
    Set<String> keys = stringRedisTemplate.keys("*");//查看所有key
    Boolean name = stringRedisTemplate.hasKey("name");//判断某个key是否存在
    stringRedisTemplate.delete("age");//根据指定key删除
    stringRedisTemplate.rename("","");//修改key的名称
    stringRedisTemplate.expire("key",10, TimeUnit.HOURS);
  	//设置key超时时间 参数1:设置key名 参数2:时间 参数3:时间的单位
    stringRedisTemplate.move("",1);//移动key
}

如想了解更多api,请看视频:

操作key和String类型数据:https://www.bilibili.com/video/BV1jD4y1Q7tU?p=12

操作list、set、zset:https://www.bilibili.com/video/BV1jD4y1Q7tU?p=13

操作hash、RedisTemplate(重要):https://www.bilibili.com/video/BV1jD4y1Q7tU?p=14

绑定key API:https://www.bilibili.com/video/BV1jD4y1Q7tU?p=15

4.Redis应用场景

视频链接:https://www.bilibili.com/video/BV1jD4y1Q7tU?p=16

验证码存储(设置超时,时效性)、

具有时效性的业务(比如订单还有多少时间失,时效性)、

分布式集群中session共享、

利用zset类型(元素 分数),可排序,可以做排行榜之类的把商品id作为key,销量作为分数,选出排名即可。

分布式缓存

存储认证后的token(时效性)

解决分布式系统集群的分布式锁问题

持续更新中。。。。。。。。。。。。。。。。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-11-12 19:39:55  更:2021-11-12 19:40:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:40:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码