关于redis:Redis高频面试题之缓存穿透缓存击穿和缓存雪崩

65次阅读

共计 6146 个字符,预计需要花费 16 分钟才能阅读完成。

一、概述

  • Redis 是什么?what?

Redis(Remote Dictionary Server ),即近程字典服务 ! 是一个开源的应用 ANSI C 语言编写、反对网络、可基于内存亦可长久化的日志型、Key-Value 数据库,并提供多种语言的 API。

redis 会周期性的把更新的数据写入磁盘或者把批改操作写入追加的记录文件,并且在此基础上实现了 master-slave(主从)同步。收费和开源!是当下最热门的 NoSQL 技术之一!也被人们称之为结构化数据库!

  • Redis 能干嘛?

1、内存存储、长久化,内存中是断电即失、所以说长久化很重要(rdb、aof)2、效率高,能够用于高速缓存 3、公布订阅零碎 4、地图信息剖析 5、计时器、计数器(浏览量!)6、……..

二、Redis 的根本理解

  1. 首先咱们能够看下官网文档是如何介绍 Redis 的:

①、英文文档 点击跳转.

②、中文文档 点击跳转.

2. Redis-Key 简略介绍一下 Redis 中队 Key 的操作命令。心愿大家能够跟着正文敲一遍,简略记一下,都是最罕用的命令!

127.0.0.1:6379> ping  #查看以后连贯是否失常,失常返回 PONG
PONG
127.0.0.1:6379> clear  #分明以后控制台(为了更好的看到上面输出的命令)127.0.0.1:6379> keys *  #查看以后库里所有的 key
1) "db"
127.0.0.1:6379> FLUSHALL  #清空所有库的内容
OK
127.0.0.1:6379> keys * 
(empty array)
127.0.0.1:6379> set name dingdada  #增加一个 key 为‘name’value 为‘dingdada’的数据
OK
127.0.0.1:6379> get name  #查问 key 为‘name’的 value 值
"dingdada"
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> set name1 dingdada2
OK
127.0.0.1:6379> get name1
"dingdada2"
127.0.0.1:6379> keys *  #查看以后库里所有的 key
1) "name1"
2) "name"
127.0.0.1:6379> EXISTS name  #判断以后 key 是否存在
(integer) 1
127.0.0.1:6379> move name 1  #移除以后库 1 的 key 为‘name‘的数据
(integer) 1
127.0.0.1:6379> keys *
1) "name1"
127.0.0.1:6379> FLUSHALL  #再次清空所有库的内容
OK

## 多加几条数据 上面测试设置 key 的过期工夫
127.0.0.1:6379> set name dingdada
OK
127.0.0.1:6379> set name1 dingdada1
OK
127.0.0.1:6379> set name2 dingdada2
OK
127.0.0.1:6379> EXPIRE name 15  #设置 key 为’name‘的数据过期工夫为 15 秒 单位 seconds
(integer) 1
127.0.0.1:6379> ttl name  #查看以后 key 为’name‘的残余生命周期工夫
(integer) 13
127.0.0.1:6379> ttl name
(integer) 12
127.0.0.1:6379> ttl name
(integer) 11
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) 0
127.0.0.1:6379> ttl name  #如若返回 -2,证实 key 已过期
(integer) -2
127.0.0.1:6379> get name    #再次查问即为空
(nil)
127.0.0.1:6379> type name1
string
127.0.0.1:6379> 

如若遇到不会的命令!记得查看 Redis 中武官网,下面有官网文档!链接下面有,能够点击跳转~

二、Redis 的五大数据类型

  1. String(字符串)

增加 查问 追加 获取长度 判断是否存在 的操作

127.0.0.1:6379> set name dingdada  #插入一个 key 为‘name’值为‘dingdada’的数据
OK
127.0.0.1:6379> get name  #获取 key 为‘name’的数据
"dingdada"
127.0.0.1:6379> get key1
"hello world!"
127.0.0.1:6379> keys *  #查看以后库的所有数据
1) "name"
127.0.0.1:6379> EXISTS name  #判断 key 为‘name’的数据存在不存在,存在返回 1
(integer) 1
127.0.0.1:6379> EXISTS name1  #不存在返回 0
(integer) 0
127.0.0.1:6379> APPEND name1 dingdada1  #追加到 key 为‘name’的数据后拼接值为‘dingdada1’,如果 key 存在相似于 java 中字符串‘+’,不存在则新增一个,相似于 Redis 中的 set name1 dingdada1,并且返回该数据的总长度
(integer) 9
127.0.0.1:6379> get name1
"dingdada1"
127.0.0.1:6379> STRLEN name1  #查看 key 为‘name1’的字符串长度
(integer) 9
127.0.0.1:6379> APPEND name1 ,dingdada2  #追加,key 存在的话,拼接‘+’,返回总长度
(integer) 19
127.0.0.1:6379> STRLEN name1
(integer) 19
127.0.0.1:6379> get name1
"dingdada1,dingdada2"
127.0.0.1:6379> set key1 "hello world!"  #留神点:插入的数据中如果有空格的数据,请用“”双引号,否则会报错!OK
127.0.0.1:6379> set key1 hello world!  #报错,因为在 Redis 中空格就是分隔符,相当于该参数已完结
(error) ERR syntax error
127.0.0.1:6379> set key1 hello,world!  #逗号是能够的
OK

自增 自减 操作

127.0.0.1:6379> set num 0  #插入一个初始值为 0 的数据
OK
127.0.0.1:6379> get num
"0"
127.0.0.1:6379> incr num  #指定 key 为‘num’的数据自增 1,返回后果  相当于 java 中 i++
(integer) 1
127.0.0.1:6379> get num  #个别用来做文章浏览量、点赞数、珍藏数等性能
"1"
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> incr num
(integer) 3
127.0.0.1:6379> get num
"3"
127.0.0.1:6379> decr num  #指定 key 为‘num’的数据自减 1,返回后果  相当于 java 中 i--
(integer) 2
127.0.0.1:6379> decr num
(integer) 1
127.0.0.1:6379> decr num
(integer) 0
127.0.0.1:6379> decr num  #能够始终减为正数~
(integer) -1
127.0.0.1:6379> decr num  #个别用来做文章勾销点赞、勾销珍藏等性能
(integer) -2
127.0.0.1:6379> decr num
(integer) -3
127.0.0.1:6379> INCRBY num 10  #前面跟上 by  指定 key 为‘num’的数据自增‘参数(10)’,返回后果
(integer) 7
127.0.0.1:6379> INCRBY num 10
(integer) 17
127.0.0.1:6379> DECRBY num 3  #前面跟上 by  指定 key 为‘num’的数据自减‘参数(3)’,返回后果
(integer) 14
127.0.0.1:6379> DECRBY num 3
(integer) 11

截取 替换 字符串操作

# 截取
127.0.0.1:6379> set key1 "hello world!"
OK
127.0.0.1:6379> get key1
"hello world!"
127.0.0.1:6379> GETRANGE key1 0 4  #截取字符串,相当于 java 中的 subString,下标从 0 开始,不会扭转原有数据
"hello"
127.0.0.1:6379> get key1
"hello world!"
127.0.0.1:6379> GETRANGE key1 0 -1  #0 至 - 1 相当于 get key1,成果统一,获取整条数据
"hello world!"
#替换
127.0.0.1:6379> set key2 "hello,,,world!"
OK
127.0.0.1:6379> get key2
"hello,,,world!"
127.0.0.1:6379> SETRANGE key2 5 888  #此语句跟 java 中 replace 有点相似,下标也是从 0 开始,然而有区别:java 中是指定替换字符,Redis 中是从指定地位开始替换,替换的数据依据你所需替换的长度统一,返回值是替换后的长度
(integer) 14
127.0.0.1:6379> get key2
"hello888world!"
127.0.0.1:6379> SETRANGE key2 5 67  #该处只替换了两位
(integer) 14
127.0.0.1:6379> get key2
"hello678world!"

设置过期工夫 不存在设置 操作

# 设置过期工夫,跟 Expire 的区别是前者设置已存在的 key 的过期工夫,而 setex 是在创立的时候设置过期工夫
127.0.0.1:6379> setex name1 15  dingdada  #新建一个 key 为‘name1’,值为‘dingdada’,过期工夫为 15 秒的字符串数据
OK
127.0.0.1:6379> ttl name1  #查看 key 为‘name1’的 key 的过期工夫
(integer) 6
127.0.0.1:6379> ttl name1
(integer) 5
127.0.0.1:6379> ttl name1
(integer) 3
127.0.0.1:6379> ttl name1
(integer) 1
127.0.0.1:6379> ttl name1
(integer) 0
127.0.0.1:6379> ttl name1  #返回为 - 2 时证实该 key 已过期,即不存在
(integer) -2
#不存在设置
127.0.0.1:6379> setnx name2 dingdada2  #如果 key 为‘name2’不存在,新增数据,返回值 1 证实胜利
(integer) 1
127.0.0.1:6379> get name2
"dingdada2"
127.0.0.1:6379> keys *
1) "name2"
127.0.0.1:6379> setnx name2 "dingdada3"  #如果 key 为‘name2’的已存在,设置失败,返回值 0,也就是说这个跟 set 的区别是:set 会替换原有的值,而 setnx 不会,存在即不设置,确保了数据误操作~
(integer) 0
127.0.0.1:6379> get name2
"dingdada2"

msetmget操作

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  #插入多条数据
OK
127.0.0.1:6379> keys *  #查问所有数据
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3  #查问 key 为‘k1’,‘k2’,‘k3’的数据
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> MSETNX k1 v1 k4 v4  #msetnx 是一个原子性的操作,在肯定水平上保障了事务!要么都胜利,要么都失败!相当于 if 中的条件 &&(与)(integer) 0
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> MSETNX k5 v5 k4 v4  #全副胜利
(integer) 1
127.0.0.1:6379> keys *
1) "k2"
2) "k4"
3) "k3"
4) "k5"
5) "k1"

增加获取对象 getset 操作

# 这里其实实质上还是字符串,然而咱们讲其 key 奇妙的设计了一下。##mset student:1:name  student 相当于类名,1 相当于 id,name 相当于属性
#如果所需数据全副这样设计,那么咱们在 java 的业务代码中,就不须要关注太多的 key
#只须要找到 student 类,上面哪个 id,须要哪个属性即可,缩小了代码的繁琐,在肯定水平上能够了解为这个一个类的对象!127.0.0.1:6379> mset student:1:name dingdada student:1:age 22  #新增一个 key 为‘student:1:name’,value 为‘dingdada’。。等数据
OK
127.0.0.1:6379> keys *  #查看所有的 key
1) "student:1:age"
2) "student:1:name"
127.0.0.1:6379> mget student:1:age student:1:name  #获取数据
1) "22"
2) "dingdada"

##getset 操作
127.0.0.1:6379> getset name1 dingdada1  #先 get 再 set,先获取 key,如果没有,set 值进去,返回的是 get 的值
(nil)
127.0.0.1:6379> get name1
"dingdada1"
127.0.0.1:6379> getset name1 dingdada2  ## 先获取 key,如果有,set(替换)最新的值进去,返回的是 get 的值
"dingdada1"
127.0.0.1:6379> get name1  #替换胜利
"dingdada2"

总结 String 是 Redis 中最罕用的一种数据类型,也是 Redis 中最简略的一种数据类型。首先,外表上它是字符串,但其实他能够灵便的示意字符串、整数、浮点数 3 种值。Redis 会主动的辨认这 3 种值。


路漫漫其修远兮,吾必将高低求索~ 因为篇幅所限,另开一篇文章写剩下的内容哦! 如果你认为博主写的不错!写作不易,请点赞、关注、评论给博主一个激励吧~

作为浏览福利,我也整顿了 Redis 相干的学习笔记(蕴含脑图、面试真题、手写 pdf 等)当初收费分享给浏览到本篇文章的 Java 程序员敌人们,须要的可【点击下方链接】即可获取!!!

最全学习笔记大厂真题 + 微服务 +MySQL+ 分布式 +SSM 框架 +Java+Redis+ 数据结构与算法 + 网络 +Linux+Spring 全家桶 +JVM+ 高并发 + 各大学习思维脑图 + 面试汇合

正文完
 0