Redis常用命令


Redis常用命令

image

基本全局命令

#查看所有键
keys *
#选择数据库 0-15
select 11
#清除所有数据 返回ok
flushall
#清除当前数据库数据 返回ok
flushdb
#键是否存在 存在1不存在0
exists key
#当前数据库中键的数量
dbsize
#删除键 多个 del key1 key2 key3 O(1)|O(n) n是键的个数
#成功返回删除键的数量 失败返回0
del key [key...] 
#设置键过期时间 惰性删除OR定期扫描
expire key second
#键剩余时间
#>=0 键剩余时间 -1未设置过期时间 -2 键不存在
ttl key
#键的类型 键不存在返回none
type key

String

特点

Key最大512M,Value最大512M。

String类型内部编码:

  • int 8个字节长整型,大概超过±922.32亿亿之后切换成embstr
  • embstr <=39字节字符串
  • raw >39字节字符串

场景

缓存

播放量计数

共享session

限速:key是IP或TEL,value是次数,每访问一次incr

命令

#设置值|添加新键值 O(1)
#ex|px设置秒级|毫秒级过期时间
#nx 不存在才可设置 xx存在才可设置
set key value [ex seconds] [px millseconds] [nx|xx]
#设置过期的缩写命令 原子执行还减少了一次网络执行时间 重点
setex key seconds value
#不存在才执行成功 作为一种分布式锁的实现方案 重点
setnx key value 
#获取值 O(1)
get key 
#批量设置值 O(N)
mset key value [key value...]
#批量获取值 不存在的返回nil
mget key [key...]
#整数返回自增1的值 非整数返回错误 键不存在自增1返回
incr key
#自增n
incrby key increment
#自减浮点数
incrbyfloat key increment
#自减
decr key
#自减n
decrby key decrement
#在指定key后追加
append key value
#value的长度 每个中文字符占3个字节
strlen key
#设置并返回原值 键不存在返回nil
getset key value
#返回指定长度字符串 
#前闭后闭 O(N) N是字符串长度 字符串较短可视为O(1)
getrange key start end

Hash

特点

Key最大512M,Value最大2^32-1个元素。

value: field:value

HASH类型内部编码:

  • ziplist(压缩列表):hash元素个数(即field) < hash-max-ziplist-entriesdefault=512)配置且hash元素的值<hash-max-ziplist-value(default=64)配置时采用。

    ziplist使用更加紧凑的结构实现多个元素连续存储,节省内存。

  • hashtable(哈希表):不满足以上条件时采用,此时ziplist读写效率下降。

场景

作为业务对象的缓存,如存用户信息。

对比

  • 使用字符串存JSON类型的对象信息

    优:简化编程 劣:序列化和反序列化有开销,更新属性需要把对象反序列化再存入。

  • 使用hash

    优:简单 劣:把控ziplisthashtable间的转换

命令

#设置值 set user:1 name k
hset key field value
#获取值 不存在返回nil
hget key field
#删除field 或多个
hdel key filed [field...]
#返回field个数 O(1)
hlen key
#批量设置
hmset key field value [field value...]
#批量获取
hmget key field [field...]
#field是否存在 有返回1 没有返回0
hexists key field
#获取所有field
hkeys key
#获取所有value
hvals key
#获取所有field-value 若f-v较多会使redis阻塞 
#建议hmget需要的或使用hscan
hgetall key
#自增
hincrbyfloat key field increment
hincrby key filed increment

List

特点

Key最大512M,Value最大2^32-1个元素。

List类型内部编码:quicklist:结合了ziplistlinkedlist优势。

场景

  • 消息队列

  • 文章列表

  • lpush + lpop

  • lpush + rpop 队列

  • lpush + ltrim 有限集合

  • lpush + brpop 消息队列

命令

#从左右push
lpush
rpush
#从左右pop
lpop
rpop
#删除key中元素
#count=0 删除所有指定元素 count>0 从左到右删除count个 <从左到右删除-count个
#返回删了几个
lrem key count value
#保留指定角标间的值 start<=end 若start>end就全删除了 
ltrim key start end
#在某元素前后插入新元素
#失败返回-1 成功返回现在list长度
linsert key before|after pivot value
#获取指定范围元素 
#角标从左到右0~lenth-1 从右到左-1~-lenth 前闭后闭
#O(s+n) s是start的偏移量 n = end -start
lrange start end
#返回指定角标元素
#不存在返回nil 存在返回值
lindex key index
#获取list长度
len key
#设置指定角标的值
lset key index newValue
#源键弹出 目地键放入 sourceKey不存在返回nil
#sourceKey=destinationKey 即原list中的value向右移动一位
rpoplpush sourceKey destinationKey
#阻塞式操作 单位:秒
# sourceKey不存在则等待timeout
brpoplpush sourceKey destinationKey timeout
brpop key [key...] timeout
blpop key [key...] timeout

Set

特点

Key最大512M,Value最大2^32-1个元素。

不允许重复元素且无序。

Set类型内部编码:

  • instset:全为整数且个数小于set-max-intset-entriesdefault = 512)配置项时
  • hashtable:不满足上诉条件时使用

场景

标签:

给用户添加标签 sadd user1:tags tag1 tag2 tag3

给标签添加用户 sadd tag1:users user1 user2 user3

删除用户标签 srem user1:tags tag1

删除标签用户 srem tag1:users user1

添加和删除是两个事务,上述关联操作应放在事务中进行。

计算用户共同感兴趣标签:sinter user1:tags user2:tags

生成随机数:

spop/srandmember

社交需求:

sadd + sinter

命令

#添加元素
sadd key element [element...]
#删除元素
srem key element [element...]
#返回元素个数 O(1) 内部维护变量
scard key
#查看指定元素是否存在于指定key中
#存在1 不存在0
sismember key element
#随机返回count个元素 O(count)
srandmember key count
#随机弹出一个元素
spop key
#获取所有元素
smembers key
#求交集 O(M*K) M键个数K集合中元素最少的个数
sinter key [key...]
#求并集 O(K) 多个集合元素个数和
sunion key [key...]
#差集 sdiff key1 key2 key3 即key1减去key2和key3中有的元素 O(K) 多个集合元素个数和
sdiff key [key...]
#求完结果并保存
sinterstore destination key [key...]
sunionstore destination key [key...]
sdiffstore destination key [key...]

Zset

特点

Key最大512M,Value最大2^32-1个元素。

元素不能重复,但对应的score可以重复。

Zset的内部编码:

ziplist:元素个数<=zset-max-ziplist-entries(default = 128) && 元素长度<=zset-max-ziplist-value(default = 64字节)

skiplist:不满足上述条件时

场景

排行榜

命令

#NX|XX 不存在才设置|存在才设置  O(K*log(n)) k是添加成员个数 n是当前成员个数
#ch 返回此次设置修改member的个数
#INCR socre自增 zadd zset xx ch incr 10 rank10 令rank10原来的值加10 返回加后的值
zadd key [NX|XX] [CH] [INCR] score member [score member ...] 
#元素个数
zcard key
#返回该元素的分数 没有返回nil
zscore key member
#返回元素的序号 没有返回nil
#从低到高的名次 0开始  O(log(n)) n是当前有序集合成员个数
zrank key member
#从高到底的名次 0开始
zrevrank key member
#删除元素 返回删除的个数 O(k*log(n)) k删除的个数 n当前的元素总数
zrem key member [member...]
#加分 不存在的元素就会自动添加 O(log(n)) 当前元素总数
zincrby key socre member
#返回指定角标范围元素 option withscores 是否返回分数 
#O(k+log(n)) k是返回的个数 n是元素总数
zrange key start end [WITHSCORES]
zrevrange key start end [WITHSCORES]
#返回指定分数范围的元素 offset指定角标 count指定返回个数 
#默认闭区间 开区间左边加(    -inf +inf表示负正无穷大
#O(k+log(n)) k是返回的个数 n是元素总数
zrangebyscore key min max [WITHSCORES] [LIMIT OFFSET COUNT]
zrevrangebyscore key max min [WITHSCORES] [LIMIT OFFSET COUNT]
#返回指定分数范围内成员个数 同样可指定开闭区间 O(log(n))
zcount key min max
#删除指定排名范围内元素 返回成功的个数
#O(k+log(n)) k是删除的个数 n是元素总数
zremrangebyrank key start end
#删除指定分数范围内的元素 返回成功的个数
#O(k+log(n)) k是删除的个数 n是元素总数
zremrangebyscore key min max
#交集 destination结果存储键 numkeys计算的总键数 key键 weights每个键的权重 默认1
#aggregate规定交集的分值如何汇总 默认sum
#O(n*k) + O(m*log(m)) n是成员数最小的集合的成员个数 k是集合的个数 m是结果集中成员的个数
zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
#并集 O(n) + O(m*log(m)) n是所有集合成员个数总数 m是结果集中成员的个数
zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

Bitmpas

特点

实际上就是字符串,只是可以对字符串进行位操作。大小限制同String

场景

独立用户访问计数。

setbit unique:users:20200405 166 1

即2020年4月5日这天,用户ID为166的用户访问了网站。

为避免setbit操作初始化较慢造成阻塞,用户id建议减去一定数字(比如10000)再存。

setbitmap都可以存独立用户访问,需要根据实际情况评估占用空间大小。

命令

#设置值setbit key 0 0|1
setbit key offset value
#获取值 返回0|1
getbit key offset
#获取范围内为1的个数 不设置start&end 就返回所有为1的个数
bitcount key [start end]
#operation = and|or|not|xor 与或非异或
bitop operation destkey key [key ...]  
#计算值中第一个值为bit的角标 start end可限制范围
bitpos key bit [start] [end] 

HyperLogLog

特点

实际上就是字符串,key最大512M,不论多少数据value固定12k。

采用了基数算法,官方误差在0.81%。

笔记本尝试存100万和1000万数据后info memory变化均约为16.1k,应该是key的大小和维护其他有关数据。

The HyperLogLog data structure can be used in order to count unique elements in a set using just a small constant amount of memory, specifically 12k bytes for every HyperLogLog.

p.plus a few bytes for the key itself.

The returned cardinality of the observed set is not exact, but approximated with a standard error of 0.81%.

p.s. 该数据结构的是对unique element进行计算。

test:hll:01 存100万数据

test:hll:11 存1000万数据

在我的机器上看到存100万数据误差率>0.81%。

127.0.0.1:6379[1]> keys *
1) "test:hll:11"
2) "test:hll:01"
127.0.0.1:6379[1]> pfcount test:hll:01 test:hll:11
(integer) 9972088
127.0.0.1:6379[1]> pfcount test:hll:01
(integer) 1009838
127.0.0.1:6379[1]> pfcount test:hll:11
(integer) 9972088

命令

#添加
pfadd key element [element...]
#计算一个或多个key的中不重复元素的总数
pfcount key [key...]
#多个key合并后再计算
pfmerage key [key...]

键管理

#重命名键 nx防止newKey存在 如果不加nx,重命名用了已有的键,键对应的值就丢失了。
#若旧键对应的值比较大 重名名时会删除旧键 可能阻塞Redis
rename key newKey
renamenx key newKey
#随机返回一个key
randomkey
#键过期 键不存在返回0 时间负数键立即被删除 时间戳小于现在立即被删除
#秒级时间戳后过期 pxpireat key 1469980800
exprieat key timestamp
#毫秒级过期
pexpire key millseconds
pexpireat key millseconds-timestamp
#清除键的过期时间
persist key
#set key value会清除过期时间
#键迁移到不同的数据库
move key db
--------------------------------------------------------------------------------------
#键迁移到不同数据库实例
#键被序列化 RDB格式
dump key
#在目标redis实例上恢复 ttl key过期时间,0即不过期 value 序列化值
restore key ttl value
#示例
sourceRedis:6379> dump key
"\x00\x03key\a\x00\x1ag\xe1\xfe\x95\x01\x17\x99"
targetRedis:6379> resore key 0 "\x00\x03key\a\x00\x1ag\xe1\xfe\x95\x01\x17\x99"
--------------------------------------------------------------------------------------
#用来进行数据迁移 结合了dump restore del命令,是原子操作
#host目标Redis port目标Redis端口 destination-db目标数据库号 COPY源数据不删除
#REPLACE覆盖目标Redis 若源Reids与目标Redis有相同键,但没加REPLACE会报错
#timeout迁移的超时时间
migrate host port key| destination-db timeout [COPY] [REPLACE] [KEYS key]
#示例
sourceRedis:6379> migrate 127.0.0.1 6380 "" 0 5000 keys key1 key2 key3
sourceRedis:6379> migrate 127.0.0.1 6380 key4 0 5000
#遍历键 pattern比如 * ? []各种匹配符
#键太多不建议这样使用
keys pattern
#渐进式遍历
#MATCH pattern匹配模式
#COUNT count每次遍历的个数
#hscan sscan zscan可以遍历值中的字段
#cursor知道cursor再次为0 即遍历完毕
scan cursor [MATCH pattern] [COUNT count]
#示例
127.0.0.1:6379[3]> mset a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z
OK
127.0.0.1:6379[3]> scan 0
1) "22"
2)  1) "x"
    2) "l"
    3) "h"
    4) "g"
    5) "m"
    6) "o"
    7) "k"
    8) "v"
    9) "j"
   10) "e"
127.0.0.1:6379[3]> scan 22
1) "19"
2)  1) "w"
    2) "d"
    3) "b"
    4) "p"
    5) "z"
    6) "a"
    7) "i"
    8) "r"
    9) "q"
   10) "u"
127.0.0.1:6379[3]> scan 19
1) "0"
2) 1) "n"
   2) "f"
   3) "c"
   4) "t"
   5) "s"
   6) "y"

TIPS

  • 对有过期时间的键重新执行set key value会清除过期时间,见源码:
void setKey(redisDb *db, robj *key, robj *val){
	if(lookUpKeyWrite(db,key) == NULL){
		dbAdd(db,key,val);
	}else{
		dbOverWrite(db,key,val);
	}
	incrRefCount(val);
    //清除了过期时间    
	removeExpire(db,key);
	signalModifiedKey(db,key);			
}
  • 不建议一个Redis实例中使用多个数据库,影响性能。而应使用多个Redis实例配置多个端口。

  • 惰性删除:del key不会立即删除,会放在一个独立字典维护,在下次get key时删除,造成内存浪费。

  • 定期扫描:配置hz项,Redis后台每X秒进行扫描。

    从过期字典中随机选择20个key;

    删除20key中已过期的key;

    如果删除比例超过25%,重复执行。


文章作者: Wendell
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Wendell !
评论
  目录