Redis循序渐进

发布时间 2023-05-08 14:25:18作者: jluo123

常见操作

String字符串

set key value [ex seconds] [px milliseconds] [nx|xx]

设置key及值,过期时间可以使用秒或毫秒为单位

setrange key offset value

从偏移量开始复写key的特定位的值

 [root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> set  first  "hello world"
OK
192.168.4.51:6379> setrange  first  6  "Redis"     //改写为hello Redis
(integer) 11
192.168.4.51:6379> get first
"hello Redis"

strlen key,统计字串长度

192.168.4.51:6379> strlen first
(integer) 11

append key value 存在则追加,不存在则创建key及value,返回key长度

192.168.4.51:6379> append myname jacob
(integer) 5

setbit key offset value 对key所存储字串,设置或清除特定偏移量上的位(bit),value值可以为1或0,offset为0~2^32之间,key不存在,则创建新key

192.168.4.51:6379> setbit  bit  0  1          //设置bit第0位为1
(integer) 0
192.168.4.51:6379> setbit  bit  1  0          //设置bit第1位为0 
(integer) 0

bitcount key 统计字串中被设置为1的比特位数量

192.168.4.51:6379> setbit  bits 0 1        //0001
(integer) 0
192.168.4.51:6379> setbit  bits 3 1        //1001
(integer) 0
192.168.4.51:6379> bitcount  bits            //结果为2
(integer) 2

记录网站用户上线频率,如用户A上线了多少天等类似的数据,如用户在某天上线,则使用setbit,以用户名为key,将网站上线日为offset,并在该offset上设置1,最后计算用户总上线次数时,使用bitcount用户名即可,这样即使网站运行10年,每个用户仅占用10*365比特位即456字节

192.168.4.51:6379> setbit  peter  100  1        //网站上线100天用户登录了一次
(integer) 0
192.168.4.51:6379> setbit  peter  105  1        //网站上线105天用户登录了一次
(integer) 0
192.168.4.51:6379> bitcount  peter
(integer) 2

decr key 将key中的值减1,key不存在则先初始化为0,再减1

192.168.4.51:6379> set z 10
OK
192.168.4.51:6379> decr z
(integer) 9
192.168.4.51:6379> decr z
(integer) 8
192.168.4.51:6379> decr bb
(integer) -1
192.168.4.51:6379> decr bb
(integer) -2

decrby key decrement 将key中的值,减去decrement

192.168.4.51:6379> set count 100
OK
192.168.4.51:6379> DECRBY cc 20    //定义每次减少20(步长)
(integer) -20
192.168.4.51:6379> DECRBY cc 20
(integer) -40

get key 返回key存储的字符串值,若key不存在则返回nil,若key的值不是字串,则返回错误,get只能处理字串

192.168.4.51:6379> get a
(nil)

getrange key start end 返回字串值中的子字串,截取范围为start和end,负数偏移量表示从末尾开始计数,-1表示最后一个字符,-2表示倒数第二个字符

192.168.4.51:6379> set x 123456789
OK
192.168.4.51:6379> getrange x -5 -1
"56789"
192.168.4.51:6379> getrange x 0 4
"12345"

incr key 将key的值加1,如果key不存在,则初始为0后再加1,主要应用为计数器

192.168.4.51:6379> set page 20
OK
192.168.4.51:6379> incr page
(integer) 21

incrby key increment 将key的值增加increment

192.168.4.51:6379> set x 10
OK
192.168.4.51:6379> incr x
(integer) 11
192.168.4.51:6379> incr x
(integer) 12

incrbyfloat key increment 为key中所储存的值加上浮点数增量 increment

192.168.4.51:6379> set num 16.1
OK
192.168.4.51:6379> incrbyfloat num 1.1
"17.2"

mset key value [key value …] 设置多个key及值,空格分隔,具有原子性

192.168.4.51:6379> mset j 9  k 29
OK

mget key [key…] 获取一个或多个key的值,空格分隔,具有原子性

192.168.4.51:6379> mget j k
1) "9"
2) "29"

list列表

Redis的list是一个字符队列,先进后出,一个key可以有多个值

lpush key value [value…] 将一个或多个值value插入到列表key的表头,Key不存在,则创建key

192.168.4.51:6379> lpush list a b c        //list值依次为c b a
(integer) 3

lrange key start stop 从开始位置读取key的值到stop结束

192.168.4.51:6379> lrange list 0 2        //从0位开始,读到2位为止
1) "c"
2) "b"
3) "a"
192.168.4.51:6379> lrange list 0 -1    //从开始读到结束为止
1) "c"
2) "b"
3) "a"
192.168.4.51:6379> lrange list 0 -2        //从开始读到倒数第2位值
1) "c"
2) "b"

lpop key 移除并返回列表头元素数据,key不存在则返回nil

192.168.4.51:6379> lpop list        //删除表头元素,可以多次执行
"c"
192.168.4.51:6379>  LPOP list
"b"

llen key 返回列表key的长度

192.168.4.51:6379>  llen list
(integer) 1

lindex key index 返回列表中第index个值

192.168.4.51:6379> lindex  list  1
"c"

lset key index value 将key中index位置的值修改为value

192.168.4.51:6379> lpush list a b c d 
(integer) 5
192.168.4.51:6379> lset list 3 test        //将list中第3个值修改为test
OK

rpush key value [value…] 将value插入到key的末尾

192.168.4.51:6379> rpush list3  a b c    //list3值为a b c
(integer) 3
192.168.4.51:6379> rpush list3 d    //末尾插入d
(integer) 4

rpop key 删除并返回key末尾的值

192.168.4.51:6379> RPOP list3 
"d"

hash表

hset key field value 将hash表中field值设置为value

192.168.4.51:6379> hset site google 'www.g.cn'
(integer) 1
192.168.4.51:6379> hset site baidu 'www.baidu.com'
(integer) 1

hget key filed 获取hash表中field的值

192.168.4.51:6379> hget site google
"www.g.cn"

hmset key field value [field value…] 同时给hash表中的多个field赋值

192.168.4.51:6379> hmset site google www.g.cn  baidu www.baidu.com
OK

hmget key field [field…] 返回hash表中多个field的值

192.168.4.51:6379> hmget site google baidu
1) "www.g.cn"
2) "www.baidu.com"

hkeys key 返回hash表中所有field名称

192.168.4.51:6379> hmset site google www.g.cn baidu www.baidu.com
OK
192.168.4.51:6379> hkeys  site
1) "google"
2) "baidu"

hgetall key 返回hash表中所有key名和对应的值列表

192.168.4.51:6379> hgetall site
1) "google"
2) "www.g.cn"
3) "baidu"
4) "www.baidu.com"

hvals key 返回hash表中所有key的值

192.168.4.51:6379> hvals site
1) "www.g.cn"
2) "www.baidu.com"

hdel key field [field…] 删除hash表中多个field的值,不存在则忽略

192.168.4.51:6379> hdel  site  google  baidu
(integer) 2

集群

方案

搭建redis集群,拓扑规划如图-1所示:
image

IP,端口规划如表-1所示:
image

准备集群环境

1)按照表-1配置主机名,ip地址,配置yum源(系统源)这里不再操作

2)把redis的软件包传到6台数据库服务器上面,安装redis服务器,六台服务器同样操作(以51为例)

[root@redisA ~]# yum -y install gcc gcc-c++ make
[root@redisA ~]# cd redis
redis/         redis-cluster/ 
[root@redisA ~]# cd redis/
[root@redisA redis]# ls
lnmp  redis-4.0.8.tar.gz
[root@redisA redis]# tar -xf redis-4.0.8.tar.gz 
[root@redisA redis]# cd redis-4.0.8/
[root@redisA redis-4.0.8]# make && make install 
[root@redisA redis-4.0.8]# ./utils/install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379] 
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] 
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!            //安装成功
[root@redisA redis-4.0.8]# ss -antlp | grep 6379            //查看时有端口
LISTEN     0      128    127.0.0.1:6379                     *:*                   users:(("redis-server",pid=10788,fd=6))   

2)修改配置文件,6台redis服务器都要修改(以51为例子)

[root@redisA redis-4.0.8]# /etc/init.d/redis_6379 stop        
//停止已经开启的redis服务
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
[root@redisA redis-4.0.8]# vim /etc/redis/6379.conf
...
bind 192.168.4.51        //修改ip
port 6351        //不允许相同,只指定物理接口的ip
daemonize yes         //以守护进程方式运行
pidfile /var/run/redis_6351.pid 
cluster-enabled yes     //是否启用集群,前提是以守护进程方式运行
cluster-config-file nodes-6351.conf        
//存储集群信息的配置文件,自动生成,不允许相同
cluster-node-timeout 5000        //集群节点通信超时时间
...
[root@redisA redis-4.0.8]# /etc/init.d/redis_6379 start     //启动服务
Starting Redis server...
[root@redisA redis-4.0.8]# ss -antlp | grep 6351            //查看有端口
LISTEN     0      128    192.168.4.51:6351                     *:*                   users:(("redis-server",pid=11092,fd=6))
LISTEN     0      128    192.168.4.51:16351                    *:*                   users:(("redis-server",pid=11092,fd=8))        //16051:集群中的主机通信时用的端口
[root@redisA redis-4.0.8]# ps -C redis
  PID TTY          TIME CMD
注意:其他几台主机在修改时请注意ip,端口等的修改,不要和51主机的一样

3)关闭防火墙51-56主机(以51为例子)

[root@redisA redis-4.0.8]#  getenforce
Permissive
[root@redisA redis-4.0.8]# systemctl disable  firewalld         
//关闭防火墙不自启

4)查看集群信息

[root@redisA redis-4.0.8]# redis-cli  -h 192.168.4.51 -p 6351
192.168.4.51:6351> ping
PONG
192.168.4.51:6351> cluster info
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:0
...
192.168.4.51:6351> cluster nodes
f81f997d5ed988ec1587558e78d5f7dbc96abcbf :6351@16351 myself,master - 0 0 0 connected

创建集群

(在任意一台上执行创建集群的脚本都可以)这里在51上面执行

1)部署ruby脚本运行环境(在51上面执行)

[root@redisA redis-4.0.8]# cd /root/redis-cluster/
[root@redisA redis-cluster]# ls
redis-3.2.1.gem  ruby-devel-2.0.0.648-30.el7.x86_64.rpm
[root@redisA redis-cluster]# yum -y install  ruby rubygems
[root@redisA redis-cluster]# rpm -ivh –nodeps \ 
 ruby-devel-2.0.0.648-30.el7.x86_64.rpm
warning: ruby-devel-2.0.0.648-30.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:ruby-devel-2.0.0.648-30.el7      ################################# [100%]
[root@redisA redis-cluster]# which gem
/usr/bin/gem
[root@redisA redis-cluster]# gem install redis        
Successfully installed redis-3.2.1
Parsing documentation for redis-3.2.1
Installing ri documentation for redis-3.2.1
1 gem installed

2)生成创建集群的脚本

[root@redisA redis-cluster]# cd /root/redis/redis-4.0.8/src/
[root@redisA src]# cp redis-trib.rb /usr/local/bin/
[root@redisA src]# ll /usr/local/bin/redis-trib.rb
-rwxr-xr-x. 1 root root 65991 Sep 27 16:12 /usr/local/bin/redis-trib.rb

3)创建集群

[root@redisA src]# redis-trib.rb  create --replicas 1 \ 
192.168.4.51:6351  192.168.4.52:6352 \ 
192.168.4.53:6353 192.168.4.54:6354  \ 
192.168.4.55:6355 192.168.4.56:6356
//--replicas 1 给每一个主配置一个从库
[root@redisA log]# redis-trib.rb create --replicas 1 192.168.4.51:6351 192.168.4.52:6352    192.168.4.53:6353 192.168.4.54:6354    192.168.4.55:6355 192.168.4.56:6356
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.4.51:6351
192.168.4.52:6352
192.168.4.53:6353
Adding replica 192.168.4.55:6355 to 192.168.4.51:6351
Adding replica 192.168.4.56:6356 to 192.168.4.52:6352
Adding replica 192.168.4.54:6354 to 192.168.4.53:6353
...
...
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

4)查看集群信息,任意一台主机访问本机的redis服务查看即可

cluster info 查看集群信息

cluster nodes 查看集群节点信息

[root@redisA log]# redis-cli  -h  192.168.4.52  -p  6352 
192.168.4.52:6352> CLUSTER INFO
cluster_state:ok            //状态
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:2
cluster_stats_messages_ping_sent:367
cluster_stats_messages_pong_sent:327
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:699
cluster_stats_messages_ping_received:327
cluster_stats_messages_pong_received:372
cluster_stats_messages_received:699
192.168.4.52:6352> CLUSTER NODES        //查看集群节点信息
63afbb5e7d63b1f142358634578a3488e3c9e634 192.168.4.54:6354@16354 slave bc5c4e082a5a3391b634cf433a6486c867cfc44b 0 1538039278871 4 connected
bc5c4e082a5a3391b634cf433a6486c867cfc44b 192.168.4.53:6353@16353 master - 0 1538039278571 3 connected 10923-16383
28e06c5f24a2b6c6412f81369e09bc9653cc51ff 192.168.4.56:6356@16356 slave 8568fbd73cb296cad6915d524e34761b2114af47 0 1538039278069 6 connected
7e8d9121f44d8331ff55b45c218b87df9bda1b70 192.168.4.55:6355@16355 slave a3083123bc5c87a76aab2655171634d4ee84f418 0 1538039278000 5 connected
8568fbd73cb296cad6915d524e34761b2114af47 192.168.4.52:6352@16352 myself,master - 0 1538039277000 2 connected 5461-10922
a3083123bc5c87a76aab2655171634d4ee84f418 192.168.4.51:6351@16351 master - 0 1538039277869 1 connected 0-5460
192.168.4.52:6352>

5)测试集群

命令:

redis-cli -c -h ip地址 -p 端口

[root@redisA log]# redis-cli  -c -h 192.168.4.51 -p 6351
192.168.4.51:6351> set name jim
-> Redirected to slot [5798] located at 192.168.4.52:6352
OK
192.168.4.52:6352> get name
"jim"
192.168.4.52:6352> set class linux
OK
192.168.4.52:6352> get class
"linux"
192.168.4.52:6352> set pay 26800
-> Redirected to slot [4013] located at 192.168.4.51:6351
OK
192.168.4.51:6351> get pay
"26800"

集群不能用的情况:

有半数或者半数以上的主库机器挂掉,集群就不能用了

把一个从库升级成主,没有从库,集群不能用(前提是:有半数或者半数以上的主库机器挂掉)

一个主库挂掉,它的从库自动顶替为主库,正常使用(前提是:有半数或者半数以上的主库机器能用),挂掉的主库修复好后,会成为从库,不会抢占为主

6)集群节点选举策略(三主,三从)

停止某个主库的redis服务,对应的从库会自动升级为主库

先查看节点信息的主从情况

[root@redisA log]# redis-cli  -c -h 192.168.4.51 -p 6351
192.168.4.51:6351> CLUSTER  nodes        
...
8568fbd73cb296cad6915d524e34761b2114af47 192.168.4.52:6352@16352 master - 0 1538040400840 2 connected 5461-10922
28e06c5f24a2b6c6412f81369e09bc9653cc51ff 192.168.4.56:6356@16356 slave 8568fbd73cb296cad6915d524e34761b2114af47 0 1538040400000 6 connected
...
192.168.4.51:6351>

看谁是谁的从库,如:

看节点前后的编号id是否有相同的

如:8568fbd73cb296cad6915d524e34761b2114af47

发现52的从库为56

停止主库52

[root@redisA log]#  redis-cli    -h 192.168.4.52 -p 6352  shutdown
[root@redisA log]# redis-cli  -c -h 192.168.4.51 -p 6351
192.168.4.51:6351> CLUSTER NODES
...
8568fbd73cb296cad6915d524e34761b2114af47 192.168.4.52:6352@16352 master,fail - 1538041052349 1538041051000 2 disconnected        //52的主库坏掉
28e06c5f24a2b6c6412f81369e09bc9653cc51ff 192.168.4.56:6356@16356 master - 0 1538041066000 7 connected 5461-10922        //56成为主库
...

开启52,发现52成为从库

[root@redisB redis-4.0.8]# /etc/init.d/redis_6352 start 
Starting Redis server...
[root@redisA log]# redis-cli  -c -h 192.168.4.51 -p 6351
192.168.4.51:6351> CLUSTER NODES
8568fbd73cb296cad6915d524e34761b2114af47 192.168.4.52:6352@16352 slave 28e06c5f24a2b6c6412f81369e09bc9653cc51ff 0 1538041254000 7 connected

管理redis集群

添加主机

1)部署一台新redis服务器,ip为192.168.4.58,装包,初始化,启用集群配置,重启服务(这里之前已经操作过,不会的可以参考案例1)

2) 添加集群4.58(添加master节点)

格式:redis-trib.rb 选项 参数

选项: add-nade 添加主机(不指定角色为主)

由于之前是在51上面创建ruby脚本,所以只有51上面有redis-trib.rb命令,在51上面执行

[root@redisA ~]# redis-trib.rb add-node 192.168.4.58:6358 192.168.4.51:6351
>>> Adding node 192.168.4.58:6358 to cluster 192.168.4.51:6351
>>> Performing Cluster Check (using node 192.168.4.51:6351)
S: a3083123bc5c87a76aab2655171634d4ee84f418 192.168.4.51:6351
   slots: (0 slots) slave
   replicates 7e8d9121f44d8331ff55b45c218b87df9bda1b70
M: 7e8d9121f44d8331ff55b45c218b87df9bda1b70 192.168.4.55:6355
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 8568fbd73cb296cad6915d524e34761b2114af47 192.168.4.52:6352
   slots: (0 slots) slave
   replicates 28e06c5f24a2b6c6412f81369e09bc9653cc51ff
M: bc5c4e082a5a3391b634cf433a6486c867cfc44b 192.168.4.53:6353
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 63afbb5e7d63b1f142358634578a3488e3c9e634 192.168.4.54:6354
   slots: (0 slots) slave
   replicates bc5c4e082a5a3391b634cf433a6486c867cfc44b
M: 28e06c5f24a2b6c6412f81369e09bc9653cc51ff 192.168.4.56:6356
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.4.58:6358 to make it join the cluster.
[OK] New node added correctly.

3)检查集群主机的状态信息

选项:check 检查权限

  [root@redisA ~]# redis-trib.rb  check 192.168.4.58:6358        //查看状态
>>> Performing Cluster Check (using node 192.168.4.58:6358)
M: c5e0da48f335c46a2ec199faa99b830f537dd8a0 192.168.4.58:6358
   slots: (0 slots) master        //发现没有hash槽
   0 additional replica(s)
M: 7e8d9121f44d8331ff55b45c218b87df9bda1b70 192.168.4.55:6355
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
...
S: a3083123bc5c87a76aab2655171634d4ee84f418 192.168.4.51:6351
   slots: (0 slots) slave
   replicates 7e8d9121f44d8331ff55b45c218b87df9bda1b70
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

4)手动对集群进行分片迁移

选项:reshard 重新分配hash槽

[root@redisA ~]# redis-trib.rb  reshard   192.168.4.58:6358  
How many slots do you want to move (from 1 to 16384)?4096   
//拿出多少个hash 槽给主机192.168.4.58
What is the receiving node ID?  c5e0da48f335c46a2ec199faa99b830f537dd8a0   
//主机192.168.4.58的id值
Source node #1:all      //从当前所有的主里面获取hash槽
Do you want to proceed with the proposed reshard plan (yes/no)?yes
...
Moving slot 12283 from 192.168.4.53:6353 to 192.168.4.58:6358: 
Moving slot 12284 from 192.168.4.53:6353 to 192.168.4.58:6358: 
Moving slot 12285 from 192.168.4.53:6353 to 192.168.4.58:6358: 
Moving slot 12286 from 192.168.4.53:6353 to 192.168.4.58:6358: 
Moving slot 12287 from 192.168.4.53:6353 to 192.168.4.58:6358:

再次查看发现4.58有4096个hash slot

[root@redisA ~]# redis-trib.rb  check 192.168.4.58:6358
>>> Performing Cluster Check (using node 192.168.4.58:6358)
M: c5e0da48f335c46a2ec199faa99b830f537dd8a0 192.168.4.58:6358
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   0 additional replica(s)

5)删除master角色的主机

先删除主机占用的hash槽

[root@redisA ~]# redis-trib.rb  reshard 192.168.4.58:6358
How many slots do you want to move (from 1 to 16384)?4096           
//移除hash 槽的个数
What is the receiving node ID?  bc5c4e082a5a3391b634cf433a6486c867cfc44b 
    //要移动给谁的id即目标主机(这里可以随机写一个master的ID)  
Source node #1: c5e0da48f335c46a2ec199faa99b830f537dd8a0
//从谁那移动即源主机(这里写4.58的ID)  
Source node #2:done           //设置完毕
...
    Moving slot 12282 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
    Moving slot 12283 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
    Moving slot 12284 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
    Moving slot 12285 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
    Moving slot 12286 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
    Moving slot 12287 from c5e0da48f335c46a2ec199faa99b830f537dd8a0
Do you want to proceed with the proposed reshard plan (yes/no)?yes        //提交
... 
Moving slot 12282 from 192.168.4.58:6358 to 192.168.4.53:6353: 
Moving slot 12283 from 192.168.4.58:6358 to 192.168.4.53:6353: 
Moving slot 12284 from 192.168.4.58:6358 to 192.168.4.53:6353: 
Moving slot 12285 from 192.168.4.58:6358 to 192.168.4.53:6353: 
Moving slot 12286 from 192.168.4.58:6358 to 192.168.4.53:6353: 
Moving slot 12287 from 192.168.4.58:6358 to 192.168.4.53:6353:

删除集群主机4.58(删除之后redis服务自动关闭)

[root@redisA ~]# redis-trib.rb del-node 192.168.4.58:6358 \ 
 c5e0da48f335c46a2ec199faa99b830f537dd8a0    //删除谁+删除的id
>>> Removing node c5e0da48f335c46a2ec199faa99b830f537dd8a0 from cluster 192.168.4.58:6358
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

6)添加从节点主机,随机添加

[root@redisA ~]# redis-trib.rb  add-node  --slave \ 
192.168.4.57:6357  192.168.4.51:6351
>>> Adding node 192.168.4.57:6357 to cluster 192.168.4.51:6351
>>> Performing Cluster Check (using node 192.168.4.51:6351)
……
……
[OK] All 16384 slots covered.
Automatically selected master 192.168.4.51:6351
>>> Send CLUSTER MEET to node 192.168.4.57:6357 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 192.168.4.51:6351.
[OK] New node added correctly. 

7)移除从节点,从节点主机没有槽位范围,直接移除即可

命令格式:

redis-trib.rb del-node 192.168.4.57:6357 主机id值

[root@redisA ~]# redis-trib.rb  del-node 192.168.4.57:6357  \ 
f6649ea99b2f01faca26217691222c17a3854381
>>> Removing node f6649ea99b2f01faca26217691222c17a3854381 
       from cluster 192.168.4.57:6351
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

主从复制

1) 配置主从,4.51为主,4.52为从

若主机做过redis集群,需要在配置文件里面把开启集群,存储集群信息的配置文件都关闭,新主机则不用,这里用之前的redis集群做主从,需要还原redis服务器,4.51和4.52都需要还原(以4.51为例)

[root@redisA ~]# redis-cli -c -h 192.168.4.51 -p 6351 shutdown    
//先关闭redis集群
[root@redisA ~]# vim /etc/redis/6379.conf
bind 192.168.4.51
port 6379 
# cluster-enabled yes
# cluster-config-file nodes-6351.conf
[root@redisA ~]# /etc/init.d/redis_6379 start 
Starting Redis server...
 [root@redisA ~]# ss -antlp | grep 6379
LISTEN     0      511    192.168.4.51:6379                     *:*                   users:(("redis-server",pid=22274,fd=6))
[root@redisA ~]# redis-cli -h 192.168.4.51 
192.168.4.51:6379> info replication        //查看主从配置信息
# Replication
role:master            //默认是master 服务器  
connected_slaves:0
master_replid:eaa14478158a71c41f947eaea036658c2087e8f2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.4.51:6379>

2)配置从库192.168.4.52/24

192.168.4.52:6379> SLAVEOF   192.168.4.51  6379            //把52配置为51的从库
OK

从库查看

192.168.4.52:6379> INFO replication
# Replication
role:slave
master_host:192.168.4.51        //主库为4.51
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0

3)主库查看

[root@redisA ~]# redis-cli -h 192.168.4.51
192.168.4.51:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.4.52,port=6379,state=online,offset=14,lag=1    //从库为4.52
master_replid:db7932eb0ea4302bddbebd395efa174fb079319f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
192.168.4.51:6379>

4)反客为主,主库宕机后,手动将从库设置为主库

[root@redisA ~]# redis-cli -h 192.168.4.51 shutdown            //关闭主库
192.168.4.52:6379> SLAVEOF  no  one      //手动设为主库
OK
192.168.4.52:6379> INFO replication
# Replication
role:master
connected_slaves:0
master_replid:00e35c62d2b673ec48d3c8c7d9c7ea3366eac33a
master_replid2:db7932eb0ea4302bddbebd395efa174fb079319f
master_repl_offset:420
second_repl_offset:421
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:420
192.168.4.52:6379>

5)哨兵模式

主库宕机后,从库自动升级为主库

在slave主机编辑sentinel.conf文件

在slave主机运行哨兵程序

[root@redisB ~]# redis-cli  -h 192.168.4.52
192.168.4.52:6379> SLAVEOF   192.168.4.51   6379
OK
192.168.4.52:6379> INFO replication
# Replication
role:slave
master_host:192.168.4.51
master_port:6379
...
[root@redisA ~]# /etc/init.d/redis_6379 start 
Starting Redis server...
[root@redisA ~]# redis-cli -h 192.168.4.51 
192.168.4.51:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.4.52,port=6379,state=online,offset=451,lag=1
master_replid:4dfa0877c740507ac7844f8dd996445d368d6d0f
master_replid2:0000000000000000000000000000000000000000
...
[root@redisB ~]# vim /etc/sentinel.conf
sentinel   monitor   redisA       192.168.4.51   6379   1
关键字      关键字    主机名自定义       ip           端口  票数
sentinel   auth-pass  redis51 密码  //连接主库密码,若主库有密码加上这一行
[root@redisB ~]# redis-sentinel /etc/sentinel.conf    //执行,之后把主库宕机
...
25371:X 28 Sep 11:16:54.993 # +sdown master redis51 192.168.4.51 6379
25371:X 28 Sep 11:16:54.993 # +odown master redis51 192.168.4.51 6379 #quorum 1/1
25371:X 28 Sep 11:16:54.993 # +new-epoch 3
25371:X 28 Sep 11:16:54.993 # +try-failover master redis51 192.168.4.51 6379
25371:X 28 Sep 11:16:54.994 # +vote-for-leader be035801d4d48eb63d8420a72796f52fc5cec047 3
...
25371:X 28 Sep 11:16:55.287 * +slave slave 192.168.4.51:6379 192.168.4.51 6379 @ redis51 192.168.4.52 6379
25371:X 28 Sep 11:17:25.316 # +sdown slave 192.168.4.51:6379 192.168.4.51 6379 @ redis51 192.168.4.52 6379

6)配置带验证的主从复制

关闭4.51和4.52,启动之后用info replication查看,各自为主

主库设置密码,在51上面操作

[root@redisA ~]# redis-cli -h 192.168.4.51 shutdown
[root@redisA ~]# vim /etc/redis/6379.conf
requirepass 123456
[root@redisA ~]# /etc/init.d/redis_6379 start 
Starting Redis server...
[root@redisA ~]# redis-cli -h 192.168.4.51 -a 123456  
192.168.4.51:6379> ping
PONG
192.168.4.51:6379>

7)配置从库主机

[root@redisB ~]# redis-cli -h 192.168.4.52 shutdown
[root@redisB ~]# vim /etc/redis/6352.conf
slaveof 192.168.4.51 6379
masterauth 123456
[root@redisB ~]# /etc/init.d/redis_6352 start 
Starting Redis server...

52上面查看 52从主库变为从库

[root@redisB ~]# redis-cli -h 192.168.4.52 -a 123456
192.168.4.52:6379> info replication
# Replication
role:slave
master_host:192.168.4.51
master_port:6379
master_link_status:up

51上面查看 51的从库为52

[root@redisA ~]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.4.52,port=6379,state=online,offset=98,lag=0

数据持久化

RDB

1、使用RDB文件恢复数据

RDB介绍:

Redis数据库文件,全称Reids DataBase

数据持久化方式之一

在指定时间间隔内,将内存中的数据集快照写入硬盘

术语叫Snapshot快照

恢复时,将快照文件直接读到内存里

相关配置参数

文件名

dbfilename “dump.rdb” 文件名

save “” 禁用RDB

数据从内存保存到硬盘的频率

save 900 1 900秒内且有1次修改

save 300 10 300秒内且有10次修改

save 60 10000 60秒内且有10000修改

[root@redisA ~]# redis-cli -h 192.168.4.51 -a 123456 shutdown
[root@redisA ~]# vim /etc/redis/6379.conf
dbfilename dump.rdb
#   save ""        //启用RDB,去掉#号为禁用RDB
save 120 10        //120秒内且有1次修改(满足三个条件中的任意一个都会保存)
save 300 10
save 60 10000
[root@redisA ~]# /etc/init.d/redis_6379 start 
Starting Redis server...
[root@redisA ~]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379>
[root@redisA ~]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> 
192.168.4.51:6379> set v1 k1
OK
192.168.4.51:6379> set v2 k1
OK
192.168.4.51:6379> set v3 k1
OK
192.168.4.51:6379> set v4 k1
OK
192.168.4.51:6379> set v45 k1
OK
192.168.4.51:6379> set v46 k1
OK
192.168.4.51:6379> set v7 k1
OK
192.168.4.51:6379> set v8 k1
OK
192.168.4.51:6379> set v9 k1
OK
192.168.4.51:6379> set v10 k1
OK
192.168.4.51:6379> keys *
 1) "v2"
 2) "v9"
 3) "v10"
 4) "v45"
 5) "v4"
 6) "v1"
 7) "v46"
 8) "v8"
 9) "v7"
10) "v3"
192.168.4.51:6379>exit

备份数据

[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456 shutdown        //停止服务
[root@redisA ~]# cd /var/lib/redis/6379/
[root@redisA 6379]# ls
dump.rdb  nodes-6351.conf
[root@redisA 6379]# cp dump.rdb dump.rdb.bak    //备份dump.rdb,之后删除

删除数据

[root@redisA 6379]# rm -rf dump.rdb
[root@redisA 6379]# /etc/init.d/redis_6379  start 
Starting Redis server...
[root@redisA 6379]# ls
dump.rdb  dump.rdb.bak  nodes-6351.conf
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> keys *        //已经没有数据
(empty list or set)
192.168.4.51:6379>

恢复数据

[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456 shutdown
[root@redisA 6379]# mv dump.rdb.bak dump.rdb
mv: overwrite ‘dump.rdb’? y
[root@redisA 6379]# /etc/init.d/redis_6379  start 
Starting Redis server...
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> keys *
 1) "v7"
 2) "v46"
 3) "v45"
 4) "v8"
 5) "v4"
 6) "v2"
 7) "v1"
 8) "v3"
 9) "v9"
10) "v10"
192.168.4.51:6379>

RDB优点:

高性能的持久化实现:创建一个子进程来执行持久化,先将数据写入临时文件,持久化过程结束后,再用这个临时文件替换上次持久化好的文件;过程中主进程不做任何IO操作

比较适合大规模数据恢复,且对数据完整性要求不是非常高的场合

RDB的缺点:

意外宕机时,最后一次持久化的数据会丢失

AOF

1、使用AOF文件恢复数据

1)AOF介绍

只做追加操作的文件,Append Only File

记录redis服务所有写操作

不断的将新的写操作,追加到文件的末尾

使用cat命令可以查看文件内容

2)参数配置

文件名

appendfilename "appendonly.aof" 指定文件名

appendonly yes 启用aof ,默认no

AOF文件记录写操作的方式

appendfsync always 有新写操作立即记录

appendfsync everysec 每秒记录一次

appendfsync no 从不记录

[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456 shutdown
[root@redisA 6379]# rm -rf dump.rdb

[root@redisA 6379]# vim /etc/redis/6379.conf
appendonly yes            //启用aof,默认no
appendfilename "appendonly.aof"    //文件名
appendfsync everysec            //每秒记录一次

[root@redisA 6379]# /etc/init.d/redis_6379  start 
Starting Redis server...
[root@redisA 6379]# ls            //会出现appendonly.aof文件
appendonly.aof  dump.rdb  nodes-6351.conf
[root@redisA 6379]# cat appendonly.aof        //无内容
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> set v1 a1
OK
192.168.4.51:6379> set v2 a2
OK
192.168.4.51:6379> set v3 a3
OK
192.168.4.51:6379> set v4 a4
OK
192.168.4.51:6379> set v5 a5
OK
192.168.4.51:6379> set v6 a6
OK
192.168.4.51:6379> set v7 a7
OK
192.168.4.51:6379> set v8 a7
OK
192.168.4.51:6379> set v9 a9
OK
192.168.4.51:6379> set v10 a10
OK
192.168.4.51:6379> keys *
 1) "v2"
 2) "v5"
 3) "v10"
 4) "v9"
 5) "v6"
 6) "v8"
 7) "v3"
 8) "v7"
 9) "v1"
10) "v4"
192.168.4.51:6379> exit
[root@redisA 6379]# cat appendonly.aof            //有数据

3)使用AOF恢复数据

备份数据

[root@redisA 6379]# cp appendonly.aof appendonly.aof.bak
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456 shutdown

删除数据

[root@redisA 6379]# rm -rf appendonly.aof
[root@redisA 6379]# /etc/init.d/redis_6379  start 
Starting Redis server...
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> keys *
(empty list or set)
192.168.4.51:6379> exit 

恢复数据

[root@redisA 6379]# mv appendonly.aof.bak appendonly.aof
mv: overwrite ‘appendonly.aof’? y
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456 shutdown
[root@redisA 6379]# /etc/init.d/redis_6379  start 
Starting Redis server...
[root@redisA 6379]# redis-cli -h 192.168.4.51 -a 123456
192.168.4.51:6379> keys *
 1) "v9"
 2) "v5"
 3) "v8"
 4) "v2"
 5) "v1"
 6) "v4"
 7) "v10"
 8) "v6"
 9) "v7"
10) "v3"
192.168.4.51:6379>

修复AOF文件,把文件恢复到最后一次的正确操作

[root@redisA 6379]# vim appendonly.aof 
*2        //可以把这一行删除
$6
SELECT
$1
0
*3
$3
set
$2
v1
$2
a1
*3
$3
...
[root@redisA 6379]# redis-check-aof --fix appendonly.aof        //恢复文件
0x               0: Expected prefix '*', got: '$'
AOF analyzed: size=311, ok_up_to=0, diff=311
This will shrink the AOF from 311 bytes, with 311 bytes, to 0 bytes
Continue? [y/N]: y
Successfully truncated AOF

RDB优点:

可以灵活的设置同步持久化appendfsync always或异步持久化appendfsync verysec

宕机时,仅可能丢失1秒的数据

RDB的缺点:

AOF文件的体积通常会大于RDB文件的体积

执行fsync策略时的速度可能会比RDB慢

FAQ