小白都能看懂的Redis讲解--针对单个键操作集锦
1 重命名键
rename key newname
可以对键重命名,
下面的例子我们创建了一个key为name,value为luke的键值对。 然后将name重命名为user,之后查询name就返回nil,而user是可以查到值的。
127.0.0.1:6379> set name luke
OK
127.0.0.1:6379> get name
"luke"
127.0.0.1:6379> rename name user
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get user
"luke"
值得注意的是,若是修改之后的新名字已经存在了,那么将被覆盖。
127.0.0.1:6379> set name luke
OK
127.0.0.1:6379> set user cedric
OK
127.0.0.1:6379> rename name user
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get user
"luke"
这时候,为了避免被误操作,redis提供了renamenx
命令,这个命令要求当新的key不存在的时候,才能更名成功。
我们继续用上边的例子,可以看到当user存在的时候,更名是失败的。
127.0.0.1:6379> set name luke
OK
127.0.0.1:6379> set user luke
OK
127.0.0.1:6379> renamenx name user
(integer) 0
127.0.0.1:6379> get name
"luke"
127.0.0.1:6379> get user
"luke"
rename的原理是:
- 找到newkey所指的值对象
- 删除这个对象
- 找到oldkey所指的值对象
- 将oldkey的值对象的引用计数加1
- 在redis数据库中添加新的键值对信息,让newkey指向之前oldkey的值对象
- 删除旧的键值对信息,让oldkey不再指向之前的值对象
2 随机返回一个键
randomkey
可以随机返回一个键,当数据库不为空的时候会返回一个key,当数据库为空的时候,返回nil。
127.0.0.1:6379> mset name1 luke name2 cedric name3 josh name4 coat
OK
127.0.0.1:6379> randomkey
"name4"
这个命令并不会删除返回的键
3 键过期
针对键的有效时间,redis有一系列的命令,我们一一说明:
expire key seconds
键在seconds秒之后过期
expireat key timestamp
键在时间戳timestamp后过期
ttl key
可以查看对应key的过期剩余时间
pttl key
可以也可以查看过期时间,不过是毫秒级的
127.0.0.1:6379> set name luke
OK
127.0.0.1:6379> expire name 20
(integer) 1
127.0.0.1:6379> ttl name
(integer) 17
127.0.0.1:6379> pttl name
(integer) 10246
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> pttl name
(integer) -2
上面的例子我们给name设定了20秒的过期时间,当没有过期的时候,ttl和pttl都可以查出值,当过期之后,则返回-2
针对没有设置过期时间的key, ttl key的返回是-1
在2.6版本之后新增了毫秒级的过期方案
pexpire key milliseconds
键在milliseconds毫秒后过期
pexpireat key milliseconds-timestamp
建在毫秒级的时间戳milliseconds-timestamp之后过期
其实在底层,不论是秒级还是毫秒级,redis都会转换为pexpireat去操作。
注意:
- 如果expire key的key不存在,将会返回0
- 如果设置的时间为负值,则会立即删除这个key
- persist命令可以删除键的过期时间
- 字符串类型的键,在执行set命令的时候会清除过期时间
- 对于哈希和列表等value是多个元素的数据结构,redis不支持对value内单个元素设置过期时间的操作
- setex命令相当于set + expire,不单是原子执行,还会减少一次网络通讯的时间
4 迁移键
迁移键多用在redis服务间的数据转储,比如我们将生产环境的迁移到测试环境
redis中提供了三种数据迁移的方法move,dump+restore,migrate。我们一一说明
4.1 move
move key db
命令可以在redis内部进行数据迁移,因为在redis中可以有多个数据库,且数据是不互通的。这个命令就是在这多个数据库之间进行数据迁移。这个多个数据库一般不建议在生产环境使用,所以就简单说一下。
4.2 dump + restore
dump key
restore key ttl value
dump + restore可以实现在不同redis实例间的数据迁移。
在源redis服务执行dump
命令,会将键值序列化,格式为RDB格式。
再在目标redis上执行restore
命令,会将序列化之后的值进行复原。
这就相当于我们转储mysql数据库数据为sql文件,然后在另一个数据库导入。 这个导出和导入认为控制时间,所以并不是原子性的。
4.3 migrate
migrate host port key| destination-db timeout [COPY] [REPLACE] [KEYS key]
migrate也是用来在redis不同实例间进行数据迁移的。
这个命令的实现和dump+restore
命令相似,不过是原子性的。
我们只需要在源redis上执行migrate命令,redis将会自行完成dump + restore + del命令。至于del命令是否执行,则取决于命令的参数。
下面我们对参数进行说明:
host
目标redis的地址port
目标redis的端口key|""
其实|后边有个空字符串,在3.0之前只支持单个键的迁移,这个地方填的就是需要转移的键,但是在3.0.6之后支持迁移多个键了,这里就填空字符串""即可destination-db
目标redis的数据库索引timeout
迁移的超时时间[copy]
若是添加了copy参数,则迁移之后并不会删除源数据[replace]
不管目标数据库是否存在相同的key,都会迁移并覆盖[KEYS key]
需要迁移的键,支持多个
我们举几个例子说明一下,为了测试,我新起了一个redis实例,端口是6380
当源redis有键name,目标redis没有的时候,是可以直接成功的
127.0.0.1:6379> set name luke
OK
127.0.0.1:6380> get name
(nil)
执行如下操作
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 name 0 1000
OK
127.0.0.1:6380> get name
"luke"
当两个redis有相同的key,并且迁移这个key的时候,会报错
127.0.0.1:6379> set name luke
OK
127.0.0.1:6380> set name cedric
OK
我们执行如下命令,会报错说数据已经存在
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 name 0 1000
(error) ERR Target instance replied with error: BUSYKEY Target key name already exists.
当添加参数replice时才可以成功
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 name 0 1000 replace
OK
此时在6380库里查看name,其value已经变为了luke
127.0.0.1:6380> get name
"luke"
当源redis没有要迁移的键的时候,会返回nokey
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 name1 0 1000
NOKEY
迁移多个key
127.0.0.1:6379> mset key1 a key2 b key3 c key4 d
OK
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 "" 0 1000 keys key1 key2 key3 key4
OK
然后在6380里查看,可以看到已经迁移成功
127.0.0.1:6380> keys *
1) "name"
2) "key2"
3) "key1"
4) "key3"
5) "key4"
转载自:https://juejin.cn/post/7151041996101009445