redis常用数据结构命令

redis作为一款高性能key-value数据库,还拥有持久化,多种数据类型,数据备份(主从)等优势,我们本篇先说结构和常用命令和使用场景

基础部分

1.string类型

string主要用于记录字符串类型的缓存数据,常用于存储对象,计数器,设计锁,字符串等
常用命令:

1
2
3
4
get set mget mset getset setex psetex 
setnx msetnx
incr decr incby decrby incrbyfloat
getrange setrange setbit getbit append

使用场景:
get set mget mset常见于普通kv存储的业务命,getset是简化了get后再set的操作,setex psetex是把 set 和 expire / pexpire 简化成一个命令了,set现在已经支持多参数设置了,(最下面的总结会说明一些场 景下为什么使用简化的命令会提升性能,但是实际生产环境下需要结合业务和开发规范来决定)
setnx msetnx 是redis实现锁的一个重要命令(set命令已经支持多参数设置可以实现设置锁且设置超时,避免死锁的风险),业务场景里可以通过该命令实现简单的互斥锁,也可以构建复杂的分布式锁.这里不展开
incr decr incby decrby incrbyfloat 常见于计数器业务,或者信号量
getrange setrange append常见业务逻辑很少用,特殊下的业务场景应该会比较方便,理解其命令用法即可
setbit getbit 这2个命令也是特殊场景下的,实际生产之中我只在构建用户历史记录当中用过,不展开

2.list类型

list常用于构建简单的任务队列
常用命令:

1
2
3
rpush lpush rpop lpop brpop blpop
rpoplpush brpoplpush
llen lindex lrange ltrim lset

使用场景:
rpush lpush rpop lpop brpop blpop队列的 入队 出队 基本操作, brpop属于阻塞pop,队列没有值的时候会等待到超时或出现值
rpoplpush brpoplpush 构建双队列,保活队列常用命令,因为list并没有完整的消息队列功能,所以需要自己设计ack机制,这个时候就需要用到rpoplpush 保证 item 被消费的时候即使出现崩溃,或者异常能把item重新导入到任务队列里继续处理,把数据丢失做到最低
llen lindex lrange ltrim lset 辅助队列的一些命令,比如业务逻辑涉及到定期裁剪,那就会用到 llen 和 ltrim,如果裁剪还有规则就会用到lrange

3.set类型

set常用于需要使用集合的业务场景,比如存放需要存储观看记录,存储ip,存储手机号,存储手机号等等
常用命令:

1
2
3
sadd spop sismember srandmember
scard smove srem smembers
sdiff sdiffstore sinter sinterstore sunion sunionstore

使用场景:
sadd spop sismember srandmember属于基本set操作,此pop是随机移除,srandmember是随机返回一个成员不移除
scard smove srem smembers根据业务来控制set大小,或者其他有删除逻辑会用到这些命令
sdiff sdiffstore sinter sinterstore sunion sunionstoreredis内部实现了差集,交集,并集的操作,但是实际生产环境里不建议使用这些命令,因为redis属于单线程应用,如果一个交集命令非常耗时会阻塞其他客户端的命令

4.zset类型

zset使用场景非常丰富且高效,比如处理排行榜,用作处理队列业务,适用排序功能的业务场景,仅用2个zset结构可以构成一个支持多人订阅消息,还能保证不丢数据的功能,可以用于聊天室业务场景.
常用命令:

1
2
3
4
5
zadd zcard zincrby zcount zscore zrank
zrevrank zrange zrevrange zrangebyscore zrevrangebyscore
zrem zremrangebyrank zremrangebyscore
zinterstore zunionstore
zlexcount zrangebylex zremrangebylex

使用场景:
zadd zcard zincrby zcount zscore zrank zset常用命令,其中zincrby是个成员incr操作的,适合用作排行榜的自增操作
zrevrank zrange zrevrange zrangebyscore zrevrangebyscore 通过索引,分数正序倒序截取zset数据用
zrem zremrangebyrank zremrangebyscore裁剪zset的常用命令
zinterstore zunionstore集合运算
zlexcount zrangebylex zremrangebylex这是一个骚功能,用于 自动识别场景, 比如通讯录里输入张开头 程序返回张开头的所有联系人, 就是用这几个命令实现的,具体做法是 ascall 表 z 的下一位是 {那么就可以 定位 张{ 就可以把张开头的人全部截取到

5.hash类型

hash结构多用于存储对象,存储用户登录token,购物车等业务场景均适用
常用命令:

1
2
hset hget hmset hmget hdel hlen hexists hincrby hincrbyfloat hsetnx
hkeys hvals hgetall

使用场景:
hset hget hmset hmget hdel hlen hexists hincrby hincrbyfloat hsetnx常用操作命令
hkeys hvals hgetall 在hash特别大的时候 hgetall 会造成阻塞, 所以可以用 hkeys 和 hvals 结合使用

其他常用命令

1
type rename del sort expire

常用的改名,删除键,设置过期时间(单位:秒)

最后

实际生产当中最常用的数据类型就是string,包括string可以代替set,zset,hash结构.因为string的速度是最快的,对redis的cpu没有什么消耗,越复杂的结构对redis性能越有影响,而redis是一个单线程应用,如果某个客户端进行复杂结构的运算, 比如 set 和 zset 进行大数量的集合运算,排序等等,就会造成其他客户端阻塞,从而引发更多的问题出现,所以当结构能优化成string时,最好用string,可以把逻辑运算的成本放在业务机器上.

其他结构也需要结合业务来慎重使用,避免热key或者慢查询的情况出现,高并发场景下需要结合业务做多层缓存,碎片化缓存看情况而合并成大缓存,提高响应性能,其他想到什么再写进来.

常用操作命令的思维导图

Bowen wechat
博客文章会同步更新在公众号[后端浪里个浪]
一毛也是爱~