Redis持久化、集群

单点redis存在的问题及解决方案

image-20231115201143316

1. Redis持久化

1.1 Redis持久化简介

​ Redis数据持久化是指将Redis内存中的数据保存到磁盘上的过程,以防止数据丢失。Redis提供了两种数据持久化的方式,分别是RDB和AOF。

1.2 RDB

1.2.1 RDB简介

​ RDB (Redis DataBase Backup file) redis数据库备份文件 也叫Redis数据快照,RDB持久化是通过定时手动触发快照命令,将内存中的数据集以二进制格式保存到磁盘上的一种方式。

优点:文件体积小(可以设置是否压缩,一般不压缩),恢复速度快,适合备份和传输

缺点:

​ 1.RDB执行时间间隔长,两次RDB之间写入数据会有丢失数据的风险

​ 2.在执行快照时会占用CPU和内存资源,fork子进程、压缩、写入RDB都比较耗时 ,可能影响服务性能。

1.2.2 RDB执行的时机:

  • 手动触发:通过执行save(一般不用)bgsave命令,可以立即或后台生成RDB文件。save命令会阻塞Redis的服务,直到RDB文件生成完毕;bgsave命令会创建一个子进程来生成RDB文件,不影响Redis的服务。
  • 自动触发:通过配置redis.conf文件中的save参数,可以设置一定的时间和修改次数的条件,当满足条件时,会自动触发bgsave命令。例如,save 900 1表示900秒内至少有一次修改则触发保存操作。
  • 关闭触发:当正常关闭Redis时,如果没有开启AOF持久化,会自动触发save命令,将最新的数据保存到RDB文件中。如果意外宕机,不会触发RDB持久化,可能会丢失最后一次持久化后的数据。
  • 清空触发:当执行flushall命令时,会自动触发bgsave命令,将空的数据集保存到RDB文件中,覆盖原有的RDB文件。

save(一般不用):

127.0.0.1:6379> save

​ save命令会直接调用rdbSave函数,阻塞Redis主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求

bgsave:

127.0.0.1:6379> bgsave

bgsave命令会fork出一个子进程,子进程负责调用rdbSave函数,并在保存完成之后向主进程发送信号,通知保存已完成。Redis服务器在bgsave执行期间仍然可以继续处理客户端的请求。

**注意:**由于save会阻塞主进程,此时服务器不能处理客户端的任何请求,bgsave会fork出一个子进程不会对主进程造成影响,因此一般使用bgsave来执行RDB

(save和bgsave的区别主要在于是否影响Redis的服务性能。save命令会导致Redis暂停服务,可能造成客户端的超时或失败。bgsave命令不会影响Redis的服务,但是会增加Redis的内存占用,因为需要复制数据集给子进程。)

1.2.3 RDB执行原理

RDB执行原理:

​ bgsave命令一开始 就会 fork 主进程得到子进程 ,子进程会共享主进程的内存数据. 完成fork之后读取内存中的数据并写入RDB文件。

fork采用的是 写时复制(copy-on-write) 技术,当主进程执行读操作的时候,访问共享内存 ,当主进程执行写的操作,则会拷贝一份数据,执行写操作

RDB执行流程:

1.2.4 RDB的相关配置

进入redis-6.2.4目录,打开redis.conf文件

  • RDB文件是否压缩:

  • RDB文件名

  • RDB文件保存目录

  • 设置Redis的RDB持久化的策略

1.3 AOF

1.3.1 AOF简介

AOFAppend Only File的缩写,是Redis的一种持久化方式,它可以将每个写命令以文本格式追加到日志文件中,实现增量持久化。AOF的主要作用是解决了数据持久化的实时性。目前已经是Redis持久化的主流方式。

优点:

  • **可以保证数据不丢失:**根据配置的同步策略,最多丢失一秒内的数据。
  • **文件内容易读:**便于修复和处理。
  • **可以自动启用重写机制:**压缩和瘦身相关的AOF文件。

缺点:

  • **文件体积大:**可能有冗余数据。
  • **恢复速度慢:**需要重新执行所有的写命令。
  • **可能影响磁盘IO性能:**需要不断地将写命令写入和同步到磁盘上。

1.3.2 AOF配置

在redis.conf文件中进行配置:

  • AOF的开启(默认为关闭状态):

  • AOF文件名

  • AOF执行策略:

    执行策略描述
    appendfsync always表每执行一次写命令,立刻记录到AOF文件。性能最低,可靠性最好
    appendfsync everysec写命令执行完毕之后先放入AOF的缓冲区,然后每间隔1秒将缓冲区的内容写入AOF文件中,这个是默认的。性能,可靠性都可以
    appendfsync no由操作系统决定什么时间写入到我们的磁盘中。性能最好,可靠性最差

  • Redis何时自动触发AOF文件的重写

1.3.3 AOF的持久化

1.开启AOF(默认为关闭)

appendonly no->appendonly yes

2.关闭RDB

#将注释取消掉,禁用RDB
#save ”“
->
save ""

3.启动Redis,连接Redis客户端

redis-server redis.conf
redis-cli -p 6379

4.进行数据读写,查看aof文件存储写操作情况

总结:RDB和AOF的对比

RDBAOF
使用场景容忍分钟数据的丢失,追求更快的启动速度,例如缓存系统对数据安全性要求较高,不允许有任何数据丢失的场景,例如金融系统。
持久化方式定时对整个内存做快照记录每一次执行的命令,以保证数据的完整性。
数据完整性不完整,两次之间会丢失数据相对完整 刷盘策略
文件大小有压缩,是二进制格式的快照,文件体积小记录每条命令,体积大
宕机恢复速度较快,因为只需加载最近的数据快照即可,数据完整性不如AOF较慢,因为需要逐一重放写操作以还原数据状态,数据完整性高
数据恢复优先级
资源占用高,在保存快照时可能会占用较多内存。低,但由于需要不断追加写操作,可能会占用较多磁盘空间。

2. Redis集群

Redis 集群是 Redis 数据库的一种分布式部署方式,它通过将数据分散存储在多个节点上来提供高可用性和可扩展性。Redis 集群通常由多个主节点和若干个从节点组成,每个节点都可以存储部分数据。下面是 Redis 集群的一些关键特点:

  1. 数据分片:Redis 集群将数据划分为多个槽(slot),默认共有 16384 个槽,每个槽可以存储一个键值对。这些槽均匀地分布在集群各个节点上,每个节点负责管理一部分槽。
  2. 主从复制:每个主节点可以有多个从节点。主节点负责响应写操作和部分读操作,而从节点则负责复制主节点的数据,并能够处理读操作。主从复制实现了数据的冗余备份和高可用性。
  3. 节点间通信:Redis 集群使用 gossip 协议进行节点间的通信和信息交换。每个节点都会定期与其他节点交换集群拓扑信息,以保持整个集群的状态一致性。
  4. 客户端路由:客户端通过集群客户端连接到 Redis 集群,集群客户端负责将不同的键值对请求路由到相应的节点上,实现对数据的读写操作。

使用 Redis 集群可以提供更高的可用性、容错性和扩展性,同时还能够分散负载和提高读写性能。在配置和管理 Redis 集群时,你需要考虑节点的部署、数据迁移、故障恢复等方面的问题。

2.1 单机安装Redis

首先需要安装Redis所需要的依赖:

yum install -y gcc tcl

然后将Redis安装包上传到虚拟机的任意目录:

image-20210629114325516

例如,我放到了/tmp目录:

image-20210629114830642

解压缩:

tar -xvf redis-6.2.4.tar.gz

解压后:

image-20210629114941810

进入redis目录:

cd redis-6.2.4

运行编译命令:

make && make install

如果没有出错,应该就安装成功了。

然后修改redis.conf文件中的一些配置:

# 绑定地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问
bind 0.0.0.0
# 数据库数量,设置为1
databases 1

启动Redis:

redis-server redis.conf

停止redis服务:

redis-cli shutdown

2.2 Redis主从集群

2.2.1 集群结构

搭建的主从集群结构如图:

image-20210630111505799

共包含三个节点,一个主节点,两个从节点。

这里我们会在同一台虚拟机中开启3个redis实例,模拟主从集群,信息如下:

IPPORT角色
192.168.150.1017001master
192.168.150.1017002slave
192.168.150.1017003slave

2.2.2 准备实例和配置

要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。

1)创建目录

我们创建三个文件夹,名字分别叫7001、7002、7003:

# 进入/tmp目录
cd /tmp
# 创建目录
mkdir 7001 7002 7003

如图:

image-20210630113929868

2)恢复原始配置

修改redis-6.2.4/redis.conf文件,将其中的持久化模式改为默认的RDB模式,AOF保持关闭状态。

# 开启RDB
# save ""
save 3600 1
save 300 100
save 60 10000

# 关闭AOF
appendonly no

3)拷贝配置文件到每个实例目录

然后将redis-6.2.4/redis.conf文件拷贝到三个目录中(在/tmp目录执行下列命令):

# 方式一:逐个拷贝
cp redis-6.2.4/redis.conf 7001
cp redis-6.2.4/redis.conf 7002
cp redis-6.2.4/redis.conf 7003
# 方式二:管道组合命令,一键拷贝
echo 7001 7002 7003 | xargs -t -n 1 cp redis-6.2.4/redis.conf

4)修改每个实例的端口、工作目录

修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录(在/tmp目录执行下列命令):

sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003\//g' 7003/redis.conf

5)修改每个实例的声明IP

虚拟机本身有多个IP,为了避免将来混乱,我们需要在redis.conf文件中指定每一个实例的绑定ip信息,格式如下:

# redis实例的声明 IP
replica-announce-ip 192.168.150.101

每个目录都要改,我们一键完成修改(在/tmp目录执行下列命令):

# 逐一执行
sed -i '1a replica-announce-ip 192.168.150.101' 7001/redis.conf
sed -i '1a replica-announce-ip 192.168.150.101' 7002/redis.conf
sed -i '1a replica-announce-ip 192.168.150.101' 7003/redis.conf

# 或者一键修改
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.150.101' {}/redis.conf

2.2.3 启动

为了方便查看日志,我们打开3个ssh窗口,分别启动3个redis实例,启动命令:

# 第1个
redis-server 7001/redis.conf
# 第2个
redis-server 7002/redis.conf
# 第3个
redis-server 7003/redis.conf

启动后:

image-20210630183914491

如果要一键停止,可以运行下面命令:

printf '%s\n' 7001 7002 7003 | xargs -I{} -t redis-cli -p {} shutdown

2.2.4 开启主从关系

现在三个实例还没有任何关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。

有临时和永久两种模式:

  • 修改配置文件(永久生效)

    • 在redis.conf中添加一行配置:
  • 使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):

    slaveof <masterip> <masterport>
    

注意:在5.0以后新增命令replicaof,与salveof效果一致。

这里我们为了演示方便,使用方式二。

通过redis-cli命令连接7002,执行下面命令:

# 连接 7002
redis-cli -p 7002
# 执行slaveof
slaveof 192.168.150.101 7001

通过redis-cli命令连接7003,执行下面命令:

# 连接 7003
redis-cli -p 7003
# 执行slaveof
slaveof 192.168.150.101 7001

然后连接 7001节点,查看集群状态:

# 连接 7001
redis-cli -p 7001
# 查看状态
info replication

结果:

image-20210630201258802

2.2.5 测试

执行下列操作以测试:

  • 利用redis-cli连接7001,执行set num 123

  • 利用redis-cli连接7002,执行get num,再执行set num 666

  • 利用redis-cli连接7003,执行get num,再执行set num 888

可以发现,只有在7001这个master节点上可以执行写操作,7002和7003这两个slave节点只能执行读操作

=============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

2.2.6 实操记录

redis/redis.conf配置文件:

  1. 75行-

    注释掉bind 127.0.0.1 -::1 配置bind 0.0.0.0

  2. 382行-

    取消注释

    save 3600 1
    save 300 100
    save 60 10000

  3. 1254行-

    appendonly no

  4. 328行-数据库

    databases 1

配置主从 一主二从

[root@xwk ~]# cd /tmp
[root@xwk tmp]# ls
hsperfdata_root   mysql.sock       redis-6.2.4
ks-script-aYmaht  mysql.sock.lock  yum.log
[root@xwk tmp]# mkdir 7001 7002 7003
[root@xwk tmp]# ll
total 12
drwxr-xr-x. 2 root  root     6 Nov 11 23:03 7001
drwxr-xr-x. 2 root  root     6 Nov 11 23:03 7002
drwxr-xr-x. 2 root  root     6 Nov 11 23:03 7003
drwxr-xr-x. 2 root  root    18 Nov 11 17:44 hsperfdata_root
-rwx------. 1 root  root   836 Nov 11 17:13 ks-script-aYmaht
srwxrwxrwx. 1 mysql mysql    0 Nov 11 18:07 mysql.sock
-rw-------. 1 mysql mysql    5 Nov 11 18:07 mysql.sock.lock
drwxrwxr-x. 7 root  root  4096 Jun  1  2021 redis-6.2.4
-rw-------. 1 root  root     0 Nov 11 17:09 yum.log
[root@xwk tmp]# cd redis-6.2.4/
[root@xwk redis-6.2.4]# ll
total 236
-rw-rw-r--.  1 root root 28118 Jun  1  2021 00-RELEASENOTES
-rw-rw-r--.  1 root root    51 Jun  1  2021 BUGS
-rw-rw-r--.  1 root root  5026 Jun  1  2021 CONDUCT
-rw-rw-r--.  1 root root  3384 Jun  1  2021 CONTRIBUTING
-rw-rw-r--.  1 root root  1487 Jun  1  2021 COPYING
drwxrwxr-x.  7 root root   213 Nov 11 18:27 deps
-rw-rw-r--.  1 root root    11 Jun  1  2021 INSTALL
-rw-rw-r--.  1 root root   151 Jun  1  2021 Makefile
-rw-rw-r--.  1 root root  6888 Jun  1  2021 MANIFESTO
-rw-rw-r--.  1 root root 21567 Jun  1  2021 README.md
-rw-rw-r--.  1 root root 93724 Jun  1  2021 redis.conf
-rwxrwxr-x.  1 root root   275 Jun  1  2021 runtest
-rwxrwxr-x.  1 root root   279 Jun  1  2021 runtest-cluster
-rwxrwxr-x.  1 root root  1046 Jun  1  2021 runtest-moduleapi
-rwxrwxr-x.  1 root root   281 Jun  1  2021 runtest-sentinel
-rw-rw-r--.  1 root root 13768 Jun  1  2021 sentinel.conf
drwxrwxr-x.  3 root root 12288 Nov 11 18:28 src
drwxrwxr-x. 11 root root   182 Jun  1  2021 tests
-rw-rw-r--.  1 root root  3055 Jun  1  2021 TLS.md
drwxrwxr-x.  9 root root  4096 Jun  1  2021 utils
[root@xwk redis-6.2.4]# vim redis.conf
[root@xwk redis-6.2.4]# cd ..
[root@xwk tmp]# cp redis-6.2.4/redis.conf 7001
[root@xwk tmp]# cp redis-6.2.4/redis.conf 7002
[root@xwk tmp]# cp redis-6.2.4/redis.conf 7003
[root@xwk tmp]# sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001
[root@xwk tmp]# sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002
[root@xwk tmp]# sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003
[root@xwk tmp]# sed -i '1a replica-announce-ip 192.168.145.130' 7001/re
[root@xwk tmp]#    sed -i '1a replica-announce-ip 192.168.145.130' 7002
[root@xwk tmp]#    sed -i '1a replica-announce-ip 192.168.145.130' 7003
[root@xwk tmp]# redis-cli -p 7002
127.0.0.1:7002> slaveof 192.168.145.130 7001
OK
127.0.0.1:7002>
[root@xwk tmp]# redis-cli -p 7003
127.0.0.1:7003> slaveof 192.168.145.130 7001
OK
127.0.0.1:7003>
[root@xwk tmp]# redis-cli -p 7001
127.0.0.1:7001> info replication  #得到奴隶的信息
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.145.130,port=7002,state=online,offset=210,lag=1
slave1:ip=192.168.145.130,port=7003,state=online,offset=210,lag=1
master_failover_state:no-failover
master_replid:61a7de3ef4bd695040410d86be01a4542ae08cad
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:210
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:210
127.0.0.1:7001> set num 123
OK
127.0.0.1:7001>
[root@xwk tmp]# redis-cli -p 7002
127.0.0.1:7002> get num
"123"
127.0.0.1:7002>
[root@xwk tmp]# redis-cli -p 7003
127.0.0.1:7003> get num
"123"
127.0.0.1:7003>

7001

image-20231115194814015

slaveof 192.168.145.130 7001告知7002与7003从属于7001之后显示最下面的success:

image-20231115195215308

2.3 Redis哨兵Sentinel

image-20231116181723591

==

image-20231116181950976

==

image-20231116215518836

==

image-20231116182635453

==

2.3.1 集群结构

这里我们搭建一个三节点形成的Sentinel集群,来监管之前的Redis主从集群。如图:

image-20210701215227018

三个sentinel实例信息如下:

节点IPPORT
s1192.168.150.10127001
s2192.168.150.10127002
s3192.168.150.10127003

2.3.2 准备实例和配置

要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。

我们创建三个文件夹,名字分别叫s1、s2、s3:

# 进入/tmp目录
cd /tmp
# 创建目录
mkdir s1 s2 s3

如图:

image-20210701215534714

然后我们在s1目录创建一个sentinel.conf文件,添加下面的内容:

port 27001
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"

解读:

  • port 27001:是当前sentinel实例的端口
  • sentinel monitor mymaster 192.168.150.101 7001 2:指定主节点信息
    • mymaster:主节点名称,自定义,任意写
    • 192.168.150.101 7001:主节点的ip和端口
    • 2:选举master时的quorum值

然后将s1/sentinel.conf文件拷贝到s2、s3两个目录中(在/tmp目录执行下列命令):

# 方式一:逐个拷贝
cp s1/sentinel.conf s2
cp s1/sentinel.conf s3
# 方式二:管道组合命令,一键拷贝
echo s2 s3 | xargs -t -n 1 cp s1/sentinel.conf

修改s2、s3两个文件夹内的配置文件,将端口分别修改为27002、27003:

sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf
sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf

2.3.3 启动

为了方便查看日志,我们打开3个ssh窗口,分别启动3个redis实例,启动命令:

# 第1个
redis-sentinel s1/sentinel.conf
# 第2个
redis-sentinel s2/sentinel.conf
# 第3个
redis-sentinel s3/sentinel.conf

启动后:

image-20210701220714104

2.3.4 测试

尝试让master节点7001宕机,查看sentinel日志:

image-20210701222857997

查看7003的日志:

image-20210701223025709

查看7002的日志:

image-20210701223131264

实操记录

[root@xwk tmp]# mkdir s1 s2 s3
[root@xwk tmp]# ls
7001  7003             ks-script-aYmaht  mysql.sock.lock  s1  s3
7002  hsperfdata_root  mysql.sock        redis-6.2.4      s2  yum.log
[root@xwk tmp]# cd s1
[root@xwk s1]# vi sentinel.conf
port 27001
sentinel announce-ip 192.168.145.130
sentinel monitor mymaster 192.168.145.130 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"
[root@xwk s1]# cd ..
[root@xwk tmp]# cp s1/sentinel.conf s2
[root@xwk tmp]# cp s1/sentinel.conf s3
[root@xwk tmp]# sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf
[root@xwk tmp]# sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf
#另开启三个窗口,分别开三个redis,再进行连接
[root@xwk tmp]# redis-cli -p 7002
127.0.0.1:7002> slaveof 192.168.145.130 7001
OK
127.0.0.1:7002>
[root@xwk tmp]# redis-cli -p 7003
127.0.0.1:7003> slaveof 192.168.145.130 7001
OK
127.0.0.1:7003>
[root@xwk tmp]# redis-cli -p 7001
127.0.0.1:7001> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.145.130,port=7002,state=online,offset=4279,lag=0
slave1:ip=192.168.145.130,port=7003,state=online,offset=4424,lag=0
master_failover_state:no-failover
master_replid:bc10942ac67ef4afa4f6169eb6d073719000278b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4424
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4424
127.0.0.1:7001>
#此处退出连接7001
#然后把7001redis服务关闭 哨兵推选7002为master(推选截图在下面:),7001redis服务再次启动,变为slave
#连接7002 查看奴隶
[root@xwk tmp]# redis-cli -p 7002
127.0.0.1:7002> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.145.130,port=7003,state=online,offset=103555,lag=0
slave1:ip=192.168.145.130,port=7001,state=online,offset=103555,lag=0
master_failover_state:no-failover
master_replid:37b6176eda88c113e136fb461f9f19b611b78d1c
master_replid2:bc10942ac67ef4afa4f6169eb6d073719000278b
master_repl_offset:103845
second_repl_offset:12746
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:103845
127.0.0.1:7002>
[root@xwk tmp]#

推选:

image-20231116204352085

image-20231116204538618

注意

要开启相应redis服务再进行连接,否则报错

image-20231116203500406

2.4 Redis分片集群

搭建一主一从,三主三从

解决海量数据存储到Redis问题和高并发读写和高可用的问题

image-20231116212508262

三个主之间互相监测,互相实现了哨兵的功能,一个主挂掉之后,推举其从节点中其中一个为主,继续完成相互监测的功能,如果原主重启会变为从

主7001挂掉之后,数据访问会自动路由到正确的节点:如果在7001挂掉之后,去访问原来存储在7001上的数据,会自动路由到7001原来的从节点8001上(此时从节点8001已经变成主节点,从节点8001有7001原有的数据(主从之间数据同步))读取数据

===

2.4.1 集群结构

分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:

image-20210702164116027

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:

IPPORT角色
192.168.150.1017001master
192.168.150.1017002master
192.168.150.1017003master
192.168.150.1018001slave
192.168.150.1018002slave
192.168.150.1018003slave

2.4.2 准备实例和配置

删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:

# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003

在/tmp下准备一个新的redis.conf文件,内容如下:

port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log

将这个文件拷贝到每个目录下:

# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:

# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

2.4.3 启动

因为已经配置了后台启动模式,所以可以直接启动服务:

# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf

通过ps查看状态:

ps -ef | grep redis

发现服务都已经正常启动:

image-20210702174255799

如果要关闭所有进程,可以执行命令:

ps -ef | grep redis | awk '{print $2}' | xargs kill

或者(推荐这种方式):

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

2.4.4 创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。

1)Redis5.0之前

Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

# 安装依赖
yum -y install zlib ruby rubygems
gem install redis

然后通过命令来管理集群:

# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

2)Redis5.0以后

我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:

redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

命令说明:

  • redis-cli --cluster或者./redis-trib.rb:代表集群操作命令
  • create:代表是创建集群
  • --replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

运行后的样子:

image-20210702181101969

这里输入yes,则集群开始创建:

image-20210702181215705

通过命令可以查看集群状态:

redis-cli -p 7001 cluster nodes

image-20210702181922809

2.4.5 测试

尝试连接7001节点,存储一个数据:

# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1

结果悲剧了:

image-20210702182343979

集群操作时,需要给redis-cli加上-c参数才可以:

redis-cli -c -p 7001

这次可以了:

image-20210702182602145

实操记录

[root@xwk tmp]# rm -rf 7001 7002 7003
[root@xwk tmp]# ls
hsperfdata_root  ks-script-aYmaht  mysql.sock  mysql.sock.lock  redis-6.2.4  s1  s2  s3  yum.log
[root@xwk tmp]# mkdir 7001 7002 7003 8001 8002 8003
[root@xwk tmp]# ls
7001  7002  7003  8001  8002  8003  hsperfdata_root  ks-script-aYmaht  mysql.sock  mysql.sock.lock  redis-6.2.4  s1  s2  s3  yum.log
[root@xwk tmp]# vim redis.conf
[root@xwk tmp]# echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
cp redis.conf 7001
cp redis.conf 7002
cp redis.conf 7003
cp redis.conf 8001
cp redis.conf 8002
cp redis.conf 8003
[root@xwk tmp]# printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf
sed -i s/6379/7001/g 7001/redis.conf
sed -i s/6379/7002/g 7002/redis.conf
sed -i s/6379/7003/g 7003/redis.conf
sed -i s/6379/8001/g 8001/redis.conf
sed -i s/6379/8002/g 8002/redis.conf
sed -i s/6379/8003/g 8003/redis.conf
[root@xwk tmp]# printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
redis-server 7001/redis.conf
redis-server 7002/redis.conf
redis-server 7003/redis.conf
redis-server 8001/redis.conf
redis-server 8002/redis.conf
redis-server 8003/redis.conf
[root@xwk tmp]# ps -ef | grep redis
root       1622      1  0 21:30 ?        00:00:00 redis-server 0.0.0.0:7001 [cluster]
root       1624      1  0 21:30 ?        00:00:00 redis-server 0.0.0.0:7002 [cluster]
root       1630      1  0 21:30 ?        00:00:00 redis-server 0.0.0.0:7003 [cluster]
root       1636      1  0 21:30 ?        00:00:00 redis-server 0.0.0.0:8001 [cluster]
root       1642      1  0 21:30 ?        00:00:00 redis-server 0.0.0.0:8002 [cluster]
root       1648      1  0 21:30 ?        00:00:00 redis-server 0.0.0.0:8003 [cluster]
root       1660   1171  0 21:31 pts/0    00:00:00 grep --color=auto redis
[root@xwk tmp]# redis-cli --cluster create --cluster-replicas 1 192.168.145.130:7                                                                                 001 192.168.145.130:7002 192.168.145.130:7003 192.168.145.130:8001 192.168.145.13                                                                                 0:8002 192.168.145.130:8003
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.145.130:8002 to 192.168.145.130:7001
Adding replica 192.168.145.130:8003 to 192.168.145.130:7002
Adding replica 192.168.145.130:8001 to 192.168.145.130:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 857a696f133fa579174b9852d0535811889ef845 192.168.145.130:7001
   slots:[0-5460] (5461 slots) master
M: 5318bdca80e7a2cb5c56c513622f9b303d813a96 192.168.145.130:7002
   slots:[5461-10922] (5462 slots) master
M: 6b6419c1ffa152076981bd82d34327bdc2357393 192.168.145.130:7003
   slots:[10923-16383] (5461 slots) master
S: c65fd284e13246b09c91e585677a9bbc5b9d7067 192.168.145.130:8001
   replicates 5318bdca80e7a2cb5c56c513622f9b303d813a96
S: d310a56550b0c2a7103c59273051bc9f9faa4f1f 192.168.145.130:8002
   replicates 6b6419c1ffa152076981bd82d34327bdc2357393
S: 6f7e594955c03e06c58408fa1d9e6c31094f49b9 192.168.145.130:8003
   replicates 857a696f133fa579174b9852d0535811889ef845
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.145.130:7001)
M: 857a696f133fa579174b9852d0535811889ef845 192.168.145.130:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: c65fd284e13246b09c91e585677a9bbc5b9d7067 192.168.145.130:8001
   slots: (0 slots) slave
   replicates 5318bdca80e7a2cb5c56c513622f9b303d813a96
M: 5318bdca80e7a2cb5c56c513622f9b303d813a96 192.168.145.130:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: d310a56550b0c2a7103c59273051bc9f9faa4f1f 192.168.145.130:8002
   slots: (0 slots) slave
   replicates 6b6419c1ffa152076981bd82d34327bdc2357393
S: 6f7e594955c03e06c58408fa1d9e6c31094f49b9 192.168.145.130:8003
   slots: (0 slots) slave
   replicates 857a696f133fa579174b9852d0535811889ef845
M: 6b6419c1ffa152076981bd82d34327bdc2357393 192.168.145.130:7003
   slots:[10923-16383] (5461 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.
[root@xwk tmp]# redis-cli -p 7001 cluster nodes
857a696f133fa579174b9852d0535811889ef845 192.168.145.130:7001@17001 myself,master                                                                                  - 0 1700141729000 1 connected 0-5460
c65fd284e13246b09c91e585677a9bbc5b9d7067 192.168.145.130:8001@18001 slave 5318bdc                                                                                 a80e7a2cb5c56c513622f9b303d813a96 0 1700141728558 2 connected
5318bdca80e7a2cb5c56c513622f9b303d813a96 192.168.145.130:7002@17002 master - 0 17                                                                                 00141728659 2 connected 5461-10922
d310a56550b0c2a7103c59273051bc9f9faa4f1f 192.168.145.130:8002@18002 slave 6b6419c                                                                                 1ffa152076981bd82d34327bdc2357393 0 1700141728000 3 connected
6f7e594955c03e06c58408fa1d9e6c31094f49b9 192.168.145.130:8003@18003 slave 857a696                                                                                 f133fa579174b9852d0535811889ef845 0 1700141729066 1 connected
6b6419c1ffa152076981bd82d34327bdc2357393 192.168.145.130:7003@17003 master - 0 17                                                                                 00141729578 3 connected 10923-16383
[root@xwk tmp]# redis-cli -p 7001
127.0.0.1:7001> set num 123
OK
127.0.0.1:7001> get num
"123"
127.0.0.1:7001> set a 1
(error) MOVED 15495 192.168.145.130:7003
127.0.0.1:7001>
[root@xwk tmp]# redis-cli -c -p 7001
127.0.0.1:7001> set a 1
-> Redirected to slot [15495] located at 192.168.145.130:7003
OK
192.168.145.130:7003> exit
[root@xwk tmp]# redis-cli -c -p 7001
127.0.0.1:7001> set age 11
OK
127.0.0.1:7001> set name gk
-> Redirected to slot [5798] located at 192.168.145.130:7002
OK
192.168.145.130:7002>


  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些关于 Redis 持久化的可能面试问题: 1. Redis持久化有哪些方式? Redis持久化有两种方式,一种是 RDB 持久化,一种是 AOF 持久化。 2. RDB 持久化和 AOF 持久化有什么区别? RDB 持久化是将 Redis 在内存中的数据快照保存到磁盘上,而 AOF 持久化则是将 Redis 执行的每条写命令记录到磁盘上。RDB 持久化可以节约磁盘空间,但可能会丢失最近的一些数据,而 AOF 持久化可以保证数据不会丢失,但可能会占用更多的磁盘空间和写入时间。 3. Redis持久化机制是如何保证数据一致性的? Redis持久化机制可以通过在每次写操作后立即同步到磁盘,或者设置定期同步时间来保证数据一致性。 4. Redis持久化可以在运行时进行吗? 可以,Redis持久化可以在运行时进行配置和切换,例如可以在运行时从 RDB 切换到 AOF 持久化,或者从 AOF 切换到 RDB 持久化。 5. Redis持久化会对性能产生影响吗? 会,Redis持久化会增加磁盘 I/O 开销,可能会对写入性能产生一定的影响,但可以通过合理的配置来平衡性能和数据一致性。 6. Redis持久化可以与 Redis 集群一起使用吗? 可以,Redis持久化可以与 Redis 集群一起使用,但需要注意配置文件的设置和数据同步的策略。 总之,Redis持久化是保证数据一致性和可靠性的重要手段,需要根据具体的业务需求和性能要求来选择合适的持久化方式,并进行合理的配置和优化。在面试中,还需要了解 Redis 持久化的原理、机制、优缺点、与集群的结合等方面的知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值