Redis 指令合集

113 阅读8分钟

最近网易面试问到了使用zset取第i个数的指令,没有回答出来😅。写这篇文章来整理一下redis常用的指令,会根据不同的数据类型进行汇总。如果大家有兴趣的话可以自己在这个网站上面尝试使用redis:在线redis指令

String 字符串

基本指令

  1. 展示所有的key
  2. 设置key,value
  3. 获取key对应的value
  4. 给一个key的值追加内容
  5. 同时设置多对key value
  6. 同时获取多个key的值
  7. 获取value某个区间内的值
  8. 替换value从某个offset开始的后续内容
> keys *  # 展示所有的key
(empty list or set)
> set k1 v1  # 设置一个key value对
OK
> get k1  # 获取k1对应的值
"v1"
> append k1 1  # 对k1的值追加内容"1"
3
> get k1
"v11"
> mset k2 v2 k3 v3  # 设置多个key value对
OK
> mget k2 k3  # 得到多个key的值
1) "v2"
2) "v3"
> getrange k1 1 2  # 得到value对应的范围内的字符串
"11"
> setrange k1 1 2222  # 替换1索引位置之后的部分为"2222"
5
> get k1
"v2222"

拓展功能

  • 计数:value除了是字符串,也可以是数字,可以应用在计数器、粉丝量等应用场景下,需要结合incrbydecrby指令使用:
set counter 1
OK
> incrby counter 2  # 将counter中的字符串转换为数字并加2
(integer) 3
> decrby counter 1  # 将counter中的字符串转换为数字并减1
(integer) 2
  • 对象存储:
> mset user:1:name zhangsan user:1:age 24
OK
  • 分布式锁:当key不存在时才能设置key,相当于在并发操作时某一个时刻最多只有一个线程能够设置这个key的值,因此可以设置为分布式锁
    • 持有锁的线程宕机了怎么办?这种情况会导致其他线程无法获取锁,因此可以添加一个失效时间,在该线程宕机之后能够通过超时机制释放锁,但是这个过期时间难以准确的设置,过短的话业务逻辑可能没处理完,过长的话可能会导致宕机之后产生的死锁时间长。可以发现过期时间接近业务逻辑的处理时间时才更好,如何设置这个业务逻辑的时间?可以通过看门狗的方式,相当于在持有锁的线程中再记录一个计时器,当时间经过一半之后会自动重新设置过期时间,让它重新开始计时,当宕机之后这个看门狗也会同时挂掉,因此不会自动续约,这样就可以保证一个合理的失效时间。
    • 如何保证释放的是自己加的锁?可能线程A释放锁之前,这个锁就过期了,但是线程B已经开始持有这个锁,如果A去释放这个锁的话就会导致A把B的锁的释放,从而产生冲突。在加锁的指令setnx key value,这个value的值会是一个随机数,当释放锁时会判断这个value是否和自己设置的随机数相同,相同的时候才会去释放锁。
    • setnx不支持直接设置失效时间需要结合expire指令使用,但是这样操作不能保证原子性,可以采用set ex nx指令set key value ex exp_time nx,该指令是原子的
    • 红锁是什么?为了保证redis的高可用,可能会使用redis集群,使其在某些redis实例挂掉的时候也能提供服务,红锁采用主节点过半机制,即获取锁或者释放锁成功的标志为:在过半的节点上操作成功。加锁步骤:参考链接
      • 获取当前的时间(单位是毫秒)。
      • 使用相同的key和随机值在N个节点上请求锁。这里获取锁的尝试时间要远远小于锁的超时时间,防止某个masterDown了,我们还在不断的获取锁,而被阻塞过长的时间。
      • 只有在大多数节点上获取到了锁,而且总的获取时间小于锁的超时时间的情况下,认为锁获取成功了。
      • 如果锁获取成功了,锁的超时时间就是最初的锁超时时间进去获取锁的总耗时时间。
      • 如果锁获取失败了,不管是因为获取成功的节点的数目没有过半,还是因为获取锁的耗时超过了锁的释放时间,都会将已经设置了key的master上的key删除。
> setnx key value  # 不存在key时才设置 set key value when key not exists

List 列表

指令都是以l开头,可以用来实现队列、栈等结构,栈:lpush lpop,队列:rpush lpop

LINDEXLLENLPOPLPUSHLRANGELREMLSETLTRIM, RPOPRPOPLPUSHRPUSH,

  • list实现栈
  • list实现队列
  • 得到列表长度
  • 获得某个索引对应的元素
  • 查看指定索引范围内的元素
  • 在指定位置前/后插入元素
  • 移除指定值的元素
> lpush mystack 1 2 3 4  # 从左侧依次插入1 2 3 4共4个元素
(integer) 4
> lrange mystack 0 -1  # 查看所有元素
1) "4"
2) "3"
3) "2"
4) "1"
> lpop mystack  # 从左侧弹出一个元素
"4"
> lpop mystack
"3"
> rpush myqueue 1 2 3 4  # 从右侧依次插入1 2 3 4共4个元素
(integer) 4
> lrange 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
> lpop myqueue
"1"
> llen myqueue  # 查看列表myqueue的长度
(integer) 3
> lindex myqueue 0  # 查看索引0处的元素值
"2"
> lrange myqueue 0 1  # 查看[0,1]范围内的元素值
1) "2"
2) "3"
> linsert myqueue after 2 1  # 在值为2的元素后面插入1
4
> lrange myqueue 0 -1
1) "2"
2) "1"
3) "3"
4) "4"
> lrem myqueue 1 2  # 从左到右移除1个值为2的元素
(integer) 1
> ltrim myqueue 0 1 # 按照索引范围截取列表
OK
> lrange myqueue 0 -1
1) "1"
2) "3"
> lset myqueue 0 3  # 设置索引0处的值为3
OK

Set 集合

无序不重复集合,set中的值不可以重复,命令都是s开头

SADDSCARD, SDIFFSDIFFSTORE, SINTER, SINTERSTORE, SISMEMBER, SMEMBERS, SMOVE, SORT, SPOP, SRANDMEMBER, SREM, SUNION, SUNIONSTORE

  1. 添加一个元素
  2. 查看某个元素是否存在
  3. 查看所有的元素
  4. 查看集合中元素的个数
  5. 随机抽取指定数量的元素
  6. 随机删除一个值
  7. 将元素从集合A移动到集合B
  8. 两个集合的交集
  9. 两个集合的并集
  10. 两个集合的差集
> sadd a 1 2 3  # 向集合a中依次加入元素1 2 3
(integer) 3
> smembers a  # 查看集合中的所有元素
1) "1"
2) "2"
3) "3"
> sismember a 1  # 查看1是否存在于a中
(integer) 1
> scard a  # 查看集合a的元素个数
3
> srem a 2  # 删除集合a中值为2的元素
1
> srandmember a 1  # 随机获取1个元素
1) "1"
> spop a  # 随机删除一个元素
"1"
> sadd b 1 2 3 4
(integer) 4
> sdiff a b  # a-b a中有但是b中没有的元素
(empty list or set)
> sdiff b a  # b-a b中有但是a中没有的元素
1) "1"
2) "2"
3) "4"
> sinter a b  # a和b的交集
1) "3"
> sunion a b  # a和b的并集
1) "1"
2) "2"
3) "3"
4) "4"

Hash 哈希

Map集合 <key, map>,本质上还是相当于String类型HDELHEXISTSHGETHGETALLHINCRBYHKEYSHLENHMGETHMSETHSETHVALS

  1. 创建一个map
  2. 在map中创建一个kv对
  3. 在map中创建多个kv对
  4. 查看map中所有的key
  5. 查看map中所有的value
  6. 查看map中所有的kv对
  7. 查看map中key的数量
  8. 判断map中某个key是否存在
  9. 删除map中的某个key
> hmset mymap k1 v1 k2 v2
OK
> hkeys mymap
1) "k1"
2) "k2"
> hvals mymap
1) "v1"
2) "v2"
> hgetall mymap
1) "k1"
2) "v1"
3) "k2"
4) "v2"
> hlen mymap
2
> hexists mymap k1
(integer) 1
> hdel mymap k1
(integer) 1

Zset 有序集合

在set的基础上,增加了一个值(float类型)来表示优先级 set k1 v1 -> zset k1 score1 v1,指令都是以z开头

  1. 增加元素
  2. 集合中元素的个数
  3. 移除元素
  4. 获取指定score区间内元素的个数
  5. 从小到大展示
  6. 从大到小展示
  7. 获取第i大的元素
> zadd myzset 1 a 2 b 3 c  # 加入元素 score在前 value在后
(integer) 3
> zcard myzset  # 查看集合中的元素
3
> zrem myzset a  # 删除集合中为a的元素
1
> zcount myzset 2 3  # 统计score>=2并且score<=3的元素数量
2
> zrangebyscore myzset -inf inf  # 根据score正序输出
1) "b"
2) "c"
> zrangebyscore myzset -inf inf withscores  # 根据score正序输出 带有score值
1) "b"
2) 2.0
3) "c"
4) 3.0
> zrevrangebyscore myzset inf -inf  # 倒序输出 
1) "c"
2) "b"
> zrevrange myzset 0 -1  # 倒序输出
1) "c"
2) "b"
> zrange myzset 0 -1  # 正序输出
1) "b"
2) "c"
> zrange myzset 1 1  # 找到集合中索引为1的元素
1) "c"