127.0.0.1:6379> keys * 1) "b" 2) "a" 127.0.0.1:6379> exists a (integer) 1 127.0.0.1:6379> exists c (integer) 0
move
将一个键值对移动到另一个数据库中
1 2 3
# move key db 127.0.0.1:6379> move a 1 (integer) 1
expire
对一个键设置过期时间,过了这段时间,这个键就会过期,消失
1 2 3
# expire key seconds 127.0.0.1:6379> expire a 10 (integer) 1
ttl
time to leave,剩余过期时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# ttl key 127.0.0.1:6379> expire a 10 (integer) 1 127.0.0.1:6379> ttl a (integer) 8 127.0.0.1:6379> ttl a (integer) 6 127.0.0.1:6379> ttl a (integer) 2 127.0.0.1:6379> ttl a (integer) 1 127.0.0.1:6379> ttl a (integer) -2
127.0.0.1:6379> keys * 1) "b" 127.0.0.1:6379> ttl b (integer) -1
一个大于0的整数表示还剩几秒,-2表示这个键不存在,-1表示这个键没有设置过期时间。
type
查询某个键的数据类型
1 2 3
# type key 127.0.0.1:6379> type b string
del
删除一个或一些键
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# del key [key ...] 127.0.0.1:6379> keys * 1) "c" 2) "b" 3) "a" 127.0.0.1:6379> del a (integer) 1 127.0.0.1:6379> keys * 1) "c" 2) "b" 127.0.0.1:6379> del b c (integer) 2 127.0.0.1:6379> keys * (empty array)
String字符串类型
就是字面意义上的字符串类型
字符串下标是从0开始的
下标-1表示最后一个
set
设置一个键的值
1 2
127.0.0.1:6379> set name shaun OK
get
查询一个键的值
1 2 3 4
127.0.0.1:6379> get name "shaun" 127.0.0.1:6379> get age (nil)
(nil)表示这个键不存在
append
字符串拼接,在一个字符串后面拼接上一段字符串,返回值为拼接之后的字符串的长度
1 2 3 4 5 6 7
# append key value 127.0.0.1:6379> get name "shaun" 127.0.0.1:6379> append name 2314 (integer) 9 127.0.0.1:6379> get name "shaun2314"
strlen
查询字符串的长度
1 2 3
# strlen key 127.0.0.1:6379> strlen name (integer) 9
incr & decr
对于字符串是整数的值,可以使用该命令进行类似于num++或num--的操作
1 2 3 4 5 6 7 8 9 10 11 12
127.0.0.1:6379> set num 5 OK # incr key 127.0.0.1:6379> incr num (integer) 6 127.0.0.1:6379> incr num (integer) 7 # decr key 127.0.0.1:6379> decr num (integer) 6 127.0.0.1:6379> decr num (integer) 5
incrby & decrby
进行类似于num += i或num -= i的操作
1 2 3 4 5 6 7 8 9 10 11 12
127.0.0.1:6379> get num "5" # incrby key increment 127.0.0.1:6379> incrby num 10 (integer) 15 127.0.0.1:6379> incrby num 10 (integer) 25 # decrby key increment 127.0.0.1:6379> decrby num 10 (integer) 15 127.0.0.1:6379> decrby num 10 (integer) 5
getrange
功能为substring,获取一个字符串的子串
1 2 3 4 5 6 7
# getrange key start end 127.0.0.1:6379> get name "shaun2314" 127.0.0.1:6379> getrange name 0 1 "sh" 127.0.0.1:6379> getrange name 0 -1 "shaun2314"
字符串下标是从0开始,start和end表示的是一个闭区间
setrange
替换一个字符串的其中的一部分,在此处不能使用-1下标表示最后一个了,且可以向后超出范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# setrange key offset value 127.0.0.1:6379> get name "shaun2314" 127.0.0.1:6379> setrange name 2 xx (integer) 9 127.0.0.1:6379> get name "shxxn2314" 127.0.0.1:6379> setrange name -1 xxx (error) ERR offset is out of range 127.0.0.1:6379> get name "shxxn2314" 127.0.0.1:6379> setrange name 9 xxx (integer) 12 127.0.0.1:6379> get name "shxxn2314xxx" 127.0.0.1:6379> setrange name 13 j (integer) 14 127.0.0.1:6379> get name "shxxn2314xxx\x00j"
127.0.0.1:6379> keys * 1) "num" 2) "b" 3) "name" # setex key seconds value 127.0.0.1:6379> setex num 10 9 OK 127.0.0.1:6379> get num "9" 127.0.0.1:6379> ttl num (integer) 2 127.0.0.1:6379> get num (nil)
127.0.0.1:6379> keys * 1) "b" 2) "name" 127.0.0.1:6379> setex num 10 8 OK 127.0.0.1:6379> get num "8" 127.0.0.1:6379> ttl num (integer) 5 127.0.0.1:6379> ttl num (integer) 1 127.0.0.1:6379> get num (nil)
setnx
set if not exist
如果这个值不存在才会进行设置,如果这个值当时存在,则什么也不做
在分布式锁中经常使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
127.0.0.1:6379> keys * 1) "a" 2) "name" 127.0.0.1:6379> get a "1" # setnx key value 127.0.0.1:6379> setnx a 8 (integer) 0 127.0.0.1:6379> get a "1" 127.0.0.1:6379> setnx b 9 (integer) 1 127.0.0.1:6379> get b "9"
mget
一次性获得多个值
1 2 3 4 5 6 7 8 9 10 11
127.0.0.1:6379> keys * 1) "b" 2) "a" 3) "name" # mget key [key ...] 127.0.0.1:6379> mget a 1) "1" 127.0.0.1:6379> mget a b c 1) "1" 2) "9" 3) (nil)
mset
一次性设置多个值
1 2 3 4 5 6 7 8 9 10 11
127.0.0.1:6379> keys * 1) "a" 2) "name" # mset key value [key value ...] 127.0.0.1:6379> mset a 3 b 4 c 5 OK 127.0.0.1:6379> keys * 1) "c" 2) "b" 3) "a" 4) "name"
127.0.0.1:6379> keys * (empty array) # getset key value 127.0.0.1:6379> getset name zhangsan (nil) 127.0.0.1:6379> getset name lisi "zhangsan"
List列表类型
就是列表
无论从哪边,编号都是从0开始,-1表示最后一个节点
lpush
头插法插入一个节点,即在左边插入一个节点
1 2 3 4 5 6 7 8 9
# lpush key element [element ...] 127.0.0.1:6379> lpush list one (integer) 1 127.0.0.1:6379> lpush list two (integer) 2 127.0.0.1:6379> lpush list three (integer) 3 127.0.0.1:6379> lpush list four five (integer) 5
# lrem key count element 127.0.0.1:6379> lrange list 0 -1 1) "c" 2) "a" 3) "b" 4) "a" 5) "b" 6) "a" 7) "a" 8) "three" 9) "two" 10) "one" 127.0.0.1:6379> lrem list 1 one (integer) 1 127.0.0.1:6379> lrange list 0 -1 1) "c" 2) "a" 3) "b" 4) "a" 5) "b" 6) "a" 7) "a" 8) "three" 9) "two" 127.0.0.1:6379> lrem list 2 two (integer) 1 127.0.0.1:6379> lrange list 0 -1 1) "c" 2) "a" 3) "b" 4) "a" 5) "b" 6) "a" 7) "a" 8) "three" 127.0.0.1:6379> lrem list 1 a (integer) 1 127.0.0.1:6379> lrange list 0 -1 1) "c" 2) "b" 3) "a" 4) "b" 5) "a" 6) "a" 7) "three"
ltrim
保留列表中的某个区间的节点,删除其他节点
1 2 3 4 5 6 7 8 9 10 11 12
# ltrim key start stop 127.0.0.1:6379> lrange list 0 -1 1) "a0" 2) "a1" 3) "a2" 4) "a3" 5) "a4" 127.0.0.1:6379> ltrim list 2 3 OK 127.0.0.1:6379> lrange list 0 -1 1) "a2" 2) "a3"
# lset key index element 127.0.0.1:6379> lrange list 0 -1 1) "a0" 2) "a1" 3) "a2" 4) "a3" 127.0.0.1:6379> lset list 0 item OK 127.0.0.1:6379> lrange list 0 -1 1) "item" 2) "a1" 3) "a2" 4) "a3" 127.0.0.1:6379> lset list 2 temp OK 127.0.0.1:6379> lrange list 0 -1 1) "item" 2) "a1" 3) "temp" 4) "a3" 127.0.0.1:6379> lset list 4 other (error) ERR index out of range
linsert
将某个值插入到一个列表的某个值的左边或者右边
若列表中不存在该值,则插入失败
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# linsert key BEFORE|AFTER pivot element 127.0.0.1:6379> lrange list 0 -1 1) "a0" 2) "a1" 3) "a2" 4) "a3" 127.0.0.1:6379> linsert list before a1 a_new (integer) 5 127.0.0.1:6379> lrange list 0 -1 1) "a0" 2) "a_new" 3) "a1" 4) "a2" 5) "a3" 127.0.0.1:6379> linsert list after aa aaa (integer) -1
# pfadd key element [element ...] 127.0.0.1:6379> pfadd mykey a s d d f g h j k l (integer) 1 127.0.0.1:6379> pfadd mykey2 z x c v d a a f t w g (integer) 1
# multi - 127.0.0.1:6379> multi OK 127.0.0.1:6379> set a 1 QUEUED 127.0.0.1:6379> set b 2 QUEUED 127.0.0.1:6379> get a QUEUED 127.0.0.1:6379> strlen a QUEUED # exec - 127.0.0.1:6379> exec 1) OK 2) OK 3) "1" 4) (integer) 1
discard
放弃事务,队列中的命令不会执行
1 2 3 4 5 6 7 8 9 10 11
# discard - 127.0.0.1:6379> multi OK 127.0.0.1:6379> set a 1 QUEUED 127.0.0.1:6379> set s 2 QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> keys * (empty array)
出错
编译型异常
代码编写有问题,命令使用错误,此时,事务中的所有命令都不会执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14
127.0.0.1:6379> multi OK 127.0.0.1:6379> set a 1 QUEUED 127.0.0.1:6379> set s 2 QUEUED 127.0.0.1:6379> set c (error) ERR wrong number of arguments for'set'command 127.0.0.1:6379> set d 3 QUEUED 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get a (nil)
运行时异常
出现了语法性错误,此时,其他命令会正常执行,错误命令会抛出异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
127.0.0.1:6379> set str hello OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> incr str QUEUED 127.0.0.1:6379> set a 1 QUEUED 127.0.0.1:6379> set s 2 QUEUED 127.0.0.1:6379> get a QUEUED 127.0.0.1:6379> exec 1) (error) ERR value is not an integer or out of range 2) OK 3) OK 4) "1" 127.0.0.1:6379> get s "2"
160:M 13 Jul 2023 15:50:33.914 * DB saved on disk 160:M 13 Jul 2023 15:51:48.780 * DB saved on disk
保存的触发机制
在配置文件中的配置的情况满足的情况下,会自动触发保存
手动调用save
执行flushall命令
退出redis,也会触发保存
持久化之AOF(Append Only File)
以日志的形式来记录每个写操作,将所有的写操作历史记录保存到一个文件中
恢复的时候就是把这个文件中的命令全部再执行一遍
默认是不开启的
1 2 3 4 5 6 7
# AOF and RDB persistence can be enabled at the same time without problems. # If the AOF is enabled on startup Redis will load the AOF, that is the file # with the better durability guarantees. # # Please check http://redis.io/topics/persistence for more information.
appendonly no
将no改为yes即可开启
文件位置
1 2 3
# The name of the append only file (default: "appendonly.aof")
# The fsync() call tells the Operating System to actually write data on disk # instead of waiting for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. # # Redis supports three different modes: # # no: don't fsync, just let the OS flush the data when it wants. Faster. # always: fsync after every write to the append only log. Slow, Safest. # everysec: fsync only one time every second. Compromise. # # The default is "everysec", as that's usually the right compromise between # speed and data safety. It's up to you to understand if you can relax this to # "no" that will let the operating system flush the output buffer when # it wants, for better performances (but if you can live with the idea of # some data loss consider the default persistence mode that's snapshotting), # or on the contrary, use "always" that's very slow but a bit safer than # everysec. # # More details please check the following article: # http://antirez.com/post/redis-persistence-demystified.html # # If unsure, use "everysec".
# appendfsync always appendfsync everysec # appendfsync no