您好、欢迎来到现金彩票网!
当前位置:2019欢乐棋牌 > 主从复制 >

10分钟彻底理解Redis持久化和主从复制

发布时间:2019-08-04 03:48 来源:未知 编辑:admin

  在这篇文章,我们一起了解 Redis 使用中非常重要的两个机制:Reids 持久化和主从复制。

  Redis 作为一个键值对内存数据库(NoSQL),数据都存储在内存当中,在处理客户端请求时,所有操作都在内存当中进行,如下所示:

  这样做有什么问题呢?其实,只要稍微有点计算机基础知识的人都知道,存储在内存当中的数据,只要服务器关机(各种原因引起的),内存中的数据就会消失了。

  不仅服务器关机会造成数据消失,Redis 服务器守护进程退出,内存中的数据也一样会消失。

  对于只把 Redis 当缓存来用的项目来说,数据消失或许问题不大,重新从数据源把数据加载进来就可以了。

  但如果直接把用户提交的业务数据存储在 Redis 当中,把 Redis 作为数据库来使用,在其放存储重要业务数据,那么 Redis 的内存数据丢失所造成的影响也许是毁灭性。

  为了避免内存中数据丢失,Redis 提供了对持久化的支持,我们可以选择不同的方式将数据从内存中保存到硬盘当中,使数据可以持久化保存。

  Redis 提供了 RDB 和 AOF 两种不同的数据持久化方式,下面我们就来详细介绍一下这种不同的持久化方式吧。

  RDB 是一种快照存储持久化方式,具体就是将 Redis 某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为 dump.rdb,而在 Redis 服务器启动时,会重新加载 dump.rdb 文件的数据到内存当中恢复数据。

  开启 RDB 持久化方式很简单,客户端可以通过向 Redis 服务器发送 Save 或 Bgsave 命令让服务器生成 RDB 文件,或者通过服务器配置文件指定触发 RDB 条件。

  当客户端向服务器发送 Save 命令请求进行持久化时,服务器会阻塞 Save 命令之后的其他客户端的请求,直到数据同步完成。

  如果数据量太大,同步数据会执行很久,而这期间 Redis 服务器也无法接收其他请求,所以,最好不要在生产环境使用 Save 命令。

  当客户端发服务发出 Bgsave 命令时,Redis 服务器主进程会 Forks 一个子进程来数据同步问题,在将数据保存到 RDB 文件之后,子进程会退出。

  所以,与 Save 命令相比,Redis 服务器在处理 Bgsave 采用子线程进行 IO 写入。

  而主进程仍然可以接收其他请求,但 Forks 子进程是同步的,所以 Forks 子进程时,一样不能接收其他请求。

  这意味着,如果 Forks 一个子进程花费的时间太久(一般是很快的),Bgsave 命令仍然有阻塞其他客户的请求的情况发生。

  服务器配置自动触发:除了通过客户端发送命令外,还有一种方式,就是在 Redis 配置文件中的 Save 指定到达触发 RDB 持久化的条件,比如【多少秒内至少达到多少写操作】就开启 RDB 数据同步。

  这种通过服务器配置文件触发 RDB 的方式,与 Bgsave 命令类似,达到触发条件时,会 Forks 一个子进程进行数据同步。

  不过最好不要通过这方式来触发 RDB 持久化,因为设置触发的时间太短,则容易频繁写入 RDB 文件,影响服务器性能,时间设置太长则会造成数据丢失。

  前面介绍了三种让服务器生成 RDB 文件的方式,无论是由主进程生成还是子进程来生成,其过程如下:

  RDB 默认生成的文件名为 dump.rdb,当然,我可以通过配置文件进行更加详细配置。

  比如在单机下启动多个 Redis 服务器进程时,可以通过端口号配置不同的 RDB 名称,如下所示:

  如果服务器宕机的话,采用 RDB 的方式会造成某个时段内数据的丢失,比如我们设置 10 分钟同步一次或 5 分钟达到 1000 次写入就同步一次,那么如果还没达到触发条件服务器就死机了,那么这个时间段的数据会丢失。

  使用 Save 命令会造成服务器阻塞,直接数据同步完成才能接收后续请求。

  使用 Bgsave 命令在 Forks 子进程时,如果数据量太大,Forks 的过程也会发生阻塞,另外,Forks 子进程会耗费内存。

  与 RDB 存储某个时刻的快照不同,AOF 持久化方式会记录客户端对服务器的每一次写操作命令,并将这些写操作以 Redis 协议追加保存到以后缀为 AOF 文件末尾。

  在 Redis 服务器重启时,会加载并运行 AOF 文件的命令,以达到恢复数据的目的。

  Redis 默认不开启 AOF 持久化方式,我们可以在配置文件中开启并进行更加详细的配置,如下面的f 文件:

  在上面的配置文件中,我们可以通过 appendfsync 选项指定写入策略,有三个选项:

  always:客户端的每一个写操作都保存到 AOF 文件当中,这种策略很安全,但是每个写操作都有 IO 操作,所以也很慢。

  everysec:appendfsync 的默认写入策略,每秒写入一次 AOF 文件,因此,最多可能会丢失 1s 的数据。

  no:Redis 服务器不负责写入 AOF,而是交由操作系统来处理什么时候写入 AOF 文件。更快,但也是最不安全的选择,不推荐使用。

  AOF 将客户端的每一个写操作都追加到 AOF 文件末尾,比如对一个 Key 多次执行 Incr 命令,这时候,AOF 保存每一次命令到 AOF 文件中,AOF 文件会变得非常大。

  AOF 文件太大,加载 AOF 文件恢复数据时,就会非常慢,为了解决这个问题,Redis 支持 AOF 文件重写。

  通过重写 AOF,可以生成一个恢复当前数据的最少命令集,比如上面的例子中那么多条命令,可以重写为:

  AOF 文件是一个二进制文件,并不是像上面的例子一样,直接保存每个命令,而使用 Redis 自己的格式,上面只是方便演示。

  这种方式会在每次 Fsync 时都重写,影响服务器性能,因此默认值为 no,不推荐使用。

  客户端向服务器发送 bgrewriteaof 命令,也可以让服务器进行 AOF 重写。

  AOF 重写方式也是异步操作,即如果要写入 AOF 文件,则 Redis 主进程会 Forks 一个子进程来处理,如下所示:

  在写入 AOF 日志文件时,如果 Redis 服务器宕机,则 AOF 日志文件文件会出格式错误。

  在重启 Redis 服务器时,Redis 服务器会拒绝载入这个 AOF 文件,可以通过以下步骤修复 AOF 并恢复数据:

  通过上面的介绍,我们了解了 RDB 与 AOF 各自的优点与缺点,到底要如何选择呢?

  通过下面的表示,我们可以从几个方面对比一下 RDB 与 AOF,在应用时,要根据自己的实际需求,选择 RDB 或者 AOF。

  其实,如果想要数据足够安全,可以两种方式都开启,但两种持久化方式同时进行 IO 操作,会严重影响服务器性能,因此有时候不得不做出选择。

  当 RDB 与 AOF 两种方式都开启时,Redis 会优先使用 AOF 日志来恢复数据,因为 AOF 保存的文件比 RDB 文件更完整。

  小结:上面讲了一大堆 Redis 的持久化机制的知识,其实,如果你只是单纯把 Redis 作为缓存服务器,那么可以完全不用考虑持久化。

  但是,在如今的大多数服务器架构中,Redis 不单单只是扮演一个缓存服务器的角色,还可以作为数据库,保存我们的业务数据,此时,我们则需要好好了解有关 Redis 持久化策略的区别与选择。

  上面,我们了解了 Redis 两种不同的持久化方式,Redis 服务器通过持久化,把 Redis 内存中持久化到硬盘当中,当 Redis 宕机时,我们重启 Redis 服务器时,可以由 RDB 文件或 AOF 文件恢复内存中的数据。

  不过持久化后的数据仍然只在一台机器上,因此当硬件发生故障时,比如主板或 CPU 坏了,这时候无法重启服务器,有什么办法可以保证服务器发生故障时数据的安全性?或者可以快速恢复数据呢?

  Redis 的主从复制机制是指可以让从服务器(Slave)能精确复制主服务器(Master)的数据,如下图所示:

  上面的图表示的是一台 Master 服务器与 Slave 服务器的情况,其实一台 Master 服务器也可以对应多台 Slave 服务器,如下图所示:

  另外,Slave 服务器也可以有自己的 Slave 服务器,这样的服务器称为 Sub-Slave。

  而这些 Sub-Slave 通过主从复制最终数据也能与 Master 保持一致,如下图所示:

  当 Master 服务器与 Slave 服务器正常连接时,Master 服务器会发送数据命令流给 Slave 服务器,将自身数据的改变复制到 Slave 服务器。

  当因为各种原因 Master 服务器与 Slave 服务器断开后,Slave 服务器在重新连上 Master 服务器时会尝试重新获取断开后未同步的数据即部分同步,或者称为部分复制。

  如果无法部分同步(比如初次同步),则会请求进行全量同步,这时 Master 服务器会将自己的 RDB 文件发送给 Slave 服务器进行数据同步,并记录同步期间的其他写入,再发送给 Slave 服务器,以达到完全同步的目的,这种方式称为全量复制。

  Master 服务器会记录一个 Replication Id 的伪随机字符串,用于标识当前的数据集版本,还会记录一个当数据集的偏移量 Offset。

  通过 redis-cli 在 Master 或 Slave 服务器执行该命令会打印类似以下信息(不同服务器数据不同,打印信息不同):

  而 Master 会计算与 Slave 之间的数据偏移量,并将缓冲区中的偏移数量同步到 Slave,此时 Master 和 Slave 的数据一致。

  Redis 的主从配置非常简单,我们可以使用两种方式来配置主从服务器,在这时我们先假设 Redis 的 Master 服务器地址为 192.168.0.101。

  Slave 服务器配置主服务器:在这里 Slave 服务器的f 通过 saveof 选项,可以指定 Master 服务器,如下:

  通过上面两种方式的配置,Master 服务器与 Slave 服务器便已经可以开始进行数据同步了。

  Master 要求验证:上面配置的是 Master 服务器没有设置密码的情况,如果 Master 设置了密码,则可以在连接到 Slave 服务器的 redis-cli 执行下面的命令:

  Slave 会被清空?Slave 不用同步了 Master 的数据吗?备份的数据怎么会清空了呢?

  当 Master 服务器关闭了持久化时,如果发生故障后自动重启时,由本地没有保存持久化的数据,重启的 Redis 内存数据为空,而 Slave 会自动同步 Master 的数据,这时候,Slave 服务器的数据也会被清空。

  如何避免 Slave 被清空呢?如果条件允许(一般都可以的),Master 服务器还是要开启持久化,这样 Master 故障重启时,可以快速恢复数据,而同步这台 Master 的 Slave 数据也不会被清空。

  如果 Master 不能开启持久化,则不应该设置让 Master 发生故障后重启(有些机器会配置自动重启),而是将某个 Slave 服务器升级为 Master 服务器,对外继续提供服务。

  在 Redis 2.6 以后,Slave 只读模式是默认开启的,我们可以通过配置文件中的 slave-read-only 选项配置是否开启只读模式:

  上面将 Slave 服务器设置为可以写入,但是要注意,如果 Slave 也配置了自己的从服务器(Sub-Slave),那么 Sub-Slave 只会同步从 Master 服务器同步到 Slave 的数据,而并会同步我们直接写入 Slave 服务器的数据。

  我们都知道 Redis 可以通过设置 Key 的过期时间来限制 Key 的生存时间,Redis 处理 Key 过期有惰性删除和定期删除两种机制。

  而在配置主从复制后,Slave 服务器就没有权限处理过期的 Key,这样的话,对于在 Master 上过期的 Key,在 Slave 服务器就可能被读取。

  如果 Slave 服务器升级为 Master 服务器 ,则它将开始独立地计算 Key 过期时间,而不需要通过 Master 服务器的帮助。

  当我们只是通过 RDB 或 AOF 把 Redis 的内存数据持久化毕竟只是在本地,并不能保证绝对的安全,而通过将数据同步 Slave 服务器上,可以保留多一个数据备份,更好地保证数据的安全。

  在配置了主从复制之后,如果 Master 服务器的读写压力太大,可以进行读写分离,客户端向 Master 服务器写入数据,在读数据时,则访问 Slave 服务器,从而减轻 Master 服务器的访问压力。

  服务器的高可用性是指服务器能提供 7*24 小时不间断的服务,Redis 可以通过 Sentinel 系统管理多个 Redis 服务器。

  当 Master 服务器发生故障时,Sentineal 系统会根据一定的规则将某台 Slave 服务器升级为 Master 服务器,继续提供服务,实现故障转移,保证 Redis 服务不间断。

  小结:Redis 的主从复制可以让我们把 Redis 中的数据同步到其他服务器上,为数据安全提供更加安全的保障,也可以让我们的服务器在发生故障而无法重启时,可以更加快速地切换服务器,继续对外提供服务。

http://api-crypt.com/zhucongfuzhi/166.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有