大数据技术栈——redis的持久化、主从架构、哨兵架构与集群

本文详细介绍了Redis的RDB和AOF两种持久化方案,对比了各自的优缺点,并阐述了主从复制、哨兵架构及集群部署,旨在提高Redis的稳定性和数据安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.redis的持久化

由于redis是一个内存数据库,所有的数据都是保存在内存当中的,内存当中的数据极易丢失,所以redis的数据持久化就显得尤为重要,在redis当中,提供了两种数据持久化的方式,分别为RDB以及AOF,且redis默认开启的数据持久化方式为RDB方式,接下来我们就分别来看下两种方式的配置吧

1.1 RDB持久化方案介绍

RDB方案介绍

Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据。可以在配置文件中配置Redis进行快照保存的时机:
save [seconds] [changes]
意为在[seconds]秒内如果发生了[changes]次数据修改,则进行一次RDB快照保存,例如

save 60 100

会让Redis每60秒检查一次数据变更情况,如果发生了100次或以上的数据变更,则进行RDB快照保存。可以配置多条save指令,让Redis执行多级的快照保存策略。Redis默认开启RDB快照。也可以通过SAVE或者BGSAVE命令手动触发RDB快照保存。
SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同:
• SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
• BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。

RDB方案优点

1、 对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。

2、 每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。

3、 使用RDB文件进行数据恢复比使用AOF要快很多

RDB方案缺点

1、 快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。

2、 如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。
RDB方案配置
修改redis的配置文件

cd /export/servers/redis-3.2.8/
vim redis.conf
save 900 1
save 300 10
save 60 10000
save 5 1

在这里插入图片描述

重新启动redis服务
每次生成新的dump.rdb都会覆盖掉之前的老的快照

ps -ef | grep redis
kill -9 69632 74217
src/redis-server redis.conf
root      69632      1  0 11:07 ?        00:00:55 redis-server 
192.168.52.100:6379

在这里插入图片描述

1.2 AOF持久化方案介绍

AOF方案介绍:

采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。AOF默认是关闭的,如要开启,进行如下配置:

appendonly yes

AOF提供了三种fsync配置,always/everysec/no,通过配置项[appendfsync]指定:
appendfsync no:不进行fsync,将flush文件的时机交给OS决定,速度最快appendfsync always:每写入一条日志就进行一次fsync操作,数据安全性最高,但速度最慢
appendfsync everysec:折中的做法,交由后台线程每秒fsync一次
随着AOF不断地记录写操作日志,因为所有的操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。不过Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。
AOF rewrite可以通过BGREWRITEAOF命令触发,也可以配置Redis定期自动进行:
auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
上面两行配置的含义是,Redis在每次AOF rewrite时,会记录完成rewrite后的AOF日志大小,当AOF日志大小在该基础上增长了100%后,自动进行AOF rewrite。同时如果增长的大小没有达到64mb,则不会进行rewrite。

AOF优点:

1、 最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据

2、 AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。

3、 AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。

AOF的缺点:

1、 AOF文件通常比RDB文件更大
2、 性能消耗比RDB高
3、 数据恢复速度比RDB慢

Redis的数据持久化工作本身就会带来延迟,需要根据数据的安全级别和性能要求制定合理的持久化策略:
AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响

AOF + fsync every second是比较好的折中方案,每秒fsync一次

AOF + fsync never会提供AOF持久化方案下的最优性能使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置

每一次RDB快照和AOF Rewrite都需要Redis主进程进行fork操作。fork操作本身可能会产生较高的耗时,与CPU和Redis占用的内存大小有关。根据具体的情况合理配置RDB快照和AOF Rewrite时机,避免过于频繁的fork带来的延迟

Redis在fork子进程时需要将内存分页表拷贝至子进程,以占用了24GB内存的Redis实例为例,共需要拷贝24GB / 4kB * 8 = 48MB的数据。在使用单Xeon 2.27Ghz的物理机上,这一fork操作耗时216ms。

AOF方案配置

在redis中,aof的持久化机制默认是关闭的
AOF持久化,默认是关闭的,默认是打开RDB持久化

appendonly yes,可以打开AOF持久化机制,在生产环境里面,一般来说AOF都是要打开的,除非你说随便丢个几分钟的数据也无所谓
打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下
而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整
可以配置AOF的fsync策略,有三种策略可以选择,一种是每次写入一条数据就执行一次fsync; 一种是每隔一秒执行一次fsync; 一种是不主动执行fsync
always: 每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 确保说redis里的数据一条都不丢,那就只能这样了
在redis当中默认的AOF持久化机制都是关闭的

配置redis的AOF持久化机制方式

cd /export/servers/redis-3.2.8
vim redis.conf
appendonly yes
# appendfsync always
appendfsync everysec
# appendfsync no

2.redis的主从复制架构

在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave),如图所示。
在这里插入图片描述
使用主从复制这种模式,实现node01作为主节点,node02与node03作为从节点,并且将node01所有的数据全部都同步到node02与node03服务器

第一步:node02与node03服务器安装redis

node02与node03执行以下命令安装依赖环境

yum -y install gcc-c++

node02与node03上传redis压缩包
在node02与node03服务器上面上传redis压缩包,然后进行解压
将安装包上传到/export/softwares路径下

cd /export/softwares
tar -zxvf redis-3.2.8.tar.gz -C ../servers/

node02与node03服务器安装tcl
node02与node03服务器执行以下命令在线装TCL

yum  -y  install  tcl

node02与node03服务器编译redis
node02与node03执行以下命令进行编译redis
执行以下命令进行编译:

cd /export/servers/redis-3.2.8/
make MALLOC=libc   #或者使用命令  make  进行编译
make test && make install

node02与node03服务器修改redis配置文件
node02服务器修改配置文件命令如下
执行以下命令修改redis配置文件

cd /export/servers/redis-3.2.8/
mkdir -p /export/servers/redis-3.2.8/logs
mkdir -p /export/servers/redis-3.2.8/redisdata
vim redis.conf
bind node02
daemonize yes
pidfile /var/run/redis_6379.pid
logfile "/export/servers/redis-3.2.8/logs/redis.log"
dir /export/servers/redis-3.2.8/redisdata
slaveof node01 6379

node03服务器修改配置文件命令如下
执行以下命令修改redis配置文件

cd /export/servers/redis-3.2.8/
mkdir -p /export/servers/redis-3.2.8/logs
mkdir -p /export/servers/redis-3.2.8/redisdata
vim redis.conf
bind node03
daemonize yes
pidfile /var/run/redis_6379.pid
logfile "/export/servers/redis-3.2.8/logs/redis.log"
dir /export/servers/redis-3.2.8/redisdata
slaveof node01 6379

第二步、启动node02与node03机器的redis服务

node02执行以下命令启动redis服务

cd  /export/servers/redis-3.2.8/src
redis-server  ../redis.conf

node03执行以下命令启动redis服务

cd  /export/servers/redis-3.2.8/src
redis-server  ../redis.conf

启动成功便可以实现redis的主从复制,node01可以读写操作,node02与node03只支持读取操作。

node01写数据:

在这里插入图片描述
node02读数据:
在这里插入图片描述
node03读数据:
在这里插入图片描述

3. redis当中的Sentinel架构(哨兵)

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
例如:
在这里插入图片描述
在Server1 掉线后:
在这里插入图片描述
升级Server2 为新的主服务器:
在这里插入图片描述

第一步:三台机器修改哨兵配置文件

三台机器执行以下命令修改redis的哨兵配置文件

cd /export/servers/redis-3.2.8
vim sentinel.conf
# 配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。
#修改bind配置,每台机器修改为自己对应的主机名
bind node01  
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>

第二步:三台机器启动哨兵服务

cd /export/servers/redis-3.2.8
src/redis-sentinel sentinel.conf 

第三步:node01服务器杀死redis服务进程

使用kill -9命令杀死redis服务进程,模拟redis故障宕机情况
过一段时间之后,就会在node02与node03服务器选择一台服务器来切换为主节点

第四步:redis的sentinel模式代码开发连接

/**
 * 测试Redis哨兵模式
 */
    @Test
    public void testSentinel() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(10);
        jedisPoolConfig.setMaxIdle(5);
        jedisPoolConfig.setMinIdle(5);
        // 哨兵信息
        Set<String> sentinels = new HashSet<>(Arrays.asList("node01:26379",
                "node02:26379","node03:26379"));
        // 创建连接池
        JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig);
        // 获取客户端
        Jedis jedis = pool.getResource();
        // 执行两个命令
        jedis.set("mykey", "myvalue");
        String value = jedis.get("mykey");
        System.out.println(value);
    }

4.redis集群

1、redis集群的介绍

Redis 集群是一个提供在多个Redis节点之间共享数据的程序集。
Redis 集群并不支持同时处理多个键的 Redis 命令,因为这需要在多个节点间移动数据,这样会降低redis集群的性能,在高负载的情况下可能会导致不可预料的错误。
Redis 集群通过分区来提供一定程度的可用性,即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

Redis 集群的优势:

1.缓存永不宕机:启动集群,永远让集群的一部分起作用。主节点失效了子节点能迅速改变角色成为主节点,整个集群的部分节点失败或者不可达的情况下能够继续处理命令;

2.迅速恢复数据:持久化数据,能在宕机后迅速解决数据丢失的问题;

3.Redis可以使用所有机器的内存,变相扩展性能;

4.使Redis的计算能力通过简单地增加服务器得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长;

5.Redis集群没有中心节点,不会因为某个节点成为整个集群的性能瓶颈;

6.异步处理数据,实现快速读写。

2、redis集群环境搭建

由于redis集群当中最少需要三个主节点,每个主节点,最少需要一个对应的从节点,所以搭建redis集群最少需要三主三从的配置,所以redis集群最少需要6台redis的实例,我们这里使用三台机器,每台服务器上面运行两个redis的实例。我们这里使用node01服务器,通过配置不同的端口,实现redis集群的环境搭建

第一步:node01服务器解压redis压缩包

node01执行以下命令重新解压redis压缩包到/export路径下

cd /export/softwares/
tar -zxf redis-3.2.8.tar.gz -C /export/

第二步:安装redis必须依赖环境并进行编译

node01执行以下命令安装redis的依赖环境

yum -y install gcc-c++ tcl

对redis进行编译

cd /export/redis-3.2.8
make && make install

第三步:创建redis不同实例的配置文件夹

创建文件夹,并将redis的配置文件拷贝到以下这些目录

cd /export/redis-3.2.8
mkdir -p /export/redis-3.2.8/clusters/7001
mkdir -p /export/redis-3.2.8/clusters/7002
mkdir -p /export/redis-3.2.8/clusters/7003
mkdir -p /export/redis-3.2.8/clusters/7004
mkdir -p /export/redis-3.2.8/clusters/7005
mkdir -p /export/redis-3.2.8/clusters/7006

第四步:修改redis的六个配置文件

node01执行以下命令修改redis的配置文件

mkdir -p /export/redis-3.2.8/logs
mkdir -p /export/redis-3.2.8/redisdata/7001
mkdir -p /export/redis-3.2.8/redisdata/7002
mkdir -p /export/redis-3.2.8/redisdata/7003
mkdir -p /export/redis-3.2.8/redisdata/7004
mkdir -p /export/redis-3.2.8/redisdata/7005
mkdir -p /export/redis-3.2.8/redisdata/7006

第一个配置文件修改

vim  /export/redis-3.2.8/redis.conf
bind node01
port 7001
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /var/run/redis_7001.pid
logfile "/export/redis-3.2.8/logs/7001.log"
dir /export/redis-3.2.8/redisdata/7001

将修改后的文件拷贝到对应的文件夹下面去

cp /export/redis-3.2.8/redis.conf /export/redis-3.2.8/clusters/7001

第二个配置文件修改

cp /export/redis-3.2.8/redis.conf /export/redis-3.2.8/clusters/7002
vim  /export/redis-3.2.8/clusters/7002/redis.conf
bind node01
port 7002
cluster-enabled yes
cluster-config-file nodes-7002.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /var/run/redis_7002.pid
logfile "/export/redis-3.2.8/logs/7002.log"
dir /export/redis-3.2.8/redisdata/7002

第三个配置文件修改

cp /export/redis-3.2.8/redis.conf /export/redis-3.2.8/clusters/7003
vim  /export/redis-3.2.8/clusters/7003/redis.conf
bind node01
port 7003
cluster-enabled yes
cluster-config-file nodes-7003.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /var/run/redis_7003.pid
logfile "/export/redis-3.2.8/logs/7003.log"
dir /export/redis-3.2.8/redisdata/7003

第四个配置文件修改

cp /export/redis-3.2.8/redis.conf /export/redis-3.2.8/clusters/7004
vim  /export/redis-3.2.8/clusters/7004/redis.conf
bind node01
port 7004
cluster-enabled yes
cluster-config-file nodes-7004.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /var/run/redis_7004.pid
logfile "/export/redis-3.2.8/logs/7004.log"
dir /export/servers/redis-3.2.8/redisdata/7004

第五个配置文件修改

cp /export/redis-3.2.8/redis.conf /export/redis-3.2.8/clusters/7005
vim  /export/redis-3.2.8/clusters/7005/redis.conf
bind node01
port 7005
cluster-enabled yes
cluster-config-file nodes-7005.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /var/run/redis_7005.pid
logfile "/export/redis-3.2.8/logs/7005.log"
dir /export/servers/redis-3.2.8/redisdata/7005

第六个配置文件修改

cp /export/redis-3.2.8/redis.conf /export/redis-3.2.8/clusters/7006
vim  /export/redis-3.2.8/clusters/7006/redis.conf
bind node01
port 7006
cluster-enabled yes
cluster-config-file nodes-7006.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /var/run/redis_7006.pid
logfile "/export/redis-3.2.8/logs/7006.log"
dir /export/servers/redis-3.2.8/redisdata/7006

第五步:启动redis进程

node01执行以下命令来启动redis集群

cd /export/redis-3.2.8
src/redis-server clusters/7001/redis.conf
src/redis-server clusters/7002/redis.conf
src/redis-server clusters/7003/redis.conf
src/redis-server clusters/7004/redis.conf
src/redis-server clusters/7005/redis.conf
src/redis-server clusters/7006/redis.conf

第六步:安装ruby运行环境

node01执行以下命令,安装ruby运行环境,因为redis集群的启动需要借助ruby的环境

yum install ruby
yum install rubygems
gem install redis

这个时候可能会报错,如下:
在这里插入图片描述

这时,需要升级Ruby版本
node01执行以下命令升级ruby版本

cd /export/redis-3.2.8
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

curl -sSL https://get.rvm.io | bash -s stable
source /etc/profile.d/rvm.sh
rvm list known
rvm install 2.4.1

第七步:创建redis集群
node01执行以下命令创建redis集群

cd /export/redis-3.2.8
gem install redis
src/redis-trib.rb create --replicas 1 192.168.100.100:7001 
192.168.100.100:7002 192.168.100.100:7003 192.168.100.100:7004 
192.168.100.100:7005 192.168.100.100:7006

第八步:连接redis客户端
node01执行以下命令连接redis客户端

cd /export/redis-3.2.8
src/redis-cli  -h node01 -c -p 7001

3、redis集群管理

添加一个新节点作为主节点
启动新节点的redis服务,然后添加到集群当中去
启动服务

src/redis-server clusters/7007/redis.conf
src/redis-trib.rb add-node 192.168.100.100:7007 192.168.100.100:7001

添加一个新节点作为副本

src/redis-server clusters/7008/redis.conf
src/redis-trib.rb add-node --slave 192.168.100.100:7008 192.168.100.100:7001

删除一个节点
命令格式

src/redis-trib del-node 127.0.0.1:7000 `<node-id>`
src/redis-trib.rb del-node 192.168.100.100:7008 
7c7b7f68bc56bf24cbb36b599d2e2d97b26c5540

重新分片

./redis-trib.rb reshard node01:7001
./redis-trib.rb reshard --from <node-id> --to <node-id> --slots <number of slots> --yes <host>:<port>

4、JavaAPI操作redis集群

@Test
public void jedisClusterTest() throws IOException {
    Set<HostAndPort> portSet = new HashSet<HostAndPort>();
    portSet.add(new HostAndPort("node01",7001));
    portSet.add(new HostAndPort("node01",7002));
    portSet.add(new HostAndPort("node01",7003));
    portSet.add(new HostAndPort("node01",7004));
    portSet.add(new HostAndPort("node01",7005));
    portSet.add(new HostAndPort("node01",7006));
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxIdle(10);
    jedisPoolConfig.setMaxWaitMillis(3000);
    jedisPoolConfig.setMaxTotal(30);
    jedisPoolConfig.setMinIdle(5);

    JedisCluster jedisCluster = new JedisCluster(portSet, jedisPoolConfig);

    jedisCluster.set("cluster","clustervalue");

    jedisCluster.close();

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值