Redis进阶实践之十一 Redis的Cluster集群搭建
转载来源:https://www.cnblogs.com/PatrickLiu/p/8458788.html
一、引言
本文档只对Redis的Cluster集群做简单的介绍,并没有对分布式系统的所涉及到的概念做深入的探讨。本文只是针对如何设置集群、测试和操作集群做了简述,并且从用户的角度描述了系统的行为,并不涉及Redis集群规范中所包含的细节。但是,本教程试图从最终用户的角度来解释有关Redis的Cluster集群的可用性和一致性的特点,并以简单易懂的方式讲解。
请注意,本教程需要使用Redis 3.0版本或更高版本。
如果您打算部署Redis的Cluster集群,即使不是严格的要求,我们也建议阅读更正式的规范。不过,从这篇文档开始,我们可以先使用Redis Cluster集群,然后再阅读规范也是一个不错的主意。
二、Redis的Cluster模式介绍
1、Redis群集101
Redis集群提供了一种运行Redis设备的方式,并且数据可以在多个Redis节点间自动分配的。Redis集群在分区期间也能提供一定程度的可用性,三、创建和使用Redis群集
注意:手动部署Redis群集,这对了解集群的操作细节方面是非常重要的。但是,如果想要启动群集并尽快运行(尽快),请跳过本节和下一节,直接使用create-cluster脚本直接创建Redis群集。
要创建一个集群,我们需要做的第一件事是在集群模式下运行几个空的Redis实例。这就意味着群集不是使用普通的Redis实例创建的,因为需要配置特殊模式,以便Redis实例启用群集特定的功能和命令。
以下是最小的Redis集群配置文件:
port 7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
正如您所看到的那样,启用群集模就是使用 cluster-enabled 这个指令。 每个Redis的实例还包含存储此节点配置信息的文件的路径,默认情况下为nodes.conf。 这个文件内容永远不要人为地去修改,但是可以修改其名称,它仅在Redis集群实例启动时生成,并在每次需要时进行更新。
请注意,按预期工作的最小群集需要至少包含三个主节点。 对于第一次测试,强烈建议启动一个由三个主服务器节点和三个从服务器节点组成的六个节点群集。我们通过以下步骤来一步一步的搭建Redis的Cluster集群环境。
1、我们创建相关目录,主文件夹是redis-cluster,在此文件夹下建立6个子文件夹,名称分别是:7000,7001,7002,7003,7004,7005,该目录以我们将在任何给定目录内运行的实例的端口号命名。
然后创建6个子目录,如下图:
mkdir redis-cluster cd redis-cluster mkdir 7000 7001 7002 7003 7004 7005
2、目录创建好后,我们把Redis源文件里面包含的配置文件redis.conf拷贝一份,存放在7000目录下,然后对其配置项进行修改,这个配置文件Redis.conf会作为其他Redis实例的配置文件的模板,并拷贝到其他目录。
由于我们是做测试,并没有启动6个真正的物理节点,而是把6个Redis实例都部署在了同一台Linux服务器上,地址:192.168.127.130,为了区分Redis实例,我们是以不同的端口号来区分Redis实例的。然后我们修改Redis.conf的配置文件,修改项如下:
bind 192.168.127.130 //绑定服务器IP地址 port 7000 //绑定端口号,必须修改,以此来区分Redis实例 daemonize yes //后台运行 pidfile /var/run/redis-7000.pid //修改pid进程文件名,以端口号命名 logfile /root/application/program/redis-cluster/7000/redis.log //修改日志文件名称,以端口号为目录来区分 dir /root/application/program/redis-cluster/7000/ //修改数据文件存放地址,以端口号为目录名来区分 cluster-enabled yes //启用集群 cluster-config-file nodes-7000.conf //配置每个节点的配置文件,同样以端口号为名称 cluster-node-timeout 15000 //配置集群节点的超时时间,可改可不改 appendonly yes //启动AOF增量持久化策略 appendfsync always //发生改变就记录日志
3、7000目录下的Redis.conf配置文件修改后,分别拷贝到其他子目录,依次为:7001,7002,7003,7004,7005,根据上面的配置,我们只需修改和端口号有关的项目,在Linux系统下,我们通过命令:%s/7000/7001/g,:%s/7000/7002/g,:%s/7000/7002/g,:%s/7000/7003/g,:%s/7000/7004/g,:%s/7000/7005/g 分别进行全局替换,并保存,完成对其他子目录下的配置文件的修改。
4、我们安装Redis的Cluster集群,需要使用Ruby命令,所以我们必须安装对Ruby的支持。
在此说明一下,以前的Redis版本下,需要安装Ruby和Rubygems,但是最新的版本不需要了,只要安装Ruby,Rubygems就会自动安装。
yum install ruby //安装ruby yum install rubygems //安装rubygems,最新版本会自动安装
5、我们安装完 Ruby 和 Rubygems 后,还需要继续安装Redis的Ruby接口程序。
gem install redis
安装Redis的ruby接口程序,可能会提示如下,错误:redis requires ruby version 2.2.2,怎么办呢?如果是第一次遇到这个问题,可能会困扰你一阵子,我这里也有解决方案,帮你解忧。地址如下:http://www.cnblogs.com/PatrickLiu/p/8454579.html,按步骤执行就可以,一切顺利。
6、开始启动我们6个Redis实例,并且要指定配置文件,这些配置文件分别在各自的子目录下面。
cd 7000 redis-server redis.conf cd 7001 redis-server redis.conf cd 7002 redis-server redis.conf cd 7003 redis-server redis.conf cd 7004 redis-server redis.conf cd 7005 redis-server redis.conf
7、创建集群,执行redis-trib.rb脚本,这个脚本文件可以拷贝出来,我是把它放在这个目录:/root/application/program/redis/,当然在这个目录下,也有其他文件,比如redis-cli,redis-server等。
ruby redis-trib.rb create --replicas 1 192.168.127.130:7000 192.168.127.130:7001 192.168.127.130:7002 192.168.127.130:7003 192.168.127.130:7004 192.168.127.130:7005
我们有Redis集群命令行实用程序redis-trib的帮助,Ruby实用程序对实例执行特殊命令以创建新集群,检查或重新设置现有集群,等等。 redis-trib实用程序位于Redis源代码分发的src目录中,当然也可以拷贝到其他目录中,以方便使用。 您需要安装redis gem才能运行redis-trib。
这里使用的命令是create,因为我们想创建一个新的集群。 选项--replicas 1 意味着我们需要为每个创建的主服务器节点创建一个从服务器节点。其他参数是我想用来创建新集群的实例的地址列表。
显然,我们要求的唯一设置是创建一个具有3个主站和3个从站的集群。
8、 如果一切顺利,你会看到类似这样的消息: [OK] All 16384 slots covered, 这意味着至少有一个主实例服务于每个16384可用的插槽,成功创建了Redis的Cluster集群环境。
9、分别登陆7000,7001,7002Redis的实例客户端,进行测试。效果如图:
1、登陆7000操作:
redis-cli -c -h 192.168.127.130 -p 7000
2、登陆7001操作:
redis-cli -c -h 192.168.127.130 -p 7001
3、登陆7002操作:
redis-cli -c -h 192.168.127.130 -p 7002
10、通过Cluster Nodes命令和Cluster Info命令来看看集群效果。
11、在集群上通过增加数据来测试集群效果。直接看截图效果吧:
每个Redis的节点都有一个ID值,此ID将被此特定redis实例永久使用,以便实例在集群上下文中具有唯一的名称。 每个节点都会记住使用此ID的每个其他节点,而不是通过IP或端口。IP地址和端口可能会发生变化,但唯一的节点标识符在节点的整个生命周期内都不会改变。 我们简单地称这个标识符为节点ID。
四、使用创建群集脚本创建Redis群集
如果您不想通过如上所述手动配置和执行单个实例来创建Redis群集,则有一个更简单的系统可以代替以上操作(但您不会学到相同数量的操作细节)。
只需在Redis发行版中检查 utils/create-cluster 目录即可。 里面有一个名为create-cluster的脚本(与其包含的目录名称相同),它是一个简单的bash脚本。 要启动具有3个主站和3个从站的6个节点群集,只需输入以下命令:
1、create-cluster start
2、create-cluster create
当redis-trib实用程序希望您接受集群布局时,在步骤2中回复yes。
您现在可以与群集交互,默认情况下,第一个节点将从端口30001开始。 完成后,停止群集:
1、create-cluster stop.
请阅读此目录中的自述文件以获取有关如何运行脚本的更多信息。
五、测试故障转移
注意:在此测试期间,应该运行一致性测试应用程序时打开选项卡。
为了触发故障转移,我们可以做的最简单的事情(这也是分布式系统中可能发生的语义上最简单的故障)是使单个进程崩溃,在我们的当前的情况下就是单个主进程。
我们可以识别一个集群并使用以下命令将其崩溃:
$ redis-cli -p 7000 cluster nodes | grep master 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385482984082 0 connected 5960-10921 2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 master - 0 1385482983582 0 connected 11423-16383 97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422
好吧,7000,7001和7002都是主服务器节点。 让我们用 DEBUG SEGFAULT 命令使节点7002崩溃:
$ redis-cli -p 7002 debug segfault Error: Server closed the connection
现在我们可以看一致性测试的输出以查看它报告的内容。
18849 R (0 err) | 18849 W (0 err) | 23151 R (0 err) | 23151 W (0 err) | 27302 R (0 err) | 27302 W (0 err) | ... many error warnings here ... 29659 R (578 err) | 29660 W (577 err) | 33749 R (578 err) | 33750 W (577 err) | 37918 R (578 err) | 37919 W (577 err) | 42077 R (578 err) | 42078 W (577 err) |
正如您在故障转移期间所看到的,系统无法接受578次读取和577次写入,但是在数据库中未创建任何不一致。 这听起来可能会出乎意料,因为在本教程的第一部分中,我们声明Redis群集在故障转移期间可能会丢失写入,因为它使用异步复制。 我们没有说的是,这种情况不太可能发生,因为Redis会将答复发送给客户端,并将命令复制到从服务器,同时,因此会有一个非常小的窗口来丢失数据。 但是很难触发这一事实并不意味着这是不可能的,所以这不会改变Redis集群提供的一致性保证。
现在我们可以检查故障转移后的群集设置(注意,在此期间,我重新启动了崩溃的实例,以便它重新加入作为从属群集):
$ redis-cli -p 7000 cluster nodes 3fc783611028b1707fd65345e763befb36454d73 127.0.0.1:7004 slave 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 0 1385503418521 0 connected a211e242fc6b22a9427fed61285e85892fa04e08 127.0.0.1:7003 slave 97a3a64667477371c4479320d683e4c8db5858b1 0 1385503419023 0 connected 97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7005 master - 0 1385503419023 3 connected 11423-16383 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385503417005 0 connected 5960-10921 2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 slave 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 0 1385503418016 3 connected
现在,主服务器节点正在端口7000,7001和7002上运行。以前是主服务器节点,即运行在端口7005上的Redis实例,现在是7002的从服务器节点。
Node ID ip:port flags: master, slave, myself, fail, ... if it is a slave, the Node ID of the master Time of the last pending PING still waiting for a reply. Time of the last PONG received. Configuration epoch for this node (see the Cluster specification). Status of the link to this node. Slots served...
六、手动故障转移
有时,强制进行故障转移并不会在主服务器上导致任何问题。例如,为了升级其中一个主节点的Redis进程,最好将其故障转移,以便将其转变为一个对可用性影响最小的从服务器。
Redis Cluster使用CLUSTER FAILOVER命令支持手动故障转移,该命令必须在要故障转移的主服务器的一个从服务器上执行。
手动故障转移是比较特殊的,并且与实际主控故障导致的故障转移相比更安全,因为它们是以避免数据丢失的方式发生,只有在系统确定新主服务器节点处理完全部来自旧主服务器节点的复制流后才将客户从原始主服务器节点切换到新主服务器节点。
这是您在执行手动故障转移时在从服务器节点的日志中看到的内容:
#接受用户的手动故障转移请求。 #已暂停的主服务器手动故障转移接收复制的偏移量:347540 #处理所有主服务器节点的复制流,手动故障转移可以开始。 #选举开始延迟0毫秒(等级#0,偏移量347540)。 #为epoch 7545启动故障转移选举。 #故障转移选举胜出:我是新主人。 # Manual failover user request accepted. # Received replication offset for paused master manual failover: 347540 # All master replication stream processed, manual failover can start. # Start of election delayed for 0 milliseconds (rank #0, offset 347540). # Starting a failover election for epoch 7545. # Failover election won: I'm the new master.
基本上连接到我们正在故障转移的主服务器节点上的客户端都已停止工作。与此同时,主服务器节点将其复制偏移量发送给从服务器节点,该从服务器节点将等待达到其侧面的偏移量。当达到复制偏移量时,将启动故障转移,并向旧主服务器通知配置开关。 当旧主服务器节点上的客户端被解锁时,它们会被重定向到新主服务器。
七、总结
今天就写到这里了,关于Cluster的内容还没有写完,有关动态扩容的内容将在下一篇文章做详细介绍。这篇文章对很多东西没有做更细致的探讨,只是从用户的角度来简单说明一下如何搭建Redis的Cluster集群环境。革命尚未成功,我还需努力。我把原文的地址也贴出来,里面的内容不完全一样,我按着我的理解写的更详细了。地址如下:【Redis cluster tutorial】