redis常用命令集锦

发布时间:2022-04-01 15:38:41 作者:yexindonglai@163.com 阅读(1288)

redis数据类型

redis的数据类型是针对value的, key是一个对象,里面有个type和encoding

  • type:类型,一般都是字符串string
  • encoding:字符集

启动redis

  1. ./redis-server &: 以后台程序方式运行redis
  2. ./redis-server /etc/redis/6379.conf:指定配置文件运行
  3. redis-cli -p 6380: 指定端口号运行

redis-cli命令 连接到服务端

redis默认有16个库,从0开始到15,每个库都是独立的数据,互不共享,连接之前下先进入/.../redis-3.0.6/src/目录;

  1. redis-cli:默认连到6379
  2. redis-cli -p 6380:连接到6380端口的redis
  3. redis-cli -n 1 // 连接到哪个库,默认第0个库
  4. redis-cli -p 6379 -a root // -p指定端口,-a指定认证密码,redis不需要用户名,redis服务是主机加密码来进行认证的
  5. /redis-cli –p 6379 --raw (终端展示中文,不加--raw时展示的是字节码:xb0\xe4\xb8\x9c)

连接密码

如果配置了密码,在连接到reids进行操作时会提示错误(error) NOAUTH Authentication required.,遇到这种问题,输入以下命令即可解决

  1. # password是你的密码,比如我的密码是123,那么命令为:auth 123
  2. auth pwssword

所有命令

  1. keys * :查看所有的key值
  2. flushdb:清空所有数据,尽量不要使用这个命令
  3. flushall:清空所有数据,尽量不要使用这个命令
  4. clear :清屏
  5. set key111:1 hello: 设置到1号库,key111,value为hello
  6. get key111:1:获取1号库,key为key111的值
  7. select 8:进入8号库
  8. help:查看帮助命令
  9. type k1 :查看k1的value数据类型
  10. exit:退出redis
  11. help @string :查看string数据类型的所有命令
  12. help @list:查看list数据类型的所有命令
  13. help @hash :查看hash数据类型的所有命令
  14. help @set :查看set数据类型的所有命令
  15. help @sortset :查看sortset数据类型的所有命令
  16. help set :查看某个命令的使用方法,比如:help rpush

string 数据类型命令

  1. set key value:设置值
  2. get key:获取指定key的值
  3. getset k1 yexindong : 取回老的值,并且设置新值
  4. set k1 hello nx:nx表示当k1这个key不存在的时候才可以设值,如果已存在则不允许设值,分布式锁的时候可以使用这个功能
  5. set k1 hello xx:xx表示只能更新,当k1这个key存在的时候才能更新值,不存在时不允许设值;
  6. mset k3 hello k4 would:同时设置多个key-value
  7. mget k3 k4:同时获取多个key的value
  8. msetnx k1 a k2 b :同时设置多个值,并且key不存在的时候才可以设值,如果已存在则不允许设值,这是个原子性操作,只要有一个失败的,那么全都失败,跟事务一样,要么一起成功,要么一起失败
  9. append k1 "world":在k1上追加字符串后在重新设回k1,如果一开始k1的值是 hell,执行完append k1 “world”命令后,k1的值就是hello world了
  10. getrange k1 6 10:相当于java的substring(6,10)方法
  11. getrange k1 6 -1: 获取k1字符串第6个下标到最后一个字符之间的内容
  12. setrange k1 6 yexindong:修改第6个下标之后的所有值,如果k1的初始值为hello world,执行完这个命令后会变成 hello yexindong
  13. strlen k1:统计k1字符串的长度,和java的length方法一样
  14. set key value ex 20 :设置一个自动过期的key,20秒后自动过期,
  15. set key value px 20 :设置一个自动过期的key,20毫秒后自动过期,
  16. ttl key: 查看一个key的有效期,返回负数-2以上表示已过期,-1是永久存在,不过期
  17. expire k4 50 :给一个key设置过期时间,不管key是否存在都可以设置;
  18. EXPIREAT runoobkey 1293840000 :设置key在指定时间后过期,这个时间需要先转成long类型时间戳;

数值的操作

  1. set knum 99.01 :设置数字或小数
  2. incr k1 : k1的数值基础上+1,前提value必须是int,支持小数
  3. incrby k1 22 :k1的数值基础上+22,前提value必须是int,支持小数
  4. decr k1:k1的数值基础上减1,前提value必须是int,支持小数
  5. decrby k1 10 :k1的数值基础上减10,前提value必须是int,支持小数

String的set命令实现hash功能

  1. # yexindong为外层的key值,冒号后面为value中的key值;一个用户有多个属性,就可以这么表示;
  2. set yexindong::id 1 // yexindong的用户id
  3. set yexindong::age 28 // yexindong的年龄
  4. set yexindong::name '叶新东' // yexindong的中文名称
  5. set yexindong::url 'http://xxx.com' //yexindong的主页
  6. # 查看所有值,展示yexindong这个key下面的所有key值,只是key,没有value;
  7. keys yexindong*

bitmap 位图操作

setbit

将二进制的第二位设为1,此时kbit的二进制为0100,转为sacii码就是@

  1. setbit k2 1 1
  2. 127.0.0.1:6379> get k2
  3. @

在K2的基础上在设置,把第7位也设为1,此时的二级制就是0100 0001,转为sacii码就是A

  1. 127.0.0.1:6379> setbit k2 7 1
  2. 127.0.0.1:6379> get k2
  3. A

bitpos 命令

bitpos命令用于查找字节的某个位的值,就拿上面的二进制来举例0100 0001

  1. # 我要找k2二进制中 1 是不是出现在第0个字节的第1个位置上
  2. bitpos k2 1 0 1
  3. 1
  4. # 我要找k2二进制中 1 是不是出现在第0个字节的第7个位置上
  5. bitpos k2 1 0 7
  6. 1
  7. # 我要找k2二进制中 1 是不是出现在第0个字节的第6个位置上,肯定找不到的,所以返回-1
  8. bitpos k2 1 0 67
  9. -1

bitcount

统计二进制中出现了几个1,
以下例子统计k2的二进制中第0个字节和第1个字节之间出现了几个1

  1. bitcount k2 0 1
  2. 2

bitop 按位与、按位或运算

将k1和k2的二进制进行按位与运算后将结果放到andkey中

  1. bitop and andkey k1 k2

将k1和k2的二进制进行按位或运算后将结果放到orkey中

  1. bitop or orkey k1 k2

bitmap 有什么用?

比如有这样一个场景,要统计用户一年中的登录天数,并且要统计某个用户在一年中某个期间登录了多少天,那么就可以用bitmap,这种需求,虽然用关系型数据库也能实现,但是会占用大量的磁盘空间,用位图存储可以节省大量空间;

用二进制来表示用户登录的天数,可以这么干,

  1. #第一天登录了,命令如下
  2. setbit zhangsan 0 1
  3. #用二进制表示如下
  4. 1000
  5. #第8天登录了,命令如下
  6. setbit zhangsan 7 1
  7. #用二进制表示如下
  8. 0000 0001
  9. #一年365天,在第364天登录了,命令如下
  10. setbit zhangsan 363 1
  11. #用二进制表示如下,其中的1在二进制的第363个位置
  12. 00000.....10

接下来,因为一个字节是8个位,所以我们可以统计某个用户头16天里面登录了几天,可以这么干

  1. bitcount zhangsan 0 1

正反向索引

可以通过反向索引统计某个用户一年中最后16天登录了几天,可以这么干,-1表示倒数第一个字节,-2表示倒数第二个字节;

  1. bitcount zhangsan -1 -2

一个统计头16天,一个统计尾16天,简单的2个命令就实现了,是不是很简单呢?

list (链表)

  1. list是一个双向链表,每个节点除了自身元素外,还维护了2个指针,一个指向上一个节点(pre),另一个指向下一个节点(next)
  2. 也是一个双端队列,有一个head变量指向队头,还一个tail变量指向队尾;
  3. 利用 lpushlpop命令组合可实现栈的功能(先入后出、后入先出)
  4. 利用rpushrpop命令组合可实现队列功能(先入先出、后入后出)
  5. 利用lindexlset可实现数组功能

常用命令

lpush 头插

前面的l表示left ,从左往右将数据添加到链表中,也就是头插法,就拿下面的例子来说

  1. lpush k1 a b c d e f
  2. # 将 a b c d e f 依次在k1的头部插入
  3. #添加a时k1的数据为 a
  4. #添加b时k1的数据为 b a
  5. #添加c时k1的数据为 c b a
  6. #添加d时k1的数据为 d c b a
  7. #添加e时k1的数据为 e d c b a
  8. #添加f时k1的数据为 f e d c b a
rpush 尾插

前面的r表示right,从右往左将数据添加到链表中,也就是尾插法,举例

  1. rpush k2 a b c d e f
  2. # 将 a b c d e f 依次在k2的尾部插入
  3. #添加a时k2的数据为 a
  4. #添加b时k2的数据为 a b
  5. #添加c时k2的数据为 a b c
  6. #添加d时k2的数据为 a b c d
  7. #添加e时k2的数据为 a b c d e
  8. #添加f时k2的数据为 a b c d e f

lrange命令

  1. LRANGE k1 0 -1 //打印k1列表的所有值,打印从0开始到最后一个(-1)元素的值;
  2. LRANGE k1 -2 -1 // 打印列表尾部的最后2个元素值
  3. LRANGE k1 0 0 // 打印列表头部第一个元素值
  4. LRANGE k1 0 1 // 打印列表头部的头2个元素值

lindex命令

lindex命令的功能是取出list中某个下标的值

  1. lindex k1 2 // 获取第二个元素的值
  2. lindex k1 -1 // 获取最后一个元素的值

lpop

lpop的功能是移除头部的第一个元素

  1. 比如k2的列表内容为: a b c
  2. lpop k2 // 取出头部第一个元素a,此时还剩下b 和c
  3. lpop k2 // 取出头部第一个元素b,此时还剩下c
  4. lpop k2 // 取出头部第一个元素c,此时列表为空

rpop

rpop的功能是移除尾部第一个元素,和队列的出队一样

  1. 比如k2的列表内容为: a b c
  2. rpop k2 // 取出尾部第一个元素c,此时还剩下a 和b
  3. rpop k2 // 取出尾部第一个元素b,此时还剩下a
  4. rpop k2 // 取出尾部第一个元素a,此时列表为空

blpop

b表示blocking,是阻塞的意思,l表示left,blpop命令是以阻塞的方式移除队头的第一个元素,如果list中没有元素,则进入阻塞状态,等到有值为止

  1. blpop kbs 2 // 获取key为kbs的头部第一个元素,如果队列为空,阻塞等待2秒,2秒后若还没有其他线程插入元素,则自动退出
  2. blpop kbs 0 //获取key为kbs的头部第一个元素,如果队列为空,一直阻塞直到有人塞值为止

brpop

blpop命令同理,区别是blpop移除头部元素,brpop移除尾部元素

lrem

lren 用于删除元素

  1. # 比如k3的list内容为 1 a 2 a 3 a
  2. lrem k3 2 a // 删除前2个a
  3. 删除后的内容为: 1 2 3 a
  4. lrem k3 1 a // 删除前一个a
  5. # 比如k4的list内容为 1 a 2 a 3 a
  6. lrem k3 -2 a // 删除最后2个a,删除后的内容为:1 a 2 3
  7. lrem k3 -1 a // 删除最后的一个a

linsert

插入命令

  1. # 比如k4目前的值为 a b c d
  2. linsert k4 after a 1 // 往字符a后面插入1,执行命令后k4的值为:a 1 b c d
  3. # 遇到有2个相同的字符怎么半?比如k5目前的值为 a 1 b c d 1
  4. linsert k5 after 1 2 //往1后面插入2,执行命令后k5的值为:a 1 2 b c d 1;只会插入一次
  5. # 比如k6目前的值为 a b c d
  6. linsert k6 before a x // 在a前面插入x,执行命令后k6的值为:x a b c d

llen

统计list的元素个数

  1. llen k5

LTRIM

和substring类似

  1. # 比如我k7的list为: a b c d e f
  2. ltrim k7 2 -1 // 截取第2个元素(元素从0开始)开始到末尾,执行命令后k7的值为:c d e f
  3. # 比如我k7的list为: a b c d e f
  4. ltrim k7 2 -2 // 截取第2个元素(元素从0开始)开始到倒数第二个元素的值,执行命令后k7的值为:c d e

hash

hash就想是java里面的hashMap,hash是key-value键值对格式的,就相当与是hashMap里面的value又是一个hashMap;

hash的lset命令

  1. # yexindong是最外层的key,name是内存的key,值为:叶新东
  2. hset yexindong name '叶新东' // 设置单个key-value
  3. hset

hget

获取某个key的值

  1. hget yexindong name // 获取yexindong的name属性
  2. hget yexindong age // 获取yexindong的age属性

hmset 命令

hmset 用于同时设置多个key-value

  1. // 设置yexindong 的性格(sex) 和 主页(url)
  2. hmset yexindong sex 1 url 'http://xxx.com'

hmget 命令

同时获取多个key的值

  1. hmget yexindong name sex

hkeys

获取某个key下面的所有key

  1. hkeys yexindong

hvals

获取所有的value,不包括key

  1. hvals yexindong

hgetall

获取所有的key-value键值对,

  1. hgetall yexindong

HINCRBY 数值计算

可对hash中的数值进行计算,但仅限于整数,不能进行小数计算,此功能可用来计算详情页的点赞数量和收藏数量;

  1. //将yexindong的age + 1
  2. HINCRBY yexindong age 1
  3. //将yexindong的age 减 2
  4. HINCRBY yexindong age -2

HINCRBYFLOAT 小数计算

  1. yexindongage + 0.5
  2. HINCRBYFLOAT yexindong age 0.5
  3. yexindongage 1.5
  4. HINCRBYFLOAT yexindong age -1.5

set

list和set的区别

  • list有序,set无序
  • list可以重复,set自动去重

sadd

添加元素,可以同时添加多个

  1. sadd s1 1 2 3 4

smembers

遍历所有的元素

  1. smembers s1

srem

删除元素

  1. // 删除元素值为1 和 2的值
  2. srem s1 1 2

sinter

sinter命令用于比较多个个key的交集部分

  1. //比如有3个key,
  2. //s1: 1 2 3 4
  3. //s2: 3 4 5 6
  4. //s3: 3 4 9 10
  5. sinter s1 s2 s3 // 输出s1、s2、 s3 的的交集数据,结果为3 4

sinterstore

sinterstore命令用于将多个key的交集保存到指定的新key中

  1. //比如有3个key,
  2. //s1: 1 2 3 4
  3. //s2: 3 4 5 6
  4. //s3: 3 4 9 10
  5. //将s1、s2、 s3 的的交集数据保存到scount中
  6. sinterstore scount s1 s2

sunion

sunion 是将多个key中并集的提取出来并输出

  1. //比如有2个key,
  2. //s1: 1 2 3 4
  3. //s2: 3 4 5 6
  4. sunion s1 s2 // 输出结果为:1 2 3 4 5 6

sunionstore

sunionstore 是将多个key中并集的提取出来保存到新的key中

  1. //比如有2个key,
  2. //s1: 1 2 3 4
  3. //s2: 3 4 5 6
  4. sunionstore socunt s1 s2 // socunt结果为:1 2 3 4 5 6

sdiff 差集

差集指的是两个key之间 第一个key中元素减去两个key中的交集部分的结果

  1. //比如有2个key,
  2. //s1: 1 2 3 4
  3. //s2: 3 4 5 6
  4. sdiff s1 s2 // 输出结果为 1 2
  5. sdiff s2 s1 // 输出结果为 5 6

SRANDMEMBER

SRANDMEMBER 用于返回集合中的随机元素,可以用来抽奖,
SRANDMEMBER有个count参数,

  • 当count为正数时,返回一个count个数的数组,并且数组中的元素不会重复
  • 当count为负数时,返回一个count个数的数组,数组中的元素可能会重复多次;
  1. SRANDMEMBER s1 5 // 返回去重后的数组,元素不会重复
  2. SRANDMEMBER s1 -10 // 返回数组,元素可能重复多次
  3. SRANDMEMBER s1 0 // 返回空

spop

spop 用来抽取set集合中随机一个元素,抽出后,会从set集合中移除此元素;spop命令更适合用来年会抽奖使用,抽中之后就从集合中移除元素;

  1. spop s1 // 每次随机抽一个元素并移除,就跟队列的出队一样

sorted set

有序的set,除了元素之外,还需要给出分值,分值是用来决定排序的;

在添加元素时,物理内存遵循左小右大原则,比如我执行以下命令后,默认排序时zhangsan是最小的,lisi是最大的

  1. zadd k1 5 zhangsan 6 xiaoming 2 lisi

其他命令

  1. // 添加sorted set 元素,k1为key值,1 2 3 是分值,a b c是元素,每个分值对应一个元素1是a,2是b,3是c
  2. zadd k1 1 a 2 b 3 c
  3. // 添加的元素也可以是浮点数,但只能是浮点数和数字
  4. zadd k2 1.1 a 2.2 b 3.3 c
  5. // 打印所有的元素,按照添加时的顺序排列
  6. zrange k2 0 -1
  7. // 打印所有元素,按照分值进行升序排序
  8. zrange k2 0 -1 withscores
  9. // 根据分值范围获取元素,获取k2中 2 ~ 8分值范围的元素,如果你的分值有1 2 4 8,那么会打印出 2 4 8分值的元素;
  10. zrangebyscore k2 2 8
  11. // 获取分值最大的前2个元素
  12. ZREVRANGE k2 0 1
  13. // 通过元素获取分值
  14. zscore k2 a
  15. // 获取元素的默认排名,比如我添加命令为 zadd k2 7 a 8 b 9 c ,当我执行下面命令后结果为:2
  16. zrank k2 b
  17. //增加某个元素的分值,key为k2,将k2中b元素的分值增加2.5,比如我的添加命令为 zadd k2 8 b ,执行下面命令后元素b的分值为:10.5
  18. zincrby k2 2.5 b // b元素的分值添加2.5
  19. zincrby k2 -2.5 b // b元素的分值减去2.5

sorted set的并集、交集处理命令zubionstore

首先使用2个key,k1和k2,他们的内容为以下结果

  1. zadd k1 60 zhangsan 20 lisi 100 wangwu
  2. zadd k2 100 zhangsan 80 lisi 10 wangwu 66 zhaoliu 77 tianqi

统计2个key元素的和

这个命令相当于将2个key中相同的元素合并,将他们的分值相加,就跟mysql的sum()函数一样

  1. // 执行命令-将相同元素的分值相加,将k1和k2统计出来的内容放到新的 sumkey 中(key值)
  2. ZUNIONSTORE sumkey 2 k1 k2
  3. (integer) 5
  4. // 以下是打印的结果
  5. 127.0.0.1:6379> zrange sumkey 0 -1 withscores
  6. 1) "zhaoliu"
  7. 2) "66"
  8. 3) "tianqi"
  9. 4) "77"
  10. 5) "lisi"
  11. 6) "100"
  12. 7) "wangwu"
  13. 8) "110"
  14. 9) "zhangsan"
  15. 10) "160"

权重统计

权重统计需要加上关键字weights

  1. // 注意后面多2个参数分别是1 0.5,
  2. ZUNIONSTORE sumkey1 2 k1 k2 weights 1 0.5
  3. // 查看结果
  4. 127.0.0.1:6379> zrange sumkey1 0 -1 withscores
  5. 1) "zhaoliu"
  6. 2) "33" // k1没有 zhaoliu ,k2的 zhaoliu 是66,得出权重公式为(66 * 0.5) =33
  7. 3) "tianqi"
  8. 4) "38.5" // k1没有 tianqi ,k2的 tianqi 是77,得出权重公式为(77 * 0.5) =38.5
  9. 5) "lisi"
  10. 6) "60" // k1的 lisi 是20,k2的 lisi 是80,得出权重公式为(20*1 + 80 * 0.5) = 60
  11. 7) "wangwu"
  12. 8) "105" // k1的 wangwu 是100,k2的wnagwu是10,得出权重公式为(100*1 + 10 * 0.5) = 105
  13. 9) "zhangsan"
  14. 10) "110" // k1 的zhangsan是60 ,k2的zhangsan是100,得出权重公式为(60*1 + 100 * 0.5) = 110

统计最大值
在2个key中取最大分值的元素,
最大值统计需要用到aggregate max关键字

  1. // 统计最大值,将结果放到sumkey2中
  2. ZUNIONSTORE sumkey2 2 k1 k2 aggregate max
  3. //以下是打印的结果
  4. 127.0.0.1:6379> zrange sumkey2 0 -1 withscores
  5. 1) "zhaoliu"
  6. 2) "66" // 最大值在k2里面
  7. 3) "tianqi"
  8. 4) "77" // 最大值在k2里面
  9. 5) "lisi"
  10. 6) "80" // 最大值在k2里面
  11. 7) "wangwu"
  12. 8) "100" // 最大值在k1里面
  13. 9) "zhangsan"
  14. 10) "100" // 最大值在k2里面

sorted set的排序是怎么实现的,它用了哪个数据类型实现

答案是 skip list(跳跃表)

关键字Redis