redis整体快速回顾
本质理解
redis的本质其实就是一个map,用于存储键值对的,他的第二个存储的对象可以是string、set、类等等。
可以吧redis抽象为java服务(因为他也要配置端口、账号、密码等),因此这个里面存储的数据可以为不同的模块提供,所以自然就可以想到redis的2大用途——锁和存储公共数据。
快速上手
在powershell中启动redis:redis-server.exe。启动后就可以看到端口号和密码。
启动redis客户端:redis-cli。可以在客户端里输入各种命令来操作。
基本操作
String
区分大小写,存储的值不支持中文(因为redis显示是以一字节为基本单位,所以会乱码)
| 操作类型 | 命令 / 接口 | 核心功能 | 使用示例 | 返回值 / 说明 | 应用场景 |
|---|---|---|---|---|---|
| 基础写入 | SET key value |
设置指定 key 的值 | `SET name zhangsan | 设置成功返回 OK |
存储普通字符串、分布式锁、更新状态值 |
| 基础读取 | GET key |
获取指定 key 的值 | GET name |
存在返回对应值;不存在返回 nil |
读取缓存值、获取配置项 |
| 仅当不存在时设置 | SETNX key value |
等价于 SET key value ,key 不存在时才设置 |
SETNX name zhangsan |
设置成功返回 1,失败返回 0 |
分布式锁(核心命令) |
| 查看剩余过期时间 | TTL key | 查看 key 的剩余过期时间(秒 / 毫秒) | TTL name |
・正数:剩余秒数• -1:永不过期• -2:key 不存在 |
检查缓存有效期、判断是否需要续期 |
| 查看存在那些键 | KEY * | 查看存在那些键( *表示匹配全部) | |||
| 判断 key 是否存在 | EXISTS key |
判断一个key 是否存在 | EXISTS name |
存在的 key 数量(单个 key 时返回 1/0) |
前置校验、避免覆盖已存在的数据 |
| 清空指定 key | DEL key |
删除一个指定 key(不限字符串类型) | DEL name |
成功删除的 key 数量 | 手动清理缓存、删除过期数据 |
| 清空所有数据 | FLUSHDB(当前库)FLUSHALL(所有库) |
・FLUSHDB:清空当前 Redis 数据库所有 key・FLUSHALL:清空所有数据库所有 key | FLUSHDB``FLUSHALL |
始终返回 OK |
测试环境清理数据、重置 Redis |
| 移除过期时间 | PERSIST key |
移除 key 的过期时间,使其永久有效 | PERSIST user:token |
成功返回 1,key 不存在 / 无过期时间返回 0 |
缓存续期、将临时数据转为永久数据 |
| 设置过期时间 | SETEX NAME 5 VALUE | 快速设置这个值和他的过期时间 |
List
| 命令 | 作用 | 简单说明 | 举例 |
|---|---|---|---|
| LRANGE | 获取列表内容 | LRANGE key start stop 查看列表指定区间的元素 |
LRANGE letter 0 -1,表示从0开始查看all元素 |
| LPUSH | 从列表 左边(头部) 添加元素 | 可一次加一个或多个,左边进 | LPUSH letter a,中间必须跟队列名 |
| RPUSH | 从列表 右边(尾部) 添加元素 | 可一次加一个或多个,右边进 | |
| LPOP | 删除并返回列表 最左边(头部) 元素 | 从头部删一个 | lpop letter 2,接2表示删除2个 |
| RPOP | 删除并返回列表 最右边(尾部) 元素 | 从尾部删一个 | |
| LTRIM | 只保留指定区间,删除其他元素 | LTRIM key start stop 裁剪列表 |
保留范围是[start,stop] |
| LLEN | 查看列表长度 |
Set
无序集合。
| 命令 | 核心功能 | 语法示例 | 返回值说明 | 关键特性 |
|---|---|---|---|---|
SADD |
向集合中添加一个或多个元素 | SADD course Redis SADD course Redis Java Python |
成功添加的新元素数量(重复元素不会被添加,不计入计数) | 集合自动去重,不允许重复元素 |
SMEMBERS |
获取集合中所有元素 | SMEMBERS course |
集合中所有元素的列表(无序) | 元素顺序不固定,Set 是无序集合 |
SISMEMBER |
判断元素是否存在于集合中 | SISMEMBER course Redis SISMEMBER course Python |
1:元素存在 0:元素不存在 |
用于快速判断成员归属,时间复杂度 O (1) |
SREM |
从集合中移除一个或多个元素 | SREM course Redis SREM course Redis Java |
成功移除的元素数量(不存在的元素不计入) | 仅移除已存在的元素,不存在则忽略 |
Sortedset
有序集合,他和set的区别在于Sortedset中每个元素都关联了一个浮点数排了序。有序集合的命令都是以Z开头的。
| 命令 | 核心功能 | 语法示例 | 返回值说明 | 关键特性 |
|---|---|---|---|---|
ZADD |
向有序集合中添加一个或多个元素(带分数) | ZADD result 680 清华 660 北大 650 复旦 640 浙大 |
成功添加的新元素数量(重复元素更新分数,不计入计数) | 按 ** 分数(score)** 自动排序,元素唯一 |
ZRANGE |
按分数升序获取指定区间的元素 | ZRANGE result 0 -1``ZRANGE result 0 -1 WITHSCORES |
元素列表(默认升序);加 WITHSCORES 同时返回元素和对应分数 |
下标从 0 开始,-1 代表最后一个元素 |
ZSCORE |
获取指定元素的分数 | ZSCORE result 清华 |
元素对应的分数(字符串格式);元素不存在返回 nil |
时间复杂度 O (1) |
ZRANK |
获取元素的升序排名(分数从小到大) | ZRANK result 清华 |
排名下标(从 0 开始);元素不存在返回 nil |
分数越小,排名越靠前 |
ZREVRANK |
获取元素的降序排名(分数从大到小) | ZREVRANK result 清华 |
排名下标(从 0 开始);元素不存在返回 nil |
分数越大,排名越靠前 |
ZREM |
移除有序集合中的一个或多个元素 | ZREM result 清华 |
成功移除的元素数量(不存在的元素不计入) | 仅移除已存在的元素 |
哈希HASH
命令都是以H开头。
| 命令 | 核心功能 | 语法示例 | 返回值说明 | 关键特性 |
|---|---|---|---|---|
HSET |
向哈希表中设置一个或多个字段值 | HSET user name 张三 age 20 |
成功新增的字段数量(更新已有字段不计入) | 字段不存在则新增,存在则覆盖值 |
HGET |
获取哈希表中指定字段的值 | HGET user name |
字段对应的值;字段不存在返回 nil |
时间复杂度 O (1) |
HGETALL |
获取哈希表中所有字段和对应的值 | HGETALL user |
字段 - 值对的列表(字段 1、值 1、字段 2、值 2…) | 一次性返回所有键值对 |
HDEL |
删除哈希表中一个或多个指定字段 | HDEL user age |
成功删除的字段数量(不存在的字段不计入) | 仅删除已存在的字段 |
HKEYS |
获取哈希表中所有字段名(键) | HKEYS user |
所有字段名的列表 | 只返回字段名,不返回值 |
HLEN |
获取哈希表中字段的总数量 | HLEN user |
哈希表中字段的个数 | 时间复杂度 O (1) |
发布订阅和Stream
发布的消息无法持久化,无法查看历史记录等功能。
| 命令 | 核心功能 | 语法示例 | 返回值 / 说明 | 关键特性 |
|---|---|---|---|---|
PUBLISH |
向指定频道发布消息 | PUBLISH geekhour redis |
返回接收到消息的订阅者数量(如 1、3) |
消息发布后,所有订阅该频道的客户端都会收到 |
SUBSCRIBE |
订阅一个或多个频道 | SUBSCRIBE geekhour |
进入订阅模式,持续接收消息 | 订阅后只能接收发布的消息,无法执行其他命令 |
| STREAM流就是弥补发布订阅的缺陷的,其中的命令都以x开头。 |
Geospatial和HyperLogLog,Bitmap和Bitfield
Geospatial:添加地理位置信息,获取某个地理位置的经纬度,也可以计算两个地理位置之间的距离,也可以查询范围之内的地区。
HyperLogLog:是一种用来基数统计的算法(精确度要求不是特别高但是数据量很庞大的统计工作)(PF开头)
位图Bitmap:可以用来记录签到情况等。
位域BitField:可以将很多小的整数存到位图中。
事务、持久化、主从复制和哨兵模式
事务(可以在一次请求中执行多个命令,无法保障所有的事务执行都能成功)
MULTI开启(将所以命令放入队列,不会立即执行)——开启后可以执行set、get等命令。
EXEC执行(所有命令都执行,不会因为其中一个命令没有执行就退出 )
redi本身是基于内存的,若无持久化一断电所以数据都没了。
下面2种持久化模式:
RDB是指在指定时间内,将内存的数据快照写入磁盘(某个时间节点的完整副本)
AOF(不仅将命令写到内存中,还会写到硬盘的追加文件中,以日志的形式记录)
bgsave可以单独创建一个子进程用来存储进硬盘中,因为如果直接进行RDB存储会进入阻塞状态,不能接受任何指令。
主从复制:将一台服务器数据复制到其他服务器,只能由主节点到从节点。
默认配置就是主节点,只需要配置从节点就行了,可以通过配置文件来配置。
进入到redis安装目录下redis.config文件是配置文件,在从节点添加主节点端口号从而完成主从配置。
哨兵模式
(1)用来监控redis节点是否正常。
(2)从而进行通知。
(3)自动故障转移。
面试问题
缓存雪崩
缓存学崩指的是在同一时间内大量的key失效或者说redis宕机,导致所有请求瞬间全部打到数据库,数据库压力暴增甚至直接被打垮,就像雪崩一样压垮整个系统。
解决办法就是可以将缓存失效时间分散开,比如可以在原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
缓存击穿
缓存击穿就是给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。
解决办法就是添加互斥锁的方式,当第一个访问到达时,他去访问数据区时加锁,后续拿到数据存redis里后解锁,此时就不会有大量请求连接到DB把它压垮了。
