Redis常用命令(Key、String)

Redis 中返回1就是成功,0、-1、nul则为失败

常用命令

  1. select   0~15                       用于在 0 ~ 15 号库之间进行切换
  2. dbsize                                    查看当前数据库的 key 的数量
  3. flushdb                                  用于清空当前库的 key
  4. flushall                                 用于清空所有库的 key

key常用命令

  1. set   k1   v1                    创建key-value
  2. get   k1                           获取k1对应的value
  3. set   k1   ty                     (当看k1有对应值时)  覆盖k1的value
  4. keys *                           查看当前 redis 库中的所有 key
  5. exists k3                     判断 k3 键是否存在
  6. move k3 1                     将当前库中的 k3 移动到 1 号库
  7. ttl k3                           查看 k3 还有多少秒过期(-1表示永不过期,-2表示已过期),过期就不存在库中
  8. randomkey                     从当前库中随机返回一个 key
  9. rename k2 k3               将键 k2 的名字改为 k3
  10. renamenx k2 k3           只有当 k3 不存在的情况下,将键 k2 的名字改为 k3
  11. expire k3 20               为 k3 设置 20 秒的失效时间
  12. type k3                         查看 k3 键是什么类型

String常用命令

Redis的字符串是动态字符串,支持扩容(一倍)。一个Key默认的储存大小的512M.

  1. del k1                             若 k1 存在,则删除 k1
  2. append k1 234               向键 k1 的 value 后面追加 “234” 字符串(拼接一个字符串,因为键默认是字符串类型
  3. strlen k1                       获取键 k1 的长度
  4. incr k1                           键 k1 对应的 value 加 1(必须是数字类型的字符串)原子操作
  5. decr k1                           键 k1 对应的 value 减 1(必须是数字类型的字符串)原子操作
  6. incrby k1 7                   键 k1 对应的 value 加 7(必须是数字类型的字符串
  7. decrby k1 5                   键 k1 对应的 value 减 5(必须是数字类型的字符串
  8. getrange k1 0 -1        获取键 k1 所对应的 value 的所有位置的值 == get k1
  9. getrange k1 0 2          获取键 k1 所对应的 value 的字符串的前三个字符串(就相当于 substring
  10. setrange k1 1 000      从键 k1 所对应的 value 的下标为 1 的位置向后覆盖 “000” 字符串
  11. setex k2 10 vvv          设置键 k2 对应的 value 为 “vvv” 过期时间为 10 秒
  12. setnx k1 v1                  如果键 k1 不存在的话就添加
  13. mset k1 v1 k2 v2      (m-more)同时设置多个 key-value
  14. mget k1 k2 k3              同时返回多个键对应的 value(不存在的键会返回 nil
  15. msetnx k3 v3 k1 v1    不存在的键才会设置(只要有一个键设置失败,其他的都失败
  16. getset k1 v1                先获取 k1 的旧值,再为它赋新值 “v1”(若之前不存在 k1 则返回 nil)

Redis的scan命令

      熟悉Redis的人都知道,它是单线程的。因此在使用一些时间复杂度为O(N)的命令时要非常谨慎。可能一不小心就会阻塞进程,导致Redis出现卡顿。

      有时,我们需要针对符合条件的一部分命令进行操作,比如删除以test_开头的key。那么怎么获取到这些key呢?在Redis2.8版本之前,我们可以使用keys命令按照正则匹配得到我们需要的key。但是这个命令有两个缺点:

  • 没有limit,我们只能一次性获取所有符合条件的key,如果结果有上百万条,那么等待你的就是“无穷无尽”的字符串输出。
  • keys命令是遍历算法,时间复杂度是O(N)。如我们刚才所说,这个命令非常容易导致Redis服务卡顿。因此,我们要尽量避免在生产环境使用该命令。

在满足需求和存在造成Redis卡顿之间究竟要如何选择呢?面对这个两难的抉择,Redis在2.8版本给我们提供了解决办法——scan命令。

相比于keys命令,scan命令有两个比较明显的优势:

  • scan命令的时间复杂度虽然也是O(N),但它是分次进行的,不会阻塞线程。
  • scan命令提供了limit参数,可以控制每次返回结果的最大条数。

这两个优势就帮助我们解决了上面的难题,不过scan命令也并不是完美的,它返回的结果有可能重复,因此需要客户端去重。

Redis的结构

Redis使用了Hash表作为底层实现,原因不外乎高效且实现简单。说到Hash表,很多Java程序员第一反应就是HashMap。没错,Redis底层key的存储结构就是类似于HashMap那样数组+链表的结构。其中第一维的数组大小为2n(n>=0)。每次扩容数组长度扩大一倍。

scan命令就是对这个一维数组进行遍历。每次返回的游标值也都是这个数组的索引。limit参数表示遍历多少个数组的元素,将这些元素下挂接的符合条件的结果都返回。因为每个元素下挂接的链表大小不同,所以每次返回的结果数量也就不同。

SCAN的遍历顺序

关于scan命令的遍历顺序,我们可以用一个小栗子来具体看一下。

127.0.0.1:6379> keys *
1) "db_number"
2) "key1"
3) "myKey"
127.0.0.1:6379> scan 0 MATCH * COUNT 1
1) "2"
2) 1) "db_number"
127.0.0.1:6379> scan 2 MATCH * COUNT 1
1) "1"
2) 1) "myKey"
127.0.0.1:6379> scan 1 MATCH * COUNT 1
1) "3"
2) 1) "key1"
127.0.0.1:6379> scan 3 MATCH * COUNT 1
1) "0"
2) (empty list or set)

我们的Redis中有3个key,我们每次只遍历一个一维数组中的元素。如上所示,SCAN命令的遍历顺序是

0->2->1->3

这个顺序看起来有些奇怪。我们把它转换成二进制就好理解一些了。

00->10->01->11

       我们发现每次这个序列是高位加1的。普通二进制的加法,是从右往左相加、进位。而这个序列是从左往右相加、进位的。这里大家可能会有疑问了,为什么要使用这样的顺序进行遍历,而不是用正常的0、1、2……这样的顺序呢,这是因为需要考虑遍历时发生字典扩容与缩容的情况(不得不佩服开发者考虑问题的全面性)。

我们来看一下在SCAN遍历过程中,发生扩容时,遍历会如何进行。加入我们原始的数组有4个元素,也就是索引有两位,这时需要把它扩充成3位,并进行rehash。
 

       原来挂接在xx下的所有元素被分配到0xx和1xx下。在上图中,当我们即将遍历10时,dict进行了rehash,这时,scan命令会从010开始遍历,而000和100(原00下挂接的元素)不会再被重复遍历。

       再来看看缩容的情况。假设dict从3位缩容到2位,当即将遍历110时,dict发生了缩容,这时scan会遍历10。这时010下挂接的元素会被重复遍历,但010之前的元素都不会被重复遍历了。所以,缩容时还是可能会有些重复元素出现的。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值