【RedisCluster】
Redis集群提供了一种运行Redis安装的方式,其中数据 在多个Redis节点上自动分区。
Redis集群还在分区期间提供一定程度的可用性,即在实际情况下能够在某些节点发生故障或无法通信时继续运行。但是,如果发生较大故障(例如,大多数主站不可用),集群将停止运行。
那么从实际角度而言,您使用Redis Cluster获得了什么?
- 在多个节点之间自动分割数据集的能力。
- 在节点子集遇到故障或无法与群集其余部分通信时继续运行的能力。
【Redis cluster TCP端口】
每个Redis群集节点都需要打开两个TCP连接。用于服务客户端的普通Redis TCP端口(例如6379),以及通过将10000添加到数据端口而获得的端口,因此示例中为16379。
第二个高端口用于群集总线,即使用二进制协议的节点到节点通信通道。群集总线被节点用于故障检测,配置更新,故障转移授权等等。客户端不应该尝试与群集总线端口进行通信,而是始终使用正常的Redis命令端口,但请确保在防火墙中打开两个端口,否则Redis群集节点将无法通信。
命令端口和集群总线端口偏移是固定的,始终为10000。
请注意,为了让Redis群集正常工作,您需要为每个节点:
集群总线使用不同的二进制协议来进行节点到节点的数据交换,这更适合于使用少量的带宽和处理时间在节点之间交换信息。
第二个高端口用于群集总线,即使用二进制协议的节点到节点通信通道。群集总线被节点用于故障检测,配置更新,故障转移授权等等。客户端不应该尝试与群集总线端口进行通信,而是始终使用正常的Redis命令端口,但请确保在防火墙中打开两个端口,否则Redis群集节点将无法通信。
命令端口和集群总线端口偏移是固定的,始终为10000。
请注意,为了让Redis群集正常工作,您需要为每个节点:
- 用于与客户端进行通信的普通客户端通信端口(通常为6379)对所有需要到达集群的客户端以及所有其他集群节点(使用客户端端口进行密钥迁移)都是开放的。
- 集群总线端口(客户端端口+ 10000)必须可从所有其他集群节点访问。
集群总线使用不同的二进制协议来进行节点到节点的数据交换,这更适合于使用少量的带宽和处理时间在节点之间交换信息。
【Redis集群数据分片】
Redis集群不使用一致的散列,而是一种不同的分片形式,其中每个键在概念上都是我们所说的散列槽的一部分。
Redis集群中有16384个哈希槽,为了计算给定关键字的哈希槽,我们简单地取16384关键码的CRC16。
Redis集群中的每个节点负责哈希槽的一个子集,例如,您可能有一个具有3个节点的集群,其中:
因为将哈希槽从一个节点移动到另一个节点不需要停止操作,添加和移除节点或者改变节点占用的哈希槽的百分比不需要任何停机时间。
只要涉及单个命令执行(或整个事务或Lua脚本执行)的所有密钥都属于同一个散列槽,Redis群集就支持多个密钥操作。用户可以使用称为散列标签的概念强制多个键成为同一个散列槽的一部分。
Hash标签记录在Redis集群规范中,但要点在于,如果在一个关键字的{}括号内有一个子字符串,则只有字符串内部的内容被散列,例如this{foo}key,another{foo}key 并保证在同一个散列槽,并且可以在多个键作为参数的命令中一起使用。
Redis集群中有16384个哈希槽,为了计算给定关键字的哈希槽,我们简单地取16384关键码的CRC16。
Redis集群中的每个节点负责哈希槽的一个子集,例如,您可能有一个具有3个节点的集群,其中:
- 节点A包含从0到5500的散列槽。
- 节点B包含从5501到11000的散列槽。
- 节点C包含从11001到16383的散列槽。
因为将哈希槽从一个节点移动到另一个节点不需要停止操作,添加和移除节点或者改变节点占用的哈希槽的百分比不需要任何停机时间。
只要涉及单个命令执行(或整个事务或Lua脚本执行)的所有密钥都属于同一个散列槽,Redis群集就支持多个密钥操作。用户可以使用称为散列标签的概念强制多个键成为同一个散列槽的一部分。
Hash标签记录在Redis集群规范中,但要点在于,如果在一个关键字的{}括号内有一个子字符串,则只有字符串内部的内容被散列,例如this{foo}key,another{foo}key 并保证在同一个散列槽,并且可以在多个键作为参数的命令中一起使用。
【Redis 集群主从模型】
为了在主节点的子集失效或不能与大多数节点通信时保持可用,Redis集群使用主 - 从模型,其中每个散列槽从1(主设备本身)到N个副本(N -1个附加的从节点)。
在我们的具有节点A,B,C的示例集群中,如果节点B失败,则集群不能继续,因为我们不再有办法在5501-11000范围内服务哈希槽。
然而,当创建集群(或者以后)时,我们为每个主节点添加一个从节点,使得最终集群由作为主节点的A,B,C以及作为从节点的A1,B1,C1组成,如果节点B发生故障,系统能够继续运行。
节点B1复制B,并且B失败,则集群将促使节点B1作为新的主节点并且将继续正确地操作。
但请注意,如果节点B和B1在同一时间发生故障,则Redis群集无法继续运行。
在我们的具有节点A,B,C的示例集群中,如果节点B失败,则集群不能继续,因为我们不再有办法在5501-11000范围内服务哈希槽。
然而,当创建集群(或者以后)时,我们为每个主节点添加一个从节点,使得最终集群由作为主节点的A,B,C以及作为从节点的A1,B1,C1组成,如果节点B发生故障,系统能够继续运行。
节点B1复制B,并且B失败,则集群将促使节点B1作为新的主节点并且将继续正确地操作。
但请注意,如果节点B和B1在同一时间发生故障,则Redis群集无法继续运行。
【创建和使用Redis集群】
要创建一个集群,我们首先需要在集群模式下运行一些空的Redis实例。这基本上意味着群集不是使用普通的Redis实例创建的,因为需要配置特殊模式,以便Redis实例启用群集特定的功能和命令。
以下是最小的Redis集群配置文件:
以下是最小的Redis集群配置文件:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
正如你可以看到什么使集群模式是简单的cluster-enabled 指令。每个实例还包含存储此节点配置的文件路径,默认情况下为nodes.conf。这个文件不会被人类触及; 它仅在Redis集群实例启动时生成,每次需要时都会进行更新。
请注意,按预期工作的最小群集需要包含至少三个主节点。对于第一次测试,强烈建议使用三个主站和三个从站来启动六个节点群集。
为此,请输入一个新目录,并创建以下目录,该目录以我们将在任何给定目录内运行的实例的端口号命名。
就像是:
mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005
redis.conf在每个目录中创建一个文件,从7000到7005.作为配置文件的模板,只需使用上面的小例子,但要确保7000使用正确的端口号替换端口号根据目录名称。
现在将您的redis-server可执行文件(从GitHub的unstable分支中的最新源编译)复制到cluster-test目录中,最后在您最喜欢的终端应用程序中打开6个终端选项卡。
开始每个实例,每个选项卡:
cd 7000
../redis-server ./redis.conf
从每个实例的日志中可以看到,由于没有nodes.conf文件存在,每个节点都会为自己分配一个新的ID。
[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1
这个ID将被这个特定的实例永远使用,以便实例在集群上下文中具有唯一的名称。每个节点都会记住使用此ID的每个其他节点,而不是通过IP或端口。IP地址和端口可能会改变,但唯一的节点标识符永远不会改变节点的整个生命周期。我们简单地称这个标识符为节点ID。
【创建集群】
现在我们有很多实例在运行,我们需要通过向节点写入一些有意义的配置来创建我们的集群。
这很容易实现,因为我们得到了Redis Cluster命令行实用程序(称为redis-tribRuby程序)的帮助,该程序在实例上执行特殊命令以创建新群集,检查或重新映射现有群集等等。
该redis-trib实用程序位于srcRedis源代码分发的目录中。你需要安装redisgem才能运行redis-trib。
这很容易实现,因为我们得到了Redis Cluster命令行实用程序(称为redis-tribRuby程序)的帮助,该程序在实例上执行特殊命令以创建新群集,检查或重新映射现有群集等等。
该redis-trib实用程序位于srcRedis源代码分发的目录中。你需要安装redisgem才能运行redis-trib。
gem install redis
要创建群集,只需输入:
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
这里使用的命令是create,因为我们要创建一个新的集群。这个选项--replicas 1意味着我们需要为每个创建的主人创建一个从属。其他参数是我想用来创建新集群的实例的地址列表。
显然,我们要求的唯一设置是创建一个具有3个主站和3个从站的集群。
Redis-trib会为你提供一个配置。通过输入yes来接受建议的配置。集群将被配置和加入,这意味着,实例将被引导到彼此交谈。最后,如果一切顺利的话,你会看到这样的消息:
[OK] All 16384 slots covered
这意味着至少有一个主实例为16384个可用的插槽提供服务。