zoukankan      html  css  js  c++  java
  • 分布式存储-Redis持久化&高可用

    分布式存储-Redis持久化&高可用

    我们知道Redis很强大的一部分原因是因为它的数据是存储在内存中的,那如果服务器挂了之后,是不是我们的数据会丢失了呢?那我们需要把内存中的数据通过一个机制给它持久化,从而对数据的安全进行保障。本篇会聊到:

    • 两种数据存储机制【RDB】 和【AOF】
    • 哨兵模式

    Redis的持久化机制

    RDB【快照模式】:在某个时间段把当前的内存中数据进行一个存储【 默认

    这种方式适合【灾备】,但是在备份的间隔时间可能造成一部分数据丢失

    触发方法->

    • 自定义规则配置。在redis.conf中有一个save的命令行 第一个参数是 【save命令】 第二个参数是 【second】 第三个参数是 【change】。举例而言:如果在900s内有任何一个key发生变化他都会去触发一个快照。 我们可以尝试修改  5s中有一个key变化,就生成它的快照文件。当我们修改后就会生成一个dump文件,这个文件的位置我们可以使用redis-config中的dir参数进行指定。我们要保障他是数据的安全性,我们就可以写脚本,不断的把dump进行备份。当出现危险情况,把dump文件还原,就可以恢复数据了。
    • 可以执行SAVE(同步-阻塞)命令和BGSAVE(异步-非阻塞)命令
    • 执行FLASHALL命令(执行这个命令的时候出发快照)
    • Master-replicate(复制的时候)

    AOF【Append Only File】:采用日志的方式来保存每个事务操作,他会把每个操作都写在文件中。

    【配置方式(redis config中)】:我们可以把no 改成 yes,然后重启配置文件,我们发现appendonly.aof文件会生成到我们指定的文件路径下面(dir中指定的,和dump文件在同样的目录下)。当我们打开这个文件发现什么都没有  

    我们插入几个数据到redis中就会在这个文件中生成相关的数据,其实它存储的数据和咱们在手写redis客户端的那里的命令是一样的

     

     那么他是实时同步数据到这个文件中的吗?这点其实我们可以配置,根据我们的cpu和数据数据安全程度进行权衡。

    • no:交给操作系统进行同步(默认30s)。
    • everysec:默认/S都进行同步。
    • always:每个命令实时同步

    但是这引发了一个弊病:每次事务操作都进行记录,那么这个文件必然是越来越大的,这对于我们后来的解析是很不友好的,这个时候就引出了rewrite

     【rewrite】:把无效的指令全部都进行压缩,本质其实是重新生成当前的AOF文件,这是因为如果去修改这个的AOF文件的话,那样的时间和效率的代价太大,生成文件之后对老的AOF文件进行覆盖

    • 自动触发重写
      •  
      • 【rewrite-percentage】:当当前的AOF的文件大小超过上一个AOF文件的百分之多少(我们自己配置的)的时候就会进行重写:
      • 【rewrite-min-size】:不会进行重写的最小大写(当文件小于64mb的时候不会进行重写)
    • 手动触发重写(bgrewriteaof)

    问题:会不会在写AOF的时候有些数据没有写入?

    主进程在进行数据操作的时候,他会把数据保存在一个重写缓存中,换而言之,他会单独开辟一块空间去存储在重写期间接受到的命令,然后在重写完成后把重写的文件再次追加到新的AOF文件中。所以不会的。 

    Redis的高可用

    主从复制:下面有多种方式可以进行选择,这些不仅可以应用在redis上,其实在很多 情况下都可以使用,比如数据库。

    • 【一主多从】:所有的事务操作全部访问master,slave进行读的操作。这样的好处就是我们可以对slave进行水平扩容,当读多写少的情况下。但是当有多个slave的情况下,master同步数据给slave的压力就变大了,这个时候就可以采用级联复制【由一个slave去同步数据给其他slaves】
    • 【双主复制(双亲热备)】:其实他们有两个角色【master、backup】,并且在同一个时刻只有一个节点在进行工作,但是这两个节点都是输入运行状态。然后在这两个前面假设一个Keepalived,他会不断发送心跳去确定master的状态,如果master挂了他就会把backup作为新的master进行顶替
    • 【多主一从】:把不同master上的数据放在同一个slave上去进行数据统计和汇总

    一主多从配置&准备

    • 准备三个节点,并且都安装好redis
    • 关闭防火墙   systemctl stop firewalld /  fifirewall-cmd --zone=public --add-port=6379/tcp --permanent
    • 配置slave 在config中加上 replicaof  <masterip > <masterport>

    • 启动子节点,这个时候我们发现,其实启动的时候,master的数据就自动同步到slave中了,并且我们可以使用 【info  replication】查看他的角色 
    •  

    同步原理(RDB模式):

    • slave连接到master服务器发送一个sync指令
    • master接受到指令后执行一个bgsave指令生成快照,并且发送快照给slave服务器
    • slave接受到快照后覆盖自己的快照文件
    • 如果在生成快照的时候有新的命令执行master会把新的命令放在缓存中,当我们slave收到了快照文件后,再把新增的增量的指令同步到slave节点

    slave告诉master自己的端口,然后手动发送一个sync命令给master,这个时候就是【全量同步

     这个时候在别的节点上执行一个set指令

     我们发现他的指令就自动同步到其他的节点,这个叫做【增量同步

    默认情况下是异步进行同步的,意味着master只要完成客户端请求后,立刻返回给客户端,不管是否同步给slave,当然我们可以修改这个机制。

    • master可以写的前提是,他的数据是已经同步给了3个节点
    • 允许slave最长失去联系的时间是10s

    哨兵模式:

    使用上面的一主多从进行主从复制的问题是,如果master节点挂了怎么办?所以这就引出了哨兵模式。他的功能为:

    • 【监控】:Sentinel会不断检查主服务器和从服务器是否正常运行。
    • 【通知】:如果某一个被监控的实例出现问题,Sentinel可以通过API发出通知。
    • 【自动故障转移(failover)】:如果主服务器发生故障,Sentinel可以启动故障转移过程。把某台服务器升级为主服务器,并发出通知。
    • 【配置管理】:客户端连接到Sentinel,获取当前的Redis主服务器的地址。

    其实他就是监控redis中的所有节点的一个进程,当然他也可以做集群。当master挂了之后他就可以从其他的slave中重新选举出一个master.在这种哨兵机制下,客户端连接的就是哨兵的地址,而不是master的地址。

    哨兵配置】:sentinel是redis自带的,这个文件本身就有,一般和redis,conf在一个文件下

    在sentinel.confi配置监听的master

    • mymaster:自己起的一个哨兵的名字
    • 192.168.221.128: master的ip
    • 6379:mater的端口
    • 2:最低的投票通过次数(至少两个哨兵认为master挂了,才算真的挂了 哨兵可以做集群)

    配置心跳超时时间:这里的意思是5s后,master没有响应,那哨兵就认为master挂了

     

    配置容错机制 一定时间master还没有活过来就启动 failover【进行选举】

     

    【 启动sentinel

     查看 日志 

     这个时候启动其他两个slave的sentinel按照同样的方式,我们发现在master的sentinel的日志中打印了他们的日志

     这个时候我们的架构就是

     模拟master宕机,看看是否会进行选举。查看哨兵的日志发现:

    • sdown指的是当前的哨兵的主观认为
    • vote-for-leader:指的是进行投票
    • odown:指的是三分之二的哨兵都认为maser宕机了
    • next failover delay:在咱们配置中指定的时间【容错机制的时候讲到了这个】内如果master没有启动那就证明要进行重新选举
    • switch master:这个时候就选举一个新的master

     这个时候发现原来的slave变成了master

    常见问题

    谁来进行故障转移:当通过上面的机制确定了master已经挂了之后,谁来把剩下的slave变成master?

    其实每次当master出现故障,他们都会使用raft 机制选举出哨兵leader 进行故障转移。raft我们后面会聊到

    故障转移的过程是什么:

    • 由Sentinel Leader向某个节点发送slaveof no one命令,让它成为独立节点
    • 然后向其他节点发送replicaof x.x.x.x xxxx(本机服务),让它们成为这个节点的子节点,故障转移完成。
    如何选择合适的slave节点成为master呢(这里有4个因素):
    • 断开连接时长,如果与哨兵连接断开的比较久,超过了某个阈值,就直接失去了选举权
    • 优先级排序,如果拥有选举权,那就看谁的优先级高,这个在配置文件里可以设置(replica
      priority 100),数值越小优先级越高
    • 复制数量,如果优先级相同,就看谁从master中复制的数据最多(复制偏移量最大)
    • 进程id,如果复制数量也相同,就选择进程id最小的那个

  • 相关阅读:
    一代人的青春--芳华
    用切面对监控日志的实现2
    一个在java后台实现的对图片进行加网纹或水印的工具类
    家乡的河
    家乡的鬼节—十来一儿
    八里沟印象
    双城记
    记忆中的那一树梨花
    用切面对监控日志的实现
    关于poi导出excel三种方式HSSFWorkbook,SXSSFWorkbook,csv的总结
  • 原文地址:https://www.cnblogs.com/UpGx/p/15439143.html
Copyright © 2011-2022 走看看