Redis实战--Redis的数据持久化与搭建Redis主从复制模式和搭建Redis的哨兵模式
Redis作为一个高性能的key-value数据库,广泛应用于缓存、消息队列、排行榜等场景。然而,Redis是基于内存的数据库,这意味着一旦服务器宕机,内存中的数据就会丢失。为了解决这个问题,Redis提供了数据持久化的机制,包括RDB和AOF两种方式。此外,为了提高数据的可用性和可扩展性,Redis还支持主从复制和哨兵模式。本文将详细介绍Redis的数据持久化机制、如何搭建Redis主从复制模式以及如何搭建Redis的哨兵模式。
Redis简单介绍与安装应用-CSDN博客
Redis实战--Windows上的Redis使用及Java代码操作Redis-CSDN博客
一、Redis的数据持久化
1)为什么要持久化?
Redis是基于内存的数据库,其优点是速度快,但缺点是数据容易丢失。为了解决这个问题,Redis提供了两种持久化机制:RDB和AOF。
2)RDB持久化
RDB持久化是通过创建数据的快照来实现的。
在redis.conf
文件中,默认开启了RDB持久化:
操作越频发,保存的间隔时间越短
目前默认的配置:
save 900 1 代表如果用户在900秒内(15分钟)操作redis一次以上就保存一下。
通过如上的配置,我们得出一个结论,用户只要操作redis越频繁,保存的间隔时间就短。
RDB持久化有两种命令:SAVE
和BGSAVE
。
SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同:
1)SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
2)BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。bg = backgroud的意思,这两个命令都是手动的保存数据。
RDB方案优点
1、对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。
2、每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。3、使用RDB文件进行数据恢复比使用AOF要快很多
RDB方案缺点
1、快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。
如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力
3)AOF持久化
AOF持久化是通过记录每次执行的命令来实现的。这种方式每操作一次就保存一次,数据安全性更高,但性能会有一定影响。
AOF功能会产生aof文件,这个文件会越来越大,如何处理? redis有一个rewrite功能。
随着AOF不断地记录写操作日志,因为所有的操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。不过Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。
AOF rewrite可以通过BGREWRITEAOF命令触发,也可以配置Redis定期自动进行:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
上面配置的含义是,Redis在每次AOF rewrite时,会记录完成rewrite后的AOF日志大小,当AOF日志大小在该基础上增长了100%后,自动进行AOF rewrite。同时如果增长的大小没有达到64mb,则不会进行rewrite。AOF文件 10M --> 20M 增长100%会触发 rewrite功能
变大了64M --> 也会触发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慢
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持久化机制都是关闭的。# appendfsync always
always: 每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 确保说redis里的数据一条都不丢,那就只能这样了appendfsync everysec
每秒将os cache中的数据fsync到磁盘,这个最常用的,生产环境一般都这么配置,性能很高,QPS还是可以上万的
# appendfsync no
4. 综合比较
RDB和AOF各有优缺点,可以根据业务需求选择合适的持久化策略。如果对数据完整性要求高,可以选择AOF;如果对性能要求高,可以选择RDB。
RDB (丢数据比较频繁)
AOF(稍微慢,但是相对来讲数据比较安全) 默认不开启。
AOF的保持机制: always everysec no
AOF 还有rewrite机制:日志有很多是垃圾数据,需要挑选一下。
二、Redis主从复制
1) 为什么要主从复制?
主从复制可以实现数据同步和读写分离,提高系统的可用性和可扩展性。
2.)搭建主从复制
搭建主从复制
我们的方案就是在服务器上安装主从,一个主,两个从,在redis.conf
中配置主从关系。例如:
[root@caiji bin]# mkdir mastersalves
[root@caiji bin]# cp redis.conf ./mastersalves/
配置隶属关系
修改从节点的配置文件 ,这个配置很重要,一定要配置
redis5.0 需要如下配置
# replicaof <masterip> <masterport>
replicaof bigdata01 6379
检查一下以前的配置是否修改了:
Redis简单介绍与安装应用-CSDN博客
配置日志文件和数据目录
产生的日志
mkdir -p /usr/local/bin/mastersalves/logs
产生的数据
mkdir -p /usr/local/bin/mastersalves/redisdata
数据路径
如果主节点配置了密码保护,从节点也需要配置密码:
masterauth 123456
启动主节点
./redis-server redis.conf
启动从节点
./redis-server mastersalves/redis.conf
验证主从效果
3)故障转移
验证主节点挂了,从节点顶上去
在从节点,cli端,输入命令
slaveof NO ONE
这种模式,虽然可以实现主从,从节点可以顶上去,但是是手动模式,不太方便。
假如主节点又修复好了,启动了,此时从节点从主节点再变为从节点:
在从节点,执行这句话
SLAVEOF bigdata01 6379
三、Redis的哨兵模式
1)哨兵模式解决的问题
哨兵模式可以自动将从节点升级为主节点,解决了主从模式下无法自动故障转移的问题。
2)搭建哨兵模式
环境搭建
在 /usr/local/bin下面:
mkdir sentinel-zc
复制外面的sentinel.conf 到 sentinel-zc 文件夹下面
cp /opt/installs/redis-4.0.14/sentinel.conf sentinel-zc
修改sentinel.conf配置
修改bind
bind bigdata01
修改端口号
port 26379 第一次不需要修改
daemonize yes 表示将来的sentinel服务,后台启动
sentinel monitor mymaster bigdata01 6379 2
将配置文件拷贝三份,修改端口号
[root@bigdata02 sentinel-zc]# cp sentinel.conf sentinel2.conf
[root@bigdata02 sentinel-zc]# cp sentinel.conf sentinel3.conf
另一个修改为 26381
假如主节点server 配置了密码,需要在sentinel.conf 文件中也配置密码:大约70行左右
sentinel auth-pass mymaster 123456谨记: 以上这个语句必须写在 sentinel monitor mymaster 192.168.32.129 6379 2
的下方,否则启动报错。
启动三台sentinel 服务
先启动 redis-server 服务
./redis-server redis.conf
./redis-server mastersalves/redis.conf
再次启动 redis-sentinel服务:
./redis-sentinel sentinel-zc/sentinel.conf
./redis-sentinel sentinel-zc/sentinel2.conf
./redis-sentinel sentinel-zc/sentinel3.conf
测试哨兵模式:将主节点杀死,从节点自动变为主节点:
哨兵模式可以自动将从节点变为主节点(重点是:自动)
假如这个时候主节点又启动起来了,会自动变为从节点,并且从主节点中同步数据。
相当于以前的主节点变从节点,从节点自动变主节点,而且两边数据会同步。从节点也可以重新变为从节点,主节点变为主节点,需要手动修改。
SLAVEOF bigdata01 6379
主节点输入命令:slaveof NO ONE 变为主节点
主节点的redis的数据默认是存储在 ./的文件夹下
启动的时候在哪里启动,数据就保存在哪里,很不方便,可以通过配置文件指定数据的位置
cd /usr/local/bin
mkdir masterdata
修改 redis.conf
dir /usr/local/bin/masterdata
如果是哨兵模式,jedis代码做稍微的调整,当然以前的也可以使用(但是假如主节点发生了变化,代码会连接不上)。
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
public class JedisSentinalPoolTest {
Jedis jedis = null;
@Before
public void initDB(){
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// idle 空闲的 最大空闲
poolConfig.setMaxIdle(200);
// 最大的连接数量
poolConfig.setMaxTotal(1000);
// 最小空闲
poolConfig.setMinIdle(5);
HashSet<String> hashSet = new HashSet<>();
hashSet.add("bigdata01:26379");
hashSet.add("bigdata01:26380");
hashSet.add("bigdata01:26381");
JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster",hashSet,poolConfig,"123456");
jedis = sentinelPool.getResource();
}
@After
public void destroyDB(){
// 数据库关闭
jedis.close();
}
/**
* 常见的数据库连接池有:c3p0 dbcp druid HikariCP等
*/
@Test
public void testPool(){
System.out.println(jedis.get("age"));
}
}
3)哨兵模式的优缺点
哨兵模式的优点是可以实现自动故障转移,提高系统的可用性。缺点是需要额外的资源来部署哨兵节点。
结语
通过本文的介绍,相信大家对Redis的数据持久化、主从复制和哨兵模式有了更深入的了解。在实际应用中,可以根据业务需求选择合适的持久化策略和部署模式,以提高Redis的可用性和可扩展性。