快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。容易丢失数据。但是恢复速度很快。
从 1.1 版本开始, Redis 增加了一种完全的持久化方式: AOF 持久化,支持将修改的每一条指令记录进文件appendonly.aof中(先写入os cache,每隔一段时间fsync到磁盘)。
注意,如果执行带过期时间的set命令,aof文件里记录的是并不是执行的原始命令,而是记录key过期的时间戳;例如:
比如执行“set tuling 888 ex 1000”,对应aof文件里记录如下
开启aof的配置:
# appendonly yes
可以配置 Redis 将数据 fsync 到磁盘频次,有三个选项:
- 1 appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
- 2 appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
- 3 appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
因为aof存储的文件是追加写入的,所以aof文件的大小会随着时间的流逝而越来越大,所以AOF文件里可能有太多没用指令;所以就有了针对aof文件的重写。
例如set key1 v1;set key1 v2;set key1 v3;经过优化之后会变成set key1 v3
如下两个配置可以控制AOF自动重写频率
1 # auto‐aof‐rewrite‐min‐size 64mb //aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就很快,重写的意义不大
2 # auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重写后文件大小增长了100%则再次触发重写。
当然AOF还可以手动重写,进入redis客户端执行命令bgrewriteaof重写AOF
注意,AOF重写redis会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多影响

生产环境可以都启用,redis启动时如果既有rdb文件又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更全一点。
重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。 4.0默认是开启混合持久化的。
配置如下:
# aof‐use‐rdb‐preamble yes
但是使用混合持久化必须要先开启aof持久化。
appendonly yes
如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的AOF 全量文件重放,因此重启效率大幅得到提升。文件后缀还是AOF。优先级高于RDB。
- 1. 写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48小时的备份
- 2. 每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份
- 3. 每次copy备份的时候,都把太旧的备份给删了
- 4. 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏

如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC命令给master请求复制数据。
master收到PSYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。然后保持这个链接,master的修改都会通过这个连接发给slave节点,保证数据的同步。(这整个过程的复制时redis的后台线程来控制的)。
当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。如果短时间的断联,master的缓存可以放下这段时间的修改,那么就将缓存中的数据发送给slave;如果断联时间很长,那么就会重新触发一次RDB。

当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,redis改用可以支持部分数据复制的命令PSYNC去master同步数据,slave与master能够在网络连接断开重连后只进行部分数据复制(断点续传)。
master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复制。
通过这样的方式可用减少主从同步的压力,降低带宽压力。
主从复制(部分复制,断点续传)流程图:
如果主节点挂载的从节点太多,那么就可能会导致主节点复制压力太大,从而影响对外部的服务。降低redis的可用性。这就是主从复制风暴。为了避免这样的情况发生,可以将从节点挂载到从节点上,形成分层的结构。主节点直连的从节点数量降低。

对于redis来说,每次在redis中操作数据是很快的;但是建立连接和数据传输不一定是很快的,所以为了提升效率,就提出了管道的概念,将多个请求一次性的发送到redis中。
需要注意到是用pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。
pipeline中发送的每个command都会被server立即执行,如果执行失败,将会在此后的响应中得到信息;也就是pipeline并不是表达“所有command都一起成功”的语义,管道中前面命令失败,后面命令不会有影响,继续执行。也就是说pipeline并不保证原子性。只是减少了和redis之间的交互,降低了网络压力。如果出现了异常,要在业务侧进行处理。
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行
例如出现了setget这样,那么队列中的全部都不执行。
若在事务队列中存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令抛出异常。
不会出现回滚的现象。
不建议使用redis的事务。
Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行。使用脚本的好处如下:
1、减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在redis服务器上完成。使用脚本,减少了网络往返时延。这点跟管道类似。
2、原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。管道不是原子的,不过redis的批量操作命令(类似mset)是原子的。
3、替代redis的事务功能:redis自带的事务功能很鸡肋,而redis的lua脚本几乎实现了常规的事务功能,官方推荐如果要使用redis的事务功能可以用redis lua替代。
注意,不要在Lua脚本中出现死循环和耗时的运算,否则redis会阻塞,将不接受其他的命令, 所以使用时要注意不能出现死循环、耗时的运算。redis是单进程、单线程执行脚本。管道不会阻塞redis。

sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)
设置主节点是6379;两个从节点分别是6380,6381.
sentinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的最下面),我们查看下如下配置文件sentinel-26379.conf,如下所示:
当redis主节点如果挂了,哨兵集群会重新选举出新的redis主节点,同时会修改所有sentinel节点配置文件的集群元数据信息,比如6379的redis如果挂了,假设选举出的新主节点是6380,则sentinel文件里的集群元数据信息会变成如下所示:
同时还会修改sentinel文件里之前配置的mymaster对应的6379端口,改为6380
当6379的redis实例再次启动时,哨兵集群根据集群元数据信息就可以将6379端口的redis节点作为从节点加入集群
Redis哨兵(Sentinel)系统是Redis用来实现高可用性和监控的工具,它能够帮助管理多个Redis服务器实例,并在出现故障时进行适当的动作,比如自动故障迁移或发送警告。以下是Redis哨兵架构的一些优缺点:
优点:
1. 高可用性:哨兵系统能够确保在主Redis实例出现故障时,自动将备用实例提升为新的主实例,以实现服务的持续可用性。
2. 监控:哨兵会不断地监控Redis实例的健康状况,包括节点是否可达、是否响应命令等,并在出现问题时发出警告。
3. 故障迁移:当主Redis实例不可用时,哨兵可以根据配置的规则自动将一个从实例转换为主实例,以实现故障的无缝迁移。
4. 配置灵活:哨兵允许用户配置多种参数,如选举超时时间、故障转移的策略等,以适应不同的业务需求。
5. 支持多数据中心:哨兵支持设置多个哨兵实例,每个实例负责不同的Redis主从集群,这样就可以实现跨数据中心的故障转移能力。
缺点:
1. 复杂性:相对于单实例的Redis,哨兵架构引入了更多的配置和组件,这可能会增加系统的复杂性。
2. 性能开销:哨兵系统会有一部分的性能开销,因为它需要监控和维护额外的信息,并处理故障转移等逻辑。
3. 多哨兵配置复杂:在复杂的环境中,多个哨兵之间的协调和配置可能会变得复杂,需要仔细规划。
4. 不支持读写分离:哨兵架构不支持传统的读写分离,因为从实例在故障转移时可能被提升为新的主实例。
5. 数据一致性:在某些复杂的故障转移情况下,可能会出现短暂的数据不一致问题,虽然Redis支持事务和持久化机制,但在极端情况下仍需注意数据一致性。
总体而言,Redis哨兵系统在提供高可用性和监控功能的同时,也带来了一定的复杂性和性能考虑。对于需要高可用性的Redis应用场景,哨兵是一个很好的选择,但在规划和部署时需要仔细考虑上述优缺点。
同时哨兵架构中,主节点会存储全部的数据,增加节点只是可以减少访问并发的压力,对写入内存压力来说没有什么提升。
在Redis哨兵(Sentinel)模式下,故障转移是指当主Redis实例因某些原因不可用时,哨兵系统将会触发一个流程,将一个从实例(Slave)升级为新的主实例(Master),并确保所有从实例跟随新的主实例。以下是故障转移的基本流程:
1. 监控状态:哨兵系统持续监控Redis主实例和从实例的健康状态。它通过向实例发送PING命令并监听实例的回复来判断实例是否健康。
2. 故障检测:如果哨兵检测到主实例不可达或者响应命令出现异常,它将认为主实例出现了故障。
3. 选举过程:当哨兵确定主实例不可用时,它将开始一个选举(Election)过程。选举过程中,哨兵会尝试联系其他哨兵实例,以确定是否有其他哨兵已经发起了一个有效的选举。
4. 领导者选举:如果哨兵实例在选举过程中被选为领导者(Leader),它将负责协调故障转移过程。如果多个哨兵实例同时争夺领导地位,它们将通过一个基于Redis投票机制的方式决定领导者。
5. 命令复制:领导者哨兵会从剩余的从实例中选择一个实例(通常是具有最高运行序号的实例)作为新的主实例,并通过Redis命令复制协议(REPL)来同步这个实例的内存状态到其他从实例。
6. 更新配置:一旦新的主实例被选举出来,哨兵将更新配置,使得其他从实例开始复制新的主实例的数据。这个过程可能包括更新从实例的配置文件或者直接通过Redis命令来更改从属关系。
7. 故障转移完成:在新的主实例准备好并配置所有从实例之后,故障转移过程完成。此时,哨兵会向客户端发送消息,告知它们新的主实例的位置,客户端可以根据这个信息更新它们的连接。
8. 后续处理:旧的故障的主实例在恢复后,可能会被配置为从实例并开始复制新的主实例的数据,或者根据具体情况被移除或重新配置。
整个故障转移过程是由哨兵系统自动完成的,不需要人工干预。但是,为了确保故障转移的顺利进行,需要正确配置哨兵系统,包括指定主实例和从实例、设置选举超时时间、配置故障转移策略等。
在Redis哨兵(Sentinel)模式的故障转移过程中,确保数据一致性是一个重要的考虑点。以下是一些措施和机制,用于确保在故障转移过程中数据的一致性:
1. 写入确认:在故障转移过程中,新的主实例在接替旧的主实例之前,会等待一些写入操作被确认。这可以通过配置参数`redis-sentinel min-slaves-to-write`来实现,它指定了一个最小数量的从实例必须处于“在线”(UP)状态,主实例才能执行写操作。
2. 复制偏移量:Redis使用复制偏移量(replication offset)来跟踪主实例和从实例之间数据同步的位置。在故障转移过程中,新的主实例会等待直到它的复制偏移量追赶上其他从实例,确保从实例有最新的一致性数据。
3. 断线重连:在故障转移后,从实例会尝试与新的主实例重新建立连接,并继续同步数据。如果从实例在一定时间内无法连接到新的主实例,它会尝试重新连接到旧的 主实例(如果旧的 主实例恢复了),这样可以避免数据不一致。
4. 配置更新:故障转移后,从实例会根据新的主实例信息更新它们的配置,确保所有从实例都知道新的主实例的位置。
5. Sentinel监控:哨兵系统会继续监控所有实例的健康状态,并在检测到任何不一致性时采取行动。例如,如果一个从实例落后于新的主实例太多,哨兵可能会尝试将该从实例从旧的 主实例那里重新同步数据。
6. 客户端重连:客户端应用需要监听主实例的变化,并在必要时更新它们连接的主实例。通常,这可以通过使用Redis客户端的哨兵支持来实现,客户端会自动重连到新的主实例。
7. 持久化机制:Redis提供了数据持久化机制,如RDB快照和AOF日志,这些机制可以帮助在故障转移后恢复数据。确保在故障转移前有最新的快照或AOF日志重做,可以减少数据不一致的风险。
通过上述机制,Redis哨兵系统在故障转移过程中尽量保证了数据的一致性。然而,在实际操作中,特别是在故障转移的初期阶段,可能会存在短暂的数据不一致。因此,设计系统时应考虑这种短暂的不一致性,并在必要时实施额外的数据一致性保障措施。
到此这篇redis 连接哨兵(redis搭建哨兵模式)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/haskellbc/69672.html