本质理解

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 返回接收到消息的订阅者数量(如 13 消息发布后,所有订阅该频道的客户端都会收到
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把它压垮了。