Redis-数据持久化及性能保障
数据安全与性能保障
持久化选项
redis提供了两种不同的持久化方法来将数据存储到硬盘里面. 一种方法叫快照(snapshotting), 它可以将存储在于某一时刻的所有数据都写入硬盘里面. 另一种方法叫只追加文件(append-only file, AOF), 它会在执行写命令时, 将被执行的写命令复制到硬盘里面. 这两种持久化方法既可以同时使用, 又可以单独使用, 在某些情况下甚至可以两种方法都不使用, 具体选择哪种持久化方法需要根据用户的数据以及应用来决定.
将内存中的数据 存储到硬盘的一个主要原因是为了在之后重用数据, 或者是为了防止系统故障而将数据备份到一个远程位置. 另外, 存储在 Redis里面的数据有可能是经过长时间计算得出的, 或者有些程序正在使用 Redis存储的数据尽心计算, 所以用户会希望自己可以将这些数据存储起来以便之后使用, 这样就不必再重新计算了. 对于一些 Redis应用来说, "计算"可能只是简单地将一个数据库的数据复制到 Redis里面, 但对于另外一些 Redis应用来说, Redis存储的数据可能是根据数十亿行日志进行聚合分析得出的结果.
1. 快照持久化
redis可以通过创建快照持久化来获得存储到内存里面的数据在某个时间点上的副本, 在创建快照后, 用户可以对快照进行备份, 可以将快照复制到其他服务器从而创建具有相同数据的服务器副本.还可以将快照留在原地, 以便重启服务时使用.
举个例子, 假设 Redis目前在内存里存储了10GB的数据, 上一个快照是在下午的2:35开始创建的,并且创建成功. 下午 3:06时, Redis又开始创建新的快照, 并且在下午3:08快照文件创建完毕之前, 有35个键进行了更新. 如果在下午3:06至3:08期间, 系统发生崩溃, 导致Redis无法完成新快照的创建工作, 那么 Redis将丢失下午2:35之后写入的所有数据. 另一方面, 如果系统恰好在新的快照文件创建完毕之后崩溃, 那么 Redis将之丢失35个键的更新数据.
快照的创建方式有以下几种:
a. 客户端可以通过向Redis发送BGSAVE命令来创建一个快照. 对于支持 BGSAVE命令的平台来说(windows平台不支持), Redis会调用 fork来创建一个子进程, 然后子进程负责将快照写入硬盘, 而父进程则继续处理命令请求.
注意: fork, 当一个进程创建子进程的时候, 底层的操作系统会创建该进程的一个副本. 在 Unix和类Unix系统上面, 创建子进程的操作会进行如下优化: 在刚开始的时候, 父子进程共享相同的内存, 直到父进程或者子进程对内存进行了写入之后, 对被写入内存的共享才会结束.
b. 客户端可以通过向 Redis发送 SAVE命令来创建一个快照, 接到 SAVE命令的 Redis服务器在快照创建完毕之前将不再响应任何其他命令. SAVE命令并不常用, 我们通常只会在没有足够内存去执行 BGSAVE命令的情况下, 又或者即使等待持久化操作执行完毕也无所谓的情况下, 才会使用这个命令.
c. 但 Redis通过 SHUTDOWN命令接收到关闭服务器的请求时, 或者接收到标准TERM信号时,会执行一个 SAVE命令, 阻塞所有客户端, 不再执行客户端发送的任何命令, 并在 SAVE 命令执行完毕之后关闭服务器.
d. 当一个Redis服务器连接另一个 Redis服务器, 并向对方发送 SYNC 命令来开始一次复制操作的时候, 如果主服务器目前没有在执行 BGSAVE操作, 或者主服务器并非刚刚执行完 BGSAVE操作, 那么主服务器就会执行 BGSAVE命令.
快照可以存储相对比较多的数据.
2. AOF持久化
AOF持久化将会被执行的写命令写到AOF文件的末尾, 以此来记录数据发生的变化. 因此,Redis只要从头到尾重新执行以此 AOF文件包含的所有写命令, 就可以恢复 AOF文件所记录的数据集.
如果用户使用appendfsync always选项的话, 那么每个Redis写命令都会被写入硬盘, 从而将发生系统崩溃时出现数据丢失减少到最小.
虽然AOF持久化非常灵活的提供了多种不同的选项来满足不同应用对数据安全的不同要求, 但 AOF持久化也有缺陷, 那就是AOF文件的体积太小. 但是可以压缩/重写AOF文件进行优化
无论是使用AOF持久化还是快照持久化, 将数据持久化到硬盘上都是费仓有必要的, 但除了进行持久化之外, 用户还必须对持久化所得的文件进行备份(最好为不同的服务器), 这样才能尽量避免数据丢失事故发生.
复制
当我们配置 Redis主从服务器时, 从服务器进行同步时, 会清空自己的所有数据,并且全部替换为主服务器发来的数据.
Redis数据库支持主从复制, 但是不支持主主复制,主主复制即两个主数据库之间无论哪个数据库执行了写的操作, 都会 同步给另一个主数据库.
大部分情况下, Redis都会尽可能的减少复制所需要的工作. 当多个从服务器同时链接主服务器的时候, 同步多个从服务器所占用的带宽可能会使得其他命令请求难以传递给主服务器, 与主服务器位于同一网络中的其他硬件的网速可能也会因此而降低.
主从链
创建多个从服务器可能会造成网络不可用, 当复制需要通过互联网进行或者需要在不同的数据中心进行时,尤为如此. 因此, Redis的主服务器和从服务器并没有特别不同的地方, 所以从服务器也可以拥有自己的从服务器, 由此形成主从链
随着负载不断上涨, 主服务器可能无法快速的更新所有从服务器, 或者因为重新连接和重新同步从服务器而导致系统超载. 为了缓解这个为题, 用户可以创建一个由 Redis 主从节点(master/slave node)组成的中间层来分担服务器的复制工作.
中间层有3个帮助开展复制工作的服务器,底层有9个从服务器.
当然树的结构是不一定的, 可以跟随实际情况.但是这样平衡树可以保持数据同步的一致性
通过使用复制主从和 AOF持久化, 用户可以增强 Redis对于系统崩溃的抵抗能力.
Redis数据库分片结构
分片(sharding)是一种广为人知的技术, 很多数据库都是用这种技术来扩展存储空间并提高自己所能处理的负载量. 分片本质上就是基于某些简单的规则将数据划分为更小的部分, 然后根据数据所属的部分来决定将数据发送到哪个位置上面.