一 全局命令
针对的全是键的命令
1. keys * :
查看所有键, 遍历查询所有键获取,为避免影响性能,当线上环境有大量键时禁止使用该命令;
2. dbsize :
查看键的数量, dbsize是一个键数量的变量,读取该变量速度很快;
3. exists key:
键是否存在, 如果存在返回1,不存在返回0
4. del key [key…]:
删除键, 结果返回删除键的个数,可以删除多个键,例如:del key1,key2
5. expire key seconds:
设置键的过期时间,
使用ttl key命令来查看键的剩余过期时间,有3种结果:
1)>=0,表示剩余过期时间;
2)-1 键没设置过期时间;
3)-2 键不存在
6. type key:
键的数据结构类型
二 单线程架构
1 单线程模型
每条客户端命令传到redis服务端, 都不会立刻执行,先放到队列中存储, 然后被逐个执行。
每条命令的执行顺序是不确定的, 但是能保证不会同时执行两条命令,保证了并发的安全。
2 单线程为什么还那么快
a 纯内存访问:数据存储在内存中,读写速度快;
b 非阻塞I/O: redis使用I/O多路复用技术实现
c 单线程避免了多线程切换和竞态产生的消耗
三 数据结构
基于key-value键值对的数据结构,和mysql、mongodb的结构都不一样
1 5种数据结构
字符串(string) 哈希(hash) 列表(list) 集合(set) 有序集合(zset)
2 内部编码
1) object encoding key: 查看内部编码
#object encoding hello
> ziplist
2) 内部编码的意义:
当内部编码数据结构改变时,不会影响到对外的数据结构,扩展性好
3 应用场景
列表list和有序集合关于排行榜、有序列表场景的使用区别:
1 当数据量小的时候,两种数据结构都可以使用;
2 当数据量很大,列表list占用的空间笔有序集合小几倍,优先使用列表集合list
四 具体数据结构
4.1 字符串
1 值类型
字符串、数字(整数、浮点数)、二进制(图片、音频、视频)
2 命令
常用命令:
都是针对字符串的value操作的命令
(1)设置值
set key value: 设置key的值
setex key value seconds: 设置key值,并设置过期时间
setnx key value: key不存在才能设置成功,否则返回0
setxx key value: key必须存在才能设置成功
setnx的使用场景:
分布式锁(多条请求同时执行setnx 只有一个客户端能设置成功,其余都失败)
(2)获取值
get key: 获取key的值
如果key不存在,则返回nil(空)
(3)批量设置值
mset key value[key vaue …]
例如:
#mset a 1 b 2 c 3
>OK
(4)批量获取值
mget key[key…]
例如:
mget a b c
>1
>2
>3
mget提高了get效率:
n次get命令用时: n次网络连接 + n次命令执行时间
mget命令用时:1次网络连接 + n次命令执行时间
因redis每秒处理数万的读写操作,处理性能很高, 一般网络连接是性能的瓶颈,n次网络连接的用时特别长,性能较慢,所以获取很多值,可以用mget命令提高查询性能
(5)计数
incr key
执行结果返回3种:
a 不是整数,返回错误
b 整数,返回自增后的数据
c 键不存在,默认是0,返回自增后的1
不常用命令:
(1)字符串尾部追加值
append key value
例如:
get key
> hello
append key world
get key
>helloworld
(2)字符串长度
strlen key
(3)设置并返回原值
getset key value
例如:
get key
>hello
getset key world
> hello
(4)获取部分字符串
getrange key start end
例如:
get key
> dajiahao
getrange key 0 3
>daji
3 内部编码
1)有3种内部编码:
int 8个字节的长整型
embstr 小于等于39个字节的字符串
raw 大于39字节的字符串
2)redis根据类型和长度自动决定使用哪种内部数据结构
例如:
set key 1234
object encoding key
>int
4 使用场景
1)缓存
2)计数
3)session共享
4)限速
用户登录网站,1分钟验证码发送次数不能超过5次,就可以用redis进行存储次数
代码片段:
isExist = redis.set(key,1,"ex 60","nx");
if(isExist != null && redis.incr(key) <= 5){
//通过
.....
}else{
//不通过
......
}
4.2 哈希
1 数据结构
key-{{field1,value1},{field2,value2}} 值本身又是一个键值对
2 命令
都是针对的field-value进行的命令
1)设置值
hset key field value
eg:
hset user name lisi
>1
2)获取值
hget key field
如果field不存在,会返回nil(空)
eg:
hget user name
>"lisi"
3)删除field
hdel key field[field …]
返回结果为成功删除field的个数
eg:
hdel user name
>1
4)field个数
hlen key
5)批量设置或批量获取field-value
hmset key field value[field value …]
hmget key field[field …]
6)判断field是否存在
hexists key field
7)获取所有的field
hkeys key
8)获取所有的value
hvals key
3 使用场景
1)缓存用户信息
类似于关系型数据表的结构,如下:
4.3 列表
1 简介:
1) 类似于java的LinkedList
2) 用来存储多个有序的字符串(元素只能是字符串类型)
3)对列表两端插入和弹出元素使用push、pop命令
2 数据结构特点:
1)列表中元素是有序的, 因此可以通过下标获取、删除指定下标元素
2)列表中元素可以重复
3 命令
1)添加
rpush key value[value …] 从右侧添加元素
lpush key value[value …] 从左侧添加元素
linsert key before|after value1 value 从列表中找到值为value1的元素,在前面或后面插入元素value
2)查找
lindex key index 按指定下标查找元素
lrange key start end 从左侧开始查询下标为start-end的元素列表
llen key 获取列表的长度
查找都是从左侧开始的!!!
lrange索引下标有两个特点:
从左到右,下标为: 0~N-1
从右到左,下标为:-1~-N
3)删除
lpop key 从左侧删除一个元素
rpop key 从右侧删除一个元素
ltrim key start end 只保留下标为start-end之间的元素列表
lrem key count value 删除指定value元素
count的取值决定删除的value数量:
count > 0 ,从左到右,最多删除count个value元素
count < 0 ,从右到左,最多删除count绝对值个value元素
count=0, 删除所有值为value的元素
4)修改
lset key index newvalue 根据下标修改制定元素的值
5)阻塞
blpop
brpop
和lpop rpop类似,只是增加了阻塞操作
4 使用场景
1)消息队列
使用redis的lpush + brpop可以实现消息队列
2) 排行榜
list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名、斗鱼年终盛典主播排名等
3)文章列表
因列表是有序的,且可以根据索引进行搜索,用于文章列表是可行的,如下:
4.4 集合set
1 数据结构特点
1)无序
2)无重复数据
2 命令
2.1 集合内命令
1)添加元素
sadd key member[member …]
返回添加成功的个数
2)删除元素
srem key member[member …]
返回删除成功的个数
3)元素个数
scard key
scard是变量,读取性能快
4)判断元素是否在集合中
sismember key member
存在返回1,不存在返回0
5)随机从集合中返回指定个数集合
srandmember key [count]
count是可选的,不填默认值是1
6)从集合随机弹出(删除)一个元素
spop key
2.2 集合间命令
1)sinter key[key …] 集合间交集
2)sunion key[key …] 集合间并集
3)sdiff key[key …] 集合间差集
3 内部编码
1)intset(整数集合):
当集合内部元素是整数且元素个数小于512个,默认使用intset进行内部实现,减少内存开销
2)hashtable(哈希集合):
当不满足intset条件,或者元素不是整数也会使用hashtable进行内部实现
4 使用场景
标签tag. 不同的人有些对新闻感兴趣,有些对漫画感兴趣, 不同的兴趣就是标签, 根据标签可以获取对应的用户群体,根据标签推送给这部分符合标签的用户群体更多相关的消息, 从而提高用户体验。
4.5 有序集合
1. 数据结构特点
1)无重复数据,和集合set这点相似
2)有顺序,每个元素新增一个score作为排序的依据,集合中的元素不可以重复,但是score是可以重复的
2 命令
2.1 集合内命令
1)添加成员
zadd key score member[score member …]
2)计算成员个数
zcard key
3)计算某成员的分数
zscore key member
4)计算成员的排名
zrank key member
5)删除某成员
zrem key member[member …]
6)增加成员的分数
zincrby key increment member
eg:
zincrby key 50 member
给member原来的分数增加50
7)返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
[withscores]可选,带上会显示分数
8)返回指定分数范围的成员
zrangebyscore key start end [withscores]
zrevrangebyscore key start end [withscores]
3 使用场景
score可以排名,典型的使用场景是排行榜。
eg: 使用用户点赞数为维度,获取用户点赞的排行版情况
展示用户信息和分数、排名:
hgetall user:info:lisi
zscore user:ranking lisi
zrank user:ranking lisi