翻译自redis官方网站Redis集群教程。
本文是对Redis Cluster的简单介绍(你个杀千刀的简单介绍,说的东西真TM多,累死人了),没有引入复杂的分布式系统的概念。文章中介绍了一些配置、测试、操作cluster用到的指令,从用户角度描述了系统行为,没有涉及到Redis集群规范(Redis Cluster Specification)中的细节。
然而文章依然以一种易于理解的方式,为最终用户提供了一些关于可用性、一致性的信息。
注意:Redis Cluster要求3.0以上版本。
如果你想部署一个真正意义上的Redis集群,即便是一个不太严格的集群,建议你去看一下更正规的Redis集群规范(Redis Cluster Specification)。但是,在去读规范之前,先从这文章开始熟悉一下也是极好的。(哈哈,娘娘附体思密达)
Redis提供一种安装的时候配置集群的方式,数据可以在多个节点之间自动分片。
Redis集群能够在分区中提供了一定程度上的可用性,这是通过当节点死掉或者丢掉连接时操作依然能够继续来实现的。但是,当大多数主节点都失去连接是,集群会停止操作。
所以,你想从Redis集群身上得到些啥?
每个Redis集群节点要求打开两个TCP连接。常规的6379端口用来为客户端服务,常规端口 +1000 的那个端口16379用来作为数据端口。
第二个端口用作集群bus,一个使用二进制的节点到节点的通信通道。节注点通过集群bus来实现失败监测、更改配置、failover授权等。我们需要保证防火墙打开了这两个端口,否则会导致节点无法通信。
两个端口的差是固定的,1000。
集群中的每个节点都会按照你的要求工作:
- 常规客户端端口(6379)向所有客户端开放,也会对所有的其他节点开放(用于键迁移)。
- 集群bus端口向其他所有节点开放。
如果其中有一个端口没打开,集群都不能正常工作。
集群使用不同的二进制协议实现节点数据交换,这种协议更适用于节点间小带宽、短时间内交换信息。
目前Redis集群不支持NAT环境,也不支持正常环境中重新映射过的ip地址和端口。
Docker使用一种叫做端口映射的技术:Docker暴漏给运行在Docker容器内部的程序一个端口,但是这个端口跟程序认为正在使用的端口并不是同一个端口。这个技术允许多个容器在同一时间、同一台server中使用同一个端口。
我们需要使用的Docker的host networking mode来兼容Redis集群。详情查看Docker文档--net=host
。
Redis集群使用我们称之为hash slot的东西来分配,而不是一致性hash算法。
Redis集群中16384个slot,一个key属于那个slot我们用 CRC16(key)16384 来算。
Redis集群中的每个节点都负责hash slots的一个子集,比方说一个集群中有三个节点:
从一个节点往另外一个节点移动hash slot不需要停止操作, 所以添加、删除节点,或者更改每个节点拥有hash slots的比例,不会造成集群停机。
当一个命令、一个事务或者一个Lua脚本中牵扯到多个key时,Redis集群会认为所有的key属于一个hash slot。用户使用hash tag
强制多个key作为hash slot的一部分。
has tag
在Redis集群规范中有介绍。大体的意思是如果一个key中有子字符串呗{}包裹,{}包裹的部分才会被hash,栗子又来了,this{foo}key
, another{foo}key
,会被保证属于同一个hash slot,也能在使用多个key作为参数的命令中一块使用(好拗口)。
当主节点无法与大部分从节点连接时,为了保持可用性,Redis集群使用主从模式,这样每个hash slot都会有1-N个复制(有N-1个从节点)。
在我们的栗子中,如果我们三个节点A、B、C中的B节点失去连接,他所拥有的5501-11000的hash slot将会失去支持。
当创建集群后,我们给A、B、C三个节点都添加一个从节点,那A、B、C会变成三个主节点,A1、B1、C1为从节点。B节点挂掉,对集群没有影响。
节点B1复制B,B节点down掉,集群投票B1作为新的主节点,继续正常操作。
如果B、B1同时挂掉,集群还是不能继续工作。