---------------------开始----------------
set hello world的时候,竟然提示read-only。使用info replication的方法查看当前复制状态,发现role变成了slave,所以使用slaveof no one来修改下属性。
代码语言:javascript复制[root@VM_48_10_centos ~]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> set hello world
(error) READONLY You can't write against a read only slave.
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:xxx.xx.5.121
master_port:20556
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1585363887
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> slaveof no one
OK
127.0.0.1:6379> set hello world
OK
---------------------小插曲结束----------------
正式开始看其他键操作
1
键重命名
rename key newkey
举例如下:
代码语言:javascript复制127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> rename hello hi
OK
127.0.0.1:6379> get hello
(nil)
127.0.0.1:6379> get hi
"world"
127.0.0.1:6379> set hello world2
OK
127.0.0.1:6379> get hello
"world2"
127.0.0.1:6379> rename hi hello
OK
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> get hi
(nil)
收件创建hello-->world键值对,然后将hello重命名为hi,发现hello键的value为空,而hi键的value为world,再重新设置hello,再次重命名,发现hello键被覆盖。
通过这个例子,我们发现,使用rename操作是有可能覆盖已经存在的键值的,这在线上可能不安全,因此,redis提供了renamenx命令,表示仅在rename的新键不存在的时候,在进行重命名,如果存在,则重命名返回数字0,而不是返回ok,这样避免了线上的键被覆盖。
除此之外,还有2点需要注意:
1、由于重命名期间会执行del命令删除旧的键,如果键对应的值比较大,则会存在阻塞redis的风险。这一点和MySQL中的rename不同,mysql中的rename操作为原子操作,本质上是对底层文件句柄的操作。
2、如果key和newkey相同,在3.2版本之前返回错误,在3.2版本之后,返回0
2
随机返回一个键
使用randomkey可以随机返回一个键。这个功能可以测试当前redis中是否有键值
3
键过期
expire和expireat
关于键过期,之前说过expire的命令,该命令可以通过:
expire key seconds
来让键在seconds秒之后过期。
但是,这个命令不够精确,我们可以使用expireat命令来指定精确的过期时间:
expireat key timestamp:键在秒级时间戳timestamp之后过期。其中timestamp需要取整数。
ttl和pttl
这两个命令是查看redis的键剩余过期时间的。pttl精度更高,可以达到毫秒级别,有3种返回值:
1、大于0的整数,值得是键剩余过期时间
2、返回1,代表键没有设置过期时间
3、返回-2,代表键不存在
代码语言:javascript复制127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> expire hello 10
(integer) 1
127.0.0.1:6379> ttl hello
(integer) 7
127.0.0.1:6379> pttl hello
(integer) 4461
毫秒级过期方案pexpire和pexpireat
这两兄弟和expire不同之处在于,最后跟的时间是毫秒。其他的使用方法都一样,本质上,redis会将expire的命令转换成pexpire的命令。
几点注意:
a、如果expire的键不存在,则会返回0
b、如果时间为负值,则键会被立即删除。
代码语言:javascript复制127.0.0.1:6379> get hello
"world"
127.0.0.1:6379>
127.0.0.1:6379> expire hello -2
(integer) 1
127.0.0.1:6379> get hello
(nil)
127.0.0.1:6379> expire hello 10
(integer) 0
c、persist命令可以将键的过期时间清除
代码语言:javascript复制127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> expire hello 50
(integer) 1
127.0.0.1:6379> ttl hello
(integer) 46
127.0.0.1:6379> persist hello
(integer) 1
127.0.0.1:6379> ttl hello
(integer) -1
127.0.0.1:6379> get hello
"world"
d、set命令会导致过期时间失败
代码语言:javascript复制127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> expire hello 50
(integer) 1
127.0.0.1:6379> ttl hello
(integer) 47
127.0.0.1:6379> set hello world~~
OK
127.0.0.1:6379> ttl hello
(integer) -1
e、redis不支持二级数据结构(哈希、列表)内部元素的过期功能。
f、setex命令作为set expire的组合,不但是原子执行,同时减少了一次网络通讯时间。
4
迁移键
redis中,提供了3中迁移键的方法:
move
dump restore
migrate
下面分别介绍:
1、move
move命令用户在多个数据库中进行键迁移。它的主要功能是将键从一个数据库迁移到另外一个数据库,但是,多数据库的功能,本身是不建议在线上使用的,这个命令大家了解一下即可。
代码语言:javascript复制127.0.0.1:6379> get hello
"world~~"
127.0.0.1:6379> move hello 1
(integer) 1
127.0.0.1:6379> get hello
(nil)
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get hello
"world~~"
2、dump restore
dump restore可以实现在不同的redis实例之间进行数据迁移的功能,整个迁移的过程分为两步:
a、在源redis上,dump命令会将键值序列化,格式采用的是rdb格式。
b、在目标redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间。
这里有2点需要注意:
第一:dump restore并非原子性的,而是通过客户端分布完成的。
第二:迁移过程是开启了2个客户端的连接,所以dump的结果不是在源redis和目标redis之间进行传输,需要有个中间过程。
举例如下:
代码语言:javascript复制###6379端口
127.0.0.1:6379> get hello
"world~~"
127.0.0.1:6379> dump hello
"x00aworld~~x06x00xe9x02ixcfnxd0xa5:"
###6380端口
127.0.0.1:6380> get hello
(nil)
127.0.0.1:6380> restore hello 0 "x00aworld~~x06x00xe9x02ixcfnxd0xa5:"
OK
127.0.0.1:6380> get hello
"world~~"
3、migrate
该命令也是在redis实例间进行数据迁移的,实际上migrate命令就是讲dump、restore、del3个命令进行组合,从而简化了操作流程。
它跟dump restore的方法有3点不同:
第一、整个过程是源自执行的,不需要要在多个redis实例上开启客户端,只需要在源redis上执行migrate命令即可
第二、migrate命令的数据传输直接在源redis和目标redis上完成的
第三、目标redis完成restore后发送ok给源redis,源redis接受后会根据migrate对应的选项来决定是否在源redis上删除对应的键。
migrate的参数如下:
host:目标redis的IP地址
port:目标redis的端口
key|“” :redis3.0.6之前,migrate只支持迁移一个键,当需要迁移多个键,此处字符串为空
destination-db:目标redis的数据库索引,例如要迁移到0号数据库,此处写0即可。
timeout:迁移的超时时间
copy:添加该参数,迁移之后不删除源键
replace:添加改参数,会覆盖目标端redis的键
keys key [key1 key2]:迁移多个键的时候用,如果要迁移多个,则使用keys key1 key2 key3
下面我们从6379端口将键迁移到6380端口:
代码语言:javascript复制127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set yeyz handsome
OK
127.0.0.1:6379> get yeyz
"handsome"
127.0.0.1:6379> migrate 127.0.0.1 6380 yeyz 0 1000
OK
127.0.0.1:6379> get yeyz
(nil)
127.0.0.1:6379> exit
[root@VM_48_10_centos ~]# redis-cli -p 6380
127.0.0.1:6380> get yeyz
"handsome"
注意:
a、如果没有加replace参数,但是目标端已经有同名键了,此时会报错,提示busykey target key name already exists.
b、如果源redis没有要迁移的键,则会提示nokey
最后,批量迁移举例:
代码语言:javascript复制[root@VM_48_10_centos ~]# redis-cli
127.0.0.1:6379> set key0 value0
OK
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> set key2 value2
OK
127.0.0.1:6379> migrate 127.0.0.1 6380 "" 0 1000 keys key0 key1 key2
OK
127.0.0.1:6379> get key0
(nil)
127.0.0.1:6379> get key1
(nil)
127.0.0.1:6379> get key2
(nil)
127.0.0.1:6379> exit
[root@VM_48_10_centos ~]# redis-cli -p 6380
127.0.0.1:6380> get key0
"value0"
127.0.0.1:6380> get key1
"value1"
127.0.0.1:6380> get key2
"value2"