axiejundong 2019-06-29
用户必须做好相应的准备以应对Redis的系统故障。本章在系统故障这个专题花费了大量的篇幅,这是因为如果我们决定要将Redis用作应用程序唯一的数据存储手段,那么就必须确保Redis不会丢失任何数据。与提供了ACID保证的传统关系数据库不同,在使用Redis为后端构建应用程序的时候,用户需要多做一些工作才能确保数据的一致性。Redis是一个软件,它允许在硬件之上,即使软件和硬件都设计的完美无瑕,也有可能会出现停电、发电机因为燃料耗尽而无法发电或者备用电池电量耗尽等情况。这一节接下来将对Redis提供的一些工具进行介绍,说明如何使用这些工具来应对潜在的系统故障。下面先来看看在出现系统故障时,用户应该采取什么措施。
ACID是指原子性(atomicity)、一致性(consistency)、隔离性(isolation)和耐久性(durability),如果一个数据库想要实现可靠的数据事务,那么它就必须保证ACID性质。无论是快照持久化还是AOF持久化,都提供了在遇到系统故障时进行数据恢复的工作。Redis提供了两个命令行程序redis-check-aof 和redis-check-dump,他们可以在系统故障发生之后,检查AOF文件和快照文件的状态,并在有需要的情况下对文件进行修复。在不给定任何参数的情况下运行这两个程序,就可以看见他们的基本使用方法:
$ redis-check-aof Usage:redis-check-of [--fix] <file.aof> $redis-check-dump Usage:redis-check-dump <dump.rdb> $
如果用户在运行redis-check-aof程序时给定了--fix参数,那么程序将对AOF文件进行修复。程序修复AOF文件的方法非常简单,它会扫描给定的AOF文件,寻找不正确或者不完整的命令,当发现第一个出错命令的时候,程序会删除出错的命令以及位于出错命令之后的所有的命令,只保留那些位于出错命令之前的正确命令。在大多数情况下,被删除的都是AOF文件末尾的不完整的写命令。
遗憾的是,目前并没有方法可以修复出错的快照文件。尽管发现快照文件首个出现错误的地方是有可能的,但因为快照文件本身经过了压缩,而出现在快照文件中间的错误有可能会导致快照文件的剩余部分无法被读取。因此,用户最好为重要的快照文件保留多个备份,并在进行数据恢复时,通过计算快照文件的sha1散列值和SHA256散列值来对内容进行验证。(当今的Linux平台和Unix平台都包含类似sha1sum和sha256sum这样的用于生成和验证散列值的命令行程序。)
校验和(checksum)与散列值(hash)从2.6版本开始,Redis会在快照文件中包含快照文件自身的crc64校验和。crc校验和对于发现典型的网络传输错误和硬盘损伤非常有帮助,而sha加密散列值则更擅长发现文件中的任意错误。简单的来说,用户可以翻转文件中任意的数量的二进制位,然后通过翻转文件最后64个二进制位的一个子集来产生于原文件相同的crc64校验和。而对于sha1和sha256,目前还没有任何已知方法可以做到这一点。
在了解了如何验证持久化文件是否完好无损,并且在有需要时对其进行修复之后,我们接下来要考虑的就是如何更换出现故障的Redis服务器。
在运行一组同时使用复制和持久化的Redis服务器时,用户迟早都会遇上某个或某些Redis服务器停止运行的情况。造成故障的原因可能是硬盘驱动器出错、内存出错或者电量耗尽,但无论服务器因为何种原因出现故障,用户最终都要对发生故障的服务器进行更换。现在让我们来看看,在拥有一个主服务器和一个从服务器的情况下,更换主服务器的具体步骤。
假设A、B两台机器都运行着Redis,其中机器A的Redis为主服务器,而机器B的Redis为从服务器。不巧的是,机器A刚刚因为某个暂时无法修复的故障而断开网络连接,因此用户决定将同样安装了Redis的机器C用作新的主服务器。
更换服务器的计划非常简单,首先向服务器B发送一个save命令,让它创建一个新的快照文件,接着将这个快照文件发送给机器C,并在机器C上面启动Redis,最后,让机器B成为机器C的从服务器。下面代码展示了更换服务器时用到的各个命令:
通过VPN网络连接机器B user@vpm-master ~:$ssh [email protected] Last Login:wed Mar 28 15:21:06 2012 from ... #启动命令行Redis客户端来执行几个简单的操作 root@machine-b ~:$redis-cli #执行save命令,并在命令完成之后,使用quit命令退出客户端 redis 127.0.0.1:6379> save OK redis 127.0.0.1:6379> quit #将快照文件发送至新的主服务器:机器C root@machine-b ~:$scp \ > /var/local/redis/dump.rdb machine-c.vpn:/var/local/redis/dump.rdb #连接新的主服务器并启动Redis root@machine-b ~:$ssh machine-c.vpn Last login:True Mar 27 12:42:31 2012 from ... root@machine-c ~:$sudo /etc/init.d/redis-server start Starting Redis server... root@machine-c ~:$ exit root@machine-b ~:$redis-cli #告知机器B的Redis,让它将机器C用作新的主服务器 redis 127.0.0.1:6379>slaveof machine-c.vpn 6379 OK redis 127.0.0.1:6379>quit root@machine-b ~:$exit user@vpm-master ~:$
另一种创建新的主服务器的方法,就是将从服务器升级为主服务,并为升级后的主服务器创建从服务器。
以上列举的两种方法都可以让Redis回到之前的一个主服务器和一个从服务器的状态,而用户接下来要做的就是更新客户端的配置,让他们去读写正确的服务器。除此之外,如果用户需要重启Redis的话,那么可能还需要对服务器的持久化配置进行更新。
Redis SentinelRedis Sentinel可以监视指定的Redis主服务器及其属下的从服务器,并在主服务器下线时自动进行故障转移。后面章节会介绍。
在接下来的一节中,我们将介绍一种保证数据安全所必不可少地功能,该功能可以在多个客户端同时对相同的数据进行写入时,防止数据出错。
上一篇文章:Python--Redis实战:第四章:数据安全与性能保障:第4节:复制