1.概览
Redis 是完全开源免费的基于内存的高性能 key-value 数据结构数据库。
可以用来作为数据库、缓存和消息队列。
官网
2.安装
安装配置
Docker 安装
docker pull redis:latest
docker run -itd --name redis-test -p 6379:6379 redis
3.数据类型
- 字符串(string)
- 哈希(hash)
- 列表(list)
- 集合(set)
- 有序集合(sorted set)
- 位图 ( Bitmaps )
- 基数统计 ( HyperLogLogs )
4.操作
使用 Redis 客户端命令, 开始输入redis-cli
4.1 键的操作
全部操作 ```shell增
就是增加内容
127.0.0.1:6379> set name ren OK
删
0 => 没有删除
1 => 已经删除
127.0.0.1:6379> del name (integer) 0
改
127.0.0.1:6379> rename name uname OK
查
查看所有的键, 使用正则表达式
127.0.0.1:6379> keys * (empty array)
判断一个键是否存在
0 => 不存在
1 => 存在
127.0.0.1:6379> exists name (integer) 0
键对应值的数据类型
127.0.0.1:6379> type name string
<a name="zLhrM"></a>
## 4.2 字符串
一个字符串中存储最多 512 M。<br />[全部操作](https://www.redis.com.cn/redis-strings.html#redis-%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%91%BD%E4%BB%A4-)
```shell
# 增
# 单个
set [key] [value]
set name ren
# 多个
mset [key] [value] [key] [value] ...
# 删
del [key]
# 改
# 直接赋值即可修改
set uname lang
OK
# 查
get [key] [value]
# 查多个
mget [key] ...
# 其他还有设置过期时间等等
4.3 哈希
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
每个哈希键中可以存储多达 40 亿个字段值对。
解释:键的值是键值对。
全部操作
# 增
hset [key] [field] [value] ...
hset car1 name 宝马 price 90万
(integer) 2
# 删
del car1
# 删除字段
hdel [key] [field]...
# 改
# 重新赋值即可
# 查
# 一个
hget car1 name
"\xe5\xae\x9d\xe9\xa9\xac"
# 多个
mhget [key] [field] ...
# 显示全部内容
hgetall [key]
# 查询所有的键
hkeys car1
# 查询所有的值
hvals car1
# 查询键值对个数
hlen [key]
4.4 列表
Redis 列表是按插入顺序排序的字符串列表。可以在列表的头部(左边)或尾部(右边)添加元素。
列表可以包含超过 40 亿 个元素 ( 232 - 1 )。
全部操作
# 增
# 头部
lpush [key] [value] ...
# 尾部
rpush [key] [value] ...
# 在某个值之前或者之后插入
linsert [key] [before|after] [value] [element]
# 删
# 使用 pop 获取并删除
lpop [key] [count]
lpop nameid
lpop nameid 2
rpop [key] [count]
rpop nameid 2
# 改
# 通过索引
lset [key] [index] [value]
# 查
# 通过索引
lindex [key] [index]
lindex nameid 1
# 全部
lrange [key] [start] [stop]
# -1 表示最后一个
lrange nameid 0 -1
# 长度
llen [key]
4.5 集合
Redis 的 Set 是 string 类型的无序集合。
集合成员是唯一的,这就意味着集合中没有重复的数据。
在 Redis 中,添加、删除和查找的时间复杂都是 O(1)(不管 Set 中包含多少元素)。
集合中最大的成员数为 232 – 1 (4294967295), 每个集合可存储 40 多亿个成员。
全部操作
# 增
sadd [key] [member]...
sadd myset a b ab c d
# 删
# 按元素删除
srem [key] [member]...
srem myset abspop myset 1
# 随机删除个数
spop [key] {count}
spop myset 1
# 改
# 没有
# 查
# 查所有
smembers [key]
# 个数
scard [key]
4.6 有序集合
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。Redis 正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数 ( score ) 却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 232 – 1 ( 4294967295 ) , 每个集合可存储 40 多亿个成员。
# 增
# 删
# 改
# 查
4.7 HyperLogLog
4.8 GEO
用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。
4.9 Stream
Redis 5.0 版本新增加的数据结构。
主要用于消息队列(MQ,Message Queue)
提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
5.事务
事务是指一个完整的动作,要么全部执行,要么什么也没有做。
Redis 事务不是严格意义上的事务,只是用于帮助用户在一个步骤中执行多个命令。单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
Redis 事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
MULTI、EXEC、DISCARD、WATCH 这四个指令构成了 redis 事务处理的基础。
- MULTI 用来组装一个事务;
- EXEC 用来执行一个事务;
- DISCARD 用来取消一个事务;
- WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。
6.备份与还原
SAVE
命令用于创建当前 Redis 数据库的备份。
会在 Redis 目录中创建dump.rdb
文件。
将 Redis 备份文件(dump.rdb)移动到 Redis 目录中并启动服务器以恢复 Redis 数据。
查看 Redis 的安装目录
config get dir
1) "dir"
2) "/data"
7.持久化
redis 提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB,简而言之,就是在不同的时间点,将 redis 存储的数据生成快照并存储到磁盘等介质上;
AOF,则是换了一个角度来实现持久化,那就是将 redis 执行过的所有写指令记录下来,在下次 redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
X.原理
X+1 面试题
Redis 穿透
当用户查询的key在redis中不存在,对应的id在数据库也不存在,此时被非法用户进行攻击,大量的请求会直接打在db上,造成宕机,从而影响整个系统,这种现象称之为缓存穿透。
解决方案一:把空的数据也缓存起来,设置一个较短的过期时间。
解决方案二:布隆过滤器,过滤非法请求
Redis击穿
缓存击穿表示某个key的缓存非常热门,有很高的并发一直在访问,如果该缓存失效,那同时会走数据库,压垮数据库。
解决方案:
1、让该热门key的缓存永不过期。
2、使用互斥锁,通过redis的setnx实现互斥锁。
Redis 雪崩
缓存雪崩:缓存中的数据大批量失效,然后这个使用又要大量的请求进来,但是由于redis中的key全部失效了所有会全部请求到db上,造成宕机
解决方案
1.设置对应热点key永不过期
2.过期时间错开,过期时间使用随机生成,并且热点数据的过期时间设置的长一点,非热点数据可以设置短一点
3.多缓存结合,例如:请求进入,可以现请求redis,当redis中不存在的时候再去请求memcache,如果都没有再去请求db
4.采购第三方Redis(阿里云或者腾讯云上的redis)
缓存失效
可能设置了相同的缓存时间
如果是这样就设置不同的缓存时间
使用双缓存策略,设置两个缓存,原始缓存和备用缓存,原始缓存失效时,访问备用缓存,备用缓存失效时间设置长点。