技术栈1 - Redis(2) - 持久化和复制

2019/01/09

《redis实战》第四章是关于redis数据安全和性能保障的,主要涉及持久化、复制、事务等知识点; 第二章是redis应用的几个实例,第三章是redis操作命令,没有记录笔记的价值。

第四章收获总结

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

4.1 持久化

p62: 持久化的概念:
  将内存数据写入硬盘,保证服务器重启数据也不丢失。

  1、两种持久化方式:
    快照持久化(snapshoting)
    AOF持久化(append-only file)

  2、快照
    1、概念: 对应某一刻的数据创建副本到硬盘。
      也就是某一个时间点的数据库的一个拷贝。例如8:00:00执行快照操作,就是将8点这一刻的数据保存到硬盘上,而8:00之后的数据更新需要再次快照才能持久化。
      一句话,某一个时间点的redis数据保存在网盘叫做一次快照。

      问题:
      如上,如果8:00之后没有快照,那么8:00之后更新的数据,服务重启就会丢失;最新数据只会复原到最新的一次快照;
      此外,如果7点的时候快照一次,8点快照的时候出错了,服务挂了,8点这次快照是在进行中,会被清理掉,也就是最新的快照备份是7点那份;
      如果服务挂了的时候8点的快照刚好完成,那么最新的备份就是8点的,但是8点之后更新的数据因为没有快照就全部丢失了。

      p63: 创建快照的方式: bgsave 和 save 两个命令;
      具体可以参考《redis实战》
      bgsave 和 save的区别:
        bgsave命令是主线程创建一个子进程去执行快照,文件越大创建和快照的时间越长; 优点是几个G的小容量数据不会影响主进程的业务操作,
        而且只有当进程执行内存写入时主进程和子进程才不共享内存,其余时间共享内存;(fork:即想内存中写入数据除外,其余都共享内存)

        save 在完成快照之前,阻塞等待;

        选取:当容易有一定的数据损失时,可以使用快照;
          对于内存数据比较小的情况,可以使用bgsave命令; 而大数据10多GB甚至更大时,bgsave创建子进程会造成卡顿,如果容忍等待,可以使用save命令。

        快照执行:
          1、自动触发
            save 60 10000 60秒内有10000次写入就会触发快照操作
          2、手动发送save或bgsave

  3、AOF持久化
    1、概念: 将redis所有的写命令追加到一个AOF文件中。 恢复数据时就依次执行AOF文件中的命令就行了。

    对比快照,对于每一条写命令都进行追加操作,这样就可以避免数据损失。

    但是要兼顾数据安全和写入性能,如appendsync everysec选项,每秒一次写入。appendsync no则是由操作系统控制何时写入。

    缺点:AOF文件的大小; 解决方案: 重写/压缩

    p68: bgrewriteaof命令,重写除去AOF文件中重复的命令;  但是这与快照中的bgsave一样,都会创建一个子进程执行,但是文件大小更大,耗时更多。
    两个命令选项:ayto-aof-rewrite-percentage 和 ayto-aof-rewrite-min-size 
    例如ayto-aof-rewrite-percentage 100 ayto-aof-rewrite-min-size 64MB AOF文件大小超过64MB,而且比之前AOF文件大了一倍(100%)时执行bgrewriteaof命令。

  4、总结
    两种持久化方式适用场景不一样,持久化之后还要对持久化文件进行备份,防止文件丢失。

4.2 复制

上一节讲的是持久化redis数据,而为了高可用,高负载的实现,需要扩展平台,也就是多服务器。这就需要复制了。

4.2.1、复制的概念:
  复制可以使得从服务器拥有一个实时更新的数据副本,使得从服务器可以处理客户端发送的请求。

  主从服务器: 1、从服务器实时更新数据; 2、客户端读请求随意访问【从】服务器,从而实现负载均衡。

p69
4.2.2、redis复制配置选项
  1、从服务器连接主服务器时(sync命令),会触发主服务器的bgsave操作(快照)。 所以有三点前提:
      1、dir选项     文件保存路径
      2、dbfilename  快照文件名称
      以及以上两个选项,对于redis进程都是可写的(writable).

  2、从服务器复制选项: slaveof命令
    三种情况:
      1、启动redis服务器时,如配置文件有slaveof host port, 服务器就会根据ip和端口连接主服务器,成为从服务器;
      2、如果redis服务器正在运行
        1、手动发送slaveof no one 可以终止服务器的复制操作,不再接受主服务器的数据更新;
        2、手动发送slaveof host port可以让服务器开始复制另一个主服务器。

  3、redis复制的启动过程

  一句话:从服务器连接主服务器,主服务器会执行快照发送给从服务器,之后从服务器实时更新。
  
  具体过程如图

如图:
  1、从服务器连接主服务sync
  2、主服务器快照
  3、快照结束,发送给从服务器
  4、快照之后的缓存写命令发送给从服务器
  5、之后的写命令实时更新给从服务器;

注意点:
  1、快照,bgsave有子进程,考虑性能,主服务器内存占用50%~65%,剩下的要预存给bgsave命令和缓存区命令;
  2、主服务器可以变为从服务器,slaveof host port
  3、从服务器进行同步时,会清空自己的所有数据 (因为复制,就是和主服务器完全一样)
  4、redis不支持主主复制,会想回不断尝试通信。

特殊情况:
多个新的从服务器同时连接主服务器时,可能会重用快照文件。

4.2.3 主从链
  问题:当多个从服务器连接主服务器,同步的带宽,网络资源占用,可能会影响同一网络下的其他硬件网速。
  解决:
  如图,从服务器也可以拥有自己的从服务器,这就是主从链(master/slave chaining)。
  从服务器对从服务器进行复制,从而降低了主服务器的同步负荷。

  1、从服务器从从服务器复制
  假如从服务器X拥有从服务器Y,X执行上图表4-2步骤4时,会断开与Y的连接,导致Y需要重新连接重新同步。
  (缓存器命令断开与Y的链接,这样Y在此连接时也相当于复制了主服务器)

  如图4.1,多从服务器同步,主服务器无法快速更新所有服务器,重新连接和重新同步都会造成负载超载的问题,
  如图可以创建一个由redis主从节点(master/slave node)组成的中间层来分担主服务器的复制工作。

结论:
以上持久化和复制,借助复制和AOF持久化,可以将数据持久化到多台机器上。
设置配置:
appendonly yes选项和appendfsync everysec。

4.2.4 检验硬盘写入
目的:检测数据是否已经被同步到硬盘中。

1、验证主服务器是否已经将写数据发送至从服务器。
  用户将所有真正的数据写入到主服务器之后,再向主服务器写入一个唯一的虚构值(unique dummy value),然后检查虚构值是否存在于从服务器。 如此就检验了。
2、判断数据是否已经保存到硬盘里。
  1、对于每秒同步一次的AOF文件,可以等待1s确保数据已经保存; (费时)
  2、节约时间,检查INFO命令的输出结果中aof_pending_bio_fsync是否为0.
  保存到硬盘之后,将主从服务器连接作为参数,检查上述验证。
  代码见p73

借助复制和AOF持久化,可以增强对系统崩溃的抵抗能力。

4.3 处理系统故障

再健壮的系统,也不可能保证100%不会出错,所以要考虑到出现故障如何修复。

4.3.1 验证快照文件和AOF文件

1、两个命令,检查快照和AOF文件的状态。 redis-check-aof 和 redis-check-dump

2、快照文件由于本身已经压缩,所以还有修复的办法。
  验证,计算快照文件SHA1和SHA256散列值进行验证。

3、AOF修复: redis-check-aof --fix

  扫描AOF文件,将第一个出粗的命令以及之后的内容全部清除。

4.3.2 更换故障主服务器

主服务器出错的话,需要设置新的主服务器进行替换。 具体步骤如下:

假如A主B从

方法1: 将新机器C作为新的主服务器;  对B save命令创建快照,发送给C,C启动,将B设置伪C的从服务器
方法2: 将B升级为主服务器,创建B的从服务器。


Show Disqus Comments