目录
a. redis是干啥的?
Redis是一个高速缓存数据库,是一种key-value(键值对)形式的存储系统,非关系型数据库
b. redis的特点
Redis的数据 是放在内存里的,所以读写会很快,Redis才能实现持久化(两种实现方式 RDB和AOF)
c. redis的用处
1.用作缓存,优点(1.可以减轻数据库压力 2.可以提高查询效率)
2.点赞数,访问量
3.鉴权,cookie和session
登陆成功后,将对应的可以和value放到redis里,下次如果再进来,先访问redis,如果说key存在,说明登陆过,鉴权通过了,如果key不存在,说明鉴权失败,去重新登陆。
1.服务器相关命令
命令 | 描述 |
ping | 检测连接是否存活 |
echo | 在命令行打印一些内容 |
quit、exit | 退出客户端 |
shutdown | 退出服务器端 |
info | 返回redis相关信息 |
config get dir/* | 实时传递接收的请求 |
showlog | 显示慢查询 |
select n | 切换到数据库n,redis默认有16个数据库(DB 0~DB 15),默认使用的第0个 |
dbsize | 查看当前数据库大小 |
move key n | 不同数据库之间数据是不能互通的,move移动键到指定数据库 |
flushdb | 清空当前数据库中的键值对。 |
flushall | 清空所有数据库的键值对。 |
2.Redis 键(key) 命令
命令 | 描述 |
keys * | 查看当前数据库中所有的key |
dbsize | 键总数 |
exists key | 检查键是否存在 |
del key [key …] | 删除键 |
expire key seconds | 用于设置 key 的过期时间。key 过期后将不再可用。 |
ttl key | 以秒为单位,返回给定 key 的剩余生存时间 |
pttl key | 以毫秒为单位返回 key 的剩余的过期时间。 |
persist key | 用于移除给定 key 的过期时间,使得 key 永不过期。 |
pexpireat key 时间戳 | 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计。key 过期后将不再可用。 |
expireat key 时间戳 | expireat 的作用和 expire 类似,都用于为 key 设置过期时间。 不同在于 expireat 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。 |
type key | 键的数据结构类型 |
randomkey | 随机返回数据库中一个键 |
rename key1 key2 | 重命名 |
renamenx key1 key2 | 当key2不存在时,key1重命名 |
3.Redis 事务 命令
命令 | 描述 |
Multi | 标记一个事务块的开始。 |
Discard | 取消事务,放弃执行事务块内的所有命令 |
Exec | 执行所有事务块内的命令。 。 |
Watch | 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
Unwatch | 取消 WATCH 命令对所有 key 的监视。 |
- Multi
执行 Multi 命令,标识一个事务的开启,Redis进入组队阶段,接下来执行的命令都将放入一个缓存队列,注意命令并不会被执行只是加入缓存队列,只有执行Exec命令队列里面的命令才会按照顺序一一开始执行,从而Redis的事务就不会导致数据脏读,不可重复读,幻读的问题,因此就没有隔离级别。
本地Redis:0>Multi // 开启事务
"OK"
本地Redis:0>set k1 1 // 命令组队
"QUEUED" // 组队成功
本地Redis:0>set k2 2
"QUEUED"
本地Redis:0>Exec // 开始执行事务中的命令
1) "OK"
2) "OK"
注意: 在开始事务后组队阶段某个命令出现了报告错误,整个队列都将会被取消,缓存队列中的命令全部作废取消
本地Redis:0>Multi // 开启事务
"OK" // 开启成功
本地Redis:0>set k1 1 // 命令入队
"QUEUED" // 入队成功
本地Redis:0>set k2 // 没有设置value 命令错误
"ERR wrong number of arguments for 'set' command" // 发生报错 整个队列取消
本地Redis:0>
- discard
在命令组队阶段可以执行 discard
命令,放弃在组队的事务,对于已经存在缓存队列中的命令不会执行全部作废,关闭当前事务
本地Redis:0>Multi // 开启事务
"OK" // 开启成功
本地Redis:0>set k1 1 // 命令入队
"QUEUED" // 入队成功
本地Redis:0>set k2 2
"QUEUED"
本地Redis:0>discard // 中断关闭事务
"OK" // 关闭成功
本地Redis:0>
- Exec
在开始事务后,要入队的命令全部入队后,可以执行Exec
命令,缓存队列中的命令将会按照顺序一一执行
本地Redis:0>Multi // 开启事务
"OK"
本地Redis:0>set k1 1 // 命令组队
"QUEUED" // 组队成功
本地Redis:0>set k2 2
"QUEUED"
本地Redis:0>Exec // 开始执行事务中的命令
1) "OK"
2) "OK"
注意: 在执行完Exec命令队列里执行的命令发生错误的话,只有发生错误的命令不执行
,其他没有报错的命令照常执行
本地Redis:0>Multi // 开启事务
"OK"
本地Redis:0>set v1 v1 // 命令入队
"QUEUED"
本地Redis:0>incr v1 // 字符串值无法加一 这条命令是有问题的
"QUEUED" // 命令入队成功
本地Redis:0>Exec // 开始执行命令
1) "OK"
2) "OK" // 其他命令照常执行
3) "OK"
4) "ERR value is not an integer or out of range" // 其中一条命令发生错误
5) "OK"
本地Redis:0>
- WATCH和UNWATCH
乐观锁回滚重试,悲观锁阻塞事务。
(1) WATCH key [ key…] 在执行multi命令之前,可以先执行WATCH key (监视一个或者多个key),如果在事务执行之前watch监视的一个或者多个key被其他命令改动,那么事务将会被打断,有点类似乐观锁。
(2) UNWATCH 取消 WATCH 命令对所有 key 的监视,如果在执行 WATCH 命令之后,EXEC 命令或DISCARD 命令先被执行了的话,那么就不需要再执行UNWATCH 了。
4.五大数据类型
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。其通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
字符串类型: string
哈希类型: hash
列表类型: list
集合类型: set
有序集合类型: sortedset(zset)
1) Redis 字符串(String) 命令
字符串类型是Redis最基础的数据结构,其它的几种数据结构都是在字符串类型基础上构建的,字符串的值可以是:字符串、数字、二进制,但其值最大不能超过512M。
使用场景: 缓存、计数器、对象存储缓存(共享session)、限速
命令 | 描述 |
set key value | 设置一个key的value值 |
setnx key value | 仅当key不存在时进行set |
setex key seconds value | set 键值对并设置过期时间 |
mset key value [key value …] | 设置多个key value |
msetnx key1 value1 [key2 value2…] | 批量设置键值对,仅当参数中所有的key都不存在时执行,原子性操作,一起成功,一起失败 |
get key | 返回key的value |
mget key [key …] | 批量获取多个key保存的值 |
exists key [key …] | 查询一个key是否存在 |
decr/incr key | 将指定key的value数值进行+1/-1(仅对于数字) |
incrby/decrbyB key n | 按指定的步长对数值进行加减 |
incrbyfloat key n | 为数值加上浮点型数值 |
append key value | 向指定的key的value后追加字符串 |
strlen key | 返回key的string类型value的长度。 |
getset key value | 设置一个key的value,并获取设置前的值,如果不存在则返回null |
setrange key offset value | 设置指定位置的字符 |
getrange key start end | 获取存储在key上的值的一个子字符串 |
2) Redis 哈希(Hash) 命令
几乎所有的编程语言都提供了哈希(hash)结构,Redis中 hash 是一个string类型的field和value的映射表value={{field1,value1},{field2,value2}…},可以将一个Hash表作为一个对象进行存储,表中存放对象的信息。
应用场景: 用户信息缓存
命令 | 描述 |
hset key field value | 将哈希表 key 中的字段 field 的值设为 value。重复设置同一个field会覆盖,返回0 |
hmset key field1 value1 [field2 value2…] | 同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
hsetnx key field value | 只有在字段 field不存在时,设置哈希表字段的值。 |
hget key field value | 获取存储在哈希表中指定字段的值 |
hmget key field1 [field2…] | 获取所有给定字段的值 |
hexists key field | 查看哈希表 key 中,指定的字段是否存在。 |
hdel key field1 [field2…] | 删除哈希表key中一个/多个field字段 |
hlen key | 获取哈希表中字段的数量 |
hkeys key | 获取所有字段field |
hvals key | 获取哈希表中所有值value |
hgetall key | 获取在哈希表key 的所有字段和值 |
hincrby key field n | 为哈希表 key 中的指定字段的整数值加上增量n,并返回增量后结果 一样只适用于整数型字段 |
hincrbyfloat key field n | 为哈希表 key 中的指定字段的浮点数值加上增量 n。 |
hscan key cursor [MATCH pattern] [COUNT count] | 迭代哈希表中的键值对。 |
3) Redis 列表(List) 命令
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),也可以获取指定范围指定下标的元素等。一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
两个特点:
1.列表中的元素是有序的,可以通过索引下标获取某个元素霍某个某个范围内的元素列表
2.列表中的元素可以是重复的
使用场景: 消息队列、栈、文章列表等。
增操作 | |
命令 | 描述 |
lpush/rpush key value1[value2…] | 从左边/右边向列表中PUSH值(一个或者多个) |
lpushx/rpushx key value | 向已存在的列名中push值(一个或者多个),list不存在 lpushx失败 |
linsert key before|after pivot value | 在指定列表元素的前/后 插入value |
删操作 | |
命令 | 描述 |
lpop/rpop key | 从最左边/最右边移除值 并返回 |
lrem key count value | count > 0:从头部开始搜索 然后删除指定的value 至多删除count个 count < 0:从尾部开始搜索… count = 0:删除列表中所有的指定value |
ltrim key start end | 通过下标截取指定范围内的列表 |
rpoplpush source destination | 将列表的尾部(右)最后一个值弹出,并返回,然后加到另一个列表的头部 |
查操作 | |
命令 | 描述 |
lindex key index | 通过索引获取列表元素 |
lrange key start end | 获取list 起止元素 (索引从左往右 递增) |
llen key | 查看列表长度 |
改操作 | |
命令 | 描述 |
lset key index value | 通过索引为元素设值 |
阻塞操作 | |
命令 | 描述 |
blpop/brpop key1[key2] timout | 移出并获取列表的第一个/最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
brpoplpush source destination timeout | 和rpoplpush功能相同,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
4) Redis 集合(Set) 命令
Redis的Set是string类型的无序集合,我们不能通过索引获取元素。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
应用场景: 标签(tag)
命令 | 描述 |
sadd key member1[member2…] | 向集合中无序增加一个/多个成员 |
srem key member1[member2…] | 移除集合中一个/多个成员 |
scard key | 获取集合的成员数 |
smembers key | 返回集合中所有的成员 |
sismember key member | 查询member元素是否是集合的成员,若存在返回1,不存在返回0 |
srandmember key [count] | 随机返回集合中count个成员,count缺省值为1 |
spop key [count] | 随机移除并返回集合中count个成员,count缺省值为1 |
sinter key1 [key2…] | 返回所有集合的交集 |
sinterstore destination key1[key2…] | 在SINTER的基础上,存储结果到集合中。覆盖 |
sunion key1 [key2…] | 返回所有集合的并集 |
sunionstore destination key1 [key2…] | 在SUNION的基础上,存储结果到集合中。覆盖 |
sdiff key1[key2…] | 返回所有集合的差集 key1- key2 - … |
sdiffstore destination key1[key2…] | 在SDIFF的基础上,将结果保存到集合中。覆盖 |
smove source destination member | 将source集合的成员member移动到destination集合 |
sscan key [MATCH pattern] [COUNT count] | 在大量数据环境下,使用此命令遍历集合中元素,每次遍历部分 |
5) Redis 有序集合(sorted set) 命令
在有序集合中保留了不能有重复成员的特性,但其中的成员是可以排序的,每一个元素都会关联一个double类型的分数(score)作为排序依据,score相同时按字典顺序排序。redis正是通过分数来为集合中的成员进行从小到大的排序。
应用场景: 排行榜系统,成绩单,工资表
命令 | 描述 |
zadd key score member1 [score2 member2] | 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
zcard key | 获取有序集合的成员数 |
zscore key member | 返回有序集中,成员的分数值 |
zcount key min max | 计算在有序集合中指定区间score的成员数 |
zlexcount key min max | 在有序集合中计算指定字典区间内成员数量 |
zincrby key n member | 有序集合中对指定成员的分数加上增量 n |
zscan key cursor [MATCH pattern] [COUNT count] | 迭代有序集合中的元素(包括元素成员和元素分值) |
zrank key member | 返回有序集合中指定成员的索引 |
zrevrank key member | 返回有序集合中指定成员的索引,从大到小排序 (从0开始) |
zrange key start end | 通过索引区间返回有序集合成指定区间内的成员 |
zrevrange key start end | 通过索引区间返回有序集合成指定区间内的成员,分数从高到底 |
zrangebylex key min max | 通过字典区间返回有序集合的成员(分数相同的情况) |
zrevrangebylex key max min | 按字典顺序倒序返回有序集合的成员 |
zrangebyscore key min max | 返回有序集中指定分数区间内的成员 -inf 和 +inf分别表示最小最大值,只支持开区间 |
zrevrangebyscore key max min | 返回有序集中指定分数区间内的成员,分数从高到低排序 |
zrem key member1 [member2…] | 移除有序集合中一个/多个成员 |
zremrangebylex key min max | 移除有序集合中给定的字典区间的所有成员 |
zremrangebyrank key start stop | 移除有序集合中给定的排名区间的所有成员 |
zremrangebyscore key min max | 移除有序集合中给定的分数区间的所有成员 |
zinterstore dest numkeys key1[key2..] [WEIGHTS weight1 [weight2...]] [AGGREGATE SUM|MIN|MAX] 该命令如下讲解:
求key1,key2的交集,key1,key2的权值分别是weight1,weight2
聚合方法用 sum|min|max,聚合结果 保存子dest集合内
注意:weights,aggregate如何理解?
答:如果有交集,交集元素又有score,score怎么处理?aggregate num->score相加,min最小score,max最大score,另外可以通过weights设置不同的key的权重,交集时 score*weight zunionstore destination numkeys key1 [key2…]: 计算给定的一个或多个有序集的并集并将结果集存储在新的有序集合 key 中。
5.几种特殊数据类型
1) Geospatial(地理位置)
使用经纬度定位地理坐标,底层实现原理就是用一个有序集合zset保存,所以zset命令也可以使用
2) Hyperloglog(基数统计)
Redis HyperLogLog 是用来做基数统计的算法,例如:网页的UV(一个人访问一个网站多次,但是还是算作一个人)。
什么是基数?
数据集中不重复的元素的个数。
应用场景: 传统实现,存储用户的id,然后每次进行比较。当用户变多之后这种方式及其浪费空间,而我们的目的只是计数,Hyperloglog就能帮助我们利用最小的空间完成。
- PFADD–PFCOUNT
127.0.0.1:6379> PFADD myelemx a b c d e f g h i j k # 添加元素
(integer) 1
127.0.0.1:6379> type myelemx # hyperloglog底层使用String
string
127.0.0.1:6379> PFCOUNT myelemx # 估算myelemx的基数
(integer) 11
127.0.0.1:6379> PFADD myelemy i j k z m c b v p q s
(integer) 1
127.0.0.1:6379> PFCOUNT myelemy
(integer) 11
- PFMERGE
127.0.0.1:6379> PFMERGE myelemz myelemx myelemy # 合并myelemx和myelemy 成为myelemz
OK
127.0.0.1:6379> PFCOUNT myelemz # 估算基数
(integer) 17
3) 发布订阅命令
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。订阅/发布消息是非持久的,即在Redis服务器重启之后,原有的订阅和消息都会丢失。
应用场景:
1. 构建实时通知系统。
2. 构建实时聊天或即时通讯系统。
3. 构建日志系统,将日志信息发布到订阅频道。
4. 构建任务队列系统,将任务发布到订阅频道。
命令 | 描述 |
SUBSCRIBE channel [channel ...] | 订阅给定的频道 |
UNSUBSCRIBE [channel [channel ...]] | 指退订给定的频道,当不带任何频道参数时,表示退订所有频道 |
PSUBSCRIBE pattern [pattern ...] | 订阅与给定模式匹配的所有频道 |
PUNSUBSCRIBE [pattern [pattern ...]] | 退订与给定模式匹配的所有频道,当不带任何模式参数时,表示退订所有模式 |
在发布订阅模式下,以下命令可供使用: | |
PUBLISH channel message | 将消息发送到指定的频道 |
PUBSUB subcommand [argument [argument ...]] | 用于在发布订阅系统中检查订阅信息 |
4) BitMaps(位图)
使用位存储,信息状态只有 0 和 1,操作二进制位进行记录 Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR,NOT以及其它位操作。
应用场景:签到统计、状态统计,统计用户信息:活跃,登陆状态等